Purpose
This is the eMbedded Visual C++ version of our combination
application.
Requirements
You need eMbedded Visual Tools and Pocket PC 2002 SDK (see tools
section).
Source
code
Below is the .cpp
file, which contains the application's logic.
For .h, .rc,
.vcw, .vcp
and others please download the ZIP
file.
// Combination.cpp
// Pocket PC
// Visual C++
#include "stdafx.h"
#include "combination.h"
#include <commctrl.h>
#include <aygshell.h>
#include <sipapi.h>
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE g_hInst; // The current instance
HWND g_hwndCB; // The command bar handle
HWND g_hwndDialog; // The main dialog
static SHACTIVATEINFO s_sai;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass (HINSTANCE, LPTSTR);
BOOL InitInstance (HINSTANCE, int);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DialogProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK IndexProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK AboutProc (HWND, UINT, WPARAM, LPARAM);
HWND CreateRpCommandBar(HWND);
//
// FUNCTION: WinMain(...)
//
// PURPOSE: Entry point and message loop of the application.
//
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_COMBINATION);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// It is important to call this function so that the application
// will get 'well formed' small icons associated with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_COMBINATION));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd = NULL;
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name
g_hInst = hInstance; // Store instance handle in our global variable
// Initialize global strings
LoadString(hInstance, IDC_COMBINATION, szWindowClass, MAX_LOADSTRING);
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
//If it is already running, then focus on the window
hWnd = FindWindow(szWindowClass, szTitle);
if (hWnd)
{
SetForegroundWindow (hWnd);
return 0;
}
MyRegisterClass(hInstance, szWindowClass);
RECT rect;
GetClientRect(hWnd, &rect);
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
//When the main window is created using CW_USEDEFAULT the height of the menubar (if one
// is created is not taken into account). So we resize the window after creating it
// if a menubar is present
{
RECT rc;
GetWindowRect(hWnd, &rc);
rc.bottom -= MENU_HEIGHT;
if (g_hwndCB)
MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, FALSE);
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_HELP_ABOUT:
DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)AboutProc);
break;
case IDM_HELP_INDEX:
DialogBox(g_hInst, (LPCTSTR)IDD_INDEXBOX, hWnd, (DLGPROC)IndexProc);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
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);
// Create the DialogWindow and center it under the commandbar
RECT rect;
GetClientRect(hWnd, &rect);
g_hwndDialog = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_MAIN), hWnd, (DLGPROC)DialogProc);
if ( g_hwndDialog )
{
MoveWindow(g_hwndDialog, rect.left, rect.top,
rect.right-rect.left,rect.bottom - rect.top, TRUE);
ShowWindow(g_hwndDialog, SW_SHOW);
UpdateWindow(g_hwndDialog);
}
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;
case WM_SETTINGCHANGE:
SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//
// FUNCTION: CreateRpCommandBar(HWND hwnd)
//
// PURPOSE: Creates menu bar for window passed in argument.
//
HWND CreateRpCommandBar(HWND hwnd)
{
SHMENUBARINFO mbi;
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hwnd;
mbi.nToolBarId = IDM_MENU;
mbi.hInstRes = g_hInst;
mbi.nBmpId = 0;
mbi.cBmpImages = 0;
if (!SHCreateMenuBar(&mbi))
return NULL;
return mbi.hwndMB;
}
// Returns factorial of argument
static ULONG Factorial(ULONG n)
{
return (n <= 1) ? 1 : n*Factorial(n-1); // heh-heh... let's mix a ternary operator (?) and recursion...
}
// Returns combination of n and p
static ULONG Combination(ULONG n, ULONG p)
{
return Factorial(n) / (Factorial(n - p) * Factorial(p));
}
// Main purpose of our app: DO the computation of factorial and combination
void Go()
{
LONG n = GetDlgItemInt(g_hwndDialog, IDC_N, NULL, true);
LONG p = GetDlgItemInt(g_hwndDialog, IDC_P, NULL, true);
if ((n <= 0) || (p <= 0))
MessageBox(g_hwndDialog, L"Please enter positive numbers for 'n' and 'p'", L"Input error", MB_ICONSTOP);
SetDlgItemInt(g_hwndDialog, IDC_FACTORIALN, Factorial(n), true);
SetDlgItemInt(g_hwndDialog, IDC_FACTORIALP, Factorial(p), true);
SetDlgItemInt(g_hwndDialog, IDC_FACTORIALNP, Factorial(n-p), true);
SetDlgItemInt(g_hwndDialog, IDC_COMBINATION, Combination(n, p), true);
}
// Message handler for the Main Dialog.
LRESULT CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
SHINITDLGINFO shidi;
switch (message)
{
case WM_INITDIALOG:
// Create a Done button and size it.
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
case IDC_COMPUTE:
Go();
return TRUE;
default:
break;
}
break;
}
return FALSE;
}
// Message handler for the Index box.
LRESULT CALLBACK IndexProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
SHINITDLGINFO shidi;
switch (message)
{
case WM_INITDIALOG:
// Create a Done button and size it.
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
// Message handler for the About box.
LRESULT CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
SHINITDLGINFO shidi;
switch (message)
{
case WM_INITDIALOG:
// Create a Done button and size it.
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
Comments
Total overhead for this small VC++ app is... over
300 lines of code. You may want to compare with the Visual
Basic version of the very same app. That's the price to pay
if you'd like to develop with VC++. However, for bigger projects,
this overhead shouldn't be much of a bother.
The core functions are located in Factorial(),
Combination() and Go().
You'll also notice that VB allows for enhanced GUI
development much easier than VC++ (Shapes, colors, fonts...).
Next sample
|