Listening to MessageBox and Dialog messages in my application

I have a ControlMonitor class that is designed to listen for events happening on the form. How it works, I pass the form that I want to control into an instance of this class, and then the class iterates through all the form controls and registers for its โ€œrelevantโ€ events. For example, if the control is a TextBox, I register for TextChanged. If the control is ComboBox, I register for SelectedIndexChanged, TextChanged and so on. Thus, an instance of "ControlMonitor" is able to report every significant action that the user has taken in my form, with a minimum amount of obsession with the form code itself.

It is great for reporting any controls on the form, but I also need to know what common dialogs / message boxes the form launched and how the user responded to them. I should mention that the main task here is automation: we want a set of repeatable steps that can be written into something that is reproduced in the automation tool. To do this, it is not enough to know that the user clicked "File / Open"; we also need to know the title of the OpenFileDialog launch window, the path that the user has chosen, and DialogResult. The same goes for MessageBox calls; we need to know the window title and DialogResult.

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

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

+4
source share
2 answers

I know that this may require quite large changes in your application, but why not go with an event brokerage design that is loosely connected instead? This will give you more flexibility on how to deal with events.

The Composite UI application block released by Microsoft has an exemplary event broker, but also not much effort to write your own. The bottom line is that you have a central broker in which your controls post events. Then any other class can subscribe to any of these events. This makes publishing / subscribing events loosely coupled and eliminates strong dependencies between different controls.

+1
source

I solved a similar problem by simply creating a wrapper function for the MessageBox.Show () calls, and then replacing all the calls in our application with this function.

something like:

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: just like Messagebox.Show is currently in use, just replace Name in the new function, for example:

 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 suggest that a similar technique can be used in a general sense. Or various wrappers for all the dialogs you need (open the / etc file)

0
source

Source: https://habr.com/ru/post/1337955/


All Articles