HomeQuestions and AnswersArticlesSamplesLibrariesForumsNewsLinks

WTL Extension library for Smartphone

By Ilya Manin, March 17, 2004.

Download

Introduction

Smartphone UI concepts are different from desktop Windows UI concepts. For example, all topmost windows must be in full screen mode and many dialogs must have a menu bar at bottom of screen. It may take much effort to implement these Smartphone-specific elements in a WTL project. To simplify this task we have developed WtlEx library. For now it includes classes to work with dialogs and property sheets. We expect to add more useful classes in the fufure. The library requires WTL 7.1, which you can download from Microsoft site.

Library Contents

  • CFakeDialogImpl is similar to CDialogImpl from WTL, but doesn't require a dialog resource. Complex dialogs are very rarely used on Smartphone. Often you need to create a dialog with one control (for example List View or Tree View). CFakeDialogImpl class enables to use fully functional dialog box without creating a new resource. This class doesn't have a Smartphone OS specific and can be use on other Win32 platforms.
  • CSPDialogExt is a basic class of WtlEx library. The class provides support for menu bar creating, bold font for static controls, handling of hardware key VK_TBACK in edit controls and many other functions for Smartphone style dialogs.
  • CSPDialogAuto, This class is a specialization of CSPDialogExt. It sets frequently used parameters for CSPDialogExt.
  • CSPSimpleDialog is similar to CSimpleDialog from WTL, but includes all additional functionality of CSPDialogExt class.
  • CSPPropertySheet and CSPPropertyPageImpl classes are similar to CPropertyPage and CPropertySheet from WTL or MFC. These classes enable to create property sheets in Smartphone style (property sheet shows a list of available pages and the user can invoke any page by selecting it in the list and hitting action or using page number key).
  • CSPSimplePropertyPage is similar to CSPSimpleDialog, but can be used with CSPPropertySheet to create a property page without inheriting a new class for it.
  • CSPListViewCtrl. This class has been published in "Creating list view a-la "Programs" list on Smartphone 2002" article. This version of the class was changed for correct use in dialogs. Also, this version of CSPListViewCtrl class supports pages navigation. The WtlEx library uses this class for internal purposes but you can use it in your own dialogs or windows.

How to use

First of all, to use this library you need to include WtlEx.rc file in your resource script. Select "View\Resource Includes:" menu and write include path to WtlEx.rc file in "Compile-time directives" field (Example "#include "..\WtlEx\WtlEx.rc"").

CFakeDialogImpl

Usage of this class is very similar to usage of CDialogImpl class, but you don't need to define a dialog resource identifier (IDD class member constant) in inherited class. Don't forget to create your own controls in WM_INITDIALOG handler. The following code shows how to use CFakeDialogImpl class:

class CFakeDialogDemo : public CFakeDialogImpl<CFakeDialogDemo>
{
public:
	//We can set a title for our dialog in CFakeDialogImpl class constructor
	CFakeDialogDemo(): CFakeDialogImpl<CFakeDialogDemo>(_T("My Dialog Caption")) {}

	BEGIN_MSG_MAP(CFakeDialogDemo)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_ID_HANDLER(IDOK, OnCloseCmd)
		COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		RECT rt = {10, 10, 150, 150};
		//Create a static control 
		CStatic wnd;
		wnd.Create(*this, &rt, _T("This is demonstration dialog without resources"), 
			WS_VISIBLE|WS_CHILD|SS_CENTER);
		return TRUE;
	}
	LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		//Close the dialog by IDOK or IDCANCEL commands
		EndDialog(wID);
		return 0;
	}
};
	

CSPDialogExt

This is a "Mix In" class. To use this class include it in the list of base classes and chain its message map to the message map of your class (by CHAIN_MSG_MAP macro - it must be the first entry in the message map of your class). Example:

class CMyDlg :	public CDialogImpl<CMyDlg>,
		public CSPDialogExt<CMyDlg>
... 
	BEGIN_MSG_MAP(CMyDlg)
		CHAIN_MSG_MAP(CSPDialogExt<CMyDlg>)
		...
	END_MSG_MAP()
	

