11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 7. Common Dialog Boxes<br />

7.9 Modeless Common Dialog Boxes<br />

Tricks<br />

It is difficult to implement modeless common dialog boxes. This is because all the common dialog<br />

boxes are designed to work in the modal style. Therefore, if we call function Create(…) instead of<br />

DoModal(), although the dialog box will pop up, it will not behave like a common dialog box. This is<br />

because function Create(…) is not overridden in a class such as CColorDialog, CFontDialog.<br />

We need to play some tricks in order to implement modeless common dialog boxes. By looking at the<br />

source code of <strong>MFC</strong>, we can find that within function CColorDialog::DoModal() or CFontDialog::<br />

DoModal(), the base class version of DoModal() is not called. Instead, API functions ::ChooseColor(…)and<br />

::ChooseFont(…) are used to implement common dialog boxes.<br />

There is no difference between the common dialog boxes implemented by API functions and <strong>MFC</strong><br />

classes. Actually, using API function is fairly simple. For example, if we want to implement a color dialog<br />

box, we can first prepare a CHOOSECOLOR object, then use it to call function ::ChooseColor(…). But here we<br />

must initialize every member of CHOOSECOLOR in order to let the dialog box have appropriate styles.<br />

By using this method we can still create only modal common dialog boxes. A “modeless” common<br />

dialog box can be implemented by using the following method:<br />

1) Before creating the common dialog box, first implement a non-visible modeless window.<br />

1) Create the modal common dialog box, use the modeless window as its parent.<br />

Although the common dialog box is modal, its parent window is modeless. So actually we can switch<br />

away from the common dialog box (and its parent window) without closing it. Because the common dialog<br />

box’s parent is invisible, this gives the user an impression that the common dialog box is modeless.<br />

But if we call function DoModal() to implement the common dialog box, we are not allowed to switch<br />

away even it has a modeless parent window. We must call API functions to create this type of common<br />

dialog boxes.<br />

Hook Function<br />

We can provide hook function when implementing common dialog boxes using API functions. In<br />

Windows programming, a hook function is used to intercept messages sent to a window, thus by handling<br />

these messages we can customize a window’s behavior. Both structure CHOOSEFONT and CHOOSECOLOR have<br />

a member lpfnHook that can be used to store a hook function’s address when the common dialog box is<br />

being implemented. If a valid hook function is provided, when a message is sent to the dialog box, the hook<br />

function will be called first to process the message. To enable hook function, we also need to set<br />

CF_ENABLEHOOK or CC_ENABLEHOOK bit for member Flags of structure CHOOSEFONT or CHOOSECOLOR. If the<br />

message is not processed in the hook function, the dialog’s default behavior will not change.<br />

A hook procedure usually looks like the following:<br />

……<br />

……<br />

UINT APIENTRY HookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)<br />

{<br />

switch(uiMsg)<br />

{<br />

case WM_INITDIALOG:<br />

{<br />

}<br />

}<br />

}<br />

break;<br />

The first parameter is the handle of the destination window where the message is being sent. The<br />

second parameter specifies the type of message. The third and fourth parameters are WPARAM and LPARAM<br />

parameters of the message respectively. For different events, the messages sent to this procedure are<br />

193

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!