随着移动设备的发展,Pocket PC应用开发的需求依然存在。然而,对于开发者来说,Visual Studio 的 Express 版本并不支持设备开发,且 Embedded Visual C++ (eVC) 不能在 Vista 及更高版本的操作系统上运行。因此,寻找一个免费且功能全面的开发环境变得尤为重要。本文将介绍如何使用 Pelles C 作为开发 Pocket PC 应用的免费替代方案。
Pelles C 是一个集成了编译器、链接器和安装构建器的免费开发环境,支持 Pocket PC 以及 Windows 平台。它还提供了一个集成开发环境(IDE),包括项目管理、源代码编辑器、调试器以及各种资源编辑器,如对话框、菜单、图标、光标等。
Pelles C 可以从官方网站下载。为了演示如何使用 Pelles C,开发了一个名为 PocketScribble 的示例应用程序。任何熟悉 C 语言 Windows 编程的人都可以利用 Pelles C 来编写Pocket PC程序。
在 Pelles C IDE 中创建一个新的 Pocket PC 应用程序,可以通过选择 "文件" -> "新建" -> "项目" 菜单命令来实现。将看到一个项目类型选择界面,选择 "WinCE Pocket PC Program(EXE)" 项目类型。
可以通过 "添加文件" 选项来添加 C 源文件。生成程序的可执行代码,可以通过选择 "项目" 菜单中的 "构建 EXE" 选项来实现。生成的 EXE 文件可以通过 Active Sync(在 Windows XP 上)或Windows MobileDevice Center(在 Vista 或更高版本的操作系统上)复制到实际的 Windows Mobile 设备或模拟器上。
Pocket PC程序或 Windows 程序的执行始于 WinMain 函数,其原型如下:
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, int nCmdShow);
在上述代码中,HINSTANCE 是一个宏,代表一个无符号 int,LPWSTR 是一个宏,代表一个长指针到 char。WinMain 函数的参数如下:
在 WinMain 函数中,使用 WNDCLASS 结构定义窗口特性:
wc.hInstance = hInst;
wc.lpszClassName = L"MYWINDOW";
wc.lpfnWndProc = myWndProc;
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
RegisterClass() 函数用于注册窗口类:
RegisterClass(&wc);
注册窗口类后,创建窗口:
hWnd = CreateWindow(L"MYWINDOW", L"Pocket Scribble", WS_OVERLAPPEDWINDOW, 20, 20, 200, 200, 0, 0, hInst, 0);
CreateWindow() 函数的参数如下:
使用以下函数调用来显示新创建的窗口:
ShowWindow(hWnd, nCmdShow);
ShowWindow() 方法的第一个参数是 CreateWindow() 方法返回的窗口句柄,第二个参数是 WinMain() 函数中的 nCmdShow 参数,代表窗口状态。
使用以下函数调用来更新窗口内容:
UpdateWindow(hWnd);
创建消息循环:
while (GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
上述消息循环执行以下任务:
以下是窗口过程的代码:
LRESULT CALLBACK myWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
HDC hDC;
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
down = 1;
x1 = LOWORD(lParam);
y1 = HIWORD(lParam);
break;
case WM_MOUSEMOVE:
if (down == 1) {
x2 = LOWORD(lParam);
y2 = HIWORD(lParam);
hDC = GetDC(hWnd);
MoveToEx(hDC, x1, y1, 0);
LineTo(hDC, x2, y2);
ReleaseDC(hWnd, hDC);
x1 = x2;
y1 = y2;
}
break;
case WM_LBUTTONUP:
down = 0;
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
在上述代码中,uMsg 参数包含生成的消息。WM_DESTROY 是在关闭窗口时生成的。使用 PostQuitMessage() 方法发布 WM_QUIT 消息,这会导致 WinMain() 函数中的消息循环终止,程序停止。
以下是 PocketScribble 应用程序的完整代码:
#include <windows.h>
LRESULT CALLBACK myWndProc(HWND, UINT, WPARAM, LPARAM);
WNDCLASS wc;
int down = 0;
int x1, y1, x2, y2;
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, int nCmdShow) {
HWND hWnd;
MSG msg;
wc.hInstance = hInst;
wc.lpszClassName = L"MYWINDOW";
wc.lpfnWndProc = myWndProc;
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
RegisterClass(&wc);
hWnd = CreateWindow(L"MYWINDOW", L"Pocket Scribble", WS_OVERLAPPEDWINDOW, 20, 20, 200, 200, 0, 0, hInst, 0);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK myWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
HDC hDC;
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
down = 1;
x1 = LOWORD(lParam);
y1 = HIWORD(lParam);
break;
case WM_MOUSEMOVE:
if (down == 1) {
x2 = LOWORD(lParam);
y2 = HIWORD(lParam);
hDC = GetDC(hWnd);
MoveToEx(hDC, x1, y1, 0);
LineTo(hDC, x2, y2);
ReleaseDC(hWnd, hDC);
x1 = x2;
y1 = y2;
}
break;
case WM_LBUTTONUP:
down = 0;
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}