IntroductionThis class enables you to have a dialog where the user can dynamically switch between modeless and modal behaviour by toggling its "pinned" state. This is similar to the Properties dialog in Developer Studio where you can display the properties of one file or class, pin the dialog and then select another file or class and see its properties displayed automatically in the properties dialog. This feature was simpler to implement than I thought it was going to be. Essentially, a pinnable dialog is a modeless dialog. When the dialog is unpinned (i.e., when it is to behave as a modal type dialog) it is hidden whenever it loses focus. When the dialog is pinned, it behaves as a standard modeless dialog.
The CPinnableDialog base class handles the switching between the pinned and unpinned states. You just derive your dialog class from CPinnableDialog and create an instance of it in the parent window or frame class and then hide and show it as appropriate. The pinnable dialog sends a message to the parent window when it is to close. The pinned state simply dictates whether it closes when it is deactivated. The class allows the developer to dictate whether a deactivation closure is treated as a cancel or as if the Ok button was pressed.
The CPinnableDialog class uses the dialog's icon in the top left hand corner to display the pin rather than using a bitmapped button as Developer Studio does. I think this looks a lot neater and allows the dialog's client area to be completely utilised. When the dialog is closed it sends a user-defined WM_PINUPCLOSE message to the parent window. Usually the parent handles this message by simply hiding the dialog. The parent window can also determined how the dialog was closed (for example, whether the Ok or Cancel buttons were pressed) so that it can retrieve any values which have been edited by the user and validate them if necessary before allowing the dialog to close.
To implement this behaviour in one of your own dialogs, follow these steps :-
- Create your dialog resource as normal and get Class Wizard to generate a dialog class and data members for you. The dialog should have the "Title Bar" and "System Menu" styles enabled.
- Add two icons to your project's resources, one for the pinned state and one for the unpinned state. I "borrowed" the ones from Developer Studio!
- Change the base class of the dialog to CPinnableDialog. Make sure you change all occurrence of CDialog to CPinnableDialog, especially in the BEGIN_MESSAGE_MAP macro block.
- When you call the CPinnableDialog's constructor, pass the resource IDs for the dialog template and the two icons as well as the parent CWnd pointer.
- Add a public function to your dialog class which can be called to set the dialog's contents when it is to be shown.
- In the parent window class, add a data member to hold a pointer to your dialog class. In the constructor, create a new dialog object using new and in the destructor delete it.
- Add a message handler to the parent window class to handle the WM_PINUPCLOSE message which the dialog will send when it is to be closed. In the handler, call the dialog's Hide function.
- Whenever you want to display the dialog, set the dialog's data (using the function you added above) and call its Show function.
Whenever you might want to
update the data that the dialog is displaying (for example, when the user selects another item), check to see if the dialog is visible (i.e., it is pinned) and if it is, call your refresh function.
The Sample ProjectI have included a sample project which illustrates how the CPinnableDialog class can be used. It is a very simple dialog-based application which displays a list of interfaces implemented by a typical ActiveX control. The user can display the properties of any particular interface by either double clicking on its entry in the list box or by selecting Properties from the context menu. Once the properties dialog is displayed, the user can pin it and select another interface to see its properties automatically displayed. The name and description fields are read-only but the user can toggle the implemented flag.
DownloadsDownload demo project - 19 Kb
Download source - 3 Kb