LISTING 1. The WinMain() function.
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TEST2);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
interest happens in here — except for
the initialization of the main window
through a call to InitInstance(). You
can take a look at that function if
you’d like, but how to set up a window is way beyond the scope of this
article. The thing to keep in mind here
is that the WinMain() function is the
very first thing that’s run, so if you
have anything to set up or initialize,
this is the place to do it.
WndProc() — The Message Handler
In this example, our message handler is defined as WndProc(), which
you should be able to find within your
source file, or by simply looking at
Listing 2. This is the place where most
IO calls will be sent or any other
“message” that the OS wishes to send
us. So, whenever a user taps the
screen or presses a button, for
example, the OS will send out a
message which will be picked up
by WndProc() — our message
handler. In there, you’ll see that we
have a simple switch() statement
to check to see what message was
sent (obviously, we don’t check for
every message right now!). You
should take note of the
WM_PAINT message which tells
our program to re-draw our
window and, in our example, print
out the text “Hello World.”
LISTING 2. The WndProc() (message handler) function.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
int wmId, wmEvent;
PAINTSTRUCT ps;
TCHAR szHello[MAX_LOADSTRING];
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
// ...
break;
case WM_CREATE:
g_hwndCB = CreateRpCommandBar(hWnd);
// Initialize the shell activate info structure
memset (&s_sai, 0, sizeof (s_sai));
s_sai.cbSize = sizeof (s_sai);
break;
case WM_PAINT:
RECT rt;
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
LoadString(g_hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
DrawText(hdc, szHello, _tcslen(szHello), &rt,
DT_SINGLELINE | DT_VCENTER | DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CommandBar_Destroy(g_hwndCB);
PostQuitMessage(0);
break;
case WM_ACTIVATE:
// Notify shell of our activate message
SHHandleWMActivate(hWnd, wParam, lParam, &s_sai,
FALSE);
break;
Compile and Run
Let’s actually compile and run
this program! Simply select
“Execute” from the “Build” menu.
This will automatically build the
program and send it off to the
emulator for testing.
So, assuming you haven’t
modified the source code in such
a way as to create errors, your
program should compile and run
without any problems.
After it compiles, you should
see the emulator pop up (it takes a
while to load the first time it’s run,
however, after that it’s faster ... just
keep it running in the background).
Give it just a few more seconds
and you’ll see your “Hello World!”
program running in all its glory!
60
June 2006