- Updates and changes to, with one add on and removal: MenuWindowProc (Not supported in kernel space), PopupMenuWndProcA, PostMessage, SendNotifyMessage and win32k hook debugs.

- Patch by Smiley <johnyadams@hotmail.com>: Wrong PostMessage and SendNotifyMessage behavior, see Bug 4646.
- Reference: Related to TranslateMessage: http://msdn.microsoft.com/en-us/library/aa912145.aspx , Related to PopupMenuWndProcA: Registration of Atom classes, Unicode only: http://www.reactos.org/archives/public/ros-dev/2007-October/009976.html

svn path=/trunk/; revision=41772
This commit is contained in:
James Tabor 2009-07-04 16:31:11 +00:00
parent 43005003c0
commit 0aeef70968
7 changed files with 239 additions and 260 deletions

View file

@ -483,8 +483,8 @@
@ stdcall MapVirtualKeyW(long long)
@ stdcall MapWindowPoints(long long ptr long)
@ stdcall MenuItemFromPoint(long long double) ; Direct call NtUserMenuItemFromPoint
@ stdcall MenuWindowProcA (long long long long)
@ stdcall MenuWindowProcW (long long long long)
@ stdcall MenuWindowProcA (long ptr long long long)
@ stdcall MenuWindowProcW (long ptr long long long)
@ stdcall MessageBeep(long)
@ stdcall MessageBoxA(long str str long)
@ stdcall MessageBoxExA(long str str long long)

View file

