Introduction to WTL for Smartphone 2002
By Alexander Shargin, May 27, 2002.
What is WTL
WTL (Windows Template Library) is yet another class library from Microsoft which you can use in your applications. "Another" because there are many other libraries out there (e. g. MFC and ATL). WTL was created as a sample ATL extension and is tightly integrated with this library. WTL allows to create user interfaces much more quickly than using "pure" API or ATL. Like ATL WTL is based on C++ templates and can be used to create very small, fast programs.
What is WTL port for Smartphone
WTL was created for desktop versions of Windows and can't be used for Smartphone development. Some features it implements are not supported on Smartphone (standard dialogs, many standard controls, some GDI objects like metafiles and DIBs etc.), others are not used in Smartphone programs (splitter windows, bitmap buttons etc.). However, ATL version for Smartphone is included in Smartphone SDK and major parts of WTL library can also be used in Smartphone programs. That's why we created WTL port for Smartphone. It includes every feature of WTL which might be useful for Smartphone developers and excludes anything else.
Why WTL
Now that you know what WTL is you might be thinking: "Why shall I use this library in my applications?". I'll try to answer this question in the following sections.
WTL vs MFC
There are several reasons to prefer WTL to MFC in the realm of Smartphone development.
- MFC is not included in Smartphone SDK. :) While this may change in the future nobody can guarantee that Microsoft will port MFC to Smartphone.
- WTL allows you to create more compact and fast programs than MFC. While on desktop computers the overhead imposed by MFC is often insignificant on Smartphones things are different. These devices have limited resources which should be used with care.
- WTL design is much more flexible, modern and elegant that the one of MFC. It's easy to include just one WTL class in your program while in MFC many classes depend on each other and you have to use them all.
- WTL is more thread-friendly than MFC.
WTL vs "pure" Win32 API
- WTL contains the implementation for many things which API programmers have to write manually (window class registration, window creation, message loops, window and dialog procedures etc.). Using the code from WTL you save your time and avoid many errors.
- WTL is a full-blown class library and simplifies code reuse considerably. It's easy to create reusable classes with WTL and in the nearest future many such classes will be available in the Internet. We are planning to place many useful classes on this site, too.
- WTL does not force you to use any particular style of programming. You can mix API code and WTL code in any proportions to create working applications.
WTL vs other third-party libraries
WTL has several advantages over other third-party libraries for Smartphone.
- Support from eVC IDE. You can use IDE to create new window classes, message handlers, command and notification handlers etc. instead of adding them manually.
- Seamless integration with ATL. You will never get any side effects when using WTL and ATL in one project.
- Large online community. While WTL is not as well-known library as MFC it has been used by many Windows programmers for years. It is well tested, there are many useful online resources about this library. If you encounter some problems using WTL you will probably find the help to solve them.
Disadvantages of WTL
WTL has its disadvantages, too. The most important are:
- No official support from Microsoft.
- No documentation.
However, we are going to publish some documentation on WTL port for Smartphone on this site in the nearest future. We will also answer questions on WTL port on this site's forums.
Installation of WTL port for Smartphone
In order to install WTL port for Smartphone you have to follow these steps.
- Download WTL for Smartphone 2002.
- Unzip the archive and copy wtl\include directory to the root of Smartphone SDK directory. On my computer Smartphone SDK is located at D:\Windows CE Tools\wce300\Smartphone 2002\.
Note: technically you can copy WTL directory anywhere else (you only have to adjust eVC paths accordingly) but it's better to keep all Smartphone include files in one place.
- Add path to WTL include files to your eVC include paths. To do this run eVC. Activate Tools->Options command and go to Directories tab. Choose Platform: Smartphone 2002, CPUs: Win32 (WCE x86), Show directories for: Include files. Add path to the directory with WTL include files to the list. Then repeat this procedure for CPUs: Win32 (WCE ARM) configuration. Your Options window should look like this.
WTL port for Smartphone overview
Header files you get in wtl.zip contain the following functionality.
| File |
Description |
| atlapp.h |
Application module class (CAppModule), message loop class (CMessageLoop), interfaces for message filters (CMessageFilter) and idle handlers (CIdleHandler) |
| atlcrack.h |
Message "crackers" for all messages supported by Smartphone. |
| atlctrls.h |
Wrapper classes for standard and common controls supported on Smartphone (CStatic, CEdit, CListBox, CListViewCtrl etc.). |
| atlddx.h |
Support for DDX mechanism for data exchange between controls and variables in your program (CWinDataExchange class and DDX map macros) |
| atlgdi.h |
Wrapper classes for GDI objects (CPen, CBrush, CBitmap etc.) and for device contexts (CDC, CPaintDC, CClientDC etc.) |
| atlmisc.h |
Support classes like CPoint, CRect, CSize and CString. |
| atlres.h |
#defines used by WTL. |
| atluser.h |
Wrapper class for menu (CMenu). |
Hello, WTL!
Smartphone version of classical "Hello, world" application looks like this.
#include
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
{
// Draw "Hello, World" string.
PAINTSTRUCT ps;
RECT rc;
GetClientRect(hWnd, &rc);
HDC hdc = BeginPaint(hWnd, &ps);
DrawText(hdc, _T("Hello, Win32!"), -1, &rc, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hWnd, &ps);
return 0;
}
case WM_DESTROY:
{
// Close application.
PostQuitMessage(0);
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int)
{
// Register main window class.
WNDCLASS wc;
ZeroMemory(&wc, sizeof(wc));
wc.lpszClassName = _T("HelloClass");
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.hInstance = hInstance;
RegisterClass(&wc);
// Create main window.
CreateWindow(
_T("HelloClass"),
_T("Hello, Smartphone!"),
WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
0,
hInstance,
NULL);
// Message loop.
MSG msg;
while(GetMessage(&msg, 0, 0, 0))
{
DispatchMessage(&msg);
}
return 0;
}
Although this sample has very limited functionality it contains many elements of any Windows program: window class registration, main window creation, message loop and window proc. Now let's see how this sample can be rewritten using WTL.
#include
#include
extern CAppModule _Module;
#include
#include
#include
CAppModule _Module;
class CMainWindow : public CWindowImpl >
{
// Message map is used to map Windows messages to handlers.
BEGIN_MSG_MAP(CMainWindow)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
END_MSG_MAP()
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
CPaintDC dc(m_hWnd);
CRect rect;
GetClientRect(rect);
dc.DrawText(_T("Hello, Wtl!"), -1, rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return 0;
}
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
PostQuitMessage(0);
return 0;
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int)
{
// Init module.
_Module.Init(0, hInstance, 0);
// Create main window.
CMainWindow wnd;
wnd.Create(NULL, CWindow::rcDefault, _T("Hello, Wtl!"));
wnd.ShowWindow(SW_SHOW);
// Run message loop.
CMessageLoop loop;
int res = loop.Run();
// Terminate.
_Module.Term();
return res;
}
As we can see WinMain is present here, too. Window proc is replaced by CMainWindow class which contains all message handlers and message map used to map WIndows messages to their handlers. Class registration is omitted since WTL handles it for us. Message loop is incapsulated in CMessageLoop class.
IDE support for WTL
To add a new class to your project:
- Run Insert->Nre Class... command.
- Choose Class type: Generic Class.
- Enter class name (Name edit box) and base class(es) (Base class(es) list). You can also change file names for new class if you want (Change... button).
- Click OK to add new class to your project.
To add message/command handler to your window class:
- Go to ClassView tab of workspace window.
- Right-click on the name of the class you want to add handler to.
- Choose Add WIndows Message Handler... command from context menu.
Note: this command is available only if message map is present in your class. If you have no message map, add an empty one. It must be located in public section of your class and looks like this:
BEGIN_MSG_MAP()
END_MSG_MAP()
- Choose the message you want to handle and click Add Handler button. The handler will be added to your class as well as message map entry to map Windows message to the new handler.
- Repeat the previous step for all messages you want to handle. Then click OK.
Conclusion
WTL is a good replacement for MFC library on Smartphone 2002 platform. Use it if you want to speed up application development and improve code reuse in your projects.
Discuss
Discuss this article.
Here you can write your comments and read comments of other developers.
|