【Win32笔记二】视窗与消息机制

1.标志

    字首 类别
    CS 视窗类别样式
    CW 建立视窗
    DT 绘制文字
    IDI 图示ID
    IDC 游标ID
    MB 讯息方块
    SND 声音
    WM 视窗讯息
    WS 视窗样式


    结构 含义
    MSG 讯息结构
    WNDCLASS 视窗类别结构
    PAINTSTRUCT 绘图结构
    RECT 矩形结构


    识别字 含义
    HINSTANCE 执行实体(程式自身)代号
    HWND 视窗代号
    HDC 装置内容代号


    在本章结束之前,我们将遇到HICON(图
    示代号)、HCURSOR(滑鼠游标代号)和HBRUSH(画刷代号)。
    代号是一个(通常为32 位元的)整数,它代表一个物件


2. 匈牙利

    字首 资料型态
    c char 或WCHAR 或TCHAR
    by BYTE (无正负号字元)
    n short
    i int
    x, y int 分别用作x 座标和y 座标
    cx, cy int 分别用作x 长度和y 长度;C 代表「计数器」
    b 或f BOOL (int);f 代表「旗标」
    w WORD (无正负号短整数)
    l LONG (长整数)
    dw DWORD (无正负号长整数)
    fn function(函式)
    s string(字串)
    sz 以位元组值0 结尾的字串
    h 代号
    p 指标


3. 窗口注册类

    #ifdef UNICODE
    typedef WNDCLASSW WNDCLASS ;
    typedef PWNDCLASSW PWNDCLASS ;
    typedef NPWNDCLASSW NPWNDCLASS ;
    typedef LPWNDCLASSW LPWNDCLASS ;
    #else
    typedef WNDCLASSA WNDCLASS ;
    typedef PWNDCLASSA PWNDCLASS ;
    typedef NPWNDCLASSA NPWNDCLASS ;
    typedef LPWNDCLASSA LPWNDCLASS ;
    #endif




4. 讯息回圈

    Windows 为当前执行的每个Windows 程式
    维护一个「讯息伫列」。在发生输入事件之後,Windows 将事件转换为一个「讯
    息」并将讯息放入程式的讯息伫列中。
    程式通过执行一块称之为「讯息回圈」的程式码从讯息伫列中取出讯息:
    while (GetMessage (&msg, NULL, 0, 0))       //通知windows 将此结构填充
    {   
    TranslateMessage (&msg) ;                   //通知windows 进行一些键盘转换
    DispatchMessage (&msg) ;                    //通知windows 呼叫相应窗口的处理函式,如窗口CALLBACK函数WndProc
    }


    消息类型
    typedef struct tagMSG
    {
    HWND hwnd ;
    UINT message ;
    WPARAM wParam ;
    LPARAM lParam ;
    DWORD time ;
    POINT pt ;
    }
    MSG, * PMSG ;


    typedef struct tagPOINT
    {
    LONG x ;
    LONG y ;
    }
    POINT, * PPOINT;




    第二、第三和第四个参数设定为NULL 或者0,表示程式接收它自己建立的所有视窗的所有讯息


    消息循环机制:


    讯息回圈以GetMessage 呼叫开始,它从讯息伫列中取出一个讯息:
    GetMessage (&msg, NULL, 0, 0)
    这一呼叫传给Windows 一个指标,指向名为msg 的MSG 结构。第二、第三
    和第四个参数设定为NULL 或者0,表示程式接收它自己建立的所有视窗的所有
    讯息。Windows 用从讯息伫列中取出的下一个讯息来填充讯息结构的各个栏位,
    结构的各个栏位包括:
    hwnd 接收讯息的视窗代号。在HELLOWIN 程式中,这一参数与CreateWindow
    传回的hwnd 值相同,因为这是该程式拥有的唯一视窗。
    message 讯息识别字。这是一个数值,用以标识讯息。对於每个讯息,均
    有一个对应的识别字,这些识别字定义於Windows 表头档案(其中大多数在
    WINUSER.H 中),以字首WM(「window message」,视窗讯息)开头。例如,


    使用者将滑鼠游标放在HELLOWIN 显示区域之内,并按下滑鼠左按钮,Windows
    就在讯息伫列中放入一个讯息,该讯息的message 栏位等於WM_LBUTTONDOWN。
    这是一个常数,其值为0x0201。
        wParam 一个32 位元的「message parameter(讯息参数)」,其含义和数值根
        据讯息的不同而不同。
        lParam 一个32 位元的讯息参数,其值与讯息有关。
        time 讯息放入讯息伫列中的时间。
        pt 讯息放入讯息伫列时的滑鼠座标。
    只要从讯息伫列中取出讯息的message栏位不为WM_QUIT(其值为0x0012),
    GetMessage 就传回一个非零值。WM_QUIT 讯息将导致GetMessage 传回0。
    叙述
    TranslateMessage (&msg) ;
    将msg 结构传给Windows,进行一些键盘转换。(关於这一点,我们将在第
    六章中深入讨论。)
    叙述
    DispatchMessage (&msg) ;
    又将msg 结构回传给Windows。然後,Windows 将该讯息发送给适当的视窗
    讯息处理程式,让它进行处理。这也就是说,Windows 将呼叫视窗讯息处理程式。
    在HELLOWIN 中,这个视窗讯息处理程式就是WndProe 函式。处理完讯息之後,
    WndProc 传回到Windows。此时,Windows 还停留在DispatchMessage 呼叫中。
    在结束DispatchMessage 呼叫的处理之後,Windows 回到HELLOWIN,并且接著
    从下一个GetMessage 呼叫开始讯息回圈。


