Программирование для карманных компьютеров
Шрифт:
Также для того чтобы отследить изменение значения переменной, можно воспользоваться инструментом Quick Watch. Для этого надо установить текстовый курсор на имя переменной, и щелкнуть на соответствующем инструменте на отладочной панели инструментов. В результате на экран будет выведено информационное окно, описывающее состояние этой переменной (рис. 3.35).
И, наконец, можно просто навести курсор мыши на имя переменной. Если значение переменной в данный момент доступно, то оно будет отображено на всплывающем ярлычке (рис. 3.36).
Нужно добавить в окно Watches все переменные, показанные на рис. 3.34, и еще раз осуществить пошаговое выполнение программы с заходом в подпрограммы.
ПРИМЕЧАНИЕ. Среде
Окно непосредственного выполнения (Immediate Window) – еще один удобный инструмент отладки в eVB. Оно выводится на экран командой меню View ? Immediate Window.
Поскольку Basic является интерпретируемым языком, то после выполнения любой строки кода можно изменить значение любой доступной в контексте выполнения переменной или выполнить любую команду. Для этого надо ввести в окно Immediate соответствующую команду и нажать клавишу Enter, после чего команда будет выполнена. Также можно в этом окне просмотреть значение любой переменной, выполнив команду? <имя переменной>, например? В. Чтобы посмотреть, как функционирует окно Immediate, нужно снова запустить проект с установленной точкой останова. Когда выполнение программы дойдет до этой точки, следует вывести на экран окно Immediate, ввести в этом окне команду MsgBox «Это сообщение из окна непосредственного выполнения!»,vbOKOnly и нажать клавишу Enter. На экран эмулятора будет выведено соответствующее сообщение.
Еще один инструмент отладки – окно стека вызовов подпрограмм. Установив точку останова в теле подпрограммы или функции, в этом окне можно увидеть последовательность вызовов, которая привела программу в эту точку (рис. 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);
};
//
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
int MyPaint (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);
DrawText (hdc, (const unsigned short *)szStr, – 1, &rectCli,
DT_LEFT | DT_WORDBREAK);
EndPaint (hWnd, &ps);
return 0;
}7. Да, кода получилось много. Почти все, что делает этот код, в eVB можно было сделать без написания кода вообще. Но в eVC практически каждое действие нужно прописывать при помощи серьезных блоков кода. Если вы пишете консольное приложение, то можно обойтись для начала несколькими строками кода. Но если нужно сделать приложение с оконным интерфейсом Windows – засучите рукава, писать придется много. Код, приведенный в листинге, всего лишь создает приложение Windwos CE с одним окном, которое реагирует на нажатие клавиш клавиатуры. Эта заготовка позволит одновременно на практике «прощупать» язык C++ и получить первые навыки работы со средой eVC. После нажатия кнопки Execute Programm программа будет скомпилирована и запущена. При нажатии цифровых клавиш 1 или 2 на виртуальной или на реальной клавиатуре программа выводит на экран соответствующие сообщения.