1.3 Writing the Window Procedure(编写窗口过程)

编写窗口过程(Writing the Window Procedure)

DispatchMessage函数调用作为消息目标窗口的窗口过程。窗口过程具有以下签名(signature)。

C++

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

4个参数:

  • hwnd 是对应窗口的一个句柄。
  • uMsg是消息代码;例如, WM_SIZE消息表明窗口被调整了大小。
  • wParamlParam包含与消息相关的其他数据。确切的含义取决于消息代码。

LRESULT是你的程序返回给Windows的一个整数值。它包含程序对特定消息的响应。这个值的含义取决于消息代码。CALLBACK是函数的调用约定。

一个典型的窗口过程就是一个大型的switch语句,它会打开消息代码。为要处理的每个消息添加case。

C++

switch (uMsg)

{

case WM_SIZE: // Handle window resizing

// etc

}

消息的其他数据包含在lParamwParam参数中。这两个参数都是指针宽度(32位或64位)大小的整数值。它们的含义取决于消息代码(uMsg)。对于每个消息,您需要在MSDN上查找消息代码,并将参数转换为正确的数据类型。通常数据要么是数值,要么是指向结构的指针。有些消息没有任何数据。

例如, WM_SIZE消息的文档表明:

  • wParam是一个标志,指示窗口是否被最小化、最大化或调整大小。
  • lParam包含窗口的新宽度和高度,将16位值打包成一个32位或64位数字。您将需要执行一些位移位(bit-shifting)来获取这些值。幸运的是,头文件WinDef.h包含执行此操作的辅助宏。

一个典型的窗口过程(window procedure)处理几十条消息,因此它可以长得相当长。使代码更模块化的一种方法是将处理每个消息的逻辑放在一个单独的函数中。在窗口过程中,将wParam和lParam参数转换为正确的数据类型,并将这些值传递给函数。例如,要处理WM_SIZE消息,窗口过程如下所示:

C++

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

    switch (uMsg)

    {

    case WM_SIZE:

        {

            int width = LOWORD(lParam);  // Macro to get the low-order word.

            int height = HIWORD(lParam); // Macro to get the high-order word.

            // Respond to the message:

            OnSize(hwnd, (UINT)wParam, width, height);

        }

        break;

    }

}

void OnSize(HWND hwnd, UINT flag, int width, int height)

{

    // Handle resizing

}

LOWORD 和HIWORD 宏从lParam获得16位的宽度和高度值。(您可以在MSDN文档中查找每个消息代码的详细信息)。窗口过程提取宽度和高度,然后将这些值传递给自己编写的OnSize函数。

默认消息处理(Default Message Handling)

如果不处理窗口过程中的特定消息,则将消息参数直接传递给DefWindowProc函数。此函数执行消息的默认操作,该操作因消息类型而异。

C++

    return DefWindowProc(hwnd, uMsg, wParam, lParam);

避免窗口过程中的瓶颈(Avoiding Bottlenecks in Your Window Procedure)

在执行窗口过程时,它会阻止(block)在同一线程上创建的窗口的任何其他消息。因此,避免在窗口过程中进行冗长的处理。例如,假设您的程序打开一个TCP连接并无限期地等待服务器响应。如果您在窗口过程中这样做,那么在请求完成之前,您的UI将不会响应。在此期间,窗口无法处理鼠标或键盘输入、重新绘制自身,甚至无法关闭。

相反,您应该将工作转移到另一个线程,使用Windows内置的多任务处理设施之一:

  • Create a new thread. 创建新线程
  • Use a thread pool. 使用线程池
  • Use asynchronous I/O calls. 使用异步I/O调用
  • Use asynchronous procedure calls. 使用异步程序调用

原文地址:https://www.cnblogs.com/wainzhang/p/9370917.html

时间: 2024-11-11 16:28:30

1.3 Writing the Window Procedure(编写窗口过程)的相关文章

32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数

32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数 (如果想看所有代码,请下载课堂资料,里面有所有代码,这里会讲解怎么生成一个窗口程序) 一丶32位汇编编写Windows窗口程序 首先我们知道32位汇编是可以调用Windows API的,那么今天我们就调用windowsAPI来写一个窗口程序 如果你有windows开发知识,那么就很理解了,如果没有,那么跟着我写,跟着步骤去写,那么也可以写出来 首先我们要编写一个窗口程序(使用SDKAPI编写)有几个步骤 1.设计窗口类 2.注

[翻译]Writing Custom Common Controls 编写自定义控件

摘要:介绍如何编写自定义的控件,用在报表的窗体上(如Edit,Button等)   Writing Custom Common Controls 编写自定义控件 FastReport contains a set of common controls which can be placed on dialogue forms inside reports. They are as follows: FastReport包含以下控件,用于报表里的对话形式窗体. TfrxLabelControl T

window.showModalDialog父子窗口参数传递

在开发过程中遇到window.showModalDialog()打开的模态对话框需要从子窗口传递返回值给父窗口中的某个插件,开始想通过window.opener得到,但是试了几次得不到,后来发现原来在当前打开窗口(子窗口)中可以通过window.returnValue=指定返回值;window.close();之后父窗口可以使用var result = window.showModalDialog(url,window,"dialogWidth=600px;dialogHeight=500px;

nw.js FrameLess Window下的窗口拖拽与窗口大小控制

nw.js FrameLess Window下的窗口拖拽与窗口大小控制 很多时候,我们觉得系统的Frame框很难看,于是想自定义. 自定义Frame的第一步是在package.config文件中将frame选项设置为false. { "name": "1", "main": "index.html", "nodejs": true, "single-instance": false, &

使用java语言编写窗口按钮

使用java语言编写窗口按钮 代码如下: package Day08; import java.awt.FlowLayout; import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JTextField; public class ShowFlowLayout extends JFrame { public ShowFlowLayout() { //Set

火狐浏览器中如何使用javascript:window.close()关闭窗口?

代码示例: <input type="button" value="关闭窗体" onclick="javascript:window.close()" /><input type="button" value="打印窗体" onclick="javascript:window.print()" /> 有时候在火狐浏览器使用javascript:window.clo

window.showModalDialog 子窗口数据回填父窗口

window.open 打开窗口时,可以很轻松的取得其父窗口.项目中需要用 showModalDialog打开窗口,想要取得父窗口值,而且还要在 open的基础上修改 为了不让 window.returnValue 所返回的值不是那么烦索,就要想办法如何用showModalDialog 打开的窗口取得其父窗口.合理利用 showModalDialog 传入的参数便可以解决这个问题. 话不多说,看例子: 父窗口:a.html <html>     <head>         <

windows 窗口过程 线程消息队列

message loop window procedure message loop: a for loop in thread or winmain  GetMessage, TranslateMessage, and DispatchMessage GetMessage: get the message DispatchMessage: Dispatches a message to a window procedure. ----- winproc WindowProc callback

pl/sql之编写分页过程

--开发一个包 --建立一个包,在该包中,我定义类型test_cursor,是个游标. 如下: Sql代码 create or replace package testpackage as TYPE test_cursor is ref cursor; end testpackage; --开始编写分页过程 create or replace procedure fenye (table_name in varchar2, page_size in number,        --每页显示的记