diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index 5631469c03c..6c849042b7a 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -60,6 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32); * content). When a ACK message is generated, the list of pair is searched for a * matching pair, so that the client memory handle can be returned. */ + typedef struct tagDDEPAIR { HGLOBAL ClientMem; @@ -2214,11 +2215,16 @@ SendMessageCallbackA( SENDASYNCPROC lpCallBack, ULONG_PTR dwData) { + CALL_BACK_INFO CallBackInfo; + + CallBackInfo.CallBack = lpCallBack; + CallBackInfo.Context = dwData; + return NtUserMessageCall(hWnd, Msg, wParam, lParam, - (ULONG_PTR)&lpCallBack, + (ULONG_PTR)&CallBackInfo, FNID_SENDMESSAGECALLBACK, TRUE); } @@ -2236,11 +2242,17 @@ SendMessageCallbackW( SENDASYNCPROC lpCallBack, ULONG_PTR dwData) { + + CALL_BACK_INFO CallBackInfo; + + CallBackInfo.CallBack = lpCallBack; + CallBackInfo.Context = dwData; + return NtUserMessageCall(hWnd, Msg, wParam, lParam, - (ULONG_PTR)&lpCallBack, + (ULONG_PTR)&CallBackInfo, FNID_SENDMESSAGECALLBACK, FALSE); } diff --git a/reactos/dll/win32/user32/windows/window.c b/reactos/dll/win32/user32/windows/window.c index 2427cd76ee0..e0c657cdfa9 100644 --- a/reactos/dll/win32/user32/windows/window.c +++ b/reactos/dll/win32/user32/windows/window.c @@ -29,9 +29,10 @@ User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength) PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs; TRACE("User32CallSendAsyncProcKernel()\n"); + CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments; - if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)) + if (ArgumentLength != sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS)) { return(STATUS_INFO_LENGTH_MISMATCH); } diff --git a/reactos/include/reactos/win32k/callback.h b/reactos/include/reactos/win32k/callback.h index 7dd97948adc..fc7c0bb95e2 100644 --- a/reactos/include/reactos/win32k/callback.h +++ b/reactos/include/reactos/win32k/callback.h @@ -33,6 +33,13 @@ typedef struct _SENDASYNCPROC_CALLBACK_ARGUMENTS LRESULT Result; } SENDASYNCPROC_CALLBACK_ARGUMENTS, *PSENDASYNCPROC_CALLBACK_ARGUMENTS; +typedef struct _CALL_BACK_INFO +{ + SENDASYNCPROC CallBack; + ULONG_PTR Context; +} CALL_BACK_INFO, * PCALL_BACK_INFO; + + typedef struct _HOOKPROC_CALLBACK_ARGUMENTS { INT HookId; diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index b626b881db4..b6d8ab70443 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -1625,12 +1625,11 @@ co_IntSendMessageWithCallBack( HWND hWnd, IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); - if (Window->pti->MessageQueue == Win32Thread->MessageQueue) + if ((Window->pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { DPRINT1("Failed to unpack message parameters\n"); - RETURN(TRUE); } RETURN(TRUE); } @@ -2621,6 +2620,18 @@ NtUserMessageCall( } break; case FNID_SENDMESSAGECALLBACK: + { + PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo; + + if (!CallBackInfo) + break; + + if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam, + CallBackInfo->CallBack, CallBackInfo->Context, NULL)) + { + DPRINT1("Callback failure!\n"); + } + } break; // CallNextHook bypass. case FNID_CALLWNDPROC: diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index fe1d9a80af7..5e408a817cc 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -894,7 +894,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) PLIST_ENTRY Entry; LRESULT Result; BOOL SenderReturned; - PUSER_SENT_MESSAGE_NOTIFY NotifyMessage; if (IsListEmpty(&MessageQueue->SentMessagesListHead)) { @@ -965,26 +964,16 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); } - /* Notify the sender if they specified a callback. */ + /* Call the callback if the message was sent with SendMessageCallback */ if (!SenderReturned && Message->CompletionCallback != NULL) { - if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool, - sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG))) - { - DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n"); - goto Notified; - } - NotifyMessage->CompletionCallback = - Message->CompletionCallback; - NotifyMessage->CompletionCallbackContext = - Message->CompletionCallbackContext; - NotifyMessage->Result = Result; - NotifyMessage->hWnd = Message->Msg.hwnd; - NotifyMessage->Msg = Message->Msg.message; - MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage); + co_IntCallSentMessageCallback(Message->CompletionCallback, + Message->Msg.hwnd, + Message->Msg.message, + Message->CompletionCallbackContext, + Result); } -Notified: /* Only if it is not a no wait message */ if (!(Message->HookMessage & MSQ_SENTNOWAIT))