在我的应用程序中侦听 MessageBox 和 Dialog 结果

发布于 2024-10-15 04:46:40 字数 974 浏览 6 评论 0原文

我有一个“ControlMonitor”类,旨在监听表单上发生的事件。它的工作方式是,我将要监视的表单传递到此类的实例中,然后该类迭代所有表单的控件并注册其“相关”事件。例如,如果控件是 TextBox,我会注册 TextChanged。如果控件是 ComboBox,我会注册 SelectedIndexChanged 和 TextChanged,依此类推。通过这种方式,“ControlMonitor”实例能够报告用户在我的表单中执行的每个重要操作,同时对表单代码本身的干扰最小。

它非常适合报告表单中的任何控件,但我还需要知道表单启动了哪些常见对话框/消息框以及用户如何响应它们。我应该提到,这里更大的目标是自动化:我们希望最终得到一组可重复的步骤,这些步骤可以编写成在自动化工具中播放的脚本。为此,仅仅知道用户单击了“文件/打开”是不够的;还需要知道用户单击了“文件/打开”。我们还需要知道启动的 OpenFileDialog 的窗口标题、用户选择的路径和 DialogResult。 MessageBox 调用也是如此;我们需要知道窗口标题和DialogResult。

常见的对话框似乎对事件的支持很少(FolderBrowserDialog 显然根本没有任何事件),而且我什至不确定在侦听 MessageBox 调用的结果时从哪里开始。当然,我可以编写一个包装类来封装常见的对话框和 MessageBox 调用,并将结果传递给“ControlMonitor”实例...但是程序的其余部分将必须始终使用此包装类,并且主要的我的“ControlMonitor”类的目标是您可以将其包含在项目中并监听其中一种表单,同时对原始代码的干扰最小。

在“ControlMonitor”类中我可以做些什么吗?我需要所有对话框/消息框的 DialogResults 和窗口标题,对于像 OpenFileDialog 这样的更复杂的对话框,我还需要知道用户选择的路径等。“ControlMonitor”类是它试图监听的程序的编译部分到,因此它可以直接访问传递给它的 Form 对象。我离这里很近;我可以监视 95% 的应用程序,因为其中大部分只是表单上的控件...我也只需要一种方法来监视对话框!

I have a "ControlMonitor" class which is designed to listen to the events that occur on a form. The way it works is, I pass the form that I want to monitor into an instance of this class, and then the class iterates through all of the form's controls and registers for their "relevant" events. For example, if the control is a TextBox, I register for TextChanged. If the control's a ComboBox, I register for both SelectedIndexChanged and TextChanged, and so on. In this way, the "ControlMonitor" instance is able to report on every significant action the user took in my form, with a minimal amount of intrusiveness to the form code itself.

It works great for reporting on any controls in the form, but I also need to know which common dialogs/message boxes were launched by the form and how the user responded to them. I should mention that the larger objective here is automation: we want to end up with a set of repeatable steps that can be scripted into something that plays back in an automation tool. To that end, it's not enough to know that the user clicked "File/Open"; we also need to know the window title of the OpenFileDialog that was launched, the path that the user selected and the DialogResult. The same goes for MessageBox calls; we need to know the window title and DialogResult.

