1 /* $Id: message.c,v 1.26 2003/11/08 09:33:14 navaraf Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/message.c
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
21 GetMessageExtraInfo(VOID
)
35 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
36 return(MAKELONG(ThreadData
->LastMessage
.pt
.x
, ThreadData
->LastMessage
.pt
.y
));
46 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
47 return(ThreadData
->LastMessage
.time
);
102 MsgiAnsiToUnicodeMessage(LPMSG UnicodeMsg
, LPMSG AnsiMsg
)
104 *UnicodeMsg
= *AnsiMsg
;
105 switch (AnsiMsg
->message
)
108 case WM_ASKCBFORMATNAME
:
110 LPWSTR Buffer
= HeapAlloc(GetProcessHeap(), 0,
111 AnsiMsg
->wParam
* sizeof(WCHAR
));
116 UnicodeMsg
->lParam
= (LPARAM
)Buffer
;
120 /* AnsiMsg->lParam is string (0-terminated) */
122 case WM_WININICHANGE
:
123 case WM_DEVMODECHANGE
:
129 UNICODE_STRING UnicodeString
;
130 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)AnsiMsg
->lParam
);
131 UnicodeMsg
->lParam
= (LPARAM
)UnicodeString
.Buffer
;
138 UNICODE_STRING UnicodeBuffer
;
141 CREATESTRUCTW cs
; /* new structure */
142 LPCWSTR lpszName
; /* allocated Name */
143 LPCWSTR lpszClass
; /* allocated Class */
145 struct s
*xs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
150 xs
->cs
= *(CREATESTRUCTW
*)AnsiMsg
->lParam
;
151 if (HIWORD(xs
->cs
.lpszName
))
153 RtlCreateUnicodeStringFromAsciiz(&UnicodeBuffer
, (LPSTR
)xs
->cs
.lpszName
);
154 xs
->lpszName
= xs
->cs
.lpszName
= UnicodeBuffer
.Buffer
;
156 if (HIWORD(xs
->cs
.lpszClass
))
158 RtlCreateUnicodeStringFromAsciiz(&UnicodeBuffer
, (LPSTR
)xs
->cs
.lpszClass
);
159 xs
->lpszClass
= xs
->cs
.lpszClass
= UnicodeBuffer
.Buffer
;
161 UnicodeMsg
->lParam
= (LPARAM
)xs
;
167 UNICODE_STRING UnicodeBuffer
;
168 MDICREATESTRUCTW
*cs
=
169 (MDICREATESTRUCTW
*)HeapAlloc(GetProcessHeap(), 0, sizeof(*cs
));
176 *cs
= *(MDICREATESTRUCTW
*)AnsiMsg
->lParam
;
178 if (HIWORD(cs
->szClass
))
180 RtlCreateUnicodeStringFromAsciiz(&UnicodeBuffer
, (LPSTR
)cs
->szClass
);
181 cs
->szClass
= UnicodeBuffer
.Buffer
;
184 RtlCreateUnicodeStringFromAsciiz(&UnicodeBuffer
, (LPSTR
)cs
->szTitle
);
185 cs
->szTitle
= UnicodeBuffer
.Buffer
;
187 UnicodeMsg
->lParam
= (LPARAM
)cs
;
197 MsgiAnsiToUnicodeReply(LPMSG UnicodeMsg
, LPMSG AnsiMsg
, LRESULT
*Result
)
199 switch (AnsiMsg
->message
)
202 case WM_ASKCBFORMATNAME
:
204 LPWSTR Buffer
= (LPWSTR
)UnicodeMsg
->lParam
;
205 LPSTR AnsiBuffer
= (LPSTR
)AnsiMsg
->lParam
;
206 if (UnicodeMsg
->wParam
> 0 &&
207 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
208 AnsiBuffer
, UnicodeMsg
->wParam
, NULL
, NULL
))
210 AnsiBuffer
[UnicodeMsg
->wParam
- 1] = 0;
212 HeapFree(GetProcessHeap(), 0, Buffer
);
216 case WM_GETTEXTLENGTH
:
217 case CB_GETLBTEXTLEN
:
220 /* FIXME: There may be one DBCS char for each Unicode char */
226 case WM_WININICHANGE
:
227 case WM_DEVMODECHANGE
:
233 UNICODE_STRING UnicodeString
;
234 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)UnicodeMsg
->lParam
);
235 RtlFreeUnicodeString(&UnicodeString
);
242 UNICODE_STRING UnicodeString
;
245 CREATESTRUCTW cs
; /* new structure */
246 LPWSTR lpszName
; /* allocated Name */
247 LPWSTR lpszClass
; /* allocated Class */
249 struct s
*xs
= (struct s
*)UnicodeMsg
->lParam
;
252 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)xs
->lpszName
);
253 RtlFreeUnicodeString(&UnicodeString
);
257 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)xs
->lpszClass
);
258 RtlFreeUnicodeString(&UnicodeString
);
260 HeapFree(GetProcessHeap(), 0, xs
);
266 UNICODE_STRING UnicodeString
;
267 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)UnicodeMsg
->lParam
;
268 if (HIWORD(cs
->szTitle
))
270 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)cs
->szTitle
);
271 RtlFreeUnicodeString(&UnicodeString
);
273 if (HIWORD(cs
->szClass
))
275 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)cs
->szClass
);
276 RtlFreeUnicodeString(&UnicodeString
);
278 HeapFree(GetProcessHeap(), 0, cs
);
287 User32ConvertToAsciiMessage(UINT
* Msg
, WPARAM
* wParam
, LPARAM
* lParam
)
296 UNICODE_STRING UString
;
299 CsW
= (CREATESTRUCTW
*)(*lParam
);
300 CsA
= RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(CREATESTRUCTA
));
301 memcpy(CsA
, CsW
, sizeof(CREATESTRUCTW
));
303 RtlInitUnicodeString(&UString
, CsW
->lpszName
);
304 RtlUnicodeStringToAnsiString(&AString
, &UString
, TRUE
);
305 CsA
->lpszName
= AString
.Buffer
;
306 if (HIWORD((ULONG
)CsW
->lpszClass
) != 0)
308 RtlInitUnicodeString(&UString
, CsW
->lpszClass
);
309 RtlUnicodeStringToAnsiString(&AString
, &UString
, TRUE
);
310 CsA
->lpszClass
= AString
.Buffer
;
312 (*lParam
) = (LPARAM
)CsA
;
317 ANSI_STRING AnsiString
;
318 UNICODE_STRING UnicodeString
;
319 RtlInitUnicodeString(&UnicodeString
, (PWSTR
) *lParam
);
320 if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString
,
324 *lParam
= (LPARAM
) AnsiString
.Buffer
;
333 User32FreeAsciiConvertedMessage(UINT Msg
, WPARAM wParam
, LPARAM lParam
)
339 ANSI_STRING AnsiString
;
340 UNICODE_STRING UnicodeString
;
343 InString
= (LPSTR
)lParam
;
344 TempString
= RtlAllocateHeap(RtlGetProcessHeap(), 0, strlen(InString
) + 1);
345 strcpy(TempString
, InString
);
346 RtlInitAnsiString(&AnsiString
, TempString
);
347 UnicodeString
.Length
= wParam
* sizeof(WCHAR
);
348 UnicodeString
.MaximumLength
= wParam
* sizeof(WCHAR
);
349 UnicodeString
.Buffer
= (PWSTR
)lParam
;
350 if (! NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString
,
356 UnicodeString
.Buffer
[0] = L
'\0';
359 RtlFreeHeap(RtlGetProcessHeap(), 0, TempString
);
364 ANSI_STRING AnsiString
;
365 RtlInitAnsiString(&AnsiString
, (PSTR
) lParam
);
366 RtlFreeAnsiString(&AnsiString
);
374 Cs
= (CREATESTRUCTA
*)lParam
;
375 RtlFreeHeap(RtlGetProcessHeap(), 0, (LPSTR
)Cs
->lpszName
);
376 if (HIWORD((ULONG
)Cs
->lpszClass
) != 0)
378 RtlFreeHeap(RtlGetProcessHeap(), 0, (LPSTR
)Cs
->lpszClass
);
380 RtlFreeHeap(RtlGetProcessHeap(), 0, Cs
);
391 CallWindowProcA(WNDPROC lpPrevWndFunc
,
402 if ((DWORD
)lpPrevWndFunc
> 0x80000000)
404 lpPrevWndFunc
-= 0x80000000;
413 AnsiMsg
.message
= Msg
;
414 AnsiMsg
.wParam
= wParam
;
415 AnsiMsg
.lParam
= lParam
;
417 if (IsWindowUnicode(hWnd
))
419 if (!MsgiAnsiToUnicodeMessage(&UnicodeMsg
, &AnsiMsg
))
423 Result
= lpPrevWndFunc(hWnd
, Msg
, wParam
, lParam
);
424 if (!MsgiAnsiToUnicodeReply(&UnicodeMsg
, &AnsiMsg
, &Result
))
432 return(lpPrevWndFunc(hWnd
, Msg
, wParam
, lParam
));
441 CallWindowProcW(WNDPROC lpPrevWndFunc
,
448 if ((DWORD
)lpPrevWndFunc
> 0x80000000)
450 lpPrevWndFunc
-= 0x80000000;
457 if (!IsWindowUnicode(hWnd
))
460 User32ConvertToAsciiMessage(&Msg
, &wParam
, &lParam
);
461 Result
= lpPrevWndFunc(hWnd
, Msg
, wParam
, lParam
);
462 User32FreeAsciiConvertedMessage(Msg
, wParam
, lParam
);
467 return(lpPrevWndFunc(hWnd
, Msg
, wParam
, lParam
));
476 DispatchMessageA(CONST MSG
*lpmsg
)
478 return(NtUserDispatchMessage(lpmsg
));
486 DispatchMessageW(CONST MSG
*lpmsg
)
488 return(NtUserDispatchMessage((LPMSG
)lpmsg
));
496 GetMessageA(LPMSG lpMsg
,
502 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
504 Res
= NtUserGetMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
);
505 if (Res
&& lpMsg
->message
!= WM_PAINT
&& lpMsg
->message
!= WM_QUIT
)
507 ThreadData
->LastMessage
= *lpMsg
;
517 GetMessageW(LPMSG lpMsg
,
523 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
525 Res
= NtUserGetMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
);
526 if (Res
&& lpMsg
->message
!= WM_PAINT
&& lpMsg
->message
!= WM_QUIT
)
528 ThreadData
->LastMessage
= *lpMsg
;
538 PeekMessageA(LPMSG lpMsg
,
545 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
547 Res
= NtUserPeekMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
548 if (Res
&& lpMsg
->message
!= WM_PAINT
&& lpMsg
->message
!= WM_QUIT
)
550 ThreadData
->LastMessage
= *lpMsg
;
569 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
571 Res
= NtUserPeekMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
572 if (Res
&& lpMsg
->message
!= WM_PAINT
&& lpMsg
->message
!= WM_QUIT
)
574 ThreadData
->LastMessage
= *lpMsg
;
591 return NtUserPostMessage(hWnd
, Msg
, wParam
, lParam
);
606 return NtUserPostMessage(hWnd
, Msg
, wParam
, lParam
);
618 (void) NtUserPostMessage(NULL
, WM_QUIT
, nExitCode
, 0);
633 return NtUserPostThreadMessage(idThread
, Msg
, wParam
, lParam
);
648 return NtUserPostThreadMessage(idThread
, Msg
, wParam
, lParam
);
656 SendMessageW(HWND hWnd
,
661 return(NtUserSendMessage(hWnd
, Msg
, wParam
, lParam
));
669 SendMessageA(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
676 AnsiMsg
.message
= Msg
;
677 AnsiMsg
.wParam
= wParam
;
678 AnsiMsg
.lParam
= lParam
;
680 if (!MsgiAnsiToUnicodeMessage(&UcMsg
, &AnsiMsg
))
684 Result
= SendMessageW(UcMsg
.hwnd
, UcMsg
.message
, UcMsg
.wParam
, UcMsg
.lParam
);
685 if (!MsgiAnsiToUnicodeReply(&UcMsg
, &AnsiMsg
, &Result
))
698 SendMessageCallbackA(
703 SENDASYNCPROC lpCallBack
,
706 return NtUserSendMessageCallback(
721 SendMessageCallbackW(
726 SENDASYNCPROC lpCallBack
,
729 return NtUserSendMessageCallback(
751 PDWORD_PTR lpdwResult
)
770 PDWORD_PTR lpdwResult
)
813 TranslateMessage(CONST MSG
*lpMsg
)
815 return(TranslateMessageEx((LPMSG
)lpMsg
, 0));
822 TranslateMessageEx(CONST MSG
*lpMsg
, DWORD unk
)
824 return(NtUserTranslateMessage((LPMSG
)lpMsg
, (HKL
)unk
));
835 return NtUserWaitMessage();
843 RegisterWindowMessageA(LPCSTR lpString
)
845 UNICODE_STRING String
;
849 Result
= RtlCreateUnicodeStringFromAsciiz(&String
, (PCSZ
)lpString
);
854 Atom
= NtUserRegisterWindowMessage(&String
);
855 RtlFreeUnicodeString(&String
);
864 RegisterWindowMessageW(LPCWSTR lpString
)
866 UNICODE_STRING String
;
868 RtlInitUnicodeString(&String
, lpString
);
869 return(NtUserRegisterWindowMessage(&String
));
876 SetCapture(HWND hWnd
)
878 return(NtUserSetCapture(hWnd
));
887 return(NtUserGetCapture());
896 NtUserSetCapture(NULL
);
906 GetQueueStatus(UINT flags
)
909 WORD changed_bits
, wake_bits
;
911 #if 0 /* wine stuff. don't know what it does... */
913 /* check for pending X events */
914 if (USER_Driver
.pMsgWaitForMultipleObjectsEx
)
915 USER_Driver
.pMsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, 0 );
918 ret
= NtUserGetQueueStatus(TRUE
/*ClearChanges*/);
920 changed_bits
= LOWORD(ret
);
921 wake_bits
= HIWORD(ret
);
923 return MAKELONG(changed_bits
& flags
, wake_bits
& flags
);
930 WINBOOL STDCALL
GetInputState(VOID
)
935 #if 0 /* wine stuff. don't know what it does... */
937 /* check for pending X events */
938 if (USER_Driver
.pMsgWaitForMultipleObjectsEx
)
939 USER_Driver
.pMsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, 0 );
942 ret
= NtUserGetQueueStatus(FALSE
/*ClearChanges*/);
944 wake_bits
= HIWORD(ret
);
946 return wake_bits
& (QS_KEY
| QS_MOUSEBUTTON
);
952 WINBOOL STDCALL
SetMessageQueue(int cMessagesMax
)
954 /* Function does nothing on 32 bit windows */