65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Pelles C 进行 Pocket PC 开发

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2013 年 3 月 31 日

CPOL

5分钟阅读

viewsIcon

23384

downloadIcon

168

本文介绍如何使用 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 手机上执行的情况:

© . All rights reserved.