Еще один инструмент отладки – окно стека вызовов подпрограмм. Установив точку останова в теле подпрограммы или функции, в этом окне можно увидеть последовательность вызовов, которая привела программу в эту точку (рис. 3.37).
Рис. 3.37. Окно стека вызовов в точке останова.
Глава 4 Разработка программ для Pocket PC с помощью Microsoft eMbedded Visual C++ 3.0
По сравнению с eVB язык C++, безусловно, предоставляет разработчику больше возможностей. Несмотря на то что в eVB можно было сделать почти все, что можно сделать в eVC (так в этой главе будет называться eMbedded Visual C++ 3.0), широта возможностей eVB практически полностью опирается на компоненты и библиотеки, написанные на C++.
Одно из главных преимуществ eVC состоит в том, что он создает исполняемые файлы, непосредственно выполняемые процессором, а не промежуточный интерпретируемый код. Однако кроме преимуществ, у eVC есть и отдельные недостатки. Для тех, кто пришел в eVC из eVB или Delphi, программирование на этом языке на первых порах покажется ужасным. Громоздкие конструкции и необходимость все прописывать вручную в коде могут обескуражить начинающего программиста. Но за все надо платить. Если вы хотите получить программу маленького размера и доступ к любой возможности устройства, то придется привыкать к сложностям многострочного кода и тяжеловесным конструкциям, дающим в награду контроль за каждым байтом вашего кода.
Рта глава будет достаточно обширной. Р’ ней РјС‹ рассмотрим язык Рё среду eVC, что послужит фундаментом для следующей главы, РІ которой РјС‹ сможем сосредоточиться только РЅР° особенностях среды eVC++ 4.0 для Pocket PC 2003.
Введение в язык или первая программа
Для того, чтобы понять все инструменты среды eVC, необходимо знать язык С++. Но для того чтобы узнать С++, необходимо на нем хоть что-то написать, а для этого надо понимать, как работает среда. Поэтому сначала мы приведем пример создания первой программы, которая просто выведет на форму текст, затем кратко рассмотрим основы языка С++, и только после этого можно будет приступить к подробному изучению среды eVC. Такой порядок работы нам кажется самым оптимальным.
Упражнение 4.1
1. Запустить среду eVC и выполнить команду меню File ? New. На экран будет выведено окно New. В этом окне следует активировать вкладку Projects и на этой вкладке выбрать пиктограмму WCE Pocket PC 2002 Application. В поле ввода Project Name следует указать имя нового проекта MyExp. После этого нужно нажать кнопку OK.
2. В следующем окне мастера создания проекта нужно выбрать пиктограмму An Empty Project и нажать кнопку Finish.
3. Снова выполнить команду File ? New. В активированном диалоговом окне нужно перейти на вкладку Files и в списке выбрать C++ Source File. Затем нужно взвести флажок Add To Project и указать имя файла MyExp.
4. Реще раз выполнить команду File ? New. Р’ диалоговом РѕРєРЅРµ, которое будет выведено РЅР° экран, перейти РЅР° вкладку Files Рё выбрать элемент C/РЎ++ Header File. Взвести флажок Add To Project Рё указать РёРјСЏ файла MyExp. Рти действия привели Рє созданию наиболее простой структуры проекта РІ eVC. Теперь нужно заполнить эту структуру РєРѕРґРѕРј.
5. В файле MyExp.h ввести код, приведенный в листинге 4.1.
Листинг 4.1
// Блок 1
#define dim(x) (sizeof(x) / sizeof(x[0]))
// Блок 2
struct decodeUINT {
UINT Code;
LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);
};
// Блок 3
struct decodeCMD {
UINT Code;
LRESULT (*Fxn)(HWND, WORD, HWND, WORD);
};
// Блок 4
int InitApp (HINSTANCE);
int InitInstance (HINSTANCE, LPWSTR, int);
int TermInstance (HINSTANCE, int);
int MyPaint (HWND, UINT, WPARAM, LPARAM);
// Блок 5
LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);
// Блок 6
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);
LRESULT CharRec (HWND, UINT, WPARAM, LPARAM);
Р’РќРРњРђРќРР•! РќРµ забывайте как можно чаще нажимать РєРЅРѕРїРєСѓ Save All РІ процессе РІРІРѕРґР° РєРѕРґР°. Набирать такой объем РєРѕРґР° второй раз после СЃР±РѕСЏ питания – РЅРµ самое веселое занятие.
6. В файле MyExp.cpp ввести код, приведенный в листинге 4.2. Листинг 4.2
// Блок 1
#include <windows.h>
#include В«MyExp.hВ»
// Блок 2
const TCHAR szAppName[] = TEXT (В«MyExpВ»);
HINSTANCE hInst;
const struct decodeUINT MainMessages[] = {
WM_DESTROY, DoDestroyMain,
WM_CHAR, CharRec,
};
// Блок 3
wchar_t *szStr;
// Блок 4
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
MSG msg;
int rc = 0;
rc = InitApp (hInstance);
if (rc) return rc;
if ((rc = InitInstance (hInstance, lpCmdLine, nCmdShow))!= 0)
return rc;
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return TermInstance (hInstance, msg.wParam);
}
// Блок 5
int InitApp (HINSTANCE hInstance) {
WNDCLASS wc;
HWND hWnd = FindWindow (szAppName, NULL);
if (hWnd) {
SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));
return -1;
}
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL,
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
if (RegisterClass (&wc) == 0) return 1;
return 0;
}
// Блок 6
int InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow){
HWND hWnd;
hInst = hInstance;
hWnd = CreateWindow (szAppName,
TEXT(В«My Experimental ProgrammВ»),
WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if ((!hWnd) || (!IsWindow (hWnd))) return 0x10;
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return 0;
}
// Блок 7
int TermInstance (HINSTANCE hInstance, int nDefRC) {
return nDefRC;
}
// Блок 8
LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
INT i;
for (i = 0; i < dim(MainMessages); i++) {
if (wMsg == MainMessages[i].Code)
return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
}
return DefWindowProc (hWnd, wMsg, wParam, lParam);
}
// Блок 9
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
PostQuitMessage (0);
return 0;
}
// Блок 10
LRESULT DoCharRecieveMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
HDC hdc;
PAINTSTRUCT ps;
RECT rectCli;
GetClientRect (hWnd, &rectCli);
ps.rcPaint = rectCli;
InvalidateRect (hWnd, &rectCli, true);
hdc = BeginPaint (hWnd, &ps);
szStr = L" GiGoGa";
DrawText (hdc, (const unsigned short *)szStr, – 1, &rectCli,
DT_CENTER | DT_SINGLELINE);
EndPaint (hWnd, &ps);
return 0;
}
// Блок 11
LRESULT CharRec (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
switch ((TCHAR)wParam){
case 49: { szStr = L" Нажата клавиша 1 на клавиатуре";}
break;
case 50: { szStr = L" А теперь на клавиатуре нажата клавиша 2";}
break;
}
MyPaint (hWnd, wMsg, wParam, lParam);
return 0;
}
// Блок 12