SDK中的消息机制

学了这么久的VC了,对WINDOWS的消息机制还是理解得不够到位,今天晚上来把SDK中得消息机制整理一下;先说明一下,这篇文章是我在边查资料的情况下写的,如果那里存在错误希望各位看客帮我指正一下,小弟感激不尽。

首先是消息得结构:

老办法先查MSDN

The MSG structure contains message information from a thread's message queue.

Syntax

ypedef struct {
    HWND hwnd;
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
    DWORD time;
    POINT pt;
} MSG, *PMSG;Members

hwnd
Handle to the window whose window procedure receives the message.
//指向消息窗口的句柄
message
Specifies the message identifier. Applications can only use the low word; the high word is reserved by the system.
//消息得表示符,应用程序只能使用低字节,高字节得作为保留字
wParam
Specifies additional information about the message. The exact meaning depends on the value of the message member.
//大致意思是不同得消息有不同的意思
lParam
Specifies additional information about the message. The exact meaning depends on the value of the message member.
//和Wparam定义一样
time
Specifies the time at which the message was posted.
//发送消息的时间
pt
Specifies the cursor position, in screen coordinates, when the message was posted.
//指明消息发送的坐标
其实消息结构也没有什么可多说的地方

关键地方是消息怎样被发送还有怎样被处理的

要是把这二个方面搞清楚了,应该能很好地理解SDK中的消息机制了。

首先是消息的发送:我开始的问题是,一个窗口在什么时候会发送消息?怎样在函数体内发送消息?也就是在一个函数内怎样调用消息函数去发送消息然后让制定的窗口作出相应的动作。

把一个消息发送到窗口有3种方式:发送、寄送和广播。
发送消息的函数有SendMessage、SendMessageCallback、SendNotifyMessage、SendMessageTimeout;

寄送消息的函数主要有PostMessage、PostThreadMessage、PostQuitMessage;

广播消息的函数我知道的只有BroadcastSystemMessage、BroadcastSystemMessageEx。

先看是拿SendMessage开刀。。。

MSDN:

The SendMessage function sends the specified message to a window or windows. It calls the window procedure for the specified window and does not return until the window procedure has processed the message.

To send a message and return immediately, use the SendMessageCallback or SendNotifyMessage function. To post a message to a thread's message immediately, queue and return use the PostMessage or PostThreadMessage function.

//SendMessage发送一个消息等待返回结果, 使用SendMessageCallback or SendNotifyMessage 立即返回,使用PostMessage or PostThreadMessage发送消息到一个线程
Syntax

LRESULT SendMessage(  HWND hWnd,
    UINT Msg,
    WPARAM wParam,
    LPARAM lParam
);Parameters

hWnd
[in] Handle to the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.

如果这个参数是HWND_BROADCAST消息将发送到所有的顶层窗口包括失效,隐藏,重叠和弹出窗口,但是这个消息不发送到子窗口
Msg
[in] Specifies the message to be sent.
wParam
[in] Specifies additional message-specific information.
lParam
[in] Specifies additional message-specific information.
Return Value

The return value specifies the result of the message processing; it depends on the message sent.


Remarks

Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function to obtain a unique message for inter-application communication.

The system only does marshalling for system messages (those in the range 0 to WM_USER). To send other messages (those above WM_USER) to another process, you must do custom marshalling.

上面这句是消息机制很关键的部分,请高手帮我翻译一下,谢谢了先

If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message. However, the sending thread will process incoming nonqueued messages while waiting for its message to be processed. To prevent this, use SendMessageTimeout with SMTO_BLOCK set. For more information on nonqueued messages, see Nonqueued Messages.

消息的接收主要有3个函数:GetMessage、PeekMessage、WaitMessage。

我们用SDK写程序都要用下面这样的代码

switch (message)
 {
  case WM_COMMAND:
         wmId    = LOWORD(wParam);
         wmEvent = HIWORD(wParam);
         // Parse the menu selections:
         switch (wmId)
         {case IDM_ABOUT:
             DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
             break;
          case IDM_EXIT:
             DestroyWindow(hWnd);
             break;
          default:
             return DefWindowProc(hWnd, message, wParam, lParam);
         }

上面那样的代码在消息少的情况下执行起来还可以,但是消息一多久会太让人受不了的

如是消息分流的概念被提出

下面是WindowsX.h中的部分内容

/****** Message crackers ****************************************************/

#define HANDLE_MSG(hwnd, message, fn)    /
    case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))

/* void Cls_OnCompacting(HWND hwnd, UINT compactRatio) */
#define HANDLE_WM_COMPACTING(hwnd, wParam, lParam, fn) /
    ((fn)((hwnd), (UINT)(wParam)), 0L)
#define FORWARD_WM_COMPACTING(hwnd, compactRatio, fn) /
    (void)(fn)((hwnd), WM_COMPACTING, (WPARAM)(UINT)(compactRatio), 0L)

/* void Cls_OnWinIniChange(HWND hwnd, LPCTSTR lpszSectionName) */
#define HANDLE_WM_WININICHANGE(hwnd, wParam, lParam, fn) /
    ((fn)((hwnd), (LPCTSTR)(lParam)), 0L)
#define FORWARD_WM_WININICHANGE(hwnd, lpszSectionName, fn) /
    (void)(fn)((hwnd), WM_WININICHANGE, 0L, (LPARAM)(LPCTSTR)(lpszSectionName))

/* void Cls_OnSysColorChange(HWND hwnd) */
#define HANDLE_WM_SYSCOLORCHANGE(hwnd, wParam, lParam, fn) /
    ((fn)(hwnd), 0L)
#define FORWARD_WM_SYSCOLORCHANGE(hwnd, fn) /
    (void)(fn)((hwnd), WM_SYSCOLORCHANGE, 0L, 0L)

/* BOOL Cls_OnQueryNewPalette(HWND hwnd) */
#define HANDLE_WM_QUERYNEWPALETTE(hwnd, wParam, lParam, fn) /
    MAKELRESULT((BOOL)(fn)(hwnd), 0L)
#define FORWARD_WM_QUERYNEWPALETTE(hwnd, fn) /
    (BOOL)(DWORD)(fn)((hwnd), WM_QUERYNEWPALETTE, 0L, 0L)

/* void Cls_OnPaletteIsChanging(HWND hwnd, HWND hwndPaletteChange) */
#define HANDLE_WM_PALETTEISCHANGING(hwnd, wParam, lParam, fn) /
    ((fn)((hwnd), (HWND)(wParam)), 0L)
#define FORWARD_WM_PALETTEISCHANGING(hwnd, hwndPaletteChange, fn) /
    (void)(fn)((hwnd), WM_PALETTEISCHANGING, (WPARAM)(HWND)(hwndPaletteChange), 0L)
.....................................................

下面就是分流的效果
switch(message)
      {
             HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);
             HANDLE_MSG(hWnd,WM_DESTROY,MsgCracker);
           default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
   }

明天在来研究了吧

睡觉了:(

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值