WIN32汇编语言学习应用之消息获取
MSG结构:
MSG STURCT
Hwnd DWORD ?
Message DWORD ?
WParam DWORD ?
LParam DWORD ?
Time DWORD ?
Pt POINT <>
MSG ENDS
:em21:
hwnd:消息要发向的窗口句柄
Message:消息标识符
Wparam:消息的参数之一
Lparam:消息的参数之二
Time:消息放入消息队列的时间。
pt:消息放入消息队列时的鼠标坐标,一个point结构。
getmessage函数
msdn解释
The GetMessage function retrieves a message from the callingthread's message queue. The function dispatches incoming sentmessages until a posted message is available for retrieval.
Unlike GetMessage, the PeekMessage function does not wait for amessage to be posted before returning.
语法
BOOL GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
);
getmessage的一个使用误区(来自msdn,算是权威了)
Because the return value can be nonzero, zero, or -1, avoid codelike this:
while (GetMessage( lpMsg, hWnd, 0, 0)) ...
虽然如果取得了WM_QUIT消息返回0,但是如果API执行发生了错误,则返回-1
The possibility of a -1 return value means that such code can leadto fatal application errors. Instead, use code like this:
下面的代码就处理了这样的问题
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) !=0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
PeekMessage Function peekmessage函数
--------------------------------------------------------------------------------
The PeekMessage function dispatches incoming sent messages, checksthe thread message queue for a posted message, and retrieves themessage (if any exist).
Syntax
BOOL PeekMessage( LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);
2、与getmessage的主要相同
PeekMessage is similar to the GetMessage function; both check amessage queue for a message that matches the filter criteria andthen copy the message to an MSG structure.
它们都可以在经过筛选标准的消息队列中,取得消息并COPY到MSG结构中。它们都可以通过参数指定得到特定的消息。
3、与getmessage的主要不同
(1)多了一个参数wRemoveMsg,定义消息如何被处理。
wRemoveMsg
Specifies how messages are handled. This parameter can be one ofthe following values.
PM_NOREMOVE
Messages are not removed from the queue after processing byPeekMessage.
在peeakmessage执行完后,不从消息队列中删除该消息
PM_REMOVE
Messages are removed from the queue after processing byPeekMessage.
在peeakmessage执行完后,从消息队列中删除该消息
You can optionally combine the value PM_NOYIELD with eitherPM_NOREMOVE or PM_REMOVE. This flag prevents the system fromreleasing any thread that is waiting for the caller to go idle (seeWaitForInputIdle).
By default, all message types are processed. To specify that onlycertain message should be processed, specify one or more of thefollowing values.
默认为处理所有类型的消息,如果只处理特定类型的消息,如下:
PM_QS_INPUT
Windows 98/Me, Windows 2000/XP: Process mouse and keyboardmessages.
PM_QS_PAINT
Windows 98/Me, Windows 2000/XP: Process paint messages.
PM_QS_POSTMESSAGE
Windows 98/Me, Windows 2000/XP: Process all posted messages,including timers and hotkeys.
PM_QS_SENDMESSAGE
Windows 98/Me, Windows 2000/XP: Process all sent messages.
(2)peekmessage如果有符合要求的消息可得到,则返回非0,如果得不到符合要求的消息则返回0;而getmessage如果在消息队列中得不到符合要求的有效消息就不会返回。
The main difference between the two functions is that GetMessagedoes not return until a message matching the filter criteria isplaced in the queue, whereas PeekMessage returns immediatelyregardless of whether a message is in the queue.
以MSDN中的例子来说,
Occasionally, an application needs to examine the contents of athread's message queue from outside the thread's message loop. Forexample, if an application's window procedure performs a lengthydrawing operation, you may want the user to be able to interruptthe operation. Unless your application periodically examines themessage queue during the operation for mouse and keyboard messages,it will not respond to user input until after the operation hascompleted. The reason for this is that the DispatchMessage functionin the thread's message loop does not return until the windowprocedure finishes processing a message.
上面的大致是说,如果你想在你定义的线程消息循环之外取得线程消息(线程消息队列是WINDOWS自动为每个线程维护的消息队列)。如一个窗口过程执行一个需要时间很长的操作,而你又想让用户能终止这一操作,比如按某一个键等等,但存在一个问题,DispatchMessage语句将一个消息分派给WINDOWS处理,WINDOWS又把这个消息转交给相应的窗口过程处理,在窗口过程处理完前,dispatchmessage是不会返回的,而这个很长的操作又正好是窗口过程执行的,
使用peekmessage来做这项检查工作最好,由它来定期检查消息队列中有无用户终止操作的相关消息,为什么不用getmessage呢,如果用户在窗口过程执行的过程中无终止的消息,或者因为用户无动作消息队列中根本无消息,那
getmessage岂不只能等着WINDOWS送消息进队列里来,否则它就不返回了,程序挂起了,无法起到检查消息队列的作用,而peekmessage则不同,取不到有效消息也返回。
下面是msdn的c++代码,只要用户按一个键或鼠标,则终止操作
The following example shows how to use PeekMessage to examine amessage queue for mouse clicks and keyboard input during a lengthyoperation.
HWND hwnd;
BOOL fDone;
MSG msg;
// Begin the operation and continue until it is complete
// or until the user clicks the mouse or presses a key.
fDone = FALSE;
while (!fDone)
{
fDone = DoLengthyOperation(); // application-defined function
// Remove any messages that may be in the queue. If the
// queue contains any mouse or keyboard
// messages, end the operation.
while (PeekMessage(&msg, hwnd, 0, 0,PM_REMOVE))
{
switch(msg.message)
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_KEYDOWN:
//
// Perform any required cleanup.
//
fDone = TRUE;
}
}
}