The common dialogs seem to have minimal support for events (the FolderBrowserDialog apparently doesn't any events at all), and I'm not even sure where to start when it comes to listening for the results of a MessageBox call. Of course, I could write a wrapper class that encapsulates common dialogs and MessageBox calls and passes the results to a "ControlMonitor" instance... but then the rest of the program would have to use this wrapper class all the time, and a primary objective with my "ControlMonitor" class is that you can include it in a project and listen in on one of the forms with minimal intrusion to the original code.

Is there anything I can do within the "ControlMonitor" class? I need DialogResults and window titles for all dialogs/message boxes, and for more complex dialogs like OpenFileDialog I also need to know the path the user selected, etc. The "ControlMonitor" class is a compiled part of the program that it's trying to listen to, so it has direct access to the Form object that is passed into it. I'm so close here; I can monitor 95% of the application because most of it is just controls on a form... I just need a way to monitor the dialogs, too!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

咿呀咿呀哟 2024-10-22 04:46:40

我知道这可能需要对您的应用程序进行相当大的更改,但是为什么不采用松散耦合的事件代理设计呢?这将使您在处理事件时更加灵活。

Microsoft 发布的复合 UI 应用程序块有一个示例事件代理,但自己编写也不费什么力气。这个想法的要点是你有一个中央代理,你的控件可以向其发布事件。然后任何其他类都可以订阅这些事件中的任何一个。这使得事件发布/订阅松散耦合,并消除了不同控件之间的强依赖性。

I know that it might require rather big changes your application, however why not go with an event broker design that is loosely coupled instead? It will give you more flexibility on how to deal with the events.

The Composite UI Application Block that Microsoft has released has a sample event broker, but it is also not much effort to write your own. The gist of the idea is that you have a central broker that your controls publish events to. It is then possible for any other class to subscribe to any of these events. This makes the events publishing / subscribing loosely coupled and removes the strong dependencies between different controls.

酒中人 2024-10-22 04:46:40

我通过为 MessageBox.Show() 调用创建一个包装函数,然后将应用程序中的所有调用替换为该函数,解决了类似的问题。

类似于:

Public Function My_MessageBox(ByVal pstrMsg As String, _
    Optional ByVal pstrCaption As String = "", _
    Optional ByVal pButtons As Windows.Forms.MessageBoxButtons = MessageBoxButtons.OK, _
    Optional ByVal pIcon As Windows.Forms.MessageBoxIcon = MessageBoxIcon.None, _
    Optional ByVal pDefButton As Windows.Forms.MessageBoxDefaultButton = MessageBoxDefaultButton.Button1) _
    As Windows.Forms.DialogResult

    Dim rval As Windows.Forms.DialogResult

    If glAutomated Then
        ' if automation is running, we don't want to show 
        ' the box to the user, just retrieve the result stored
        rval = AutomateThisMessageBox("MsgBox" & pstrCaption.Replace(" ", ""))
    Else
        rval = MessageBox.Show(pstrMsg, pstrCaption, pButtons, pIcon, pDefButton)

        If glRecording Then 'Only record the result when in "record" mode
            Hooks.RecordMessageBox(pstrCaption.Replace(" ", ""), rval.ToString)
        End If
    End If

    Return rval

End Function

用法:与当前使用的 Messagebox.Show 完全相同,只需替换为新函数名称
例如:

MessageBox.Show("This is a test", "Test Msg", 
    MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, 
    MessageBoxDefaultButton.Button1)

变成

My_MessageBox("This is a test", "Test Msg", 
    MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, 
    MessageBoxDefaultButton.Button1)

编辑:

只需重新阅读有关所有不同对话框的问题的结尾。我猜想在一般意义上可以使用类似的技术。或者您需要的所有对话框的不同包装器(文件打开/等)

I solved a similar problem by just creating a wrapper function for the MessageBox.Show() calls, then replacing all of the calls in our app to this function.

something akin to:

Public Function My_MessageBox(ByVal pstrMsg As String, _
    Optional ByVal pstrCaption As String = "", _
    Optional ByVal pButtons As Windows.Forms.MessageBoxButtons = MessageBoxButtons.OK, _
    Optional ByVal pIcon As Windows.Forms.MessageBoxIcon = MessageBoxIcon.None, _
    Optional ByVal pDefButton As Windows.Forms.MessageBoxDefaultButton = MessageBoxDefaultButton.Button1) _
    As Windows.Forms.DialogResult

    Dim rval As Windows.Forms.DialogResult

    If glAutomated Then
        ' if automation is running, we don't want to show 
        ' the box to the user, just retrieve the result stored
        rval = AutomateThisMessageBox("MsgBox" & pstrCaption.Replace(" ", ""))
    Else
        rval = MessageBox.Show(pstrMsg, pstrCaption, pButtons, pIcon, pDefButton)

        If glRecording Then 'Only record the result when in "record" mode
            Hooks.RecordMessageBox(pstrCaption.Replace(" ", ""), rval.ToString)
        End If
    End If

    Return rval

End Function

Usage: exactly the same as Messagebox.Show is currently used, just substitute in the new function Name
eg:

MessageBox.Show("This is a test", "Test Msg", 
    MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, 
    MessageBoxDefaultButton.Button1)

becomes

My_MessageBox("This is a test", "Test Msg", 
    MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, 
    MessageBoxDefaultButton.Button1)

Edit:

Just re-read the end of your question about all the different dialogs. I'm guessing a similar technique could be used in a general sense. Or different wrappers for all the dialogs you need (file open/etc)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文