Home > Pocket PC > Samples > Combination > Visual C++
 
  Combination in Visual C++

 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

 
[ Copyright © 2000- Eric Poncet - All rights reserved ]

[ Stage de musique classique | Stage de musique baroque | Stage de musique de chambre | Stage de musique latine ]
[ Stage de jazz | Stage de musiques actuelles | Stage de funk | Stage de metal | Stage de pop | Stage de reggae | Stage de rock ]
[ Stage d'improvisation | Colonie musicale ]