@ -72,6 +72,7 @@ typedef struct
POINT Pt;
} MTRACKER;
static LRESULT WINAPI PopupMenuWndProcA(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
static LRESULT WINAPI PopupMenuWndProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
/*********************************************************************
@ -971,6 +972,70 @@ MenuDrawPopupMenu(HWND Wnd, HDC Dc, HMENU Menu)
}
}
static LRESULT WINAPI
PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam);
switch(Message)
{
case WM_CREATE:
{
CREATESTRUCTA *cs = (CREATESTRUCTA *) lParam;
SetWindowLongPtrA(Wnd, 0, (LONG) cs->lpCreateParams);
return 0;
}
case WM_MOUSEACTIVATE: /* We don't want to be activated */
return MA_NOACTIVATE;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(Wnd, &ps);
MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrA(Wnd, 0));
EndPaint(Wnd, &ps);
return 0;
}
case WM_ERASEBKGND:
return 1;
case WM_DESTROY:
/* zero out global pointer in case resident popup window was destroyed. */
if (Wnd == TopPopup)
{
TopPopup = NULL;
}
break;
case WM_SHOWWINDOW:
if (0 != wParam)
{
if (0 == GetWindowLongPtrA(Wnd, 0))
{
OutputDebugStringA("no menu to display\n");
}
}
else
{
SetWindowLongPtrA(Wnd, 0, 0);
}
break;
case MM_SETMENUHANDLE:
SetWindowLongPtrA(Wnd, 0, wParam);
break;
case MM_GETMENUHANDLE:
return GetWindowLongPtrA(Wnd, 0);
default:
return DefWindowProcA(Wnd, Message, wParam, lParam);
}
return 0;
}
static LRESULT WINAPI
PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
@ -5161,33 +5226,56 @@ GetMenuContextHelpId(HMENU hmenu)
/*
* @unimplemented
*/
LRESULT
BOOL
WINAPI
MenuWindowProcA(
HWND hWnd,
ULONG_PTR Result,
UINT Msg,
WPARAM wParam,
LPARAM lParam
)
{
UNIMPLEMENTED;
return FALSE;
if ( Msg < WM_USER)
{
LRESULT lResult;
lResult = PopupMenuWndProcA(hWnd, Msg, wParam, lParam );
if (Result)
{
Result = (ULONG_PTR)lResult;
return TRUE;
}
return FALSE;
}
return NtUserMessageCall(hWnd, Msg, wParam, lParam, Result, FNID_MENU, TRUE);
}
/*
* @unimplemented
*/
LRESULT
BOOL
WINAPI
MenuWindowProcW(
HWND hWnd,
ULONG_PTR Result,
UINT Msg,
WPARAM wParam,
LPARAM lParam
)
{
UNIMPLEMENTED;
return FALSE;
if ( Msg < WM_USER)
{
LRESULT lResult;
lResult = PopupMenuWndProcW(hWnd, Msg, wParam, lParam );
if (Result)
{
Result = (ULONG_PTR)lResult;
return TRUE;
}
return FALSE;
}
return NtUserMessageCall(hWnd, Msg, wParam, lParam, Result, FNID_MENU, FALSE);
}
/*

View file

@ -1632,51 +1632,12 @@ PeekMessageW(
return Res;
}
/*
* @implemented
*/
//
// Worker function for post message.
//
BOOL
WINAPI
PostMessageA(
HWND Wnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
MSG AnsiMsg, UcMsg;
MSG KMMsg;
LRESULT Result;
AnsiMsg.hwnd = Wnd;
AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
if (! MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
{
return FALSE;
}
if (! MsgiUMToKMMessage(&UcMsg, &KMMsg, TRUE))
{
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
return FALSE;
}
Result = NtUserPostMessage(KMMsg.hwnd, KMMsg.message,
KMMsg.wParam, KMMsg.lParam);
MsgiUMToKMCleanup(&UcMsg, &KMMsg);
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
return Result;
}
/*
* @implemented
*/
BOOL
WINAPI
PostMessageW(
FASTCALL
PostMessageWorker(
HWND Wnd,
UINT Msg,
WPARAM wParam,
@ -1690,60 +1651,25 @@ PostMessageW(
UMMsg.wParam = wParam;
UMMsg.lParam = lParam;
if (! MsgiUMToKMMessage(&UMMsg, &KMMsg, TRUE))
{
return FALSE;
}
Result = NtUserPostMessage(KMMsg.hwnd, KMMsg.message,
KMMsg.wParam, KMMsg.lParam);
{
return FALSE;
}
Result = NtUserPostMessage( KMMsg.hwnd,
KMMsg.message,
KMMsg.wParam,
KMMsg.lParam);
MsgiUMToKMCleanup(&UMMsg, &KMMsg);
return Result;
}
/*
* @implemented
*/
BOOL
WINAPI
PostMessageWX(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
LRESULT Ret;
/* Check for combo box or a list box to send names. */
if (Msg == CB_DIR || Msg == LB_DIR)
{
/*
Set DDL_POSTMSGS, so use the PostMessage function to send messages to the
combo/list box. Forces a call like DlgDirListComboBox.
*/
wParam |= DDL_POSTMSGS;
return NtUserPostMessage(hWnd, Msg, wParam, lParam);
}
/* No drop files or current Process, just post message. */
if ( (Msg != WM_DROPFILES) ||
( NtUserQueryWindow( hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
PtrToUint(NtCurrentTeb()->ClientId.UniqueProcess) ) )
{
return NtUserPostMessage(hWnd, Msg, wParam, lParam);
}
/* We have drop files or this is not the same process for this window. */
/* Just incase, check wParam for Global memory handle and send size. */
Ret = SendMessageW( hWnd,
WM_COPYGLOBALDATA,
(WPARAM)GlobalSize((HGLOBAL)wParam), // Zero if not a handle.
(LPARAM)wParam); // Send wParam as lParam.
if ( Ret ) return NtUserPostMessage(hWnd, Msg, (WPARAM)Ret, lParam);
return FALSE;
}
BOOL
WINAPI
PostMessageAX(
PostMessageA(
HWND hWnd,
UINT Msg,
WPARAM wParam,
@ -1762,13 +1688,58 @@ PostMessageAX(
return FALSE;
}
Ret = PostMessageWX( hWnd, UcMsg.message, UcMsg.wParam, UcMsg.lParam);
Ret = PostMessageW( hWnd, UcMsg.message, UcMsg.wParam, UcMsg.lParam);
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
return Ret;
}
/*
* @implemented
*/
BOOL
WINAPI
PostMessageW(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
LRESULT Ret;
/* Check for combo box or a list box to send names. */
if (Msg == CB_DIR || Msg == LB_DIR)
{
/*
Set DDL_POSTMSGS, so use the PostMessage function to send messages to the
combo/list box. Forces a call like DlgDirListComboBox.
*/
wParam |= DDL_POSTMSGS;
return PostMessageWorker(hWnd, Msg, wParam, lParam);
}
/* No drop files or current Process, just post message. */
if ( (Msg != WM_DROPFILES) ||
( NtUserQueryWindow( hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
PtrToUint(NtCurrentTeb()->ClientId.UniqueProcess) ) )
{
return PostMessageWorker(hWnd, Msg, wParam, lParam);
}
/* We have drop files and this is not the same process for this window. */
/* Just incase, check wParam for Global memory handle and send size. */
Ret = SendMessageW( hWnd,
WM_COPYGLOBALDATA,
(WPARAM)GlobalSize((HGLOBAL)wParam), // Zero if not a handle.
(LPARAM)wParam); // Send wParam as lParam.
if ( Ret ) return PostMessageWorker(hWnd, Msg, (WPARAM)Ret, lParam);
return FALSE;
}
/*
* @implemented
*/
@ -2113,9 +2084,8 @@ SendMessageTimeoutW(
return Result;
}
/*
* @unimplemented
* @implemented
*/
BOOL
WINAPI
@ -2125,35 +2095,26 @@ SendNotifyMessageA(
WPARAM wParam,
LPARAM lParam)
{
BOOL Ret;
MSG AnsiMsg, UcMsg;
MSG KMMsg;
LRESULT Result;
AnsiMsg.hwnd = hWnd;
AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
if (! MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
{
return FALSE;
}
{
return FALSE;
}
Ret = SendNotifyMessageW(hWnd, UcMsg.message, UcMsg.wParam, UcMsg.lParam);
if (! MsgiUMToKMMessage(&UcMsg, &KMMsg, TRUE))
{
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
return FALSE;
}
Result = NtUserSendNotifyMessage(KMMsg.hwnd, KMMsg.message,
KMMsg.wParam, KMMsg.lParam);
MsgiUMToKMCleanup(&UcMsg, &KMMsg);
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
return Result;
return Ret;
}
/*
* @unimplemented
* @implemented
*/
BOOL
WINAPI
@ -2171,52 +2132,20 @@ SendNotifyMessageW(
UMMsg.wParam = wParam;
UMMsg.lParam = lParam;
if (! MsgiUMToKMMessage(&UMMsg, &KMMsg, TRUE))
{
return FALSE;
}
Result = NtUserSendNotifyMessage(KMMsg.hwnd, KMMsg.message,
KMMsg.wParam, KMMsg.lParam);
MsgiUMToKMCleanup(&UMMsg, &KMMsg);
return Result;
}
BOOL
WINAPI
SendNotifyMessageAX(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
BOOL Ret;
MSG AnsiMsg, UcMsg;
AnsiMsg.hwnd = hWnd;
AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
if (! MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
{
return FALSE;
}
/* ATM, ReactOS does not support Ansi in win32k. */
Ret = NtUserMessageCall(hWnd, UcMsg.message, UcMsg.wParam, UcMsg.lParam, 0, FNID_SENDNOTIFYMESSAGE, FALSE);
Result = NtUserMessageCall( hWnd,
KMMsg.message,
KMMsg.wParam,
KMMsg.lParam,
0,
FNID_SENDNOTIFYMESSAGE,
FALSE);
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
MsgiUMToKMCleanup(&UMMsg, &KMMsg);
return Ret;
}
BOOL
WINAPI
SendNotifyMessageWX(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
return NtUserMessageCall(hWnd, Msg, wParam, lParam, 0, FNID_SENDNOTIFYMESSAGE, FALSE);
return Result;
}
/*
@ -2234,6 +2163,8 @@ TranslateMessageEx(CONST MSG *lpMsg, DWORD unk)
return(NtUserTranslateMessage((LPMSG)lpMsg, (HKL)unk));
default:
if ( lpMsg->message & ~WM_MAXIMUM )
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
@ -2245,7 +2176,20 @@ TranslateMessageEx(CONST MSG *lpMsg, DWORD unk)
BOOL WINAPI
TranslateMessage(CONST MSG *lpMsg)
{
return(TranslateMessageEx((LPMSG)lpMsg, 0));
BOOL Ret = FALSE;
// Ref: msdn ImmGetVirtualKey:
// http://msdn.microsoft.com/en-us/library/aa912145.aspx
/*
if ( (LOWORD(lpMsg->wParam) != VK_PROCESSKEY) ||
!(Ret = IMM_ImmTranslateMessage( lpMsg->hwnd,
lpMsg->message,
lpMsg->wParam,
lpMsg->lParam)) )*/
{
Ret = TranslateMessageEx((LPMSG)lpMsg, 0);
}
return Ret;
}

View file

@ -566,6 +566,7 @@ typedef struct _USERCONNECT
#define WM_SYSTIMER 280
#define WM_POPUPSYSTEMMENU 787
#define WM_CBT 1023 // ReactOS only.
#define WM_MAXIMUM 0x0001FFFF
//
// Non SDK DCE types.
@ -3078,16 +3079,6 @@ NtUserSendMessageTimeout(HWND hWnd,
ULONG_PTR *uResult,
PNTUSERSENDMESSAGEINFO Info);
/* use NtUserMessageCall */
BOOL
NTAPI
NtUserSendNotifyMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
typedef struct _SETSCROLLBARINFO
{
int nTrackPos;

View file

@ -785,14 +785,14 @@ UserCallNextHookEx(PHOOK Hook,
}
case WH_CBT:
DPRINT1("HOOK WH_CBT!\n");
DPRINT("HOOK WH_CBT!\n");
switch (Code)
{
case HCBT_CREATEWND:
{
LPCBT_CREATEWNDW pcbtcww = (LPCBT_CREATEWNDW)lParam;
DPRINT1("HOOK HCBT_CREATEWND\n");
DPRINT("HOOK HCBT_CREATEWND\n");
_SEH2_TRY
{
if (Ansi)
@ -856,7 +856,7 @@ UserCallNextHookEx(PHOOK Hook,
{
RECTL rt;
DPRINT1("HOOK HCBT_MOVESIZE\n");
DPRINT("HOOK HCBT_MOVESIZE\n");
if (lParam)
{
@ -893,7 +893,7 @@ UserCallNextHookEx(PHOOK Hook,
{
CBTACTIVATESTRUCT CbAs;
DPRINT1("HOOK HCBT_ACTIVATE\n");
DPRINT("HOOK HCBT_ACTIVATE\n");
if (lParam)
{
_SEH2_TRY
@ -927,7 +927,7 @@ UserCallNextHookEx(PHOOK Hook,
/* The rest just use default. */
default:
DPRINT1("HOOK HCBT_ %d\n",Code);
DPRINT("HOOK HCBT_ %d\n",Code);
lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam);
break;
}

View file

@ -1314,10 +1314,14 @@ UserPostMessage(HWND Wnd,
LPARAM lParam)
{
PTHREADINFO pti;
MSG UserModeMsg, KernelModeMsg;
MSG Message;
LARGE_INTEGER LargeTickCount;
NTSTATUS Status;
PMSGMEMORY MsgMemoryEntry;
if (FindMsgMemory(Msg) != 0)
{
SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
pti = PsGetCurrentThreadWin32Thread();
if (Wnd == HWND_BROADCAST)
@ -1358,24 +1362,14 @@ UserPostMessage(HWND Wnd,
}
else
{
UserModeMsg.hwnd = Wnd;
UserModeMsg.message = Msg;
UserModeMsg.wParam = wParam;
UserModeMsg.lParam = lParam;
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
IntGetCursorLocation(pti->Desktop->WindowStation,
&KernelModeMsg.pt);
Message.hwnd = Wnd;
Message.message = Msg;
Message.wParam = wParam;
Message.lParam = lParam;
IntGetCursorLocation(pti->Desktop->WindowStation, &Message.pt);
KeQueryTickCount(&LargeTickCount);
pti->timeLast = KernelModeMsg.time = MsqCalculateMessageTime(&LargeTickCount);
MsqPostMessage(Window->MessageQueue, &KernelModeMsg,
NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
QS_POSTMESSAGE);
pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
MsqPostMessage(Window->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
}
}
@ -1410,14 +1404,20 @@ NtUserPostThreadMessage(DWORD idThread,
WPARAM wParam,
LPARAM lParam)
{
MSG UserModeMsg, KernelModeMsg;
MSG Message;
PETHREAD peThread;
PTHREADINFO pThread;
NTSTATUS Status;
PMSGMEMORY MsgMemoryEntry;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserPostThreadMessage\n");
if (FindMsgMemory(Msg) != 0)
{
SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
UserEnterExclusive();
Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
@ -1431,21 +1431,11 @@ NtUserPostThreadMessage(DWORD idThread,
RETURN( FALSE);
}
UserModeMsg.hwnd = NULL;
UserModeMsg.message = Msg;
UserModeMsg.wParam = wParam;
UserModeMsg.lParam = lParam;
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
{
ObDereferenceObject( peThread );
SetLastWin32Error(ERROR_INVALID_PARAMETER);
RETURN( FALSE);
}
MsqPostMessage(pThread->MessageQueue, &KernelModeMsg,
NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
QS_POSTMESSAGE);
Message.hwnd = NULL;
Message.message = Msg;
Message.wParam = wParam;
Message.lParam = lParam;
MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
ObDereferenceObject( peThread );
RETURN( TRUE);
}
@ -1682,7 +1672,7 @@ co_IntPostOrSendMessage(HWND hWnd,
}
pti = PsGetCurrentThreadWin32Thread();
if(Window->MessageQueue != pti->MessageQueue)
if(Window->MessageQueue != pti->MessageQueue && FindMsgMemory(Msg) ==0)
{
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
}
@ -1878,6 +1868,13 @@ UserSendNotifyMessage(HWND hWnd,
LPARAM lParam)
{
BOOL Result = TRUE;
if (FindMsgMemory(Msg) != 0)
{
SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
// Basicly the same as IntPostOrSendMessage
if (hWnd == HWND_BROADCAST) //Handle Broadcast
{
@ -1902,10 +1899,7 @@ UserSendNotifyMessage(HWND hWnd,
ULONG_PTR PResult;
PTHREADINFO pti;
PWINDOW_OBJECT Window;
NTSTATUS Status;
MSG UserModeMsg;
MSG KernelModeMsg;
PMSGMEMORY MsgMemoryEntry;
MSG Message;
if(!(Window = UserGetWindowObject(hWnd))) return FALSE;
@ -1916,55 +1910,18 @@ UserSendNotifyMessage(HWND hWnd,
}
else
{ // Handle message and callback.
UserModeMsg.hwnd = hWnd;
UserModeMsg.message = Msg;
UserModeMsg.wParam = wParam;
UserModeMsg.lParam = lParam;
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
Result = co_IntSendMessageTimeoutSingle(
KernelModeMsg.hwnd, KernelModeMsg.message,
KernelModeMsg.wParam, KernelModeMsg.lParam,
SMTO_NORMAL, 0, &PResult);
Message.hwnd = hWnd;
Message.message = Msg;
Message.wParam = wParam;
Message.lParam = lParam;
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
if (! NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
Result = co_IntSendMessageTimeoutSingle( hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &PResult);
}
}
return Result;
}
BOOL APIENTRY
NtUserSendNotifyMessage(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
DECLARE_RETURN(BOOL);
DPRINT("EnterNtUserSendNotifyMessage\n");
UserEnterExclusive();
RETURN(UserSendNotifyMessage(hWnd, Msg, wParam, lParam));
CLEANUP:
DPRINT("Leave NtUserSendNotifyMessage, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
BOOL APIENTRY
NtUserWaitMessage(VOID)
{

View file

@ -699,5 +699,4 @@ NtUserRegisterClassEx 6
NtUserMonitorFromWindow 2
NtUserSendMessage 5
NtUserSendMessageTimeout 8
NtUserSendNotifyMessage 4
NtUserSetScrollBarInfo 3