5. 视窗讯息处理函式



    视窗讯息处理程式可任意命名(只要求不和其他名字发生冲突)。一个Windows 程式可以
    包含多个视窗讯息处理程式。一个视窗讯息处理程式总是与呼叫RegisterClass
    注册的特定视窗类别相关联。CreateWindow 函式根据特定视窗类别建立一个视
    窗。但依据一个视窗类别,可以建立多个视窗。


    视窗讯息处理程式总是定义为如下形式:
    #define CALLBACK __stdcall
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);


    注意,视窗讯息处理程式的四个参数与MSG 结构的前四个栏位是相同的。
    第一个参数hwnd 是接收讯息的视窗的代号,它与CreateWindow 函式的传回值
    相同。对於与HELLOWIN 相似的程式(只建立一个视窗),这个参数是程式所知
    道的唯一视窗代号。如果程式是依据同一视窗类别(同时也是同一视窗讯息处
    理程式)建立多个视窗,则hwnd 标识接收讯息的特定视窗。
    第二个参数与MSG 结构中的message 栏位相同,它是标识讯息的数值。最
    後两个参数都是32位元的讯息参数,提供关於讯息的更多资讯。这些参数包含
    每个讯息型态的详细资讯。有时讯息参数是两个存放在一起的16位元值,而有
    时讯息参数又是一个指向字串或资料结构的指标。


    程式通常不直接呼叫视窗讯息处理程式,视窗讯息处理程式通常由Windows
    本身呼叫。通过呼叫SendMessage 函式,程式能够直接呼叫它自己的视窗讯息
    处理程式.


6. 处理讯息



    视窗讯息处理程式在处理讯息时,必须传回0。视窗讯息处理程式不予处理的所有讯息应该被传给名为
    DefWindowProc 的Windows函式。从DefWindowProc 传回的值必须由视窗讯息处
    理程式传回。

WndProc(...)
{

    switch(message)
    {
        ...


        default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}




    WM_PAINT讯息
    WndProc 处理的第二个讯息为WM_PAINT。这个讯息在Windows 程式设计中
    是很重要的。当视窗显示区域的一部分显示内容或者全部变为「无效」,以致
    於必须「更新画面」时,将由这个讯息通知程式。

 
    如:最小化再显示、区域覆盖等,window并不保存这些信息,所以再显示时就需要重画


    对WM_PAINT 的处理几乎总是从一个BeginPaint 呼叫开始:
    hdc = BeginPaint (hwnd, &ps) ;
    而以一个EndPaint 呼叫结束:
    EndPaint (hwnd, &ps) ;


    WNDCLASS 中的hbrBackground刷来删除背景,这是一个白色备用画刷,这意味著,Windows
    将通过把视窗背景设定为白色来删除视窗背景


    WM_DESTROY


    WM_DESTROY 讯息是另一个重要讯息。这一个讯息指示,Windows 正在根据
    使用者的指示关闭视窗。该讯息是使用者单击Close 按钮或者在程式的系统功
    能表上选择 Close时发生的(在本章的後面,我们将详细讨论WM_DESTROY讯息
    是如何生效的)。
    HELLOWIN 通过呼叫PostQuitMessage 以标准方式回应WM_DESTROY 讯息:
    PostQuitMessage (0) ;
    该函式在程式的讯息伫列中插入一个WM_QUIT 讯息。前面提到过,
    GetMessage 对於除了WM_QUIT 之外的从讯息伫列中取出的所有讯息都传回非0
    值。而当GetMessage 得到一个WM_QUIT 讯息时,它传回0。这将导致WinMain
    退出讯息回圈,并终止程式


7. 别呼叫我,我会呼叫您

    视窗讯息处理程式与视窗类别相关,视窗类别是程式呼叫RegisterClass 注册的。
    依据该类别建立的视窗使用这个视窗讯息处理程式来处理视窗的所有讯息。
    Windows 通过呼叫视窗讯息处理程式对视窗发送讯息


8. 伫列化讯息与非伫列化讯息

    讯息能够被分为「伫列化的」和「非伫列化的」。伫列化的讯息是由Windows
    放入程式讯息伫列中的。在程式的讯息回圈中,重新传回并分配给视窗讯息处
    理程式。非伫列化的讯息在Windows 呼叫视窗时直接送给视窗讯息处理程式。
    也就是说,伫列化的讯息被「发送」给讯息伫列,而非伫列化的讯息则「发送」
    给视窗讯息处理程式


    伫列化讯息基本上是使用者输入的结果,以击键(如WM_KEYDOWN和WM_KEYUP
    讯息)、击键产生的字元(WM_CHAR)、滑鼠移动(WM_MOUSEMOVE)和滑鼠按钮
    (WM_LBUTTONDOWN)的形式给出。伫列化讯息还包含时钟讯息(WM_TIMER)、
    更新讯息(WM_PAINT)和退出讯息(WM_QUIT)。


    非伫列化讯息则是其他讯息。在许多情况下,非伫列化讯息来自呼叫特定
    的Windows 函式。例如,当WinMain 呼叫CreateWindow 时,Windows 将建立视
    窗并在处理中给视窗讯息处理程式发送一个WM_CREATE 讯息。当WinMain 呼叫
    ShowWindow 时,Windows 将给视窗讯息处理程式发送WM_SIZE 和WM_SHOWWINDOW
    讯息。当WinMain 呼叫UpdateWindow 时,Windows 将给视窗讯息处理程式发送
    WM_PAINT 讯息。键盘或滑鼠输入时发出的伫列化讯息信号,也能在非伫列化讯
    息中出现。例如,用键盘或滑鼠选择了一个功能表项时,键盘或滑鼠讯息就是
    伫列化的,而说明功能表项已选中的WM_COMMAND 讯息则可能就是非伫列化的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值