It is very important to keep in mind that the class intercepts the WM_INITDIALOG message. Your class will not be able to process this message, instead of this the class CSPDialogExt will call BOOL OnInitDialog(LPARAM lParam) method. It is recommended to override this method in your own classes and use it instead of handling WM_INITDIALOG directly. Also you can not process the WM_COMMAND messages for common IDOK and IDCANCEL command identifiers. The class automatically processes these messages and calls BOOL OnOK() method for IDOK and BOOL OnCancel() for IDCANCEL. You can override these methods to perform additional operations. These methods of CSPDialogExt class simply close a modal dialog. For example, dialog declaration from the first example, when using CSPDialogExt class, will look like this:

class CFakeDialogDemo : public CFakeDialogImpl<CFakeDialogDemo>,
				 public CSPDialogExt<CFakeDialogDemo>
{
public:
	CFakeDialogDemo(): CFakeDialogImpl<CFakeDialogDemo>(_T("My Dialog Caption")) {}
	typedef CSPDialogExt<CFakeDialogDemo> _baseSPClass;

	BEGIN_MSG_MAP(CFakeDialogDemo)
		CHAIN_MSG_MAP(_baseSPClass)
	END_MSG_MAP()

	BOOL OnInitDialog(LPARAM lParam)
	{	
		RECT rt;
		CStatic wnd;
		GetClientRect(&rt);
		wnd.Create(*this, &rt, _T("This is a demonstration dialog without 
                       resources"), 
			WS_VISIBLE|WS_CHILD|SS_CENTER);
		return TRUE;
	}
	BOOL OnOK()
	{
		if ( IDYES == MessageBox(_T("Are you sure you want to close the dialog?"), 
					_T("Fake dialog 2"),  MB_YESNO) )
		{
			//For close a dialog call the base method 
			_baseSPClass::OnOK();
		}
		return FALSE;
	}
};
	

Note that we can call GetClientRect from OnInitDialog method, and that function will return real size of dialog's client area because CSPDialogExt already positioned the dialog correctly in its WM_INITDIALOG handler.

By default, CSPDialogExt class performs the following actions:

  • Creates normal (m_hDlgFont) and bold (m_hBoldFont) fonts which you can assign to your controls or use SetFontToAllControls method to automatically set a new font to all child windows of your dialog. These fonts are recreated each time WM_SETFONT message is received.
  • Removes WS_EX_DLGMODALFRAME style from a dialog window (to create dialog without border)
  • Calls SHInitDialog in WM_INITDIALOG handler before OnInitDialog method is called (to make the dialog full screen)
  • Automatically processes WM_COMMAND messages for the common message identifiers (IDOK and IDCANCEL)

Besides that, you can pass the following flags to CSPDailogExt class as a second template parameter:

  • FSPDE_STATICBOLD. After a call to OnInitDialog method the class assigns bold font to all static controls in the dialog. This operation is also performed when the current font of the dialog is changed (while processing a WM_SETFONT message).
  • FSPDE_HBACK. Removes the default handling of back key (VK_TBACK) messages from menu bar. Instead, these messages are always redirected back to control with focus (by using SHSendBackToFocusWindow function).
  • FSPDE_HBACKAUTO. This flag is similar to FSPDE_HBACK, but VK_TBACK key presses are redirected to edit boxes (controls with "edit" or "capedit" windows class) only. This enables back key to work as a backspace in edit boxes while preserving common back key functionality.
  • FSPDE_SCROLL. Assigns WS_VSCROLL style to dialog.
  • CSPDialogExt class

Here is how these additional styles are used:

class CMyDlg : public CDialogImpl<CMyDlg>,
		public CSPDialogExt<CMyDlg, FSPDE_STATICBOLD | FSPDE_HBACKAUTO | 
								FSPDE_SCROLL>
. . . 
	typedef CSPDialogExt<CMyDlg, FSPDE_STATICBOLD | FSPDE_HBACKAUTO | 
							FSPDE_SCROLL> _baseSPClass;
	BEGIN_MSG_MAP(CMyDlg)
		CHAIN_MSG_MAP(_baseSPClass)
		. . .
	END_MSG_MAP()	
	

Also, the CSPDialodExt class can create a menu bar from your resources or one of predefined commonly used menu bars. To make CSPDialodExt create a menu bar in WM_INITDIALOG handler, add an IDM constant to your class (you can use enum to create it) and assign it a resource id of your menu bar, or use one of the following constants to create a predefined common menu bar:

  • IDM_INTERNAL_MENU_EMPTY. Create empty menu bar.
  • Empty bar

  • IDM_INTERNAL_MENU_DONE. Create menu bar with one "Done" button (IDOK command identifier).
  • Done bar

  • IDM_INTERNAL_MENU_CANCEL. Create menu bar with one "Cancel" button (IDCANCEL command identifier).
  • Cancel bar

  • IDM_INTERNAL_MENU_DONECANCEL. Create menu bar with two "Done" and "Cancel" buttons.
  • Done Cancel bar

    So, the following code if enough to create a fully functional Smartphone-style dialog:

    class CDemoSPDialog : 
    	public CDialogImpl<CDemoSPDialog>, 
    	public CSPDialogExt<CDemoSPDialog, FSPDE_HBACKAUTO | FSPDE_STATICBOLD>
    {
    public:
    	enum {IDD = IDD_MYSIMPLE,
    	      IDM = IDM_INTERNAL_MENU_DONE}; //Use internal "Done" menu bar
    	typedef CSPDialogExt<CDemoSPDialog, FSPDE_HBACKAUTO | FSPDE_STATICBOLD> _baseSPClass;
    	BEGIN_MSG_MAP(CDemoSPDialog)
    		CHAIN_MSG_MAP(_baseSPClass)
    	END_MSG_MAP()
    };
    	

    CSPDialogAuto

    Using this class is similar to using CSPDialogExt. The only difference is that this class sets the most commonly used FSPDE_HBACKAUTO and FSPDE_STATICBOLD flags by default and you don't need to specify them manually.

    CSPSimpleDialog

    This class allows you to create a Smartphone-style dialog without inheriting a new class for it. For example, to create an "About" dialog you just need to write the following code:

    CSPSimpleDialog<IDD_ABOUTBOX, IDM_INTERNAL_MENU_DONE> dlg; //Resource identifiers pass by template parameters
    dlg.DoModal();
    	

    CSPPropertyPageImpl, CSPSimplePropertyPage and CSPPropertySheet

    CSPPropertySheet. This class is used to display a Smartphone-style property sheet. It stores an array of property pages (each page must be derived from CSPPropertyPageImpl class) and calls DoModal method of a page when the user invokes it from the list.

    Property Sheet sample

    CSPPropertyPageImpl. Using this class is very similar to using CDialogImpl class. The only difference is that this class can be used in conjunction with CSPPropertySheet class.

    Property Sheet sample

    CSPSimplePropertyPage. Similar to CSimpleDialog. Can be used with CSPPropertySheet to create a property page without inheriting a new class for it.

    Example of using:

    //Declare derived property page 
    class CPropPage1 : 	public CSPPropertyPageImpl<CPropPage1>,
    	           	public CSPDialogExtAuto<CPropPage1, FSPDE_SCROLL>
    {
    public:
    
    	enum {	IDD = IDD_PROP1,
    		IDM = IDM_INTERNAL_MENU_DONE }; //for CSPDialogExt
    
    	typedef CSPDialogExtAuto<CPropPage1, FSPDE_SCROLL> _baseSPClass;
    	BEGIN_MSG_MAP(CPropPage1)
    		CHAIN_MSG_MAP(_baseSPClass)
    	END_MSG_MAP()
    	
    	BOOL OnInitDialog(LPARAM lParam)
    	{
    		//Init some controls
    		CButton(GetDlgItem(IDC_CHECK2)).SetCheck(BST_CHECKED);
    		CButton(GetDlgItem(IDC_CHECK4)).SetCheck(BST_CHECKED);
    		SetDlgItemText(IDC_EDIT1, _T("Text for edit"));
    		return TRUE;
    	}
    
    };
    
    ...
    
    //Create first property page. Use default title from dialog resource
    CPropPage1 p1;
    
    //Create second property page without derives. Use another title. 
    CSPSimplePropertyPage<IDD_ABOUTBOX, IDM_INTERNAL_MENU_DONE> p2(_T("Simple page"));
    
    //Create Property Sheet
    CSPPropertySheet sheet(_T("Select some properties"));
    
    //Add pages to property sheet
    sheet.AddPage(p1);
    sheet.AddPage(p2);
    
    //Run Property Sheet dialog
    sheet.DoModal();
    	

    Conclusion

    First version of WtlEx library contains useful classes for dialog and property sheet development. Using these classes in your project would allow you to avoid writing routine code and speed up application development.

    Discuss

    Discuss this article. Here you can write your comments and read comments of other developers.

      © 2002 Smartphone Developer Network | Want to be an author? | Contact Us