reactos操作系统实现(178)
SendMessageW函数主要用来向窗口发送消息。下面就是它的实现代码:
#001 LRESULT WINAPI
#002 SendMessageW(HWND Wnd,
#003 UINT Msg,
#004 WPARAM wParam,
#005 LPARAM lParam)
#006 {
#007 MSG UMMsg, KMMsg;
#008 NTUSERSENDMESSAGEINFO Info;
#009 LRESULT Result;
#010
如果不是广播消息,并且在合适范围的消息,就可以直接发送过去。
#011 if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
#012 {
#013 PWINDOW Window;
获取当前线程的结构。
#014 PW32THREADINFO ti = GetW32ThreadInfo();
#015
检查窗口句柄是否有效,并获取窗口指针。
#016 Window = ValidateHwnd(Wnd);
#017 if (Window != NULL && SharedPtrToUser(Window->ti) == ti && !IsThreadHooked(ti))
#018 {
#019 /* NOTE: We can directly send messages to the window procedure
#020 if *all* the following conditions are met:
#021
#022 * Window belongs to calling thread
#023 * The calling thread is not being hooked
#024 */
#025
直接发送给窗口处理函数。
#026 return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, FALSE);
#027 }
#028 }
#029
填写消息结构。
#030 UMMsg.hwnd = Wnd;
#031 UMMsg.message = Msg;
#032 UMMsg.wParam = wParam;
#033 UMMsg.lParam = lParam;
执行进程间的通讯消息,主要是WM_DDE_ACK,WM_DDE_EXECUTE,WM_COPYDATA。
#034 if (! MsgiUMToKMMessage(&UMMsg, &KMMsg, FALSE))
#035 {
#036 return FALSE;
#037 }
#038 Info.Ansi = FALSE;
调用内核函数NtUserSendMessage来发送消息给窗口。
#039 Result = NtUserSendMessage(KMMsg.hwnd, KMMsg.message,
#040 KMMsg.wParam, KMMsg.lParam, &Info);
#041 if (! Info.HandledByKernel)
#042 {
如果内核发送不成功,就需要直接调用窗口消息函数。
#043 MsgiUMToKMCleanup(&UMMsg, &KMMsg);
#044 /* We need to send the message ourselves */
#045 Result = IntCallWindowProcW(Info.Ansi, Info.Proc, UMMsg.hwnd, UMMsg.message,
#046 UMMsg.wParam, UMMsg.lParam);
#047 }
#048 else if (! MsgiUMToKMReply(&UMMsg, &KMMsg, &Result))
#049 {
#050 return FALSE;
#051 }
#052
#053 return Result;
#054 }