⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 123.txt

📁 jin tian xin qing hen hao nimen kuaikuai xiazai
💻 TXT
📖 第 1 页 / 共 5 页
字号:
CS_GLOBALCLASS  表示类是全局的。这个标志只是出于兼容性才提供的,因为Windows CE中所有窗口类都是进程级全局类。
CS_HREDRAW      告诉系统如果窗口改变了水平大小,就强制重画窗口。
CS_VREDRAW      告诉系统如果窗口改变了垂直大小,就强制重画窗口。
CS_NOCLOSE      如果[关闭]按钮出现在标题栏上,则使其失效。
CS_PARENTDC 让窗口使用父窗口的设备环境变量
CS_DBLCLKS      允许[双击]通知(Windows CE下敲击两次为双击)传递给父窗口

lpfnWndProc分配的是窗口的窗口过程的地址。因为该域定义为指向窗口过程的指针,所以在源代码中,必须在域被设置之前,定义该过程的声明。否则,编译器类型检查时会警告该行。


cbClsExra允许程序员为类结构增加额外的空间来存储只有应用程序才知道的类特定数据。cbWndExtra更加便于使用,这个域为Windows内部结构增加空间,该结构负责维护窗口每个实例的状态。不在窗口结构本身里存储大量的数据,应用程序应该存储一个指向应用程序特定结构的指针,该结构包含窗口每个实例的数据。在Windows CE里,cbClsExtra 和cbWndExtra域必须时4字节的倍数。


hInstance域设置为程序的实例句柄,该句柄指明拥有窗口的进程。hIcon域设置为窗口默认图标的句柄,但在Windows CE中并不支持该域,所以该域应该设置为NULL。(在Windows CE中,会在类的第一个窗口被创建后设置类的图标。对于Hello3,没有图标提供,并且与其它Windows版本不同,Windows CE中没有任何预定义图标用于装载。)

除非应用程序是为带鼠标的Windows CE系统设计的,否则hCursor域应该设置为NULL。幸运的是,如果系统不支持光标,调用LoadCursor (IDC_ARROW) 函数会返回NULL。

hbrBackground域规定Windows CE如何画窗口背景。Windows用这个域中指定的刷子brush(一个小的预定义的像素数组)来画窗口背景。Windows CE提供许多预定义的刷子,你可以用GetStockObject函数来装载。如果hbrBackground域是NULL,窗口必须处理WM_ERASEBKGND消息,重画窗口背景。

lpszMenuName域必须设置为NULL,因为Windows CE不直接支持有菜单的窗口。在Windows CE中,菜单由主窗口创建的命令工具条、命令带或菜单条控件提供。

lpszClassName设置为程序员定义的字符串,用于为Windows指明类的名字。Hello3用的是“MyClass”做为类名。

整个WNDCLASS类被填充后,RegisterClass函数被调用,并用指向WNDCLASS结构的指针作为唯一的参数。如果函数成功,一个标记窗口类的值被返,如果失败,函数返回0。

创建窗口
一旦窗口类注册成功,就可以创建主窗口了。所有Windows程序员在他们的我Windows编程生涯里都会学习到CreateWindow和CreateWindowEx函数调用。CreateWindowEx 的原型如下:
HWND CreateWindowEx (DWORD dwExStyle, LPCTSTR lpClassName, 
                     LPCTSTR lpWindowName, DWORD dwStyle, 
                     int x, int y, int nWidth, int nHeight, 
                     HWND hWndParent, HMENU hMenu, 
                     HINSTANCE hInstance, LPVOID lpParam);

虽然参数数量让人畏惧,但是一旦你了解了这些参数,会发现它们很有逻辑性。第1个参数是扩展风格标志位。Windows CE能够支持的扩展风格标志如下:
WS_EX_TOPMOST  窗口置顶
WS_EX_WINDOWEDGE  窗口有凸起的边框
WS_EX_CLIENTEDGE  窗口有凹陷的边框
WS_EX_STATICEDGE  静态窗口具有3D外观
WS_EX_OVERLAPPEDWINDOW  是WS_EX_WINDOWEDGE 和WS_EX_CLIENTEDGE两个风格的组合
WS_EX_CAPTIONOKBUTTON  在标题栏上有OK按钮
WS_EX_CONTEXTHELP      在标题栏上有帮助按钮
WS_EX_NOACTIVATE       点击窗口时,窗口不成为活动窗口
WS_EX_NOANIMATION      当窗口创建的时候,顶层窗口没有弹出矩形,在任务条上也没有按钮。
WS_EX_NODRAG        防止窗口被移动

