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

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

bugfixes

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