Introduction
This article describes a scarcely documented feature of Pocket PC 2002 property sheets: how to include a title and a footer with link. Both title and footer will be present in all pages of the property sheet. This article also shows how to hide the application menu bar, like a standard CDialog
.
Callbacks
Both titles and footers are implemented through a callback function present in all MFC handled property sheets, through CPropertySheet
. The callback function address is stored in the pfnCallback
member of the PROPSHEETHEADER
structure stored in CPropertySheet
's m_psh
member. When you create a property sheet, MFC will fill in this pointer with the address of its own handler, AfxPropSheetCallback
. This callback handles the PSCB_INITIALIZED
and PSCB_GETVERSION
messages. This is needed in order to put the tabs in the bottom, and to report which version of the controls, the property sheet is using. But we can do more with this callback: we can use it to insert a title and a footer, just like the property sheet in the demo project (see picture).
In order to access these functionalities, we must handle the PSCB_GETTITLE
and PSCB_GETLINKTEXT
messages in the callback. The problem is that MFC has already provided one callback for the property sheet, so how can we provide our own callback function? The answer is very simple: we hook it.
CCePropertySheet
All the relevant code is in the CCePropertySheet
class. This class derives from MFC's CPropertySheet
, and specializes its functionality in the following aspects:
- Provides a standard
CCeCommandBar
;
- Inserts a caption taken from the constructor parameters;
- Allows the user to insert a footer with an optional link.
Using CCePropertySheet
Using the class is very straightforward:
CLinkSheet dlg(_T("Link"));
dlg.SetLink(_T("Start <file:pword.exe{Word}>"));
dlg.DoModal();
The first line declares the object (derived from CCePropertySheet
). The second line sets the footer link text. Finally, the dialog is called.
Implementing CCePropertySheet
The class is not complex, as you can see from the source code.
The first thing we have to do is hook the callback function (see HookCallback
). This function is called from the constructors, where we store the sheet's caption in a static CString
. When HookCallback
is called, MFC has already stored its own callback function pointer in m_psh.pfnCallback
. The pointer is stored in a static member, and is replaced by the class' own callback.
Serving the callback is quite straightforward. The title and link messages are checked for and served. The MFC callback is always called to handle the message, so we retain all the functionality we already know. Serving the messages means copying the specific strings to the address given by lParam
.
Finally, the OnInitDialog
handler is used to create an empty CCeCommandBar
. Besides hiding the application's command bar, this can be used as a regular command bar, meaning you can insert menus and buttons.
Note that both m_strLink
and m_strTitle
are static member variables. This is required because they are both referenced by the callback function that must be static itself (will not receive the implicit this
in the parameter list). Also, note that these variables are only accessed once, during the property sheet creation cycle. If you need to create a second property sheet as a result of a command issued by the first, you can be sure that the overridden string values will have no effect on the first property sheet.
Thanks
I work on R&D for Frotcom International, a company that develops web-based fleet management solutions.