使用 Pelles C 进行 Pocket PC 开发





5.00/5 (5投票s)
本文介绍如何使用 Pelles C IDE 开发 Pocket PC 应用程序。

引言
在 Pocket PC 上进行程序开发有多种选择,例如,嵌入式 VC 和 Visual Studio。但是使用 eVC 进行 Pocket PC 开发的缺点是,eVC 目前在 Vista 及更高版本的操作系统上无法运行。此外,Visual Studio 的 Express 版本不支持设备开发。它需要完整版本的 Visual Studio 才能为 Pocket PC 进行开发。因此,如果您想要一个免费的 Pocket PC 应用程序开发环境,您需要寻找一个替代方案。
Pocket PC 开发的一个很好的免费替代方案是 Pelles C。Pelles C 包含用于 Pocket PC 和 Windows 的编译器、链接器和安装构建器。它还拥有一个集成开发环境,包含项目管理、源代码编辑器、调试器以及用于对话框、菜单、图标、光标等各种资源的资源编辑器。
背景
Pelles C 可在此处下载:http://www.pellesc.de/。
为了演示 Pelles C 的用法,我开发了一个名为 PocketScribble
的示例应用程序。
任何熟悉 C 语言 Windows 编程的人都可以使用 Pelles C 编写 Pocket PC 程序。
要在 Pelles C IDE 中创建新的 Pocket PC 应用程序,请选择“文件”->“新建”->“项目”菜单命令。您将看到以下屏幕:

选择 WinCE Pocket PC 程序(EXE) 项目类型。
您可以使用“添加文件”选项添加 C 源文件,如下所示:

您可以通过从“项目”菜单中选择“构建 EXE”选项来生成程序的执行代码,如下所示:

生成的 EXE 文件可以使用 Active Sync(在 Windows XP 上)或 Windows Mobile Device Center(在 Vista 或更高版本的操作系统上)复制到实际的 Windows Mobile 设备或模拟器上。
Using the Code
Pocket PC 程序或 Windows 程序的执行以 WinMain
函数开始,其原型如下:
int PASCAL WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPWSTR lpCmdLine,int nCmdShow)
在上面的代码中,HISNTANCE
是一个代表无符号 int
的宏,而 LPWSTR
是一个代表指向 char
的 long
指针的宏。
WinMain
函数的参数如下:
- 第一个参数是
hInst
,它代表当前实例。 - 如果程序有多个实例同时运行,则
hPrevInst
参数包含最后启动的副本的hInstance
值。 lpCmdLine
参数是指向包含传递给程序的命令行参数的字符字符串
的指针。nCmdShow
参数是一个整数值,表示程序启动时的窗口状态(最小化、正常或最大化)。
在 WinMain
函数中,我们使用 WNDCLASS
结构来定义窗口特性,如下所示:
wc.hInstance=hInst; // Current Instance
wc.lpszClassName=L"MYWINDOW"; // Window Class Name
wc.lpfnWndProc=myWndProc; // Window Procedure to handle window events.
wc.hbrBackground=GetStockObject(WHITE_BRUSH); // Window Background
RegisterClass()
函数用于注册窗口类,如下所示:
RegisterClass(&wc);
注册窗口类后,将创建一个窗口,如下所示:
hWnd=CreateWindow(L"MYWINDOW",L"Pocket Scribble",
WS_OVERLAPPEDWINDOW,20,20,200,200,0,0,hInst,0);
CreateWindow()
函数的参数如下:
- 第一个参数是窗口类名。
- 第二个参数是窗口标题。
- 第三个参数是窗口样式(
WS_OVERLAPPEDWINDOW
)。 - 第四个参数是窗口左上角的 x 坐标。
- 第五个参数是窗口左上角的 y 坐标。
- 第六个参数是窗口的宽度。
- 第七个参数是窗口的高度。
- 第八个参数是父窗口句柄。此参数的值为零表示当前窗口没有父窗口。
- 第九个参数是窗口的菜单。此参数的值为零表示当前窗口没有菜单。
- 第十个参数是当前程序实例。
- 第十一个参数是指向窗口创建数据的指针。
使用以下函数调用显示新创建的窗口:
ShowWindow(hWnd,nCmdShow);
在 ShowWindow()
方法中,第一个参数是 CreateWindow()
方法返回的窗口句柄,第二个参数是 WinMain()
函数中的 nCmdShow
参数,表示窗口状态。
可以使用以下函数调用更新窗口内容:
UpdateWindow(hWnd);
之后,将创建一个消息循环,如下所示:
while(GetMessage(&msg,0,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
上述消息循环执行以下任务:
- 它使用
GetMessage()
方法从消息队列读取消息并将其存储在MSG
结构中。 - 它使用
TranslateMesage()
方法将msg
结构中的键盘消息转换为字符消息。 - 然后,它使用
DispatchMessage()
方法将翻译后的消息发送到处理消息的窗口过程。
以下是窗口过程:
LRESULT CALLBACK myWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
HDC hDC;
switch(uMsg)
{
case WM_DESTROY: // Window is closed
PostQuitMessage(0); // Post the WM_QUIT message
break;
case WM_LBUTTONDOWN: // Left mouse button pressed
down=1; // Trap the left mouse button state
x1=LOWORD(lParam); // Store the current x co-ordinate
y1=HIWORD(lParam); // Store the current y co-ordinate
break;
case WM_MOUSEMOVE:
if(down==1) // If left mouse button pressed
{
x2=LOWORD(lParam); // Store the new x co-ordinate
y2=HIWORD(lParam); // Store the new y co-ordinate
hDC=GetDC(hWnd); // Get the device context
MoveToEx(hDC,x1,y1,0);// Move to the starting point
LineTo(hDC,x2,y2); // Draw a line
// upto the second point
ReleaseDC(hWnd,hDC);// Release the device context
x1=x2;
y1=y2;
}
break;
case WM_LBUTTONUP: // Left mouse button released
down=0;
break;
default:
break;
}
//Call the default window procedure to provide default processing
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
在上面的代码中,uMsg
参数包含生成的消息。WM_DESTROY
在关闭窗口时生成。我们使用 PostQuitMessage()
方法发送 WM_QUIT
消息,这会导致 WinMain()
函数中的消息循环终止,程序停止。
WM_LBUTTONDOWN
消息在按下鼠标左键时生成。将 down
变量设置为 1
以指示鼠标左键已按下。LOWORD
和 HIWORD
宏分别用于捕获当前的 x 和 y 坐标。
WM_LBUTTONUP
消息在释放鼠标左键时生成。将 down
变量设置为 0
以指示鼠标左键已释放。
WM_MOUSEMOVE
消息在鼠标移动时生成。我们使用 LOWORD
和 HIWORD
宏来捕获新的 x 和 y 坐标,并在旧坐标和新坐标之间绘制一条线。MoveToEx
和 LineTo
函数需要设备上下文,该设备上下文是通过 GetDC()
函数获取的。
以下是 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);
}
关注点
我一直以来都在寻找 Pocket PC 编程的 Visual Studio 替代方案,很幸运找到了这个出色的 IDE。我希望本文能对所有正在寻找 Pocket PC 开发替代 IDE 的 Pocket PC 爱好者有所帮助。
下图显示了该应用程序在我装有 Windows Mobile 6 Professional 的 HTC_P3450 手机上执行的情况:
