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.
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