参数dwExStyle是CreateWindowEx和CreateWindow之间唯一有差别的地方。实际上,如果你在Windows CE头文件里看CreateWindow的声明,会发现CreateWindow只是简单的将dwExStyle设置为0并调用CreateWindowEx而已。

第2个参数是实例化窗口所使用的窗口类的名字。在Hello3里,类名是MyClass,也就是用RegisterClass注册的类的名字。

第3个参数用做窗口文本。在Windows其它版本里,它是用做标准窗口标题栏里的文字。在H/PC里,主窗口很少有标题栏,这个文字只用在任务条按钮上。在Pocket PC里,这个文字出现在显示屏顶部导航条里。文字使用TEXT宏,确保字符串在Windows CE下可以转换成Unicode。

风格标志规定了窗口的初始风格。风格标志即用于系统里所有相关窗口的普通风格,也用于特定类的风格,比如按钮类或者列表框类的风格。在这种情况下,我们需要指定的就是用WS_VISIBLE标志来指明窗口在创建时可视。经验丰富的Win32程序员应该查阅关于CreateWindow的文档,因为许多窗口风格标志在Windows CE下并不支持。

接下来的四个参数指定了窗口初始位置和大小。因为Wimdows CE下大部分应用程序都是全屏窗口,所以每一个大小和位置域都使用CW_USEDEFAULT标志作为默认值。在Windows CE当前版本里,默认值创建的窗口,其大小覆盖整个屏幕。注意不要为Windows CE设备假设任何特殊的尺寸,因为不同的实现有不同的屏幕尺寸。

下一个域填写为父窗口的句柄。因为是顶层窗口,所以父窗口域设置为NULL。菜单域也设置为NULL,因为Windows CE不支持顶层窗口菜单。

hInstance参数就是传递给程序的实例句柄。窗口创建中实例句柄总会用的上,实例句柄是在程序开始时就被存储的。最后的参数是一个指针,在WM_CREATE消息期间,用于在CreateWindow调用时传递数据给窗口过程。本例中,没有额外数据需要传递,所以该参数设置为NULL。


如果创建窗口成功,CreateWindow返回刚创建的窗口的句柄,如果函数调用期间有错误发生,则返回0。在通过错误检查语句--if语句之后,该窗口句柄用在接下来的两个语句里(ShowWindow 和UpdateWindow里)。ShowWindow函数修改窗口状态,使其同传给WinMain的参数nCmdShow中给的状态一致。UpdateWindow函数则强制Windows发送WM_PAINT消息给刚创建的窗口。

消息循环
主窗口创建后,WinMain进入消息循环,这是每个Windows 应用程序的心脏。Hello3的消息循环定义如下:
while (GetMessage (&msg, NULL, 0, 0)) {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
}

该循环很简单:调用GetMessage函数,从应用程序消息队列中获取下一个消息。如果没有消息可用,则调用进入等待期,阻塞应用程序线程直到消息可用。当消息可用,该函数返回包含在MSG结构的消息数据。MSG结构自身包含几个域,有的用于识别消息,有的提供特定消息参数,有的识别在消息被发送之前,被笔触摸过的最后屏幕位置点。该位置信息不同于标准Win32消息位置数据,在XP下,返回的位置是当前鼠标位置而不是最后点击(或者tapped,在Windows CE里)的位置。

TranslateMessage 把适当的键盘信息转换成字符信息。(后面会讨论其它信息过滤器,比如IsDialogMsg。)DispatchMessage 接下来告诉Windows把消息发给应用程序适当的窗口。

获取消息、转换消息、分发消息这个过程会一直循环到GetMessage 收到WM_QUIT消息,这会使GetMessage返回0,这一点不同于其它消息。从while子句可以看出,GetMessage返回0将导致循环终止。

消息循环终止后,程序除了清理和退出外几乎不做什么。在Hello3里,程序简单的从WinMain中返回。WinMain的返回值成为程序的返回码。传统上,最后一个消息WM_QUIT的wParam参数值包含有返回值。为了响应应用程序对PostQuitMessage的调用,WM_QUIT消息被发送出去,此时WM_QUIT的wParam参数值被填充。


窗口过程
发送或提交(send 或 post方式)到Hello3主窗口的消息被送到MainWndProc过程中。和所有窗口过程一样,MainWndProc原型如下:
LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam, 
                              LPARAM lParam);

