source: trunk/src/user32/windowmsg.cpp@ 9928

Last change on this file since 9928 was 9928, checked in by sandervl, 22 years ago

WindowFromPoint: only send WM_NCHITTEST to windows belonging to the current thread

File size: 35.9 KB
Line 
1/* $Id: windowmsg.cpp,v 1.41 2003-03-20 09:15:31 sandervl Exp $ */
2/*
3 * Win32 window message APIs for OS/2
4 *
5 * Copyright 1999-2001 Sander van Leeuwen
6 *
7 * Parts based on Wine Windows code (windows\message.c) 990508
8 *
9 * Copyright 1993, 1994 Alexandre Julliard
10 *
11 * TODO: GetQueueStatus: QS_HOTKEY (oslibmsg.cpp) & low word bits
12 * TODO: MsgWaitForMultipleObjects: timeout isn't handled correctly (can return too late)
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17
18#include <odin.h>
19#include <odinwrap.h>
20#include <os2sel.h>
21
22#include <string.h>
23#include <os2win.h>
24#include <misc.h>
25#include <win32wbase.h>
26#include <win.h>
27#include <heapstring.h>
28#include <handlemanager.h>
29#include <wprocess.h>
30#include "oslibutil.h"
31#include "oslibwin.h"
32#include "oslibmsg.h"
33#include "hook.h"
34
35#define DBG_LOCALLOG DBG_windowmsg
36#include "dbglocal.h"
37
38ODINDEBUGCHANNEL(USER32-WINDOWMSG)
39
40
41//******************************************************************************
42//******************************************************************************
43LONG WIN32API DispatchMessageA(const MSG * msg)
44{
45 dprintf2(("DispatchMessageA %x %x %x %x %x", msg->hwnd, msg->message, msg->wParam, msg->lParam, msg->time));
46 return OSLibWinDispatchMsg((MSG *)msg);
47}
48//******************************************************************************
49//******************************************************************************
50LONG WIN32API DispatchMessageW( const MSG * msg)
51{
52 dprintf2(("DispatchMessageW %x %x %x %x %x", msg->hwnd, msg->message, msg->wParam, msg->lParam, msg->time));
53 return OSLibWinDispatchMsg((MSG *)msg, TRUE);
54}
55//******************************************************************************
56//******************************************************************************
57BOOL WIN32API TranslateMessage(const MSG *msg)
58{
59 // check the message code
60 if ( (msg->message < WM_KEYDOWN) ||
61 (msg->message > WM_SYSKEYUP)||
62 (msg->message == WM_CHAR) ||
63 (msg->message == WM_DEADCHAR) )
64 {
65 SetLastError(ERROR_INVALID_PARAMETER);
66 return FALSE;
67 }
68
69 // only WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP
70 // can go into TranslateMessage
71
72 return OSLibWinTranslateMessage((MSG *)msg);
73}
74//******************************************************************************
75//******************************************************************************
76BOOL WIN32API GetMessageA( LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax)
77{
78 BOOL ret;
79
80 dprintf2(("GetMessageA %x %x-%x", hwnd, uMsgFilterMin, uMsgFilterMax));
81 ret = OSLibWinGetMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax);
82 if(ret) dprintf2(("GetMessageA %x %x %x %x", hwnd, pMsg->message, pMsg->wParam, pMsg->lParam));
83 HOOK_CallHooksA(WH_GETMESSAGE, HC_ACTION, PM_REMOVE, (LPARAM)pMsg);
84 return ret;
85}
86//******************************************************************************
87//******************************************************************************
88BOOL WIN32API GetMessageW( LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax)
89{
90 BOOL ret;
91
92 dprintf2(("GetMessageW %x %x-%x", hwnd, uMsgFilterMin, uMsgFilterMax));
93 ret = OSLibWinGetMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, TRUE);
94 HOOK_CallHooksW(WH_GETMESSAGE, HC_ACTION, PM_REMOVE, (LPARAM)pMsg);
95 return ret;
96}
97//******************************************************************************
98//******************************************************************************
99BOOL WIN32API PeekMessageA(LPMSG msg, HWND hwndOwner, UINT uMsgFilterMin,
100 UINT uMsgFilterMax, UINT fuRemoveMsg)
101{
102 BOOL fFoundMsg;
103
104 dprintf2(("PeekMessageA %x %d-%d %d", hwndOwner, uMsgFilterMin, uMsgFilterMax, fuRemoveMsg));
105 fFoundMsg = OSLibWinPeekMsg(msg, hwndOwner, uMsgFilterMin, uMsgFilterMax,
106 fuRemoveMsg, FALSE);
107 if(fFoundMsg) {
108 dprintf2(("PeekMessageA %x %d-%d %d found message %x %d %x %x", hwndOwner, uMsgFilterMin, uMsgFilterMax, fuRemoveMsg, msg->hwnd, msg->message, msg->wParam, msg->lParam));
109 HOOK_CallHooksA(WH_GETMESSAGE, HC_ACTION, fuRemoveMsg & PM_REMOVE, (LPARAM)msg );
110 if (msg->message == WM_QUIT && (fuRemoveMsg & PM_REMOVE)) {
111 //TODO: Post WM_QUERYENDSESSION message when WM_QUIT received and system is shutting down
112 }
113 }
114 return fFoundMsg;
115}
116//******************************************************************************
117//******************************************************************************
118BOOL WIN32API PeekMessageW(LPMSG msg, HWND hwndOwner, UINT uMsgFilterMin,
119 UINT uMsgFilterMax, UINT fuRemoveMsg)
120{
121 BOOL fFoundMsg;
122
123 dprintf2(("PeekMessageW %x %d-%d %d", hwndOwner, uMsgFilterMin, uMsgFilterMax, fuRemoveMsg));
124 fFoundMsg = OSLibWinPeekMsg(msg, hwndOwner, uMsgFilterMin, uMsgFilterMax,
125 fuRemoveMsg, TRUE);
126 if(fFoundMsg) {
127 dprintf2(("PeekMessageW %x %d-%d %d found message %x %d %x %x", hwndOwner, uMsgFilterMin, uMsgFilterMax, fuRemoveMsg, msg->hwnd, msg->message, msg->wParam, msg->lParam));
128 HOOK_CallHooksW(WH_GETMESSAGE, HC_ACTION, fuRemoveMsg & PM_REMOVE, (LPARAM)msg );
129 if (msg->message == WM_QUIT && (fuRemoveMsg & (PM_REMOVE))) {
130 //TODO: Post WM_QUERYENDSESSION message when WM_QUIT received and system is shutting down
131 }
132 }
133 return fFoundMsg;
134}
135//******************************************************************************
136//TODO:
137//******************************************************************************
138LONG WIN32API GetMessageExtraInfo()
139{
140 dprintf(("USER32: GetMessageExtraInfo %x", GetThreadMessageExtraInfo()));
141 return GetThreadMessageExtraInfo();
142}
143//******************************************************************************
144//******************************************************************************
145LPARAM WIN32API SetMessageExtraInfo(LPARAM lParam)
146{
147 dprintf(("USER32: SetMessageExtraInfo %x", lParam));
148 return SetThreadMessageExtraInfo(lParam);
149}
150//******************************************************************************
151//******************************************************************************
152DWORD WIN32API GetMessagePos(void)
153{
154 DWORD pos;
155
156 pos = OSLibWinGetMessagePos();
157 dprintf(("USER32: GetMessagePos -> (%d,%d)", LOWORD(pos), HIWORD(pos)));
158 return pos;
159}
160//******************************************************************************
161//******************************************************************************
162LONG WIN32API GetMessageTime(void)
163{
164 dprintf(("USER32: GetMessageTime"));
165 return OSLibWinGetMessageTime();
166}
167//******************************************************************************
168//******************************************************************************
169BOOL WIN32API WaitMessage(void)
170{
171#ifdef DEBUG
172 MSG msg;
173
174 if(PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE) == FALSE) {
175 dprintf2(("USER32: WaitMessage %x", GetThreadHAB()));
176 }
177 else dprintf2(("USER32: WaitMessage %x; message %x present", GetThreadHAB(), msg.message));
178#endif
179
180 BOOL ret = OSLibWinWaitMessage();
181#ifdef DEBUG
182 if(PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE) == FALSE) {
183 dprintf2(("USER32: WaitMessage returned with no message in the queue"));
184 }
185#endif
186 return ret;
187}
188//******************************************************************************
189//******************************************************************************
190BOOL WIN32API InSendMessage(void)
191{
192 dprintf(("USER32: InSendMessage"));
193 return OSLibWinInSendMessage();
194}
195//******************************************************************************
196//******************************************************************************
197BOOL WIN32API ReplyMessage(LRESULT result)
198{
199 dprintf(("USER32: ReplyMessage %x", result));
200 return OSLibWinReplyMessage(result);
201}
202//******************************************************************************
203//******************************************************************************
204VOID WIN32API PostQuitMessage( int nExitCode)
205{
206 dprintf(("USER32: PostQuitMessage\n"));
207 OSLibWinPostQuitMessage(nExitCode);
208}
209//******************************************************************************
210//******************************************************************************
211UINT WIN32API RegisterWindowMessageA(LPCSTR lpString)
212{
213 UINT rc;
214
215 rc = GlobalAddAtomA(lpString);
216 dprintf(("USER32: RegisterWindowMessageA %s returned %X\n", lpString, rc));
217 return(rc);
218}
219//******************************************************************************
220//******************************************************************************
221UINT WIN32API RegisterWindowMessageW( LPCWSTR lpString)
222{
223 dprintf(("USER32: RegisterWindowMessageW\n"));
224 return GlobalAddAtomW(lpString);
225}
226//******************************************************************************
227//No need to support this (obsolete, not implemented by Win32)
228//******************************************************************************
229BOOL WIN32API SetMessageQueue(int cMessagesMax)
230{
231 dprintf(("USER32: SetMessageQueue\n"));
232 return(TRUE);
233}
234//******************************************************************************
235//******************************************************************************
236/**********************************************************************
237 * WINPROC_TestCBForStr
238 *
239 * Return TRUE if the lparam is a string
240 */
241BOOL WINPROC_TestCBForStr ( HWND hwnd )
242{
243 BOOL retvalue;
244 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
245 retvalue = ( !(LOWORD(dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
246 (LOWORD(dwStyle) & CBS_HASSTRINGS) );
247 return retvalue;
248}
249/**********************************************************************
250 * WINPROC_TestLBForStr
251 *
252 * Return TRUE if the lparam is a string
253 */
254BOOL WINPROC_TestLBForStr ( HWND hwnd )
255{
256 BOOL retvalue;
257 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
258 retvalue = ( !(LOWORD(dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
259 (LOWORD(dwStyle) & LBS_HASSTRINGS) );
260 return retvalue;
261}
262
263/**********************************************************************
264 * WINPROC_MapMsg32ATo32W
265 *
266 * Map a message from Ansi to Unicode.
267 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
268 *
269 * FIXME:
270 * WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
271 *
272 * FIXME:
273 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
274 * the first four bytes are the handle of the icon
275 * when the WM_SETTEXT message has been used to set the icon
276 */
277INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
278{
279 switch(msg)
280 {
281 case WM_GETTEXT:
282 {
283 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
284 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
285 if (!ptr) return -1;
286 *ptr++ = *plparam; /* Store previous lParam */
287 *plparam = (LPARAM)ptr;
288 }
289 return 1;
290 /* lparam is string (0-terminated) */
291 case WM_SETTEXT:
292 case WM_WININICHANGE:
293 case CB_DIR:
294 case LB_DIR:
295 case LB_ADDFILE:
296#ifndef __WIN32OS2__
297 case CB_FINDSTRING:
298 case CB_FINDSTRINGEXACT:
299 case CB_SELECTSTRING:
300 case LB_FINDSTRING:
301 case LB_SELECTSTRING:
302#endif
303 case EM_REPLACESEL:
304 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
305 return (*plparam ? 1 : -1);
306
307 case WM_NCCREATE:
308 case WM_CREATE:
309 {
310 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
311 sizeof(*cs) );
312 if (!cs) return -1;
313 *cs = *(CREATESTRUCTW *)*plparam;
314 if (HIWORD(cs->lpszName))
315 cs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
316 (LPCSTR)cs->lpszName );
317 if (HIWORD(cs->lpszClass))
318 cs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
319 (LPCSTR)cs->lpszClass );
320 *plparam = (LPARAM)cs;
321 }
322 return 1;
323 case WM_MDICREATE:
324 {
325 MDICREATESTRUCTW *cs =
326 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
327 if (!cs) return -1;
328 *cs = *(MDICREATESTRUCTW *)*plparam;
329 if (HIWORD(cs->szClass))
330 cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
331 (LPCSTR)cs->szClass );
332 if (HIWORD(cs->szTitle))
333 cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
334 (LPCSTR)cs->szTitle );
335 *plparam = (LPARAM)cs;
336 }
337 return 1;
338
339/* Listbox */
340 case LB_ADDSTRING:
341#ifdef __WIN32OS2__
342 case LB_FINDSTRING:
343 case LB_FINDSTRINGEXACT:
344 case LB_SELECTSTRING:
345#endif
346 case LB_INSERTSTRING:
347 if ( WINPROC_TestLBForStr( hwnd ))
348 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
349 return (*plparam ? 1 : -1);
350
351 case LB_GETTEXT: /* fixme: fixed sized buffer */
352 { if ( WINPROC_TestLBForStr( hwnd ))
353 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
354 if (!ptr) return -1;
355 *ptr++ = *plparam; /* Store previous lParam */
356 *plparam = (LPARAM)ptr;
357 }
358 }
359 return 1;
360
361/* Combobox */
362 case CB_ADDSTRING:
363#ifdef __WIN32OS2__
364 case CB_FINDSTRING:
365 case CB_FINDSTRINGEXACT:
366 case CB_SELECTSTRING:
367#endif
368 case CB_INSERTSTRING:
369 if ( WINPROC_TestCBForStr( hwnd ))
370 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
371 return (*plparam ? 1 : -1);
372
373 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
374 { if ( WINPROC_TestCBForStr( hwnd ))
375 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
376 if (!ptr) return -1;
377 *ptr++ = *plparam; /* Store previous lParam */
378 *plparam = (LPARAM)ptr;
379 }
380 }
381 return 1;
382
383/* Multiline edit */
384 case EM_GETLINE:
385 { WORD len = (WORD)*plparam;
386 LPARAM *ptr = (LPARAM *) HEAP_xalloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
387 if (!ptr) return -1;
388 *ptr++ = *plparam; /* Store previous lParam */
389 *((WORD *) ptr) = len; /* Store the length */
390 *plparam = (LPARAM)ptr;
391 }
392 return 1;
393
394 case WM_ASKCBFORMATNAME:
395 case WM_DEVMODECHANGE:
396 case WM_PAINTCLIPBOARD:
397 case WM_SIZECLIPBOARD:
398 case EM_SETPASSWORDCHAR:
399 // FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
400 return -1;
401 default: /* No translation needed */
402 return 0;
403 }
404}
405
406
407/**********************************************************************
408 * WINPROC_UnmapMsg32ATo32W
409 *
410 * Unmap a message that was mapped from Ansi to Unicode.
411 */
412void WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
413{
414 switch(msg)
415 {
416 case WM_GETTEXT:
417 {
418 LPARAM *ptr = (LPARAM *)lParam - 1;
419 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)lParam, wParam );
420 HeapFree( GetProcessHeap(), 0, ptr );
421 }
422 break;
423
424 case WM_NCCREATE:
425 case WM_CREATE:
426 {
427 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
428 if (HIWORD(cs->lpszName))
429 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
430 if (HIWORD(cs->lpszClass))
431 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
432 HeapFree( GetProcessHeap(), 0, cs );
433 }
434 break;
435
436 case WM_MDICREATE:
437 {
438 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
439 if (HIWORD(cs->szTitle))
440 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
441 if (HIWORD(cs->szClass))
442 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
443 HeapFree( GetProcessHeap(), 0, cs );
444 }
445 break;
446
447 case WM_SETTEXT:
448 case WM_WININICHANGE:
449 case CB_DIR:
450 case LB_DIR:
451 case LB_ADDFILE:
452#ifndef __WIN32OS2__
453 case CB_FINDSTRING:
454 case CB_FINDSTRINGEXACT:
455 case CB_SELECTSTRING:
456 case LB_FINDSTRING:
457 case LB_SELECTSTRING:
458#endif
459 case EM_REPLACESEL:
460 HeapFree( GetProcessHeap(), 0, (void *)lParam );
461 break;
462
463/* Listbox */
464 case LB_ADDSTRING:
465#ifdef __WIN32OS2__
466 case LB_FINDSTRING:
467 case LB_FINDSTRINGEXACT:
468 case LB_SELECTSTRING:
469#endif
470 case LB_INSERTSTRING:
471 if ( WINPROC_TestLBForStr( hwnd ))
472 HeapFree( GetProcessHeap(), 0, (void *)lParam );
473 break;
474
475 case LB_GETTEXT:
476 { if ( WINPROC_TestLBForStr( hwnd ))
477 { LPARAM *ptr = (LPARAM *)lParam - 1;
478 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
479 HeapFree( GetProcessHeap(), 0, ptr );
480 }
481 }
482 break;
483
484/* Combobox */
485 case CB_ADDSTRING:
486#ifdef __WIN32OS2__
487 case CB_FINDSTRING:
488 case CB_FINDSTRINGEXACT:
489 case CB_SELECTSTRING:
490#endif
491 case CB_INSERTSTRING:
492 if ( WINPROC_TestCBForStr( hwnd ))
493 HeapFree( GetProcessHeap(), 0, (void *)lParam );
494 break;
495
496 case CB_GETLBTEXT:
497 { if ( WINPROC_TestCBForStr( hwnd ))
498 { LPARAM *ptr = (LPARAM *)lParam - 1;
499 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
500 HeapFree( GetProcessHeap(), 0, ptr );
501 }
502 }
503 break;
504
505/* Multiline edit */
506 case EM_GETLINE:
507 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
508 WORD len = *(WORD *) lParam;
509 lstrcpynWtoA( (LPSTR)*ptr , (LPWSTR)lParam, len );
510 HeapFree( GetProcessHeap(), 0, ptr );
511 }
512 break;
513 }
514}
515
516
517/**********************************************************************
518 * WINPROC_MapMsg32WTo32A
519 *
520 * Map a message from Unicode to Ansi.
521 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
522 */
523INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam)
524{ switch(msg)
525 {
526 case WM_GETTEXT:
527 {
528 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
529 wParam + sizeof(LPARAM) );
530 if (!ptr) return -1;
531 *ptr++ = *plparam; /* Store previous lParam */
532 *plparam = (LPARAM)ptr;
533 }
534 return 1;
535
536 case WM_SETTEXT:
537 case WM_WININICHANGE:
538 case CB_DIR:
539 case LB_DIR:
540 case LB_ADDFILE:
541#ifndef __WIN32OS2__
542 case CB_FINDSTRING:
543 case CB_FINDSTRINGEXACT:
544 case CB_SELECTSTRING:
545 case LB_FINDSTRING:
546 case LB_SELECTSTRING:
547#endif
548 case EM_REPLACESEL:
549 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
550 return (*plparam ? 1 : -1);
551
552 case WM_NCCREATE:
553 case WM_CREATE:
554 {
555 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
556 sizeof(*cs) );
557 if (!cs) return -1;
558 *cs = *(CREATESTRUCTA *)*plparam;
559 if (HIWORD(cs->lpszName))
560 cs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
561 (LPCWSTR)cs->lpszName );
562 if (HIWORD(cs->lpszClass))
563 cs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
564 (LPCWSTR)cs->lpszClass);
565 *plparam = (LPARAM)cs;
566 }
567 return 1;
568 case WM_MDICREATE:
569 {
570 MDICREATESTRUCTA *cs =
571 (MDICREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
572
573 if (!cs) return -1;
574 *cs = *(MDICREATESTRUCTA *)*plparam;
575 if (HIWORD(cs->szTitle))
576 cs->szTitle = HEAP_strdupWtoA( GetProcessHeap(), 0,
577 (LPCWSTR)cs->szTitle );
578 if (HIWORD(cs->szClass))
579 cs->szClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
580 (LPCWSTR)cs->szClass );
581 *plparam = (LPARAM)cs;
582 }
583 return 1;
584
585/* Listbox */
586 case LB_ADDSTRING:
587#ifdef __WIN32OS2__
588 case LB_FINDSTRING:
589 case LB_FINDSTRINGEXACT:
590 case LB_SELECTSTRING:
591#endif
592 case LB_INSERTSTRING:
593 if ( WINPROC_TestLBForStr( hwnd ))
594 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
595 return (*plparam ? 1 : -1);
596
597 case LB_GETTEXT: /* fixme: fixed sized buffer */
598 { if ( WINPROC_TestLBForStr( hwnd ))
599 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
600 if (!ptr) return -1;
601 *ptr++ = *plparam; /* Store previous lParam */
602 *plparam = (LPARAM)ptr;
603 }
604 }
605 return 1;
606
607/* Combobox */
608 case CB_ADDSTRING:
609#ifdef __WIN32OS2__
610 case CB_FINDSTRING:
611 case CB_FINDSTRINGEXACT:
612 case CB_SELECTSTRING:
613#endif
614 case CB_INSERTSTRING:
615 if ( WINPROC_TestCBForStr( hwnd ))
616 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
617 return (*plparam ? 1 : -1);
618
619 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
620 { if ( WINPROC_TestCBForStr( hwnd ))
621 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
622 if (!ptr) return -1;
623 *ptr++ = *plparam; /* Store previous lParam */
624 *plparam = (LPARAM)ptr;
625 }
626 }
627 return 1;
628
629/* Multiline edit */
630 case EM_GETLINE:
631 { WORD len = (WORD)*plparam;
632 LPARAM *ptr = (LPARAM *) HEAP_xalloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
633 if (!ptr) return -1;
634 *ptr++ = *plparam; /* Store previous lParam */
635 *((WORD *) ptr) = len; /* Store the length */
636 *plparam = (LPARAM)ptr;
637 }
638 return 1;
639
640 case WM_ASKCBFORMATNAME:
641 case WM_DEVMODECHANGE:
642 case WM_PAINTCLIPBOARD:
643 case WM_SIZECLIPBOARD:
644 case EM_SETPASSWORDCHAR:
645 // FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
646 return -1;
647 default: /* No translation needed */
648 return 0;
649 }
650}
651
652
653/**********************************************************************
654 * WINPROC_UnmapMsg32WTo32A
655 *
656 * Unmap a message that was mapped from Unicode to Ansi.
657 */
658void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
659{
660 switch(msg)
661 {
662 case WM_GETTEXT:
663 {
664 LPARAM *ptr = (LPARAM *)lParam - 1;
665 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam );
666 HeapFree( GetProcessHeap(), 0, ptr );
667 }
668 break;
669
670 case WM_SETTEXT:
671 case WM_WININICHANGE:
672 case CB_DIR:
673 case LB_DIR:
674 case LB_ADDFILE:
675#ifndef __WIN32OS2__
676 case CB_FINDSTRING:
677 case CB_FINDSTRINGEXACT:
678 case CB_SELECTSTRING:
679 case LB_FINDSTRING:
680 case LB_SELECTSTRING:
681#endif
682 case EM_REPLACESEL:
683 HeapFree( GetProcessHeap(), 0, (void *)lParam );
684 break;
685
686 case WM_NCCREATE:
687 case WM_CREATE:
688 {
689 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
690 if (HIWORD(cs->lpszName))
691 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
692 if (HIWORD(cs->lpszClass))
693 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
694 HeapFree( GetProcessHeap(), 0, cs );
695 }
696 break;
697
698 case WM_MDICREATE:
699 {
700 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
701 if (HIWORD(cs->szTitle))
702 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
703 if (HIWORD(cs->szClass))
704 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
705 HeapFree( GetProcessHeap(), 0, cs );
706 }
707 break;
708
709/* Listbox */
710 case LB_ADDSTRING:
711#ifdef __WIN32OS2__
712 case LB_FINDSTRING:
713 case LB_FINDSTRINGEXACT:
714 case LB_SELECTSTRING:
715#endif
716 case LB_INSERTSTRING:
717 if ( WINPROC_TestLBForStr( hwnd ))
718 HeapFree( GetProcessHeap(), 0, (void *)lParam );
719 break;
720
721 case LB_GETTEXT:
722 { if ( WINPROC_TestLBForStr( hwnd ))
723 { LPARAM *ptr = (LPARAM *)lParam - 1;
724 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
725 HeapFree(GetProcessHeap(), 0, ptr );
726 }
727 }
728 break;
729
730/* Combobox */
731 case CB_ADDSTRING:
732#ifdef __WIN32OS2__
733 case CB_FINDSTRING:
734 case CB_FINDSTRINGEXACT:
735 case CB_SELECTSTRING:
736#endif
737 case CB_INSERTSTRING:
738 if ( WINPROC_TestCBForStr( hwnd ))
739 HeapFree( GetProcessHeap(), 0, (void *)lParam );
740 break;
741
742 case CB_GETLBTEXT:
743 { if ( WINPROC_TestCBForStr( hwnd ))
744 { LPARAM *ptr = (LPARAM *)lParam - 1;
745 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
746 HeapFree( GetProcessHeap(), 0, ptr );
747 }
748 }
749 break;
750
751/* Multiline edit */
752 case EM_GETLINE:
753 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
754 WORD len = *(WORD *)ptr;
755 lstrcpynAtoW( (LPWSTR) *ptr, (LPSTR)lParam, len );
756 HeapFree( GetProcessHeap(), 0, ptr );
757 }
758 break;
759 }
760}
761
762/**********************************************************************
763 * WINPROC_CallProc32ATo32W
764 *
765 * Call a window procedure, translating args from Ansi to Unicode.
766 */
767LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
768 UINT msg, WPARAM wParam,
769 LPARAM lParam )
770{
771 LRESULT result;
772
773 if (WINPROC_MapMsg32ATo32W( hwnd, msg, wParam, &lParam ) == -1) return 0;
774 result = func( hwnd, msg, wParam, lParam );
775 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
776 return result;
777}
778
779/**********************************************************************
780 * WINPROC_CallProc32WTo32A
781 *
782 * Call a window procedure, translating args from Unicode to Ansi.
783 */
784LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
785 UINT msg, WPARAM wParam,
786 LPARAM lParam )
787{
788 LRESULT result;
789
790 if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0;
791
792 result = func( hwnd, msg, wParam, lParam );
793 WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
794 return result;
795}
796//******************************************************************************
797//TODO: QS_HOTKEY (oslibmsg.cpp) & low word bits
798//high word = messages currently in queue
799//low word = messages that have been added to the queue and are still in the
800// queue since the last call to GetQueueStatus
801//******************************************************************************
802DWORD WIN32API GetQueueStatus( UINT flags)
803{
804 DWORD queueStatus;
805
806 queueStatus = OSLibWinQueryQueueStatus();
807 queueStatus = MAKELONG(queueStatus, queueStatus);
808
809 dprintf(("USER32: GetQueueStatus %x returned %x", flags, queueStatus & MAKELONG(flags, flags)));
810
811 return queueStatus & MAKELONG(flags, flags);
812}
813/*****************************************************************************
814 * Name : BOOL WIN32API GetInputState
815 * Purpose : The GetInputState function determines whether there are
816 * mouse-button or keyboard messages in the calling thread's message queue.
817 * Parameters:
818 * Variables :
819 * Result : If the queue contains one or more new mouse-button or keyboard
820 * messages, the return value is TRUE.
821 * If the function fails, the return value is FALSE.
822 * Remark :
823 * Status : UNTESTED STUB
824 *
825 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
826 *****************************************************************************/
827BOOL WIN32API GetInputState(VOID)
828{
829 DWORD queueStatus;
830 BOOL rc;
831
832 queueStatus = OSLibWinQueryQueueStatus();
833
834 rc = (queueStatus & (QS_KEY | QS_MOUSEBUTTON)) ? TRUE : FALSE;
835 dprintf(("USER32:GetInputState() returned %d", rc));
836 return rc;
837}
838//******************************************************************************
839/* Synchronization Functions */
840//******************************************************************************
841DWORD WIN32API MsgWaitForMultipleObjects(DWORD nCount, LPHANDLE pHandles, BOOL fWaitAll,
842 DWORD dwMilliseconds, DWORD dwWakeMask)
843{
844 DWORD curtime, endtime, ret;
845 MSG msg;
846
847 //TODO: Functions such as GetMessage, PeekMessage and WaitMessage can mark messages as old
848 // MsgWaitForMultipleObjects shouldn't return until new input has arrived (MSDN)
849 // We are not 100% correct with this implementation. GetQueueStatus checks all messages
850 // in the queue.
851 // Very obscure behaviour, so it's unlikely any application depends on it
852
853 //4 cases:
854 //1: Wait for all -> check for message arrival, call WaitForMultipleObjects
855 //2: Timeout = 0 ms -> call WaitForMultipleObjects with timeout 0, check for message arrival
856 //3: nCount = 0 -> check for message arrival
857 //4: rest -> check for either message arrival or signalled object
858
859 dprintf(("MsgWaitForMultipleObjects %x %x %d %d %x", nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask));
860 if(fWaitAll) //case 1
861 { //wait for message arrival first
862 curtime = GetCurrentTime();
863 endtime = curtime + dwMilliseconds;
864 while(curtime < endtime || dwMilliseconds == INFINITE) {
865 if(OSLibWinWaitMessage() == FALSE) {
866 dprintf(("OSLibWinWaitMessage returned FALSE!"));
867 return WAIT_ABANDONED;
868 }
869 if(GetQueueStatus(dwWakeMask) != 0) {
870 break;
871 }
872 //TODO: Ignoring all messages could be dangerous. But processing them,
873 //while the app doesn't expect any, isn't safe either.
874 if(PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
875 {
876 if (msg.message == WM_QUIT) {
877 dprintf(("ERROR: MsgWaitForMultipleObjects call abandoned because WM_QUIT msg was received!!"));
878 return WAIT_ABANDONED;
879 }
880
881 /* otherwise dispatch it */
882 DispatchMessageA(&msg);
883 }
884 curtime = GetCurrentTime();
885 }
886 if(dwMilliseconds != INFINITE && curtime > endtime) {
887 dprintf(("No messages found in specified time"));
888 return WAIT_TIMEOUT;
889 }
890 //ok, the right message has arrived, now try to grab all objects
891 ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, dwMilliseconds);
892 if(ret >= WAIT_OBJECT_0 + nCount) {
893 //failure
894 dprintf(("WaitForMultipleObjects failed with %d", ret));
895 return ret;
896 }
897 return ret;
898 }
899 if(dwMilliseconds == 0) { //case 2
900 if(nCount) {
901 ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, dwMilliseconds);
902 if(ret < WAIT_OBJECT_0 + nCount) {
903 return ret;
904 }
905 }
906 if(GetQueueStatus(dwWakeMask) == 0) {
907 return WAIT_TIMEOUT;
908 }
909 return WAIT_OBJECT_0 + nCount; //right message has arrived
910 }
911 if(nCount == 0) //case 3
912 {
913 //SvL: Check time, wait for any message, check msg type and determine if
914 // we have to return
915 //TODO: Timeout isn't handled correctly (can return too late)
916 curtime = GetCurrentTime();
917 endtime = curtime + dwMilliseconds;
918 while(curtime < endtime || dwMilliseconds == INFINITE) {
919 if(OSLibWinWaitMessage() == FALSE) {
920 dprintf(("OSLibWinWaitMessage returned FALSE!"));
921 return WAIT_ABANDONED;
922 }
923 if(GetQueueStatus(dwWakeMask) != 0) {
924 return WAIT_OBJECT_0;
925 }
926 //TODO: Ignoring all messages could be dangerous. But processing them,
927 //while the app doesn't expect any, isn't safe either.
928 if(PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
929 {
930 if (msg.message == WM_QUIT) {
931 dprintf(("ERROR: MsgWaitForMultipleObjects call abandoned because WM_QUIT msg was received!!"));
932 return WAIT_ABANDONED;
933 }
934
935 /* otherwise dispatch it */
936 DispatchMessageA(&msg);
937 }
938 curtime = GetCurrentTime();
939 }
940 return WAIT_TIMEOUT;
941 }
942
943 //Case 4:
944#if 1
945 //Note: The WGSS implementation of this function is flawed. Returns
946 // when a message is sent to the msg queue, regardless of dwWakeMask
947 TEB *teb = GetTEBFromThreadId(GetCurrentThreadId());
948 if(teb == NULL) {
949 DebugInt3();
950 return WAIT_ABANDONED;
951 }
952 //check if any object is already signalled
953 ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, 0);
954 if(ret < WAIT_OBJECT_0 + nCount) {
955 return ret;
956 }
957 //if the msg queue already contains the messages defined by dwWakeMask,
958 //then return immediately
959 if(GetQueueStatus(dwWakeMask) != 0) {
960 return WAIT_OBJECT_0+nCount;
961 }
962 if(dwWakeMask & QS_POSTMESSAGE) {
963 HANDLE *pHandlesTmp = (HANDLE *)alloca((nCount+1)*sizeof(HANDLE));
964 if(pHandlesTmp == NULL || !teb->o.odin.hPostMsgEvent) {
965 DebugInt3();
966 return WAIT_ABANDONED;
967 }
968 memcpy(pHandlesTmp, pHandles, nCount*sizeof(HANDLE));
969 pHandlesTmp[nCount] = teb->o.odin.hPostMsgEvent;
970
971 //mark this thread as waiting for window messages
972 teb->o.odin.dwWakeMask = dwWakeMask;
973
974 ResetEvent(teb->o.odin.hPostMsgEvent);
975 ret = HMMsgWaitForMultipleObjects(nCount+1,pHandlesTmp,fWaitAll,dwMilliseconds,dwWakeMask);
976
977 //unmark thread
978 teb->o.odin.dwWakeMask = 0;
979
980 //nCount + 2 -> message event -> return nCount + 1
981 return (ret == nCount + 2) ? (nCount + 1) : ret;
982 }
983 //Call handlemanager function as we need to translate handles (KERNEL32)
984 ret = HMMsgWaitForMultipleObjects(nCount,pHandles,fWaitAll,dwMilliseconds,dwWakeMask);
985 return ret;
986#else
987 //This method has a high latency (too high for some apps)
988 //TODO: Timeout isn't handled correctly (can return too late)
989 curtime = GetCurrentTime();
990 endtime = curtime + dwMilliseconds;
991 while(curtime < endtime || dwMilliseconds == INFINITE) {
992 //check queue status for presence of requested message types
993 if(GetQueueStatus(dwWakeMask) != 0) {
994 dprintf(("Found message(s) we were looking for. Return success"));
995 return WAIT_OBJECT_0 + nCount; //present, return success
996 }
997 //TODO: Ignoring all messages could be dangerous. But processing them,
998 //while the app doesn't expect any, isn't safe either.
999 if(PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
1000 {
1001 if (msg.message == WM_QUIT) {
1002 dprintf(("ERROR: MsgWaitForMultipleObjects call abandoned because WM_QUIT msg was received!!"));
1003 return WAIT_ABANDONED;
1004 }
1005
1006 /* otherwise dispatch it */
1007 DispatchMessageA(&msg);
1008 }
1009 //check if any object is signalled (timeout 10ms)
1010 ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, 4);
1011 if(ret < WAIT_OBJECT_0 + nCount) {
1012 //an object was signalled, return immediately
1013 dprintf(("WaitForMultipleObjects success with %d", ret));
1014 return ret;
1015 }
1016 else
1017 if(ret != WAIT_TIMEOUT) {
1018 //failure, abort
1019 dprintf(("WaitForMultipleObjects failed with %d", ret));
1020 return ret;
1021 }
1022 curtime = GetCurrentTime();
1023 }
1024 return WAIT_TIMEOUT;
1025#endif
1026}
Note: See TracBrowser for help on using the repository browser.