SendMessageTimeout函数使用方法的例子代码
2009-02-25 14:38

lresult sendmessagetimeout(
hwnd hwnd, // handle to window
uint msg, // message
wparam wparam, // first message parameter
lparam lparam, // second message parameter
uint fuflags, // send options
uint utimeout, // time-out duration
pdword_ptr lpdwresult // return value for synchronous call
);
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. the function does not return until each window has timed out. therefore, the total wait time can be up to utimeout times the number of top-level windows.

msg
[in] specifies the message to be sent.
wparam
[in] specifies additional message-specific information.
lparam
[in] specifies additional message-specific information.
fuflags
[in] specifies how to send the message. this parameter can be one or more of the following values. value meaning
smto_abortifhung returns without waiting for the time-out period to elapse if the receiving process appears to be in a "hung" state.
smto_block prevents the calling thread from processing any other requests until the function returns.
smto_normal the calling thread is not prevented from processing other requests while waiting for the function to return.
smto_notimeoutifnothung windows 2000/xp: does not return when the time-out period elapses if the receiving thread is not hung.


utimeout
[in] specifies the duration, in milliseconds, of the time-out period. if the message is a broadcast message, each window can us the full time-out period. for example, if you specify a 5 second time-out period and there are three top-level windows that fail to process the message, you could have up to a 15 second delay.
lpdwresult
[in] receives the result of the message processing. this value depends on the message sent.

 

#include <windows.h>

bool callback enumwindowsproc(
hwnd hwnd,
dword lparam
);

//
// enumwindowsproc must be called from a windows
// application on windows 95.
//
int winapi winmain(
hinstance hinstance,
hinstance hprevinstance,
lpstr lpcmdline,
int ncmdshow
)
{
//
// close all open applications.
//
enumwindows(enumwindowsproc, 0);

// now do a regular logoff.
exitwindowsex(ewx_logoff , 0);

}

bool callback enumwindowsproc(
hwnd hwnd,
dword lparam
)
{
dword pid = 0;
lresult lresult;
handle hprocess;
dword dwresult;

lresult = sendmessagetimeout(
hwnd,
wm_queryendsession,
0,
endsession_logoff,
smto_abortifhung,
2000,
&dwresult);

if( lresult )
{
//
// application will terminate nicely, so let it.
//
lresult = sendmessagetimeout(
hwnd,
wm_endsession,
true,
endsession_logoff,
smto_abortifhung,
2000,
&dwresult);

}
else // you have to take more forceful measures.
{
//
// get the processid for this window.
//
getwindowthreadprocessid( hwnd, &pid );
//
// open the process with all access.
//
hprocess = openprocess(process_all_access, false, pid);
//
// terminate the process.
//
terminateprocess(hprocess, 0);

}
//
// continue the enumeration.
//
return true;
}    

 

 

SendMessage : 如果指定窗口由调用线程创建,那么窗口过程会被当成一个子程序立即调用。如果指定窗口由另外一个线程创建,那么系统会切换到那个线程,并且调用合适的窗口过程。在线程之间传递的消息仅仅当接收线程执行message retrieval code才会被处理。发送线程会被堵塞直到接收线程处理完消息。但是,发送线程在等待的同时会处理收到的nonqueued messages 。为了阻止这一点,使用带有SMTO_BLOCK参数 的SendMessageTimeout .

==

我曾经遇到这个问题,我调用SendMessage向另外一个线程窗口发message,本来以为他会一直block住,但是他却调用了另外一个消息的处理程序,导致了行为不正确。所以一定要小心使用SendMessage发给其他线程的窗口。

我修改了一下,把
pWnd->SendMessage(MSG_LOG_MESSAGE, nMsgType, (LPARAM)(LPCTSTR)m_cstrMessage);
改成了
HWND hWnd = pWnd->GetSafeHwnd();
::SendMessageTimeout(hWnd,MSG_LOG_MESSAGE, nMsgType, (LPARAM)(LPCTSTR)m_cstrMessage,SMTO_BLOCK,15000,0);
解决了这个bug.