This class modifies the regular message_tap
to make it suitable for dialog boxes which
use Windows’ dialog box mechanism. That is, you can use this to handle messages from
dialog boxes which use the Win32 DialogBox and CreateDialog functions,
or with property sheet pages, all of which are characterised by:
DialogProc rather than a WinProc.
IsDialogMessage for that window
So, if you have a dialog box designed using a template, or want to create a page for a property sheet, this class will handle the details and allow you to write the “dialog proc” as a member function of an object.
Read about:
A Modeless dialog box is the simplest case. This is essentially like any other window, so all that is necessary is to hide the differences that the Windows API imposes on you.
The program message_tap_demo.cxx contains a class testhook_2 which shows how
to use the Dialog_message_tap. The basic steps are:
Dialog_message_tap.
handle_message member function.
on_attach member function, if needed.
ModelessDialogBox.
The Dialog_message_tap class is intended to be used as a base class. Instances of your concrete class
are bound 1:1 to Windows dialog boxes. You supply virtual function overrides to make it do what you want of
the dialog box.
handle_message functionWhere the Win32 API uses a supplied DialogProc callback function, you use the
handle_message
virtual member function of the object bound to the on-screen window. This is inherited from the
regular message_tap class, and is used with no difference.
In the example program, a WM_COMMAND message is handled. It illustrates basic interaction with
some common controls. See the sMSG class and message casts for a discussion on how the
message is “cracked” based on the actual message type.
on_attach functionThis function is called as soon as the actual on-screen window handle has been created. In this function, you can obtain the child control window information, and do any run-time customization of the dialog box. In this example, it hides the OK Button if used as a Modal dialog box. The same code and dialog template is used for both modal and modeless dialog boxes, and here is where it can accomidate the slight differences.
Like the message_tap class, your concrete instance will be tracked using smart pointers and will be “owned” by the on-screen window itself. So, there is no need to keep a pointer to this object if you don’t otherwise need one. It will be destroyed when the window is closed, so the instance will not be a memory leak. But, being a smart pointer, if you do maintain a pointer to the instance you may use it to get values out after the window has closed, as it will not have been destructed yet.
It is important to note that instances of your class, derived from Dialog_message_tap, must be
created on the heap using new, not defined as whole objects on the stack or elsewhere.
The code in testhook_1::on_attach (the set-up code for the application’s main window) creates a
modeless dialog box.
//member declared as: classics::handle<testhook_2> dialogbox; dialogbox= new testhook_2 (classics::baro<testhook_1>(this)); // this is a smart pointer handle. dialogbox->ModelessDialogBox (ratwin::util::get_Instance(), "SampleDialog", window_handle());
The constructor for testhook_2 takes a baro-style (that is, un-owned) smart
pointer to the parent window. The testhook_1 object (the main app window) also wants to keep
track of the modeless dialog box, so it remembers this as a smart pointer in its member data.
ModelessDialogBoxOnce the object is created, the code calls ModelessDialogBox. This is modeled after the Win32
primitive CreateDialog. It takes parameters for HINSTANCE in which to find resources,
the name of the dialog template resource, and optionally the HWND of a parent window. Missing is a
parameter for the DialogProc, since that is handled by the implicit this parameter.
Now the on-screen window exists and will interact with this object instance. The object’s smart pointer
and the Windows HWND may he handled in the same manner as with a regular message_tap
object.
It is important that the message pump in the program do the right thing for a dialog box. This is the
case for any Windows program that uses CreateDialog. You could use the dialog box’s HWND
with IsDialog in the traditional way. But, Tomahawk will handle it automatically with its
simple_message_pump class.
This explains what is different from the example of the Modeless Dialog Box, above. The same example class handles all the different ways to run the dialog box.
A modal dialog box is somewhat different from a normal window. Normally when creating a window, the call to create returns right away and you have a new handle. The program will send events to that window along with all the others, and the code that called create continues on its way.
A modal dialog box is more like a function call. It does not return until the user dismisses the window, and it returns a value reflecting what the user chose.
The Dialog_message_tap supports a
ModalDialogBox function which wraps the Win32 primitive
DialogBox. The class takes care of the details, and your virtual functions get called just like with
the modeless case.
However, the code within the modal dialog must at some point call
EndDialog. This is
wrapped as a member function of Dialog_message_tap. In the example code, you can see it is
called in responce to clicking the OK button.
The code that calls
ModalDialogBox creates a local variable popup that is a smart
pointer to an instance, creates an instance, and then calls popup->ModalDialogBox. It notes the return
value, and then simply allows popup to go out of scope.
The property page is more complex to demonstrate, not because this class is any more difficult to use in that case, but because it needs to put the resulting page into a sheet and run that sheet, things which are unrelated to this class. This class takes care of the single page in exactly the same manner as a dialog box.
Within the demo_prop_page function in the example code, you can see it call
CreatePropertySheetPage
on the instance. This is modeled after the Win32 primitive by the same name, and the result is used
in the same way as well.