2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: lib/user32/windows/message.c
6 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * 06-06-2001 CSH Created
13 #include <wine/debug.h>
14 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
16 /* DDE message exchange
18 * - Session initialization
19 * Client sends a WM_DDE_INITIATE message, usually a broadcast message. lParam of
20 * this message contains a pair of global atoms, the Application and Topic atoms.
21 * The client must destroy the atoms.
22 * Server window proc handles the WM_DDE_INITIATE message and if the Application
23 * and Topic atoms are recognized sends a WM_DDE_ACK message to the client. lParam
24 * of the reply message contains another pair of global atoms (Application and
25 * Topic again), which must be destroyed by the server.
28 * Client posts a WM_DDE_EXECUTE message to the server window. lParam of that message
29 * is a global memory handle containing the string to execute. After the command has
30 * been executed the server posts a WM_DDE_ACK message to the client, which contains
31 * a packed lParam which in turn contains that global memory handle. The client takes
32 * ownership of both the packed lParam (meaning it needs to call FreeDDElParam() on
33 * it and the global memory handle.
34 * This might work nice and easy in Win3.1, but things are more complicated for NT.
35 * Global memory handles in NT are not really global, they're still local to the
36 * process. So, what happens under the hood is that PostMessage must handle the
37 * WM_DDE_EXECUTE message specially. It will obtain the contents of the global memory
38 * area, repack that into a new structure together with the original memory handle
39 * and pass that off to the win32k. Win32k will marshall that data over to the target
40 * (server) process where it will be unpacked and stored in a newly allocated global
41 * memory area. The handle of that area will then be sent to the window proc, after
42 * storing it together with the "original" (client) handle in a table.
43 * The server will eventually post the WM_DDE_ACK response, containing the global
44 * memory handle it received. PostMessage must then lookup that memory handle (only
45 * valid in the server process) and replace it with the corresponding client memory
46 * handle. To avoid memory leaks, the server-side global memory block must be freed.
47 * Also, the WM_DDE_ACK lParam (a PackDDElParam() result) is unpacked and the
48 * individual components are handed to win32k.sys to post to the client side. Since
49 * the server side app hands over ownership of the packed lParam when it calls
50 * PostMessage(), the packed lParam needs to be freed on the server side too.
51 * When the WM_DDE_ACK message (containing the client-side global memory handle)
52 * arrives at the client side a new lParam is PackDDElParam()'ed and this is handed
53 * to the client side window proc which is expected to free/reuse it.
56 /* since the WM_DDE_ACK response to a WM_DDE_EXECUTE message should contain the handle
57 * to the memory handle, we keep track (in the server side) of all pairs of handle
58 * used (the client passes its value and the content of the memory handle), and
59 * the server stored both values (the client, and the local one, created after the
60 * content). When a ACK message is generated, the list of pair is searched for a
61 * matching pair, so that the client memory handle can be returned.
64 typedef struct tagDDEPAIR
70 static PDDEPAIR DdePairs
= NULL
;
71 static unsigned DdeNumAlloc
= 0;
72 static unsigned DdeNumUsed
= 0;
73 static CRITICAL_SECTION DdeCrst
;
76 DdeAddPair(HGLOBAL ClientMem
, HGLOBAL ServerMem
)
80 EnterCriticalSection(&DdeCrst
);
82 /* now remember the pair of hMem on both sides */
83 if (DdeNumUsed
== DdeNumAlloc
)
89 New
= HeapReAlloc(GetProcessHeap(), 0, DdePairs
,
90 (DdeNumAlloc
+ GROWBY
) * sizeof(DDEPAIR
));
94 New
= HeapAlloc(GetProcessHeap(), 0,
95 (DdeNumAlloc
+ GROWBY
) * sizeof(DDEPAIR
));
100 LeaveCriticalSection(&DdeCrst
);
104 /* zero out newly allocated part */
105 memset(&DdePairs
[DdeNumAlloc
], 0, GROWBY
* sizeof(DDEPAIR
));
106 DdeNumAlloc
+= GROWBY
;
110 for (i
= 0; i
< DdeNumAlloc
; i
++)
112 if (NULL
== DdePairs
[i
].ServerMem
)
114 DdePairs
[i
].ClientMem
= ClientMem
;
115 DdePairs
[i
].ServerMem
= ServerMem
;
120 LeaveCriticalSection(&DdeCrst
);
125 static HGLOBAL FASTCALL
126 DdeGetPair(HGLOBAL ServerMem
)
131 EnterCriticalSection(&DdeCrst
);
132 for (i
= 0; i
< DdeNumAlloc
; i
++)
134 if (DdePairs
[i
].ServerMem
== ServerMem
)
137 DdePairs
[i
].ServerMem
= 0;
139 Ret
= DdePairs
[i
].ClientMem
;
143 LeaveCriticalSection(&DdeCrst
);
150 MsgiUMToKMMessage(PMSG UMMsg
, PMSG KMMsg
, BOOL Posted
)
154 switch (UMMsg
->message
)
158 PKMDDELPARAM DdeLparam
;
159 DdeLparam
= HeapAlloc(GetProcessHeap(), 0, sizeof(KMDDELPARAM
));
160 if (NULL
== DdeLparam
)
166 DdeLparam
->Packed
= TRUE
;
167 if (! UnpackDDElParam(UMMsg
->message
, UMMsg
->lParam
,
168 &DdeLparam
->Value
.Packed
.uiLo
,
169 &DdeLparam
->Value
.Packed
.uiHi
))
173 if (0 != HIWORD(DdeLparam
->Value
.Packed
.uiHi
))
175 /* uiHi should contain a hMem from WM_DDE_EXECUTE */
176 HGLOBAL h
= DdeGetPair((HGLOBAL
)(ULONG_PTR
)DdeLparam
->Value
.Packed
.uiHi
);
179 GlobalFree((HGLOBAL
)(ULONG_PTR
)DdeLparam
->Value
.Packed
.uiHi
);
180 DdeLparam
->Value
.Packed
.uiHi
= (UINT_PTR
) h
;
183 FreeDDElParam(UMMsg
->message
, UMMsg
->lParam
);
187 DdeLparam
->Packed
= FALSE
;
188 DdeLparam
->Value
.Unpacked
= UMMsg
->lParam
;
190 KMMsg
->lParam
= (LPARAM
) DdeLparam
;
197 PKMDDEEXECUTEDATA KMDdeExecuteData
;
200 Size
= GlobalSize((HGLOBAL
) UMMsg
->lParam
);
201 Data
= GlobalLock((HGLOBAL
) UMMsg
->lParam
);
204 SetLastError(ERROR_INVALID_HANDLE
);
207 KMDdeExecuteData
= HeapAlloc(GetProcessHeap(), 0, sizeof(KMDDEEXECUTEDATA
) + Size
);
208 if (NULL
== KMDdeExecuteData
)
210 SetLastError(ERROR_OUTOFMEMORY
);
213 KMDdeExecuteData
->Sender
= (HWND
) UMMsg
->wParam
;
214 KMDdeExecuteData
->ClientMem
= (HGLOBAL
) UMMsg
->lParam
;
215 memcpy((PVOID
) (KMDdeExecuteData
+ 1), Data
, Size
);
216 KMMsg
->wParam
= sizeof(KMDDEEXECUTEDATA
) + Size
;
217 KMMsg
->lParam
= (LPARAM
) KMDdeExecuteData
;
218 GlobalUnlock((HGLOBAL
) UMMsg
->lParam
);
224 PCOPYDATASTRUCT pUMCopyData
= (PCOPYDATASTRUCT
)UMMsg
->lParam
;
225 PCOPYDATASTRUCT pKMCopyData
;
227 pKMCopyData
= HeapAlloc(GetProcessHeap(), 0,
228 sizeof(COPYDATASTRUCT
) + pUMCopyData
->cbData
);
229 if (pKMCopyData
== NULL
)
231 SetLastError(ERROR_OUTOFMEMORY
);
235 pKMCopyData
->dwData
= pUMCopyData
->dwData
;
236 pKMCopyData
->cbData
= pUMCopyData
->cbData
;
237 pKMCopyData
->lpData
= pKMCopyData
+ 1;
239 RtlCopyMemory(pKMCopyData
+ 1, pUMCopyData
->lpData
,
240 pUMCopyData
->cbData
);
242 KMMsg
->lParam
= (LPARAM
)pKMCopyData
;
255 MsgiUMToKMCleanup(PMSG UMMsg
, PMSG KMMsg
)
257 switch (KMMsg
->message
)
262 HeapFree(GetProcessHeap(), 0, (LPVOID
) KMMsg
->lParam
);
272 MsgiKMToUMMessage(PMSG KMMsg
, PMSG UMMsg
)
276 switch (UMMsg
->message
)
281 CREATESTRUCTW
*Cs
= (CREATESTRUCTW
*) KMMsg
->lParam
;
283 Cs
->lpszName
= (LPCWSTR
) ((PCHAR
) Cs
+ (DWORD_PTR
) Cs
->lpszName
);
284 Class
= (PCHAR
) Cs
+ (DWORD_PTR
) Cs
->lpszClass
;
285 if (L
'A' == *((WCHAR
*) Class
))
287 Class
+= sizeof(WCHAR
);
288 Cs
->lpszClass
= (LPCWSTR
)(DWORD_PTR
) (*((ATOM
*) Class
));
292 ASSERT(L
'S' == *((WCHAR
*) Class
));
293 Class
+= sizeof(WCHAR
);
294 Cs
->lpszClass
= (LPCWSTR
) Class
;
301 PKMDDELPARAM DdeLparam
= (PKMDDELPARAM
) KMMsg
->lParam
;
302 if (DdeLparam
->Packed
)
304 UMMsg
->lParam
= PackDDElParam(KMMsg
->message
,
305 DdeLparam
->Value
.Packed
.uiLo
,
306 DdeLparam
->Value
.Packed
.uiHi
);
310 UMMsg
->lParam
= DdeLparam
->Value
.Unpacked
;
317 PKMDDEEXECUTEDATA KMDdeExecuteData
;
321 KMDdeExecuteData
= (PKMDDEEXECUTEDATA
) KMMsg
->lParam
;
322 GlobalData
= GlobalAlloc(GMEM_MOVEABLE
, KMMsg
->wParam
- sizeof(KMDDEEXECUTEDATA
));
323 if (NULL
== GlobalData
)
327 Data
= GlobalLock(GlobalData
);
330 GlobalFree(GlobalData
);
333 memcpy(Data
, (PVOID
) (KMDdeExecuteData
+ 1), KMMsg
->wParam
- sizeof(KMDDEEXECUTEDATA
));
334 GlobalUnlock(GlobalData
);
335 if (! DdeAddPair(KMDdeExecuteData
->ClientMem
, GlobalData
))
337 GlobalFree(GlobalData
);
340 UMMsg
->wParam
= (WPARAM
) KMDdeExecuteData
->Sender
;
341 UMMsg
->lParam
= (LPARAM
) GlobalData
;
347 PCOPYDATASTRUCT pKMCopyData
= (PCOPYDATASTRUCT
)KMMsg
->lParam
;
348 pKMCopyData
->lpData
= pKMCopyData
+ 1;
360 MsgiKMToUMCleanup(PMSG KMMsg
, PMSG UMMsg
)
362 switch (KMMsg
->message
)
366 HeapFree(GetProcessHeap(), 0, (LPVOID
) KMMsg
->lParam
);
367 GlobalUnlock((HGLOBAL
) UMMsg
->lParam
);
378 MsgiKMToUMReply(PMSG KMMsg
, PMSG UMMsg
, LRESULT
*Result
)
380 MsgiKMToUMCleanup(KMMsg
, UMMsg
);
386 MsgiAnsiToUnicodeMessage(HWND hwnd
, LPMSG UnicodeMsg
, LPMSG AnsiMsg
)
388 UNICODE_STRING UnicodeString
;
390 *UnicodeMsg
= *AnsiMsg
;
392 switch (AnsiMsg
->message
)
395 case WM_ASKCBFORMATNAME
:
397 LPWSTR Buffer
= HeapAlloc(GetProcessHeap(), 0,
398 AnsiMsg
->wParam
* sizeof(WCHAR
));
403 UnicodeMsg
->lParam
= (LPARAM
)Buffer
;
407 /* AnsiMsg->lParam is string (0-terminated) */
409 case WM_WININICHANGE
:
410 case WM_DEVMODECHANGE
:
416 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)AnsiMsg
->lParam
);
417 UnicodeMsg
->lParam
= (LPARAM
)UnicodeString
.Buffer
;
422 case LB_ADDSTRING_LOWER
:
423 case LB_ADDSTRING_UPPER
:
424 case LB_INSERTSTRING
:
425 case LB_INSERTSTRING_UPPER
:
426 case LB_INSERTSTRING_LOWER
:
428 case LB_FINDSTRINGEXACT
:
429 case LB_SELECTSTRING
:
431 DWORD dwStyle
= GetWindowLongPtrW(AnsiMsg
->hwnd
, GWL_STYLE
);
432 if (!(dwStyle
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) &&
433 (dwStyle
& LBS_HASSTRINGS
))
435 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)AnsiMsg
->lParam
);
436 UnicodeMsg
->lParam
= (LPARAM
)UnicodeString
.Buffer
;
442 case CB_INSERTSTRING
:
444 case CB_FINDSTRINGEXACT
:
445 case CB_SELECTSTRING
:
447 DWORD dwStyle
= GetWindowLongPtrW(AnsiMsg
->hwnd
, GWL_STYLE
);
448 if (!(dwStyle
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) &&
449 (dwStyle
& CBS_HASSTRINGS
))
451 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)AnsiMsg
->lParam
);
452 UnicodeMsg
->lParam
= (LPARAM
)UnicodeString
.Buffer
;
460 MDICREATESTRUCTW mdi_cs
;
463 CREATESTRUCTW cs
; /* new structure */
464 LPCWSTR lpszName
; /* allocated Name */
465 LPCWSTR lpszClass
; /* allocated Class */
468 struct s
*xs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
473 xs
->cs
= *(CREATESTRUCTW
*)AnsiMsg
->lParam
;
474 if (!IS_INTRESOURCE(xs
->cs
.lpszName
))
476 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)xs
->cs
.lpszName
);
477 xs
->lpszName
= xs
->cs
.lpszName
= UnicodeString
.Buffer
;
479 if (!IS_ATOM(xs
->cs
.lpszClass
))
481 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)xs
->cs
.lpszClass
);
482 xs
->lpszClass
= xs
->cs
.lpszClass
= UnicodeString
.Buffer
;
485 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
487 mdi_cs
= *(MDICREATESTRUCTW
*)xs
->cs
.lpCreateParams
;
488 mdi_cs
.szTitle
= xs
->cs
.lpszName
;
489 mdi_cs
.szClass
= xs
->cs
.lpszClass
;
490 xs
->cs
.lpCreateParams
= &mdi_cs
;
493 UnicodeMsg
->lParam
= (LPARAM
)xs
;
499 MDICREATESTRUCTW
*cs
=
500 (MDICREATESTRUCTW
*)HeapAlloc(GetProcessHeap(), 0, sizeof(*cs
));
507 *cs
= *(MDICREATESTRUCTW
*)AnsiMsg
->lParam
;
509 if (!IS_ATOM(cs
->szClass
))
511 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)cs
->szClass
);
512 cs
->szClass
= UnicodeString
.Buffer
;
515 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)cs
->szTitle
);
516 cs
->szTitle
= UnicodeString
.Buffer
;
518 UnicodeMsg
->lParam
= (LPARAM
)cs
;
528 MsgiAnsiToUnicodeCleanup(LPMSG UnicodeMsg
, LPMSG AnsiMsg
)
530 UNICODE_STRING UnicodeString
;
532 switch (AnsiMsg
->message
)
535 case WM_ASKCBFORMATNAME
:
537 HeapFree(GetProcessHeap(), 0, (PVOID
) UnicodeMsg
->lParam
);
542 case WM_WININICHANGE
:
543 case WM_DEVMODECHANGE
:
549 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)UnicodeMsg
->lParam
);
550 RtlFreeUnicodeString(&UnicodeString
);
555 case LB_ADDSTRING_LOWER
:
556 case LB_ADDSTRING_UPPER
:
557 case LB_INSERTSTRING
:
558 case LB_INSERTSTRING_UPPER
:
559 case LB_INSERTSTRING_LOWER
:
561 case LB_FINDSTRINGEXACT
:
562 case LB_SELECTSTRING
:
564 DWORD dwStyle
= GetWindowLongPtrW(AnsiMsg
->hwnd
, GWL_STYLE
);
565 if (!(dwStyle
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) &&
566 (dwStyle
& LBS_HASSTRINGS
))
568 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)UnicodeMsg
->lParam
);
569 RtlFreeUnicodeString(&UnicodeString
);
575 case CB_INSERTSTRING
:
577 case CB_FINDSTRINGEXACT
:
578 case CB_SELECTSTRING
:
580 DWORD dwStyle
= GetWindowLongPtrW(AnsiMsg
->hwnd
, GWL_STYLE
);
581 if (!(dwStyle
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) &&
582 (dwStyle
& CBS_HASSTRINGS
))
584 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)UnicodeMsg
->lParam
);
585 RtlFreeUnicodeString(&UnicodeString
);
595 CREATESTRUCTW cs
; /* new structure */
596 LPWSTR lpszName
; /* allocated Name */
597 LPWSTR lpszClass
; /* allocated Class */
600 struct s
*xs
= (struct s
*)UnicodeMsg
->lParam
;
603 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)xs
->lpszName
);
604 RtlFreeUnicodeString(&UnicodeString
);
608 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)xs
->lpszClass
);
609 RtlFreeUnicodeString(&UnicodeString
);
611 HeapFree(GetProcessHeap(), 0, xs
);
617 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)UnicodeMsg
->lParam
;
618 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)cs
->szTitle
);
619 RtlFreeUnicodeString(&UnicodeString
);
620 if (!IS_ATOM(cs
->szClass
))
622 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)cs
->szClass
);
623 RtlFreeUnicodeString(&UnicodeString
);
625 HeapFree(GetProcessHeap(), 0, cs
);
635 MsgiAnsiToUnicodeReply(LPMSG UnicodeMsg
, LPMSG AnsiMsg
, LRESULT
*Result
)
637 switch (AnsiMsg
->message
)
640 case WM_ASKCBFORMATNAME
:
642 LPWSTR Buffer
= (LPWSTR
)UnicodeMsg
->lParam
;
643 LPSTR AnsiBuffer
= (LPSTR
)AnsiMsg
->lParam
;
644 if (UnicodeMsg
->wParam
> 0 &&
645 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
646 AnsiBuffer
, UnicodeMsg
->wParam
, NULL
, NULL
))
648 AnsiBuffer
[UnicodeMsg
->wParam
- 1] = 0;
654 MsgiAnsiToUnicodeCleanup(UnicodeMsg
, AnsiMsg
);
661 MsgiUnicodeToAnsiMessage(HWND hwnd
, LPMSG AnsiMsg
, LPMSG UnicodeMsg
)
663 ANSI_STRING AnsiString
;
664 UNICODE_STRING UnicodeString
;
666 *AnsiMsg
= *UnicodeMsg
;
668 switch(UnicodeMsg
->message
)
673 MDICREATESTRUCTA mdi_cs
;
678 CsW
= (CREATESTRUCTW
*)(UnicodeMsg
->lParam
);
679 CsA
= RtlAllocateHeap(GetProcessHeap(), 0, sizeof(CREATESTRUCTA
));
684 memcpy(CsA
, CsW
, sizeof(CREATESTRUCTW
));
686 RtlInitUnicodeString(&UnicodeString
, CsW
->lpszName
);
687 Status
= RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeString
, TRUE
);
688 if (! NT_SUCCESS(Status
))
690 RtlFreeHeap(GetProcessHeap(), 0, CsA
);
693 CsA
->lpszName
= AnsiString
.Buffer
;
694 if (HIWORD((ULONG_PTR
)CsW
->lpszClass
) != 0)
696 RtlInitUnicodeString(&UnicodeString
, CsW
->lpszClass
);
697 Status
= RtlUnicodeStringToAnsiString(&AnsiString
, &UnicodeString
, TRUE
);
698 if (! NT_SUCCESS(Status
))
700 RtlInitAnsiString(&AnsiString
, CsA
->lpszName
);
701 RtlFreeAnsiString(&AnsiString
);
702 RtlFreeHeap(GetProcessHeap(), 0, CsA
);
705 CsA
->lpszClass
= AnsiString
.Buffer
;
708 if (GetWindowLongW(hwnd
, GWL_EXSTYLE
) & WS_EX_MDICHILD
)
710 mdi_cs
= *(MDICREATESTRUCTA
*)CsW
->lpCreateParams
;
711 mdi_cs
.szTitle
= CsA
->lpszName
;
712 mdi_cs
.szClass
= CsA
->lpszClass
;
713 CsA
->lpCreateParams
= &mdi_cs
;
716 AnsiMsg
->lParam
= (LPARAM
)CsA
;
721 /* Ansi string might contain MBCS chars so we need 2 * the number of chars */
722 AnsiMsg
->wParam
= UnicodeMsg
->wParam
* 2;
723 AnsiMsg
->lParam
= (LPARAM
) RtlAllocateHeap(GetProcessHeap(), 0, AnsiMsg
->wParam
);
724 if (NULL
== (PVOID
) AnsiMsg
->lParam
)
735 RtlInitUnicodeString(&UnicodeString
, (PWSTR
) UnicodeMsg
->lParam
);
736 if (! NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString
,
742 AnsiMsg
->lParam
= (LPARAM
) AnsiString
.Buffer
;
747 case LB_ADDSTRING_LOWER
:
748 case LB_ADDSTRING_UPPER
:
749 case LB_INSERTSTRING
:
750 case LB_INSERTSTRING_UPPER
:
751 case LB_INSERTSTRING_LOWER
:
753 case LB_FINDSTRINGEXACT
:
754 case LB_SELECTSTRING
:
756 DWORD dwStyle
= GetWindowLongPtrW(AnsiMsg
->hwnd
, GWL_STYLE
);
757 if (!(dwStyle
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) &&
758 (dwStyle
& LBS_HASSTRINGS
))
760 RtlInitUnicodeString(&UnicodeString
, (PWSTR
) UnicodeMsg
->lParam
);
761 if (! NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString
,
767 AnsiMsg
->lParam
= (LPARAM
) AnsiString
.Buffer
;
773 case CB_INSERTSTRING
:
775 case CB_FINDSTRINGEXACT
:
776 case CB_SELECTSTRING
:
778 DWORD dwStyle
= GetWindowLongPtrW(AnsiMsg
->hwnd
, GWL_STYLE
);
779 if (!(dwStyle
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) &&
780 (dwStyle
& CBS_HASSTRINGS
))
782 RtlInitUnicodeString(&UnicodeString
, (PWSTR
) UnicodeMsg
->lParam
);
783 if (! NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString
,
789 AnsiMsg
->lParam
= (LPARAM
) AnsiString
.Buffer
;
796 MDICREATESTRUCTA
*cs
=
797 (MDICREATESTRUCTA
*)HeapAlloc(GetProcessHeap(), 0, sizeof(*cs
));
804 *cs
= *(MDICREATESTRUCTA
*)UnicodeMsg
->lParam
;
806 if (!IS_ATOM(cs
->szClass
))
808 RtlInitUnicodeString(&UnicodeString
, (LPCWSTR
)cs
->szClass
);
809 if (! NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString
,
815 cs
->szClass
= AnsiString
.Buffer
;
818 RtlInitUnicodeString(&UnicodeString
, (LPCWSTR
)cs
->szTitle
);
819 if (! NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString
,
823 if (!IS_ATOM(cs
->szClass
))
825 RtlInitAnsiString(&AnsiString
, cs
->szClass
);
826 RtlFreeAnsiString(&AnsiString
);
830 cs
->szTitle
= AnsiString
.Buffer
;
832 AnsiMsg
->lParam
= (LPARAM
)cs
;
842 MsgiUnicodeToAnsiCleanup(LPMSG AnsiMsg
, LPMSG UnicodeMsg
)
844 ANSI_STRING AnsiString
;
846 switch(UnicodeMsg
->message
)
850 RtlFreeHeap(GetProcessHeap(), 0, (PVOID
) AnsiMsg
->lParam
);
855 RtlInitAnsiString(&AnsiString
, (PSTR
) AnsiMsg
->lParam
);
856 RtlFreeAnsiString(&AnsiString
);
864 Cs
= (CREATESTRUCTA
*) AnsiMsg
->lParam
;
865 RtlInitAnsiString(&AnsiString
, Cs
->lpszName
);
866 RtlFreeAnsiString(&AnsiString
);
867 if (HIWORD((ULONG_PTR
)Cs
->lpszClass
) != 0)
869 RtlInitAnsiString(&AnsiString
, Cs
->lpszClass
);
870 RtlFreeAnsiString(&AnsiString
);
872 RtlFreeHeap(GetProcessHeap(), 0, Cs
);
877 case LB_ADDSTRING_LOWER
:
878 case LB_ADDSTRING_UPPER
:
879 case LB_INSERTSTRING
:
880 case LB_INSERTSTRING_UPPER
:
881 case LB_INSERTSTRING_LOWER
:
883 case LB_FINDSTRINGEXACT
:
884 case LB_SELECTSTRING
:
886 DWORD dwStyle
= GetWindowLongPtrW(AnsiMsg
->hwnd
, GWL_STYLE
);
887 if (!(dwStyle
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
)) &&
888 (dwStyle
& LBS_HASSTRINGS
))
890 RtlInitAnsiString(&AnsiString
, (PSTR
) AnsiMsg
->lParam
);
891 RtlFreeAnsiString(&AnsiString
);
897 case CB_INSERTSTRING
:
899 case CB_FINDSTRINGEXACT
:
900 case CB_SELECTSTRING
:
902 DWORD dwStyle
= GetWindowLongPtrW(AnsiMsg
->hwnd
, GWL_STYLE
);
903 if (!(dwStyle
& (CBS_OWNERDRAWFIXED
| CBS_OWNERDRAWVARIABLE
)) &&
904 (dwStyle
& CBS_HASSTRINGS
))
906 RtlInitAnsiString(&AnsiString
, (PSTR
) AnsiMsg
->lParam
);
907 RtlFreeAnsiString(&AnsiString
);
914 MDICREATESTRUCTA
*cs
= (MDICREATESTRUCTA
*)AnsiMsg
->lParam
;
915 RtlInitAnsiString(&AnsiString
, (PCSTR
)cs
->szTitle
);
916 RtlFreeAnsiString(&AnsiString
);
917 if (!IS_ATOM(cs
->szClass
))
919 RtlInitAnsiString(&AnsiString
, (PCSTR
)cs
->szClass
);
920 RtlFreeAnsiString(&AnsiString
);
922 HeapFree(GetProcessHeap(), 0, cs
);
933 MsgiUnicodeToAnsiReply(LPMSG AnsiMsg
, LPMSG UnicodeMsg
, LRESULT
*Result
)
935 switch (UnicodeMsg
->message
)
938 case WM_ASKCBFORMATNAME
:
940 LPSTR Buffer
= (LPSTR
) AnsiMsg
->lParam
;
941 LPWSTR UBuffer
= (LPWSTR
) UnicodeMsg
->lParam
;
942 if (0 < AnsiMsg
->wParam
&&
943 ! MultiByteToWideChar(CP_ACP
, 0, Buffer
, -1, UBuffer
, UnicodeMsg
->wParam
))
945 UBuffer
[UnicodeMsg
->wParam
- 1] = L
'\0';
951 MsgiUnicodeToAnsiCleanup(AnsiMsg
, UnicodeMsg
);
961 GetMessageExtraInfo(VOID
)
963 return (LPARAM
)NtUserCallNoParam(NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
);
974 return NtUserCallNoParam(NOPARAM_ROUTINE_GETMSESSAGEPOS
);
984 return NtUserGetThreadState(THREADSTATE_GETMESSAGETIME
);
995 PCLIENTTHREADINFO pcti
= GetWin32ClientInfo()->pClientThreadInfo
;
998 if (pcti
->CTI_flags
& CTI_INSENDMESSAGE
)
1003 return(NtUserGetThreadState(THREADSTATE_INSENDMESSAGE
) != ISMEX_NOSEND
);
1015 PCLIENTTHREADINFO pcti
= GetWin32ClientInfo()->pClientThreadInfo
;
1016 if (pcti
&& !(pcti
->CTI_flags
& CTI_INSENDMESSAGE
))
1017 return ISMEX_NOSEND
;
1019 return NtUserGetThreadState(THREADSTATE_INSENDMESSAGE
);
1031 return NtUserCallOneParam(lResult
, ONEPARAM_ROUTINE_REPLYMESSAGE
);
1040 SetMessageExtraInfo(
1043 return NtUserSetMessageExtraInfo(lParam
);
1047 IntCallWindowProcW(BOOL IsAnsiProc
,
1057 BOOL Hook
= FALSE
, MsgOverride
= FALSE
, Dialog
;
1058 LRESULT Result
= 0, PreResult
= 0;
1061 if (WndProc
== NULL
)
1063 WARN("IntCallWindowsProcW() called with WndProc = NULL!\n");
1068 Dialog
= (pWnd
->fnid
== FNID_DIALOG
);
1072 Hook
= BeginIfHookedUserApiHook();
1076 MsgOverride
= IsMsgOverride( Msg
, &guah
.WndProcArray
);
1078 MsgOverride
= IsMsgOverride( Msg
, &guah
.DlgProcArray
);
1083 UnicodeMsg
.hwnd
= hWnd
;
1084 UnicodeMsg
.message
= Msg
;
1085 UnicodeMsg
.wParam
= wParam
;
1086 UnicodeMsg
.lParam
= lParam
;
1087 if (! MsgiUnicodeToAnsiMessage(hWnd
, &AnsiMsg
, &UnicodeMsg
))
1092 if (Hook
&& MsgOverride
)
1097 PreResult
= guah
.PreWndProc(AnsiMsg
.hwnd
, AnsiMsg
.message
, AnsiMsg
.wParam
, AnsiMsg
.lParam
, (ULONG_PTR
)&Result
, &Data
);
1099 PreResult
= guah
.PreDefDlgProc(AnsiMsg
.hwnd
, AnsiMsg
.message
, AnsiMsg
.wParam
, AnsiMsg
.lParam
, (ULONG_PTR
)&Result
, &Data
);
1101 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1107 if (PreResult
) goto Exit
;
1109 _SEH2_TRY
// wine does this.
1111 Result
= WndProc(AnsiMsg
.hwnd
, AnsiMsg
.message
, AnsiMsg
.wParam
, AnsiMsg
.lParam
);
1113 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1118 if (Hook
&& MsgOverride
)
1123 guah
.PostWndProc(AnsiMsg
.hwnd
, AnsiMsg
.message
, AnsiMsg
.wParam
, AnsiMsg
.lParam
, (ULONG_PTR
)&Result
, &Data
);
1125 guah
.PostDefDlgProc(AnsiMsg
.hwnd
, AnsiMsg
.message
, AnsiMsg
.wParam
, AnsiMsg
.lParam
, (ULONG_PTR
)&Result
, &Data
);
1127 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1133 if (! MsgiUnicodeToAnsiReply(&AnsiMsg
, &UnicodeMsg
, &Result
))
1140 if (Hook
&& MsgOverride
)
1145 PreResult
= guah
.PreWndProc(hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&Result
, &Data
);
1147 PreResult
= guah
.PreDefDlgProc(hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&Result
, &Data
);
1149 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1155 if (PreResult
) goto Exit
;
1159 Result
= WndProc(hWnd
, Msg
, wParam
, lParam
);
1161 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1166 if (Hook
&& MsgOverride
)
1171 guah
.PostWndProc(hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&Result
, &Data
);
1173 guah
.PostDefDlgProc(hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&Result
, &Data
);
1175 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1183 if (Hook
) EndUserApiHook();
1187 static LRESULT FASTCALL
1188 IntCallWindowProcA(BOOL IsAnsiProc
,
1198 BOOL Hook
= FALSE
, MsgOverride
= FALSE
, Dialog
;
1199 LRESULT Result
= 0, PreResult
= 0;
1202 if (WndProc
== NULL
)
1204 WARN("IntCallWindowsProcA() called with WndProc = NULL!\n");
1209 Dialog
= (pWnd
->fnid
== FNID_DIALOG
);
1213 Hook
= BeginIfHookedUserApiHook();
1217 MsgOverride
= IsMsgOverride( Msg
, &guah
.WndProcArray
);
1219 MsgOverride
= IsMsgOverride( Msg
, &guah
.DlgProcArray
);
1224 if (Hook
&& MsgOverride
)
1229 PreResult
= guah
.PreWndProc(hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&Result
, &Data
);
1231 PreResult
= guah
.PreDefDlgProc(hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&Result
, &Data
);
1233 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1239 if (PreResult
) goto Exit
;
1243 Result
= WndProc(hWnd
, Msg
, wParam
, lParam
);
1245 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1250 if (Hook
&& MsgOverride
)
1255 guah
.PostWndProc(hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&Result
, &Data
);
1257 guah
.PostDefDlgProc(hWnd
, Msg
, wParam
, lParam
, (ULONG_PTR
)&Result
, &Data
);
1259 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1267 AnsiMsg
.hwnd
= hWnd
;
1268 AnsiMsg
.message
= Msg
;
1269 AnsiMsg
.wParam
= wParam
;
1270 AnsiMsg
.lParam
= lParam
;
1271 if (! MsgiAnsiToUnicodeMessage(hWnd
, &UnicodeMsg
, &AnsiMsg
))
1276 if (Hook
&& MsgOverride
)
1281 PreResult
= guah
.PreWndProc(UnicodeMsg
.hwnd
, UnicodeMsg
.message
, UnicodeMsg
.wParam
, UnicodeMsg
.lParam
, (ULONG_PTR
)&Result
, &Data
);
1283 PreResult
= guah
.PreDefDlgProc(UnicodeMsg
.hwnd
, UnicodeMsg
.message
, UnicodeMsg
.wParam
, UnicodeMsg
.lParam
, (ULONG_PTR
)&Result
, &Data
);
1285 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1291 if (PreResult
) goto Exit
;
1295 Result
= WndProc(UnicodeMsg
.hwnd
, UnicodeMsg
.message
,
1296 UnicodeMsg
.wParam
, UnicodeMsg
.lParam
);
1298 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1303 if (Hook
&& MsgOverride
)
1308 guah
.PostWndProc(UnicodeMsg
.hwnd
, UnicodeMsg
.message
, UnicodeMsg
.wParam
, UnicodeMsg
.lParam
, (ULONG_PTR
)&Result
, &Data
);
1310 guah
.PostDefDlgProc(UnicodeMsg
.hwnd
, UnicodeMsg
.message
, UnicodeMsg
.wParam
, UnicodeMsg
.lParam
, (ULONG_PTR
)&Result
, &Data
);
1312 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1318 if (! MsgiAnsiToUnicodeReply(&UnicodeMsg
, &AnsiMsg
, &Result
))
1325 if (Hook
) EndUserApiHook();
1330 static LRESULT WINAPI
1331 IntCallMessageProc(IN PWND Wnd
, IN HWND hWnd
, IN UINT Msg
, IN WPARAM wParam
, IN LPARAM lParam
, IN BOOL Ansi
)
1337 Class
= DesktopPtrToUser(Wnd
->pcls
);
1340 if ( Wnd
->head
.pti
!= GetW32ThreadInfo())
1341 { // Must be inside the same thread!
1342 SetLastError( ERROR_MESSAGE_SYNC_ONLY
);
1346 This is the message exchange for user32. If there's a need to monitor messages,
1349 TRACE("HWND 0x%x, MSG %d, WPARAM 0x%x, LPARAM 0x%x, Ansi &d\n",hWnd
,Msg
,wParam
,lParam
,Ansi
);
1350 // if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON )
1351 if (Class
->fnid
<= FNID_GHOST
&& Class
->fnid
>= FNID_FIRST
)
1355 if (GETPFNCLIENTW(Class
->fnid
) == Wnd
->lpfnWndProc
)
1356 WndProc
= GETPFNCLIENTA(Class
->fnid
);
1360 if (GETPFNCLIENTA(Class
->fnid
) == Wnd
->lpfnWndProc
)
1361 WndProc
= GETPFNCLIENTW(Class
->fnid
);
1368 IsAnsi
= !Wnd
->Unicode
;
1369 WndProc
= Wnd
->lpfnWndProc
;
1374 IsAnsi
= !Wnd
->Unicode
;
1375 WndProc
= Wnd
->lpfnWndProc
;
1378 Message caller can be Ansi/Unicode and the receiver can be Unicode/Ansi or
1382 return IntCallWindowProcW(IsAnsi
, WndProc
, Wnd
, hWnd
, Msg
, wParam
, lParam
);
1384 return IntCallWindowProcA(IsAnsi
, WndProc
, Wnd
, hWnd
, Msg
, wParam
, lParam
);
1392 CallWindowProcA(WNDPROC lpPrevWndFunc
,
1399 PCALLPROCDATA CallProc
;
1401 if (lpPrevWndFunc
== NULL
)
1403 WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
1407 pWnd
= ValidateHwnd(hWnd
);
1409 if (!IsCallProcHandle(lpPrevWndFunc
))
1410 return IntCallWindowProcA(TRUE
, lpPrevWndFunc
, pWnd
, hWnd
, Msg
, wParam
, lParam
);
1413 CallProc
= ValidateCallProc((HANDLE
)lpPrevWndFunc
);
1414 if (CallProc
!= NULL
)
1416 return IntCallWindowProcA(!(CallProc
->wType
& UserGetCPDA2U
),
1417 CallProc
->pfnClientPrevious
,
1426 WARN("CallWindowProcA: can not dereference WndProcHandle\n");
1437 CallWindowProcW(WNDPROC lpPrevWndFunc
,
1444 PCALLPROCDATA CallProc
;
1446 /* FIXME - can the first parameter be NULL? */
1447 if (lpPrevWndFunc
== NULL
)
1449 WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
1453 pWnd
= ValidateHwnd(hWnd
);
1455 if (!IsCallProcHandle(lpPrevWndFunc
))
1456 return IntCallWindowProcW(FALSE
, lpPrevWndFunc
, pWnd
, hWnd
, Msg
, wParam
, lParam
);
1459 CallProc
= ValidateCallProc((HANDLE
)lpPrevWndFunc
);
1460 if (CallProc
!= NULL
)
1462 return IntCallWindowProcW(!(CallProc
->wType
& UserGetCPDA2U
),
1463 CallProc
->pfnClientPrevious
,
1472 WARN("CallWindowProcW: can not dereference WndProcHandle\n");
1483 DispatchMessageA(CONST MSG
*lpmsg
)
1489 if ( lpmsg
->message
& ~WM_MAXIMUM
)
1491 SetLastError( ERROR_INVALID_PARAMETER
);
1495 if (lpmsg
->hwnd
!= NULL
)
1497 Wnd
= ValidateHwnd(lpmsg
->hwnd
);
1503 if ((lpmsg
->message
== WM_TIMER
|| lpmsg
->message
== WM_SYSTIMER
) && lpmsg
->lParam
!= 0)
1505 WNDPROC WndProc
= (WNDPROC
)lpmsg
->lParam
;
1507 if ( lpmsg
->message
== WM_SYSTIMER
)
1508 return NtUserDispatchMessage( (PMSG
)lpmsg
);
1510 _SEH2_TRY
// wine does this. Hint: Prevents call to another thread....
1512 Ret
= WndProc(lpmsg
->hwnd
,
1517 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1522 else if (Wnd
!= NULL
)
1524 if ( (lpmsg
->message
!= WM_PAINT
) && !(Wnd
->state
& WNDS_SERVERSIDEWINDOWPROC
) )
1526 Ret
= IntCallMessageProc(Wnd
,
1535 if (!MsgiAnsiToUnicodeMessage(lpmsg
->hwnd
, &UnicodeMsg
, (LPMSG
)lpmsg
))
1540 Ret
= NtUserDispatchMessage(&UnicodeMsg
);
1542 if (!MsgiAnsiToUnicodeReply(&UnicodeMsg
, (LPMSG
)lpmsg
, &Ret
))
1556 DispatchMessageW(CONST MSG
*lpmsg
)
1561 if ( lpmsg
->message
& ~WM_MAXIMUM
)
1563 SetLastError( ERROR_INVALID_PARAMETER
);
1567 if (lpmsg
->hwnd
!= NULL
)
1569 Wnd
= ValidateHwnd(lpmsg
->hwnd
);
1575 if ((lpmsg
->message
== WM_TIMER
|| lpmsg
->message
== WM_SYSTIMER
) && lpmsg
->lParam
!= 0)
1577 WNDPROC WndProc
= (WNDPROC
)lpmsg
->lParam
;
1579 if ( lpmsg
->message
== WM_SYSTIMER
)
1580 return NtUserDispatchMessage( (PMSG
) lpmsg
);
1584 Ret
= WndProc(lpmsg
->hwnd
,
1589 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1594 else if (Wnd
!= NULL
)
1596 if ( (lpmsg
->message
!= WM_PAINT
) && !(Wnd
->state
& WNDS_SERVERSIDEWINDOWPROC
) )
1598 Ret
= IntCallMessageProc(Wnd
,
1606 Ret
= NtUserDispatchMessage( (PMSG
) lpmsg
);
1617 GetMessageA(LPMSG lpMsg
,
1624 if ( (wMsgFilterMin
|wMsgFilterMax
) & ~WM_MAXIMUM
)
1626 SetLastError( ERROR_INVALID_PARAMETER
);
1630 Res
= NtUserGetMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
);
1631 if (-1 == (int) Res
)
1643 GetMessageW(LPMSG lpMsg
,
1650 if ( (wMsgFilterMin
|wMsgFilterMax
) & ~WM_MAXIMUM
)
1652 SetLastError( ERROR_INVALID_PARAMETER
);
1656 Res
= NtUserGetMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
);
1657 if (-1 == (int) Res
)
1666 PeekMessageWorker( PMSG pMsg
,
1673 PCLIENTTHREADINFO pcti
;
1674 pci
= GetWin32ClientInfo();
1675 pcti
= pci
->pClientThreadInfo
;
1677 if (!hWnd
&& pci
&& pcti
)
1681 if ((pci
->cSpins
>= 100) && (pci
->dwTIFlags
& TIF_SPINNING
))
1682 { // Yield after 100 spin cycles and ready to swap vinyl.
1683 if (!(pci
->dwTIFlags
& TIF_WAITFORINPUTIDLE
))
1684 { // Not waiting for idle event.
1685 if (!pcti
->fsChangeBits
&& !pcti
->fsWakeBits
)
1686 { // No messages are available.
1687 if ((GetTickCount() - pcti
->tickLastMsgChecked
) > 1000)
1688 { // Up the msg read count if over 1 sec.
1689 NtUserGetThreadState(THREADSTATE_UPTIMELASTREAD
);
1693 FIXME("seeSpins!\n");
1699 return NtUserPeekMessage(pMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1706 PeekMessageA(LPMSG lpMsg
,
1714 Res
= PeekMessageWorker(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1715 if (-1 == (int) Res
|| !Res
)
1738 Res
= PeekMessageWorker(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1739 if (-1 == (int) Res
|| !Res
)
1760 /* Check for combo box or a list box to send names. */
1761 if (Msg
== CB_DIR
|| Msg
== LB_DIR
)
1764 Set DDL_POSTMSGS, so use the PostMessage function to send messages to the
1765 combo/list box. Forces a call like DlgDirListComboBox.
1767 //wParam |= DDL_POSTMSGS;
1768 return NtUserPostMessage(hWnd
, Msg
, wParam
, lParam
);
1771 /* No drop files or current Process, just post message. */
1772 if ( (Msg
!= WM_DROPFILES
) ||
1773 ( NtUserQueryWindow( hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
) ==
1774 PtrToUint(NtCurrentTeb()->ClientId
.UniqueProcess
) ) )
1776 return NtUserPostMessage(hWnd
, Msg
, wParam
, lParam
);
1779 /* We have drop files and this is not the same process for this window. */
1781 /* Just incase, check wParam for Global memory handle and send size. */
1782 Ret
= SendMessageA( hWnd
,
1784 (WPARAM
)GlobalSize((HGLOBAL
)wParam
), // Zero if not a handle.
1785 (LPARAM
)wParam
); // Send wParam as lParam.
1787 if ( Ret
) return NtUserPostMessage(hWnd
, Msg
, (WPARAM
)Ret
, lParam
);
1805 /* Check for combo box or a list box to send names. */
1806 if (Msg
== CB_DIR
|| Msg
== LB_DIR
)
1809 Set DDL_POSTMSGS, so use the PostMessage function to send messages to the
1810 combo/list box. Forces a call like DlgDirListComboBox.
1812 //wParam |= DDL_POSTMSGS;
1813 return NtUserPostMessage(hWnd
, Msg
, wParam
, lParam
);
1816 /* No drop files or current Process, just post message. */
1817 if ( (Msg
!= WM_DROPFILES
) ||
1818 ( NtUserQueryWindow( hWnd
, QUERY_WINDOW_UNIQUE_PROCESS_ID
) ==
1819 PtrToUint(NtCurrentTeb()->ClientId
.UniqueProcess
) ) )
1821 return NtUserPostMessage(hWnd
, Msg
, wParam
, lParam
);
1824 /* We have drop files and this is not the same process for this window. */
1826 /* Just incase, check wParam for Global memory handle and send size. */
1827 Ret
= SendMessageW( hWnd
,
1829 (WPARAM
)GlobalSize((HGLOBAL
)wParam
), // Zero if not a handle.
1830 (LPARAM
)wParam
); // Send wParam as lParam.
1832 if ( Ret
) return NtUserPostMessage(hWnd
, Msg
, (WPARAM
)Ret
, lParam
);
1845 NtUserCallOneParam(nExitCode
, ONEPARAM_ROUTINE_POSTQUITMESSAGE
);
1860 return NtUserPostThreadMessage(idThread
, Msg
, wParam
, lParam
);
1875 return NtUserPostThreadMessage(idThread
, Msg
, wParam
, lParam
);
1883 SendMessageW(HWND Wnd
,
1891 PTHREADINFO ti
= GetW32ThreadInfo();
1893 if ( Msg
& ~WM_MAXIMUM
)
1895 SetLastError( ERROR_INVALID_PARAMETER
);
1899 if (Wnd
!= HWND_BROADCAST
&& (Msg
< WM_DDE_FIRST
|| Msg
> WM_DDE_LAST
))
1901 Window
= ValidateHwnd(Wnd
);
1903 if ( Window
!= NULL
&&
1904 Window
->head
.pti
== ti
&&
1905 // !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
1906 !ISITHOOKED(WH_CALLWNDPROC
) &&
1907 !ISITHOOKED(WH_CALLWNDPROCRET
) &&
1908 !(Window
->state
& WNDS_SERVERSIDEWINDOWPROC
) )
1910 /* NOTE: We can directly send messages to the window procedure
1911 if *all* the following conditions are met:
1913 * Window belongs to calling thread
1914 * The calling thread is not being hooked for CallWndProc
1915 * Not calling a server side proc:
1916 Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage
1919 return IntCallMessageProc(Window
, Wnd
, Msg
, wParam
, lParam
, FALSE
);
1924 UMMsg
.message
= Msg
;
1925 UMMsg
.wParam
= wParam
;
1926 UMMsg
.lParam
= lParam
;
1928 if (! MsgiUMToKMMessage(&UMMsg
, &KMMsg
, FALSE
))
1933 Result
= NtUserMessageCall( Wnd
,
1941 MsgiUMToKMCleanup(&UMMsg
, &KMMsg
);
1951 SendMessageA(HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
1953 MSG AnsiMsg
, UcMsg
, KMMsg
;
1956 PTHREADINFO ti
= GetW32ThreadInfo();
1958 if ( Msg
& ~WM_MAXIMUM
)
1960 SetLastError( ERROR_INVALID_PARAMETER
);
1964 if (Wnd
!= HWND_BROADCAST
&& (Msg
< WM_DDE_FIRST
|| Msg
> WM_DDE_LAST
))
1966 Window
= ValidateHwnd(Wnd
);
1968 if ( Window
!= NULL
&&
1969 Window
->head
.pti
== ti
&&
1970 // !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
1971 !ISITHOOKED(WH_CALLWNDPROC
) &&
1972 !ISITHOOKED(WH_CALLWNDPROCRET
) &&
1973 !(Window
->state
& WNDS_SERVERSIDEWINDOWPROC
) )
1975 /* NOTE: We can directly send messages to the window procedure
1976 if *all* the following conditions are met:
1978 * Window belongs to calling thread
1979 * The calling thread is not being hooked for CallWndProc
1980 * Not calling a server side proc:
1981 Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage
1984 return IntCallMessageProc(Window
, Wnd
, Msg
, wParam
, lParam
, TRUE
);
1989 AnsiMsg
.message
= Msg
;
1990 AnsiMsg
.wParam
= wParam
;
1991 AnsiMsg
.lParam
= lParam
;
1993 if (!MsgiAnsiToUnicodeMessage(Wnd
, &UcMsg
, &AnsiMsg
))
1998 if (!MsgiUMToKMMessage(&UcMsg
, &KMMsg
, FALSE
))
2000 MsgiAnsiToUnicodeCleanup(&UcMsg
, &AnsiMsg
);
2004 Result
= NtUserMessageCall( Wnd
,
2012 MsgiUMToKMCleanup(&UcMsg
, &KMMsg
);
2013 MsgiAnsiToUnicodeReply(&UcMsg
, &AnsiMsg
, &Result
);
2023 SendMessageCallbackA(
2028 SENDASYNCPROC lpCallBack
,
2033 CALL_BACK_INFO CallBackInfo
;
2035 CallBackInfo
.CallBack
= lpCallBack
;
2036 CallBackInfo
.Context
= dwData
;
2038 AnsiMsg
.hwnd
= hWnd
;
2039 AnsiMsg
.message
= Msg
;
2040 AnsiMsg
.wParam
= wParam
;
2041 AnsiMsg
.lParam
= lParam
;
2043 if (!MsgiAnsiToUnicodeMessage(hWnd
, &UcMsg
, &AnsiMsg
))
2048 Result
= NtUserMessageCall( hWnd
,
2052 (ULONG_PTR
)&CallBackInfo
,
2053 FNID_SENDMESSAGECALLBACK
,
2056 MsgiAnsiToUnicodeCleanup(&UcMsg
, &AnsiMsg
);
2066 SendMessageCallbackW(
2071 SENDASYNCPROC lpCallBack
,
2074 CALL_BACK_INFO CallBackInfo
;
2076 CallBackInfo
.CallBack
= lpCallBack
;
2077 CallBackInfo
.Context
= dwData
;
2079 return NtUserMessageCall(hWnd
,
2083 (ULONG_PTR
)&CallBackInfo
,
2084 FNID_SENDMESSAGECALLBACK
,
2093 SendMessageTimeoutA(
2100 PDWORD_PTR lpdwResult
)
2106 PTHREADINFO ti
= GetW32ThreadInfo();
2108 if ( Msg
& ~WM_MAXIMUM
|| fuFlags
& ~(SMTO_NOTIMEOUTIFNOTHUNG
|SMTO_ABORTIFHUNG
|SMTO_BLOCK
))
2110 SetLastError( ERROR_INVALID_PARAMETER
);
2114 if (lpdwResult
) *lpdwResult
= 0;
2116 if (hWnd
!= HWND_BROADCAST
&& (Msg
< WM_DDE_FIRST
|| Msg
> WM_DDE_LAST
))
2118 Window
= ValidateHwnd(hWnd
);
2120 if ( Window
!= NULL
&&
2121 Window
->head
.pti
== ti
&&
2122 !ISITHOOKED(WH_CALLWNDPROC
) &&
2123 !ISITHOOKED(WH_CALLWNDPROCRET
) &&
2124 !(Window
->state
& WNDS_SERVERSIDEWINDOWPROC
) )
2126 Result
= IntCallMessageProc(Window
, hWnd
, Msg
, wParam
, lParam
, TRUE
);
2127 if (lpdwResult
) *lpdwResult
= Result
;
2131 SPY_EnterMessage(SPY_SENDMESSAGE
, hWnd
, Msg
, wParam
, lParam
);
2133 dsm
.uFlags
= fuFlags
;
2134 dsm
.uTimeout
= uTimeout
;
2136 AnsiMsg
.hwnd
= hWnd
;
2137 AnsiMsg
.message
= Msg
;
2138 AnsiMsg
.wParam
= wParam
;
2139 AnsiMsg
.lParam
= lParam
;
2141 if (! MsgiAnsiToUnicodeMessage(hWnd
, &UcMsg
, &AnsiMsg
))
2146 Result
= NtUserMessageCall( hWnd
,
2151 FNID_SENDMESSAGETIMEOUT
,
2154 MsgiAnsiToUnicodeReply(&UcMsg
, &AnsiMsg
, &Result
);
2156 if (lpdwResult
) *lpdwResult
= dsm
.Result
;
2158 SPY_ExitMessage(SPY_RESULT_OK
, hWnd
, Msg
, Result
, wParam
, lParam
);
2169 SendMessageTimeoutW(
2176 PDWORD_PTR lpdwResult
)
2181 PTHREADINFO ti
= GetW32ThreadInfo();
2183 if ( Msg
& ~WM_MAXIMUM
|| fuFlags
& ~(SMTO_NOTIMEOUTIFNOTHUNG
|SMTO_ABORTIFHUNG
|SMTO_BLOCK
))
2185 SetLastError( ERROR_INVALID_PARAMETER
);
2189 if (lpdwResult
) *lpdwResult
= 0;
2191 if (hWnd
!= HWND_BROADCAST
&& (Msg
< WM_DDE_FIRST
|| Msg
> WM_DDE_LAST
))
2193 Window
= ValidateHwnd(hWnd
);
2195 if ( Window
!= NULL
&&
2196 Window
->head
.pti
== ti
&&
2197 !ISITHOOKED(WH_CALLWNDPROC
) &&
2198 !ISITHOOKED(WH_CALLWNDPROCRET
) &&
2199 !(Window
->state
& WNDS_SERVERSIDEWINDOWPROC
) )
2201 Result
= IntCallMessageProc(Window
, hWnd
, Msg
, wParam
, lParam
, FALSE
);
2202 if (lpdwResult
) *lpdwResult
= Result
;
2206 SPY_EnterMessage(SPY_SENDMESSAGE
, hWnd
, Msg
, wParam
, lParam
);
2208 dsm
.uFlags
= fuFlags
;
2209 dsm
.uTimeout
= uTimeout
;
2211 Result
= NtUserMessageCall( hWnd
,
2216 FNID_SENDMESSAGETIMEOUT
,
2219 if (lpdwResult
) *lpdwResult
= dsm
.Result
;
2221 SPY_ExitMessage(SPY_RESULT_OK
, hWnd
, Msg
, Result
, wParam
, lParam
);
2240 AnsiMsg
.hwnd
= hWnd
;
2241 AnsiMsg
.message
= Msg
;
2242 AnsiMsg
.wParam
= wParam
;
2243 AnsiMsg
.lParam
= lParam
;
2244 if (! MsgiAnsiToUnicodeMessage(hWnd
, &UcMsg
, &AnsiMsg
))
2248 Ret
= SendNotifyMessageW(hWnd
, UcMsg
.message
, UcMsg
.wParam
, UcMsg
.lParam
);
2250 MsgiAnsiToUnicodeCleanup(&UcMsg
, &AnsiMsg
);
2270 UMMsg
.message
= Msg
;
2271 UMMsg
.wParam
= wParam
;
2272 UMMsg
.lParam
= lParam
;
2273 if (! MsgiUMToKMMessage(&UMMsg
, &KMMsg
, TRUE
))
2277 Result
= NtUserMessageCall( hWnd
,
2282 FNID_SENDNOTIFYMESSAGE
,
2285 MsgiUMToKMCleanup(&UMMsg
, &KMMsg
);
2294 TranslateMessageEx(CONST MSG
*lpMsg
, UINT Flags
)
2296 switch (lpMsg
->message
)
2302 return(NtUserTranslateMessage((LPMSG
)lpMsg
, Flags
));
2305 if ( lpMsg
->message
& ~WM_MAXIMUM
)
2306 SetLastError(ERROR_INVALID_PARAMETER
);
2316 TranslateMessage(CONST MSG
*lpMsg
)
2320 // Ref: msdn ImmGetVirtualKey:
2321 // http://msdn.microsoft.com/en-us/library/aa912145.aspx
2323 if ( (LOWORD(lpMsg->wParam) != VK_PROCESSKEY) ||
2324 !(Ret = IMM_ImmTranslateMessage( lpMsg->hwnd,
2329 Ret
= TranslateMessageEx((LPMSG
)lpMsg
, 0);
2339 RegisterWindowMessageA(LPCSTR lpString
)
2341 UNICODE_STRING String
;
2345 Result
= RtlCreateUnicodeStringFromAsciiz(&String
, (PCSZ
)lpString
);
2350 Atom
= NtUserRegisterWindowMessage(&String
);
2351 RtlFreeUnicodeString(&String
);
2360 RegisterWindowMessageW(LPCWSTR lpString
)
2362 UNICODE_STRING String
;
2364 RtlInitUnicodeString(&String
, lpString
);
2365 return(NtUserRegisterWindowMessage(&String
));
2374 return (HWND
)NtUserGetThreadState(THREADSTATE_CAPTUREWINDOW
);
2381 ReleaseCapture(VOID
)
2383 NtUserSetCapture(NULL
);
2393 RealGetQueueStatus(UINT flags
)
2395 #define QS_TEMPALLINPUT 255 // ATM, do not support QS_RAWINPUT
2396 if (flags
& ~(QS_SMRESULT
|QS_ALLPOSTMESSAGE
|QS_TEMPALLINPUT
))
2398 SetLastError( ERROR_INVALID_FLAGS
);
2401 return NtUserCallOneParam(flags
, ONEPARAM_ROUTINE_GETQUEUESTATUS
);
2408 BOOL WINAPI
GetInputState(VOID
)
2410 PCLIENTTHREADINFO pcti
= GetWin32ClientInfo()->pClientThreadInfo
;
2412 if ((!pcti
) || (pcti
->fsChangeBits
& (QS_KEY
|QS_MOUSEBUTTON
)))
2413 return (BOOL
)NtUserGetThreadState(THREADSTATE_GETINPUTSTATE
);
2420 User32CallWindowProcFromKernel(PVOID Arguments
, ULONG ArgumentLength
)
2422 PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs
;
2425 PCLIENTINFO pci
= GetWin32ClientInfo();
2427 /* Make sure we don't try to access mem beyond what we were given */
2428 if (ArgumentLength
< sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
))
2430 return STATUS_INFO_LENGTH_MISMATCH
;
2433 CallbackArgs
= (PWINDOWPROC_CALLBACK_ARGUMENTS
) Arguments
;
2434 KMMsg
.hwnd
= CallbackArgs
->Wnd
;
2435 KMMsg
.message
= CallbackArgs
->Msg
;
2436 KMMsg
.wParam
= CallbackArgs
->wParam
;
2437 /* Check if lParam is really a pointer and adjust it if it is */
2438 if (0 <= CallbackArgs
->lParamBufferSize
)
2440 if (ArgumentLength
!= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
)
2441 + CallbackArgs
->lParamBufferSize
)
2443 return STATUS_INFO_LENGTH_MISMATCH
;
2445 KMMsg
.lParam
= (LPARAM
) ((char *) CallbackArgs
+ sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
));
2449 if (ArgumentLength
!= sizeof(WINDOWPROC_CALLBACK_ARGUMENTS
))
2451 return STATUS_INFO_LENGTH_MISMATCH
;
2453 KMMsg
.lParam
= CallbackArgs
->lParam
;
2456 if (WM_NCCALCSIZE
== CallbackArgs
->Msg
&& CallbackArgs
->wParam
)
2458 NCCALCSIZE_PARAMS
*Params
= (NCCALCSIZE_PARAMS
*) KMMsg
.lParam
;
2459 Params
->lppos
= (PWINDOWPOS
) (Params
+ 1);
2462 if (! MsgiKMToUMMessage(&KMMsg
, &UMMsg
))
2466 if (pci
->CallbackWnd
.hWnd
== UMMsg
.hwnd
)
2467 pWnd
= pci
->CallbackWnd
.pWnd
;
2469 CallbackArgs
->Result
= IntCallWindowProcW( CallbackArgs
->IsAnsiProc
,
2477 if (! MsgiKMToUMReply(&KMMsg
, &UMMsg
, &CallbackArgs
->Result
))
2481 return ZwCallbackReturn(CallbackArgs
, ArgumentLength
, STATUS_SUCCESS
);
2487 BOOL WINAPI
SetMessageQueue(int cMessagesMax
)
2489 /* Function does nothing on 32 bit windows */
2492 typedef DWORD (WINAPI
* RealGetQueueStatusProc
)(UINT flags
);
2493 typedef DWORD (WINAPI
* RealMsgWaitForMultipleObjectsExProc
)(DWORD nCount
, CONST HANDLE
*lpHandles
, DWORD dwMilliseconds
, DWORD dwWakeMask
, DWORD dwFlags
);
2495 typedef struct _USER_MESSAGE_PUMP_ADDRESSES
{
2497 //NtUserRealInternalGetMessageProc NtUserRealInternalGetMessage;
2498 //NtUserRealWaitMessageExProc NtUserRealWaitMessageEx;
2499 RealGetQueueStatusProc RealGetQueueStatus
;
2500 RealMsgWaitForMultipleObjectsExProc RealMsgWaitForMultipleObjectsEx
;
2501 } USER_MESSAGE_PUMP_ADDRESSES
, * PUSER_MESSAGE_PUMP_ADDRESSES
;
2505 RealMsgWaitForMultipleObjectsEx(
2507 CONST HANDLE
*pHandles
,
2508 DWORD dwMilliseconds
,
2512 typedef BOOL (WINAPI
* MESSAGEPUMPHOOKPROC
)(BOOL Unregistering
,PUSER_MESSAGE_PUMP_ADDRESSES MessagePumpAddresses
);
2514 CRITICAL_SECTION gcsMPH
;
2515 MESSAGEPUMPHOOKPROC gpfnInitMPH
;
2516 DWORD gcLoadMPH
= 0;
2517 USER_MESSAGE_PUMP_ADDRESSES gmph
= {sizeof(USER_MESSAGE_PUMP_ADDRESSES
),
2518 //NtUserRealInternalGetMessage,
2519 //NtUserRealInternalWaitMessageEx,
2521 RealMsgWaitForMultipleObjectsEx
2524 DWORD gfMessagePumpHook
= 0;
2526 BOOL WINAPI
IsInsideMessagePumpHook()
2527 { // FF uses this and polls it when Min/Max
2528 PCLIENTTHREADINFO pcti
= GetWin32ClientInfo()->pClientThreadInfo
;
2529 return (gfMessagePumpHook
&& pcti
&& (pcti
->dwcPumpHook
> 0));
2532 void WINAPI
ResetMessagePumpHook(PUSER_MESSAGE_PUMP_ADDRESSES Addresses
)
2534 Addresses
->cbSize
= sizeof(USER_MESSAGE_PUMP_ADDRESSES
);
2535 //Addresses->NtUserRealInternalGetMessage = (NtUserRealInternalGetMessageProc)NtUserRealInternalGetMessage;
2536 //Addresses->NtUserRealWaitMessageEx = (NtUserRealWaitMessageExProc)NtUserRealInternalWaitMessageEx;
2537 Addresses
->RealGetQueueStatus
= RealGetQueueStatus
;
2538 Addresses
->RealMsgWaitForMultipleObjectsEx
= RealMsgWaitForMultipleObjectsEx
;
2541 BOOL WINAPI
RegisterMessagePumpHook(MESSAGEPUMPHOOKPROC Hook
)
2543 EnterCriticalSection(&gcsMPH
);
2545 SetLastError(ERROR_INVALID_PARAMETER
);
2546 LeaveCriticalSection(&gcsMPH
);
2550 USER_MESSAGE_PUMP_ADDRESSES Addresses
;
2552 ResetMessagePumpHook(&Addresses
);
2553 if(!Hook(FALSE
, &Addresses
) || !Addresses
.cbSize
) {
2554 LeaveCriticalSection(&gcsMPH
);
2557 memcpy(&gmph
, &Addresses
, Addresses
.cbSize
);
2559 if(gpfnInitMPH
!= Hook
) {
2560 LeaveCriticalSection(&gcsMPH
);
2564 if(NtUserCallNoParam(NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
)) {
2565 LeaveCriticalSection(&gcsMPH
);
2569 InterlockedExchange((PLONG
)&gfMessagePumpHook
, 1);
2571 LeaveCriticalSection(&gcsMPH
);
2575 BOOL WINAPI
UnregisterMessagePumpHook(VOID
)
2577 EnterCriticalSection(&gcsMPH
);
2579 if(NtUserCallNoParam(NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
)) {
2582 InterlockedExchange((PLONG
)&gfMessagePumpHook
, 0);
2583 gpfnInitMPH(TRUE
, NULL
);
2584 ResetMessagePumpHook(&gmph
);
2587 LeaveCriticalSection(&gcsMPH
);
2591 LeaveCriticalSection(&gcsMPH
);
2595 DWORD WINAPI
GetQueueStatus(UINT flags
)
2597 return IsInsideMessagePumpHook() ? gmph
.RealGetQueueStatus(flags
) : RealGetQueueStatus(flags
);
2601 * @name RealMsgWaitForMultipleObjectsEx
2603 * Wait either for either message arrival or for one of the passed events
2607 * Number of handles in the pHandles array.
2609 * Handles of events to wait for.
2610 * @param dwMilliseconds
2613 * Mask specifying on which message events we should wakeup.
2615 * Wait type (see MWMO_* constants).
2621 RealMsgWaitForMultipleObjectsEx(
2623 const HANDLE
*pHandles
,
2624 DWORD dwMilliseconds
,
2628 LPHANDLE RealHandles
;
2629 HANDLE MessageQueueHandle
;
2632 PCLIENTTHREADINFO pcti
;
2634 if (dwFlags
& ~(MWMO_WAITALL
| MWMO_ALERTABLE
| MWMO_INPUTAVAILABLE
))
2636 SetLastError(ERROR_INVALID_PARAMETER
);
2640 pci
= GetWin32ClientInfo();
2641 if (!pci
) return WAIT_FAILED
;
2643 pcti
= pci
->pClientThreadInfo
;
2644 if (pcti
&& ( !nCount
|| !(dwFlags
& MWMO_WAITALL
) ))
2646 if ( (pcti
->fsChangeBits
& LOWORD(dwWakeMask
)) ||
2647 ( (dwFlags
& MWMO_INPUTAVAILABLE
) && (pcti
->fsWakeBits
& LOWORD(dwWakeMask
)) ) )
2649 //FIXME("Chg 0x%x Wake 0x%x Mask 0x%x nCnt %d\n",pcti->fsChangeBits, pcti->fsWakeBits, dwWakeMask, nCount);
2654 MessageQueueHandle
= NtUserMsqSetWakeMask(MAKELONG(dwWakeMask
, dwFlags
));
2655 if (MessageQueueHandle
== NULL
)
2657 SetLastError(0); /* ? */
2661 RealHandles
= HeapAlloc(GetProcessHeap(), 0, (nCount
+ 1) * sizeof(HANDLE
));
2662 if (RealHandles
== NULL
)
2664 NtUserMsqClearWakeMask();
2665 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2669 RtlCopyMemory(RealHandles
, pHandles
, nCount
* sizeof(HANDLE
));
2670 RealHandles
[nCount
] = MessageQueueHandle
;
2672 Result
= WaitForMultipleObjectsEx(nCount
+ 1, RealHandles
,
2673 dwFlags
& MWMO_WAITALL
,
2674 dwMilliseconds
, dwFlags
& MWMO_ALERTABLE
);
2676 HeapFree(GetProcessHeap(), 0, RealHandles
);
2677 NtUserMsqClearWakeMask();
2678 //FIXME("Result 0X%x\n",Result);
2686 MsgWaitForMultipleObjectsEx(
2688 CONST HANDLE
*lpHandles
,
2689 DWORD dwMilliseconds
,
2693 return IsInsideMessagePumpHook() ? gmph
.RealMsgWaitForMultipleObjectsEx(nCount
, lpHandles
, dwMilliseconds
, dwWakeMask
, dwFlags
) : RealMsgWaitForMultipleObjectsEx(nCount
, lpHandles
,dwMilliseconds
, dwWakeMask
, dwFlags
);
2700 MsgWaitForMultipleObjects(
2702 CONST HANDLE
*lpHandles
,
2704 DWORD dwMilliseconds
,
2707 return MsgWaitForMultipleObjectsEx(nCount
, lpHandles
, dwMilliseconds
,
2708 dwWakeMask
, fWaitAll
? MWMO_WAITALL
: 0);
2712 BOOL FASTCALL
MessageInit(VOID
)
2714 InitializeCriticalSection(&DdeCrst
);
2715 InitializeCriticalSection(&gcsMPH
);
2720 VOID FASTCALL
MessageCleanup(VOID
)
2722 DeleteCriticalSection(&DdeCrst
);
2723 DeleteCriticalSection(&gcsMPH
);
2726 /***********************************************************************
2729 * Convert the wparam of an ASCII message to Unicode.
2732 map_wparam_AtoW( UINT message
, WPARAM wparam
)
2737 case EM_SETPASSWORDCHAR
:
2741 case WM_SYSDEADCHAR
:
2746 ch
[0] = (wparam
& 0xff);
2747 ch
[1] = (wparam
>> 8);
2748 MultiByteToWideChar(CP_ACP
, 0, ch
, 2, wch
, 2);
2749 wparam
= MAKEWPARAM(wch
[0], wch
[1]);
2756 ch
[0] = (wparam
>> 8);
2757 ch
[1] = (wparam
& 0xff);
2758 if (ch
[0]) MultiByteToWideChar(CP_ACP
, 0, ch
, 2, &wch
, 1);
2759 else MultiByteToWideChar(CP_ACP
, 0, &ch
[1], 1, &wch
, 1);
2760 wparam
= MAKEWPARAM( wch
, HIWORD(wparam
) );
2771 IsDialogMessageA( HWND hwndDlg
, LPMSG pmsg
)
2774 msg
.wParam
= map_wparam_AtoW( msg
.message
, msg
.wParam
);
2775 return IsDialogMessageW( hwndDlg
, &msg
);
2780 IntBroadcastSystemMessage(
2782 LPDWORD lpdwRecipients
,
2790 DWORD recips
= BSM_ALLCOMPONENTS
;
2791 BOOL ret
= -1; // Set to return fail
2792 static const DWORD all_flags
= ( BSF_QUERY
| BSF_IGNORECURRENTTASK
| BSF_FLUSHDISK
| BSF_NOHANG
2793 | BSF_POSTMESSAGE
| BSF_FORCEIFHUNG
| BSF_NOTIMEOUTIFNOTHUNG
2794 | BSF_ALLOWSFW
| BSF_SENDNOTIFYMESSAGE
| BSF_RETURNHDESK
| BSF_LUID
);
2796 if ((dwflags
& ~all_flags
) ||
2797 (!pBSMInfo
&& (dwflags
& (BSF_RETURNHDESK
|BSF_LUID
))) )
2799 SetLastError(ERROR_INVALID_PARAMETER
);
2803 if(uiMessage
>= WM_USER
&& uiMessage
< 0xC000)
2805 SetLastError(ERROR_INVALID_PARAMETER
);
2809 if (dwflags
& BSF_FORCEIFHUNG
) dwflags
|= BSF_NOHANG
;
2811 if (dwflags
& BSF_QUERY
) dwflags
&= ~BSF_SENDNOTIFYMESSAGE
|BSF_POSTMESSAGE
;
2813 if (!lpdwRecipients
)
2814 lpdwRecipients
= &recips
;
2816 if (*lpdwRecipients
& ~(BSM_APPLICATIONS
|BSM_ALLDESKTOPS
|BSM_INSTALLABLEDRIVERS
|BSM_NETDRIVER
|BSM_VXDS
))
2818 SetLastError(ERROR_INVALID_PARAMETER
);
2822 if ( pBSMInfo
&& (dwflags
& BSF_QUERY
) )
2824 if (pBSMInfo
->cbSize
!= sizeof(BSMINFO
))
2826 SetLastError(ERROR_INVALID_PARAMETER
);
2833 parm
.flags
= dwflags
;
2834 parm
.recipients
= *lpdwRecipients
;
2836 if (dwflags
& BSF_LUID
) parm
.luid
= pBSMInfo
->luid
;
2838 if (*lpdwRecipients
& BSM_APPLICATIONS
)
2840 ret
= NtUserMessageCall(GetDesktopWindow(),
2845 FNID_BROADCASTSYSTEMMESSAGE
,
2851 if ( pBSMInfo
&& (dwflags
& BSF_QUERY
) )
2853 pBSMInfo
->hdesk
= parm
.hDesk
;
2854 pBSMInfo
->hwnd
= parm
.hWnd
;
2865 BroadcastSystemMessageA(
2867 LPDWORD lpdwRecipients
,
2872 return IntBroadcastSystemMessage( dwFlags
, lpdwRecipients
, uiMessage
, wParam
, lParam
, NULL
, TRUE
);
2880 BroadcastSystemMessageW(
2882 LPDWORD lpdwRecipients
,
2887 return IntBroadcastSystemMessage( dwFlags
, lpdwRecipients
, uiMessage
, wParam
, lParam
, NULL
, FALSE
);
2895 BroadcastSystemMessageExA(
2897 LPDWORD lpdwRecipients
,
2903 return IntBroadcastSystemMessage( dwflags
, lpdwRecipients
, uiMessage
, wParam
, lParam
, pBSMInfo
, TRUE
);
2911 BroadcastSystemMessageExW(
2913 LPDWORD lpdwRecipients
,
2919 return IntBroadcastSystemMessage( dwflags
, lpdwRecipients
, uiMessage
, wParam
, lParam
, pBSMInfo
, FALSE
);