用C语言撰写的Win32程序中,会见到如下的标准代码段:
hwnd = CreateWindow (szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
我以前常常疑惑,不知道窗口创建时的消息是怎样流动的。
消息队列的解释
今天重新看书(《深入浅出MFC》和《Programming Windows》),才较为彻底的了解了,程序有两个消息队列,见《深入浅出MFC》第一章P72:
"如果把應用程式獲得的各種「輸入」分類,可以分為由硬體裝置所產生的訊息(如滑鼠 移動或鍵盤被按下),放在系統佇列(system queue)中,以及由Windows 系統或其它 Windows 程式傳送過來的訊息,放在程式佇列(application queue)中。以應用程式的眼光來看,訊息就是訊息,來自哪裡或放在哪裡其實並沒有太大區別,反正程式呼叫GetMessage API 就取得一個訊息,程式的生命靠它來推動。所有的GUI 系統,包括UNIX的X Window 以及OS/2 的Presentation Manager,都像這樣,是以訊息為基礎的事件驅動系統。"
收到的第一个消息WM_CREATE
不会进入消息队列,而是由CreateWindow直接调用WndProc,见《Programming Windows》第三章中的说明:
"The very first message that a window procedure receives—and the first that HELLOWIN's WndProc chooses to process—is WM_CREATE. WndProc receives this message while Windows is processing the CreateWindow function in WinMain. That is, when HELLOWIN calls CreateWindow, Windows does what it has to do and, in the process, Windows calls WndProc with the first argument set to the window handle and the second argument set to WM_CREATE (the value 1). WndProc processes the WM_CREATE message and returns controls back to Windows. Windows can then return to HELLOWIN from the CreateWindow call to continue further progress in WinMain. "
窗口的显示与重绘
关于这个问题,《Programming Windows》第三章中也已经说得很明白了,就是CreateWindow只负责创建窗口,而显示窗口的工作就落在了ShowWindow这个函数上。那UpdateWindow又用来干嘛的呢?因为窗口被创建后,整个客户区都是无效的(invalid),ShowWindow也只是会用刷出个背景,而UpdateWindow就是用来产生WM_PAINT消息的,这个消息进不进消息队列呢?答案是不进消息队列。这个我们在MSDN上查找UpdateWindow函数的说明便可以知道。《Programming Window》中关于这一段解释的原文如下:
"How does a client area become invalid? When the window is first created, the entire client area is invalid because the program has not yet drawn anything on the window. The first WM_PAINT message (which normally occurs when the program calls UpdateWindow in WinMain) directs the window procedure to draw something on the client area. "
分享到:
相关推荐
要在Win32程序中正确显示和处理Qt界面,需要确保两个事件循环能够协同工作。有几种方法可以解决这个问题: 1. **集成事件循环**:通过`QApplication::exec`启动Qt的事件循环,并在Win32主循环中适时调用`...
一个简单的基于控制台的Win32程序通常包含以下几个部分: - 主函数(`int main()` 或 `int WinMain()`):程序的入口点。 - `WinMain`替代:在Win32程序中,可能使用`WinMain`替代`main`,因为它提供了额外的参数...
创建Win32服务主要涉及以下几个步骤: 1. **服务结构体定义**:首先需要定义一个`SERVICE_TABLE_ENTRY`结构体数组,这个数组包含了服务的名称和服务控制函数的指针。 2. **服务控制函数**:创建一个处理服务控制...
2. **初始化状态栏**:在程序启动时,我们调用`CreateStatusWindow`函数来创建状态栏。这个函数需要指定窗口类、样式、父窗口的句柄以及状态栏的初始文本。样式可以包括`WS_CHILD`(表示状态栏是父窗口的一个子窗口...
在这个实例中,服务程序可能包括以下几个关键部分: 1. **服务初始化**: 这通常涉及设置服务的基本信息,如服务描述、服务类型、错误控制等。 2. **服务入口点**: `ServiceMain()`函数,这是服务执行的主要逻辑。...
Win32.mak通常包含以下几个关键部分: 1. **变量定义**:定义了各种路径、编译器选项、链接器选项等全局变量。例如,`CC`代表C编译器,`CFLAGS`存储了C编译器的选项,`LIBS`则列出了链接时所需的库文件。 2. **...
Win32 API包含了以下几个主要的组件: 1. **用户界面组件**:这部分API提供了创建和管理窗口、菜单、对话框、控件以及图形绘制的功能。例如CreateWindow函数用于创建窗口,DrawText用于在窗口上显示文本,而...
在实际编程中,Win32 API的使用往往涉及以下几个关键步骤: 1. **初始化**:首先,需要通过WinMain函数启动应用程序,调用InitInstance初始化实例,注册窗口类并创建主窗口。 2. **消息循环**:通过PeekMessage/...
开发Win32对话框程序的过程中,还会涉及到以下几个关键知识点: - **Win32 API**:它是Windows操作系统的核心接口,提供了创建窗口、处理消息、绘制图形等功能。 - **对话框模板资源**:在资源文件(.rc)中,...
在Win32编程中,音乐播放主要涉及以下几个核心知识点: 1. **窗口创建**:使用`CreateWindowEx`函数创建应用程序的主窗口。这是所有Win32应用程序的起点,它定义了窗口的大小、位置、样式等属性。 2. **消息循环**...
Win32 API主要包含以下几个核心部分: 1. **系统服务**:这部分API提供了对进程、线程、内存管理、错误处理和系统调用的功能。例如,CreateProcess函数用于启动新的进程,CloseHandle用于关闭系统对象的句柄,...
Win32汇编语言程序设计涵盖了以下几个关键知识点: 1. **基本概念**:首先,学习汇编语言需要了解二进制、十六进制、八进制和十进制之间的转换,以及基本的计算机体系结构,如CPU的寄存器、指令集和内存模型。 2. ...
在我们的时钟程序中,我们主要会用到以下几个关键API: 1. `CreateWindow`:用于创建窗口对象,这是GUI应用程序的基本元素。 2. `ShowWindow`:控制窗口的显示状态,如隐藏、显示、最大化等。 3. `UpdateWindow`:...
计算器应用通常由以下几个主要部分构成: - **主窗口**:展示计算器界面,可能继承自`CFrameWnd`。 - **按钮控件**:表示数字和运算符,继承自`CButton`。 - **文本框控件**:显示输入和计算结果,继承自`CEdit`。 ...
一个简单的Win32程序通常包含以下几个步骤: 1. **程序初始化**:这包括设置程序的入口点,通常是`WinMain`函数。`WinMain`函数接收四个参数:当前实例句柄`hInstance`,前一个实例句柄`hPrevInstance`(在现代...
在Linux世界中,当我们需要制作可引导的USB启动盘来安装操作系统时,win32DiskImager是一个非常重要的工具。它特别适用于那些无法通过常规方法(如 Rufus 或 DiskPart)成功创建引导USB的情况。 描述中提到,...
Win32 API涵盖了以下几个主要方面: 1. **窗口管理**:包括创建、销毁、移动、调整大小、绘制和响应窗口消息等功能。例如CreateWindowEx函数用于创建窗口,DestroyWindow函数则用于销毁窗口。窗口消息是Windows应用...
在IT领域,游戏开发是一项复杂而充满挑战的任务,尤其是在使用像VC++这样的编程语言和Win32 API进行原生Windows应用程序开发时。本教程将深入探讨如何利用这些工具创建有趣的游戏。 **Windows API编程基础** ...
源码分析可能会包括以下几个方面: 1. **程序入口点**:程序的启动点,通常在`main()`函数或者Windows程序中的`WinMain()`函数。 2. **消息循环**:Windows程序通过消息循环来处理用户的输入和系统事件,这是GUI...
在本例中,源码可能会包括以下几个关键部分: 1. **程序启动与初始化**:易语言中的程序启动函数是`.程序启动子程序`,在这里会进行一些必要的初始化操作,比如设置程序窗口的属性,如大小、位置和标题。 2. **...