返回值类型LRESULT 实际上就是long型(在Windows里long是一个32位值),写成这种形式是为源代码和机器之间提供一个中间级。虽然你可以轻易的从包含文件中确定Windows编程时使用的变量的真实类型,但当你试图把代码做跨平台的转换时会产生问题。虽然了解变量类型的大小对计算内存使用是有用的,但没有什么好的理由去使用(实际上有很多不使用的理由)windows.h文件中提供的类型定义。

CALLBACK 类型指明该函数是EXE的外部入口点,这是Windows直接调用该过程所必须的。在桌面系统里,CALLBACK 指出参数是按类Pascal风格从右到左方式压进程序栈的,这和标准C语言方式相反。为外部入口点使用Pascal语言栈框架的原因可以追朔到Windows开发非常早的时期。使用固定大小、Pascal栈方式,意味着由被调用的过程来清理栈,而不是留给调用者来清理。这种方式可以有效的减少Windows及其附属程序的大小,所以早期的微软开发者认为这是一个好的方式。在Windows CE里,应用程序对所有函数都使用C栈框架,不管是否是外部调用。

传给窗口过程的第一个参数是窗口句柄,当您需要定义具体的窗口实例的时候,这个句柄是很有用的。wMsg参数表示发给窗口的消息。这不是WinMain消息循环里使用的MSG结构,而是一个包含消息值的unsigned整型。剩余两个参数,wParam 和lParam, 传递和具体消息有关的数据给窗口过程。它们的名字来自Win16时代,那时wParam是个16位值而lParam是32位值。同其它Win32操作系统一样,在Windows CE里,两个都是32位的。

和传统的窗口过程一样,Hello3的窗口过程通过一个switch语句解析wMsg消息ID。该switch语句包含2个case语句,一个用来解析WM_PAINT消息,另一个用来解析WM_DESTROY消息。这个窗口过程大概是窗口过程所能简化到及至的一个窗口过程了。

WM_PAINT
绘制窗口,处理WM_PAINT消息,这在任何Windows 程序中都是很重要的功能之一。窗口的外观是在程序处理WM_PAINT消息的过程中完成的。除了用您在注册窗口类时指定的刷子绘制默认背景外,Windows对处理该消息不提供任何帮助。Hello3中处理WM_PAINT消息如下:
case WM_PAINT:
    // Get the size of the client rectangle
    GetClientRect (hWnd, &rect);
   
    hdc = BeginPaint (hWnd, &ps); 
    DrawText (hdc, TEXT ("Hello Windows CE!"), -1, &rect, 
              DT_CENTER | DT_VCENTER | DT_SINGLELINE);
   
    EndPaint (hWnd, &ps); 
    return 0;
在窗口绘制之前,程序必须确定窗口大小。在Windows程序里,一个标准窗口被划分为两个区域--非客户区和客户区。窗口标题栏和可变大小的边框通常占据了窗口的非客户区,这个区域由Windows负责绘制。客户区属于窗口的内部区域,由应用程序负责绘制。应用程序通过调用GetClientRect 函数来确定客户区的大小和位置。该函数返回一个RECT结构,包含左上角、右下角坐标等描述客户区矩形边界的信息。分成客户区和非客户区的好处是,应用程序不必绘制那些窗口标准元素,例如标题栏。

其它版本的Windows提供一系列WM_NCxxx消息,允许您的应用程序绘制非客户区。在Windows CE里,窗口很少有标题栏。因为很少有非客户区,所以Windows CE不发送非客户端消息给窗口过程。

WM_PAINT消息里执行的所有绘制工作都必须由两个函数BeginPaint 和EndPaint包围。BeginPaint 函数返回设备环境句柄HDC。设备环境是物理显示设备(例如视频显示器或打印机)的逻辑代表。Windows程序从不直接修改显示硬件。相反,Windows用设备环境将程序与具体硬件隔离开。

BeginPaint 填充一个PAINTSTRUCT结构,其结构如下:
typedef struct tagPAINTSTRUCT {
    HDC  hdc;
    BOOL fErase;
    RECT rcPaint;
    BOOL fRestore;
    BOOL fIncUpdate;
    BYTE rgbReserved[32];
} PAINTSTRUCT;

hdc就是BeginPaint函数返回的句柄。fErase指出窗口过程是否需要重画窗口背景。rcPaint是RECT结构,定义了需要重画的客户区。Hello3忽略该域,并假设在每个WM_PAINT消息中,整个客户区窗口都需要重画。当性能是需要考虑的问题时,该域是很有用的,因为有时仅仅需要重画部分窗口即可。即使当程序尝试重画rcPaint矩形以外的区域

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -