update for HEAD-2003091401
[reactos.git] / lib / user32 / windows / message.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS user32.dll
5  * FILE:            lib/user32/windows/message.c
6  * PURPOSE:         Messages
7  * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
8  * UPDATE HISTORY:
9  *      06-06-2001  CSH  Created
10  */
11 #include <windows.h>
12 #include <user32.h>
13 #include <string.h>
14 #include <debug.h>
15
16 /*
17  * @implemented
18  */
19 LPARAM
20 STDCALL
21 GetMessageExtraInfo(VOID)
22 {
23   UNIMPLEMENTED;
24   return (LPARAM)0;
25 }
26
27
28 /*
29  * @implemented
30  */
31 DWORD
32 STDCALL
33 GetMessagePos(VOID)
34 {
35   PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
36   return(MAKELONG(ThreadData->LastMessage.pt.x, ThreadData->LastMessage.pt.y));
37 }
38
39
40 /*
41  * @implemented
42  */
43 LONG STDCALL
44 GetMessageTime(VOID)
45 {
46   PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
47   return(ThreadData->LastMessage.time);
48 }
49
50
51 /*
52  * @unimplemented
53  */
54 WINBOOL
55 STDCALL
56 InSendMessage(VOID)
57 {
58   return FALSE;
59 }
60
61
62 /*
63  * @unimplemented
64  */
65 DWORD
66 STDCALL
67 InSendMessageEx(
68   LPVOID lpReserved)
69 {
70   UNIMPLEMENTED;
71   return 0;
72 }
73
74
75 /*
76  * @unimplemented
77  */
78 WINBOOL
79 STDCALL
80 ReplyMessage(
81   LRESULT lResult)
82 {
83   UNIMPLEMENTED;
84   return FALSE;
85 }
86
87
88 /*
89  * @unimplemented
90  */
91 LPARAM
92 STDCALL
93 SetMessageExtraInfo(
94   LPARAM lParam)
95 {
96   UNIMPLEMENTED;
97   return (LPARAM)0;
98 }
99
100
101 VOID STATIC
102 User32FreeAsciiConvertedMessage(UINT Msg, WPARAM wParam, LPARAM lParam)
103 {
104   switch(Msg)
105     {
106     case WM_GETTEXT:
107       {
108         ANSI_STRING AnsiString;
109         UNICODE_STRING UnicodeString;
110         LPSTR TempString;
111         LPSTR InString;
112         InString = (LPSTR)lParam;
113         TempString = RtlAllocateHeap(RtlGetProcessHeap(), 0, strlen(InString) + 1);
114         strcpy(TempString, InString);
115         RtlInitAnsiString(&AnsiString, TempString);
116         UnicodeString.Length = wParam * sizeof(WCHAR);
117         UnicodeString.MaximumLength = wParam * sizeof(WCHAR);
118         UnicodeString.Buffer = (PWSTR)lParam;
119         if (! NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
120                                                       &AnsiString,
121                                                       FALSE)))
122           {
123             if (1 <= wParam)
124               {
125                 UnicodeString.Buffer[0] = L'\0';
126               }
127           }
128         RtlFreeHeap(RtlGetProcessHeap(), 0, TempString);
129         break;
130       }
131     case WM_SETTEXT:
132       {
133         ANSI_STRING AnsiString;
134         RtlInitAnsiString(&AnsiString, (PSTR) lParam);
135         RtlFreeAnsiString(&AnsiString);
136         break;
137       }
138     case WM_NCCREATE:
139       {
140         CREATESTRUCTA* Cs;
141
142         Cs = (CREATESTRUCTA*)lParam;
143         RtlFreeHeap(RtlGetProcessHeap(), 0, (LPSTR)Cs->lpszName);
144         if (HIWORD((ULONG)Cs->lpszClass) != 0)
145           {
146             RtlFreeHeap(RtlGetProcessHeap(), 0, (LPSTR)Cs->lpszClass);
147           }
148         RtlFreeHeap(RtlGetProcessHeap(), 0, Cs);
149         break;
150       }
151     }
152 }
153
154
155 VOID STATIC
156 User32ConvertToAsciiMessage(UINT* Msg, WPARAM* wParam, LPARAM* lParam)
157 {
158   switch((*Msg))
159     {
160     case WM_NCCREATE:
161       {
162         CREATESTRUCTA* CsA;
163         CREATESTRUCTW* CsW;
164         UNICODE_STRING UString;
165         ANSI_STRING AString;
166
167         CsW = (CREATESTRUCTW*)(*lParam);
168         CsA = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(CREATESTRUCTA));
169         memcpy(CsA, CsW, sizeof(CREATESTRUCTW));
170
171         RtlInitUnicodeString(&UString, CsW->lpszName);
172         RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
173         CsA->lpszName = AString.Buffer;
174         if (HIWORD((ULONG)CsW->lpszClass) != 0)
175           {
176             RtlInitUnicodeString(&UString, CsW->lpszClass);
177             RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
178             CsA->lpszClass = AString.Buffer;
179           }
180         (*lParam) = (LPARAM)CsA;
181         break;
182       }
183     case WM_SETTEXT:
184       {
185         ANSI_STRING AnsiString;
186         UNICODE_STRING UnicodeString;
187         RtlInitUnicodeString(&UnicodeString, (PWSTR) *lParam);
188         if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString,
189                                                     &UnicodeString,
190                                                     TRUE)))
191           {
192             *lParam = (LPARAM) AnsiString.Buffer;
193           }
194         break;
195       }
196     }
197 }
198
199
200 VOID STATIC
201 User32FreeUnicodeConvertedMessage(UINT Msg, WPARAM wParam, LPARAM lParam)
202 {
203   UNIMPLEMENTED;
204 }
205
206
207 VOID STATIC
208 User32ConvertToUnicodeMessage(UINT* Msg, WPARAM* wParam, LPARAM* lParam)
209 {
210   UNIMPLEMENTED;
211 }
212
213
214 /*
215  * @implemented
216  */
217 LRESULT STDCALL
218 CallWindowProcA(WNDPROC lpPrevWndFunc,
219                 HWND hWnd,
220                 UINT Msg,
221                 WPARAM wParam,
222                 LPARAM lParam)
223 {
224   BOOL IsHandle;
225   if ((DWORD)lpPrevWndFunc > 0x80000000)
226   {
227           lpPrevWndFunc -= 0x80000000;
228           IsHandle = TRUE;
229   }
230   else
231   {
232           IsHandle = FALSE;
233   }
234   if (IsWindowUnicode(hWnd))
235     {
236       LRESULT Result;
237       User32ConvertToUnicodeMessage(&Msg, &wParam, &lParam);
238       Result = lpPrevWndFunc(hWnd, Msg, wParam, lParam);
239       User32FreeUnicodeConvertedMessage(Msg, wParam, lParam);
240       return(Result);
241     }
242   else
243     {
244       return(lpPrevWndFunc(hWnd, Msg, wParam, lParam));
245     }
246 }
247
248
249 /*
250  * @implemented
251  */
252 LRESULT STDCALL
253 CallWindowProcW(WNDPROC lpPrevWndFunc,
254                 HWND hWnd,
255                 UINT Msg,
256                 WPARAM wParam,
257                 LPARAM lParam)
258 {
259   BOOL IsHandle;
260   if ((DWORD)lpPrevWndFunc > 0x80000000)
261   {
262           lpPrevWndFunc-= 0x80000000;
263           IsHandle = TRUE;
264   }
265   else
266   {
267           IsHandle = FALSE;
268   }
269   if (!IsWindowUnicode(hWnd))
270     {
271       LRESULT Result;
272       User32ConvertToAsciiMessage(&Msg, &wParam, &lParam);
273       Result = lpPrevWndFunc(hWnd, Msg, wParam, lParam);
274       User32FreeAsciiConvertedMessage(Msg, wParam, lParam);
275       return(Result);
276     }
277   else
278     {
279       return(lpPrevWndFunc(hWnd, Msg, wParam, lParam));
280     }
281 }
282
283
284 BOOL
285 MsgiAnsiToUnicodeMessage(LPMSG UnicodeMsg, LPMSG AnsiMsg)
286 {
287   *UnicodeMsg = *AnsiMsg;
288   switch (AnsiMsg->message)
289     {
290     case WM_GETTEXT:
291       {
292         UnicodeMsg->wParam = UnicodeMsg->wParam / 2;
293         break;
294       }
295     case WM_SETTEXT:
296       {
297         ANSI_STRING AnsiString;
298         UNICODE_STRING UnicodeString;
299         RtlInitAnsiString(&AnsiString, (PSTR) AnsiMsg->lParam);
300         if (! NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
301                                                       &AnsiString,
302                                                       TRUE)))
303           {
304           return FALSE;
305           }
306         UnicodeMsg->lParam = (LPARAM) UnicodeString.Buffer;
307         break;
308       }
309     }
310   return TRUE;
311 }
312
313
314 BOOL
315 MsgiAnsiToUnicodeReply(LPMSG UnicodeMsg, LPMSG AnsiMsg, LRESULT Result)
316 {
317   switch (AnsiMsg->message)
318     {
319     case WM_GETTEXT:
320       {
321         ANSI_STRING AnsiString;
322         UNICODE_STRING UnicodeString;
323         LPWSTR TempString;
324         LPWSTR InString;
325         InString = (LPWSTR)UnicodeMsg->lParam;
326         TempString = RtlAllocateHeap(RtlGetProcessHeap(), 0, 
327                                      wcslen(InString) * sizeof(WCHAR));
328         wcscpy(TempString, InString);
329         RtlInitUnicodeString(&UnicodeString, TempString);
330         AnsiString.Length = AnsiMsg->wParam;
331         AnsiString.MaximumLength = AnsiMsg->wParam;
332         AnsiString.Buffer = (PSTR)AnsiMsg->lParam;
333         RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
334         RtlFreeHeap(RtlGetProcessHeap(), 0, TempString);
335         break;
336       }
337     case WM_SETTEXT:
338       {
339         UNICODE_STRING UnicodeString;
340         RtlInitUnicodeString(&UnicodeString, (PCWSTR) UnicodeMsg->lParam);
341         RtlFreeUnicodeString(&UnicodeString);
342         break;
343       }
344     }
345   return(TRUE);
346 }
347
348
349 /*
350  * @implemented
351  */
352 LRESULT STDCALL
353 DispatchMessageA(CONST MSG *lpmsg)
354 {
355   return(NtUserDispatchMessage(lpmsg));
356 }
357
358
359 /*
360  * @implemented
361  */
362 LRESULT STDCALL
363 DispatchMessageW(CONST MSG *lpmsg)
364 {
365   return(NtUserDispatchMessage((LPMSG)lpmsg));
366 }
367
368
369 /*
370  * @implemented
371  */
372 WINBOOL STDCALL
373 GetMessageA(LPMSG lpMsg,
374             HWND hWnd,
375             UINT wMsgFilterMin,
376             UINT wMsgFilterMax)
377 {
378   BOOL Res;
379   PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
380
381   Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
382   if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
383     {
384       ThreadData->LastMessage = *lpMsg;
385     }
386   return(Res);
387 }
388
389
390 /*
391  * @implemented
392  */
393 WINBOOL STDCALL
394 GetMessageW(LPMSG lpMsg,
395             HWND hWnd,
396             UINT wMsgFilterMin,
397             UINT wMsgFilterMax)
398 {
399   BOOL Res;
400   PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
401
402   Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
403   if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
404     {
405       ThreadData->LastMessage = *lpMsg;
406     }
407   return(Res);
408 }
409
410
411 /*
412  * @implemented
413  */
414 WINBOOL STDCALL
415 PeekMessageA(LPMSG lpMsg,
416              HWND hWnd,
417              UINT wMsgFilterMin,
418              UINT wMsgFilterMax,
419              UINT wRemoveMsg)
420 {
421   BOOL Res;
422   PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
423
424   Res =  NtUserPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
425   if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
426     {
427       ThreadData->LastMessage = *lpMsg;
428     }
429   return(Res);
430 }
431
432
433 /*
434  * @implemented
435  */
436 WINBOOL
437 STDCALL
438 PeekMessageW(
439   LPMSG lpMsg,
440   HWND hWnd,
441   UINT wMsgFilterMin,
442   UINT wMsgFilterMax,
443   UINT wRemoveMsg)
444 {
445   BOOL Res;
446   PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
447   
448   Res = NtUserPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
449   if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
450     {
451       ThreadData->LastMessage = *lpMsg;
452     }
453   return(Res);
454 }
455
456
457 /*
458  * @implemented
459  */
460 WINBOOL
461 STDCALL
462 PostMessageA(
463   HWND hWnd,
464   UINT Msg,
465   WPARAM wParam,
466   LPARAM lParam)
467 {
468   return NtUserPostMessage(hWnd, Msg, wParam, lParam);
469 }
470
471
472 /*
473  * @implemented
474  */
475 WINBOOL
476 STDCALL
477 PostMessageW(
478   HWND hWnd,
479   UINT Msg,
480   WPARAM wParam,
481   LPARAM lParam)
482 {
483   return NtUserPostMessage(hWnd, Msg, wParam, lParam);
484 }
485
486
487 /*
488  * @implemented
489  */
490 VOID
491 STDCALL
492 PostQuitMessage(
493   int nExitCode)
494 {
495   (void) NtUserPostMessage(NULL, WM_QUIT, nExitCode, 0);
496 }
497
498
499 /*
500  * @implemented
501  */
502 WINBOOL
503 STDCALL
504 PostThreadMessageA(
505   DWORD idThread,
506   UINT Msg,
507   WPARAM wParam,
508   LPARAM lParam)
509 {
510   return NtUserPostThreadMessage(idThread, Msg, wParam, lParam);
511 }
512
513
514 /*
515  * @implemented
516  */
517 WINBOOL
518 STDCALL
519 PostThreadMessageW(
520   DWORD idThread,
521   UINT Msg,
522   WPARAM wParam,
523   LPARAM lParam)
524 {
525   return NtUserPostThreadMessage(idThread, Msg, wParam, lParam);
526 }
527
528
529 /*
530  * @implemented
531  */
532 LRESULT STDCALL
533 SendMessageW(HWND hWnd,
534              UINT Msg,
535              WPARAM wParam,
536              LPARAM lParam)
537 {
538   return(NtUserSendMessage(hWnd, Msg, wParam, lParam));
539 }
540
541
542 /*
543  * @implemented
544  */
545 LRESULT STDCALL
546 SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
547 {
548   MSG AnsiMsg;
549   MSG UcMsg;
550   LRESULT Result;
551
552   AnsiMsg.hwnd = hWnd;
553   AnsiMsg.message = Msg;
554   AnsiMsg.wParam = wParam;
555   AnsiMsg.lParam = lParam;
556
557   if (!MsgiAnsiToUnicodeMessage(&UcMsg, &AnsiMsg))
558     {
559       return(FALSE);
560     }
561   Result = SendMessageW(UcMsg.hwnd, UcMsg.message, UcMsg.wParam, UcMsg.lParam);
562   if (!MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, Result))
563     {
564       return(FALSE);
565     }
566   return(Result);
567 }
568
569
570 /*
571  * @implemented
572  */
573 WINBOOL
574 STDCALL
575 SendMessageCallbackA(
576   HWND hWnd,
577   UINT Msg,
578   WPARAM wParam,
579   LPARAM lParam,
580   SENDASYNCPROC lpCallBack,
581   ULONG_PTR dwData)
582 {
583   return NtUserSendMessageCallback(
584     hWnd,
585     Msg,
586     wParam,
587     lParam,
588     lpCallBack,
589     dwData);
590 }
591
592
593 /*
594  * @implemented
595  */
596 WINBOOL
597 STDCALL
598 SendMessageCallbackW(
599   HWND hWnd,
600   UINT Msg,
601   WPARAM wParam,
602   LPARAM lParam,
603   SENDASYNCPROC lpCallBack,
604   ULONG_PTR dwData)
605 {
606   return NtUserSendMessageCallback(
607     hWnd,
608     Msg,
609     wParam,
610     lParam,
611     lpCallBack,
612     dwData);
613 }
614
615
616 /*
617  * @implemented
618  */
619 LRESULT
620 STDCALL
621 SendMessageTimeoutA(
622   HWND hWnd,
623   UINT Msg,
624   WPARAM wParam,
625   LPARAM lParam,
626   UINT fuFlags,
627   UINT uTimeout,
628   PDWORD_PTR lpdwResult)
629 {
630   UNIMPLEMENTED;
631   return (LRESULT)0;
632 }
633
634
635 /*
636  * @implemented
637  */
638 LRESULT
639 STDCALL
640 SendMessageTimeoutW(
641   HWND hWnd,
642   UINT Msg,
643   WPARAM wParam,
644   LPARAM lParam,
645   UINT fuFlags,
646   UINT uTimeout,
647   PDWORD_PTR lpdwResult)
648 {
649   UNIMPLEMENTED;
650   return (LRESULT)0;
651 }
652
653
654 /*
655  * @unimplemented
656  */
657 WINBOOL
658 STDCALL
659 SendNotifyMessageA(
660   HWND hWnd,
661   UINT Msg,
662   WPARAM wParam,
663   LPARAM lParam)
664 {
665   UNIMPLEMENTED;
666   return FALSE;
667 }
668
669
670 /*
671  * @unimplemented
672  */
673 WINBOOL
674 STDCALL
675 SendNotifyMessageW(
676   HWND hWnd,
677   UINT Msg,
678   WPARAM wParam,
679   LPARAM lParam)
680 {
681   UNIMPLEMENTED;
682   return FALSE;
683 }
684
685
686 /*
687  * @implemented
688  */
689 WINBOOL STDCALL
690 TranslateMessage(CONST MSG *lpMsg)
691 {
692   return(TranslateMessageEx((LPMSG)lpMsg, 0));
693 }
694
695 /*
696  * @implemented
697  */
698 WINBOOL STDCALL
699 TranslateMessageEx(CONST MSG *lpMsg, DWORD unk)
700 {
701   return(NtUserTranslateMessage((LPMSG)lpMsg, unk));
702 }
703
704
705 /*
706  * @implemented
707  */
708 WINBOOL
709 STDCALL
710 WaitMessage(VOID)
711 {
712   return NtUserWaitMessage();
713 }
714
715
716 /*
717  * @implemented
718  */
719 UINT STDCALL
720 RegisterWindowMessageA(LPCSTR lpString)
721 {
722   UNICODE_STRING String;
723   BOOLEAN Result;
724   UINT Atom;
725
726   Result = RtlCreateUnicodeStringFromAsciiz(&String, (PCSZ)lpString);
727   if (!Result)
728     {
729       return(0);
730     }
731   Atom = NtUserRegisterWindowMessage(&String);
732   RtlFreeUnicodeString(&String);
733   return(Atom);
734 }
735
736
737 /*
738  * @implemented
739  */
740 UINT STDCALL
741 RegisterWindowMessageW(LPCWSTR lpString)
742 {
743   UNICODE_STRING String;
744
745   RtlInitUnicodeString(&String, lpString);
746   return(NtUserRegisterWindowMessage(&String));
747 }
748
749 /*
750  * @implemented
751  */
752 HWND STDCALL
753 SetCapture(HWND hWnd)
754 {
755   return(NtUserSetCapture(hWnd));
756 }
757
758 /*
759  * @implemented
760  */
761 HWND STDCALL
762 GetCapture(VOID)
763 {
764   return(NtUserGetCapture());
765 }
766
767 /*
768  * @implemented
769  */
770 WINBOOL STDCALL
771 ReleaseCapture(VOID)
772 {
773   NtUserSetCapture(NULL);
774   return(TRUE);
775 }
776
777
778 /*
779  * @unimplemented
780  */
781 DWORD
782 STDCALL
783 GetQueueStatus(UINT flags)
784 {
785    DWORD ret;
786    WORD changed_bits, wake_bits; 
787
788 #if 0 /* wine stuff. don't know what it does... */
789
790    /* check for pending X events */
791    if (USER_Driver.pMsgWaitForMultipleObjectsEx)
792       USER_Driver.pMsgWaitForMultipleObjectsEx( 0, NULL, 0, 0, 0 );
793 #endif
794
795    ret = NtUserGetQueueStatus(TRUE /*ClearChanges*/);
796
797    changed_bits = LOWORD(ret);
798    wake_bits = HIWORD(ret);
799
800    return MAKELONG(changed_bits & flags, wake_bits & flags);
801 }
802
803
804 /*
805  * @unimplemented
806  */
807 WINBOOL STDCALL GetInputState(VOID)
808 {
809    DWORD ret;
810    WORD  wake_bits;
811
812 #if 0 /* wine stuff. don't know what it does... */ 
813
814    /* check for pending X events */
815    if (USER_Driver.pMsgWaitForMultipleObjectsEx)
816      USER_Driver.pMsgWaitForMultipleObjectsEx( 0, NULL, 0, 0, 0 );
817 #endif
818
819    ret = NtUserGetQueueStatus(FALSE /*ClearChanges*/);
820    
821    wake_bits = HIWORD(ret);
822
823    return wake_bits & (QS_KEY | QS_MOUSEBUTTON);
824 }
825
826 /*
827  * @implemented
828  */
829 WINBOOL STDCALL SetMessageQueue(int cMessagesMax)
830 {
831   /* Function does nothing on 32 bit windows */
832   return TRUE;
833 }
834
835
836
837 /* EOF */