source: trunk/src/user32/oslibmsg.cpp@ 7612

Last change on this file since 7612 was 7612, checked in by sandervl, 24 years ago

hook, scancode + altgr fixes

File size: 21.8 KB
Line 
1/* $Id: oslibmsg.cpp,v 1.51 2001-12-11 17:34:53 sandervl Exp $ */
2/*
3 * Window message translation functions for OS/2
4 *
5 *
6 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 * TODO: Some messages that are sent to the frame window are directly passed on to the client
12 * -> Get/PeekMessage never gets them as we return a dummy message for non-client windows
13 * (i.e. menu WM_COMMAND messages)
14 *
15 * TODO: Filter translation isn't correct! (for posted messages or messages that don't have
16 * a PM version.
17 *
18 */
19#define INCL_WIN
20#define INCL_PM
21#define INCL_DOSPROCESS
22#include <os2wrap.h>
23#include <odinwrap.h>
24#include <string.h>
25#include <misc.h>
26#include "oslibmsg.h"
27#include <winconst.h>
28#include <win32api.h>
29#include <winuser32.h>
30#include "oslibutil.h"
31#include "timer.h"
32#include <thread.h>
33#include <wprocess.h>
34#include "pmwindow.h"
35#include "oslibwin.h"
36#include <win\hook.h>
37#include <winscan.h>
38#include <winkeyboard.h>
39
40#define DBG_LOCALLOG DBG_oslibmsg
41#include "dbglocal.h"
42
43
44ODINDEBUGCHANNEL(USER32-OSLIBMSG)
45
46
47
48typedef BOOL (EXPENTRY FNTRANS)(MSG *, QMSG *);
49typedef FNTRANS *PFNTRANS;
50
51typedef struct
52{
53 ULONG msgOS2;
54 ULONG msgWin32;
55// PFNTRANS toOS2;
56// PFNTRANS toWIN32;
57} MSGTRANSTAB, *PMSGTRANSTAB;
58
59//NOTE: Must be ordered by win32 message id!!
60MSGTRANSTAB MsgTransTab[] = {
61 WM_NULL, WINWM_NULL,
62 WM_CREATE, WINWM_CREATE,
63 WM_DESTROY, WINWM_DESTROY,
64 WM_MOVE, WINWM_MOVE, //TODO: Sent directly
65 WM_SIZE, WINWM_SIZE, //TODO: Sent directly
66 WM_ACTIVATE, WINWM_ACTIVATE,
67 WM_SETFOCUS, WINWM_SETFOCUS,
68 WM_SETFOCUS, WINWM_KILLFOCUS,
69 WM_ENABLE, WINWM_ENABLE,
70 WM_PAINT, WINWM_PAINT,
71 WM_CLOSE, WINWM_CLOSE,
72 WM_QUIT, WINWM_QUIT,
73 WM_SHOW, WINWM_SHOWWINDOW,
74
75 WM_HITTEST, WINWM_NCHITTEST,
76
77 //todo: not always right if mouse msg turns out to be for the client window
78 WM_MOUSEMOVE, WINWM_NCMOUSEMOVE,
79 WM_BUTTON1DOWN, WINWM_NCLBUTTONDOWN,
80 WM_BUTTON1UP, WINWM_NCLBUTTONUP,
81 WM_BUTTON1DBLCLK, WINWM_NCLBUTTONDBLCLK,
82 WM_BUTTON2DOWN, WINWM_NCRBUTTONDOWN,
83 WM_BUTTON2UP, WINWM_NCRBUTTONUP,
84 WM_BUTTON2DBLCLK, WINWM_NCRBUTTONDBLCLK,
85 WM_BUTTON3DOWN, WINWM_NCMBUTTONDOWN,
86 WM_BUTTON3UP, WINWM_NCMBUTTONUP,
87 WM_BUTTON3DBLCLK, WINWM_NCMBUTTONDBLCLK,
88
89 //TODO: Needs better translation!
90 WM_CHAR, WINWM_KEYDOWN, //WM_KEYFIRST
91 WM_CHAR, WINWM_KEYUP,
92 WM_CHAR, WINWM_CHAR,
93 WM_CHAR, WINWM_DEADCHAR,
94 WM_CHAR, WINWM_SYSKEYDOWN,
95 WM_CHAR, WINWM_SYSKEYUP,
96 WM_CHAR, WINWM_SYSCHAR,
97 WM_CHAR, WINWM_SYSDEADCHAR,
98 WM_CHAR, WINWM_KEYLAST,
99
100 //
101 WM_TIMER, WINWM_TIMER,
102
103 //
104 //todo: not always right if mouse msg turns out to be for the nonclient window
105 WM_MOUSEMOVE, WINWM_MOUSEMOVE, //WM_MOUSEFIRST
106 WM_BUTTON1DOWN, WINWM_LBUTTONDOWN,
107 WM_BUTTON1UP, WINWM_LBUTTONUP,
108 WM_BUTTON1DBLCLK, WINWM_LBUTTONDBLCLK,
109 WM_BUTTON2DOWN, WINWM_RBUTTONDOWN,
110 WM_BUTTON2UP, WINWM_RBUTTONUP,
111 WM_BUTTON2DBLCLK, WINWM_RBUTTONDBLCLK,
112 WM_BUTTON3DOWN, WINWM_MBUTTONDOWN,
113 WM_BUTTON3UP, WINWM_MBUTTONUP,
114 WM_BUTTON3DBLCLK, WINWM_MBUTTONDBLCLK,
115 WM_BUTTON3DBLCLK, WINWM_MOUSEWHEEL, //WM_MOUSELAST
116 999999999, 999999999,
117};
118#define MAX_MSGTRANSTAB (sizeof(MsgTransTab)/sizeof(MsgTransTab[0]))
119
120//******************************************************************************
121//******************************************************************************
122void WinToOS2MsgTranslate(MSG *winMsg, QMSG *os2Msg, BOOL isUnicode)
123{
124 dprintf(("WinToOS2MsgTranslate not implemented"));
125// memcpy(os2Msg, winMsg, sizeof(MSG));
126// os2Msg->hwnd = Win32ToOS2Handle(winMsg->hwnd);
127// os2Msg->reserved = 0;
128}
129//******************************************************************************
130//TODO: NOT COMPLETE nor 100% CORRECT!!!
131//If both the minimum & maximum message are unknown, the result can be wrong (max > min)!
132//******************************************************************************
133ULONG TranslateWinMsg(ULONG msg, BOOL fMinFilter)
134{
135 if(msg == 0)
136 return 0;
137
138 if(msg >= WINWM_USER)
139 return msg + WIN32APP_POSTMSG;
140
141 for(int i=0;i<MAX_MSGTRANSTAB;i++)
142 {
143 if(fMinFilter && MsgTransTab[i].msgWin32 >= msg) {
144 return MsgTransTab[i].msgOS2;
145 }
146 else
147 if(!fMinFilter && MsgTransTab[i].msgWin32 >= msg) {
148 if(MsgTransTab[i].msgWin32 == msg)
149 return MsgTransTab[i].msgOS2;
150 else return MsgTransTab[i-1].msgOS2;
151 }
152 }
153
154 //not found, get everything
155 dprintf(("WARNING: TranslateWinMsg: message %x not found", msg));
156 return 0;
157}
158//******************************************************************************
159//******************************************************************************
160void OSLibWinPostQuitMessage(ULONG nExitCode)
161{
162 APIRET rc;
163
164 rc = WinPostQueueMsg(NULLHANDLE, WM_QUIT, MPFROMLONG(nExitCode), 0);
165 dprintf(("WinPostQueueMsg %d returned %d", nExitCode, rc));
166}
167//******************************************************************************
168//******************************************************************************
169LONG OSLibWinDispatchMsg(MSG *msg, BOOL isUnicode)
170{
171 TEB *teb;
172 QMSG os2msg;
173 LONG rc;
174
175 teb = GetThreadTEB();
176 if(teb == NULL) {
177 DebugInt3();
178 return FALSE;
179 }
180
181 //TODO: What to do if app changed msg? (translate)
182 // WinToOS2MsgTranslate(msg, &qmsg, isUnicode);
183
184 if(!memcmp(msg, &teb->o.odin.winmsg, sizeof(MSG)) || msg->hwnd == 0) {
185 memcpy(&os2msg, &teb->o.odin.os2msg, sizeof(QMSG));
186 teb->o.odin.os2msg.time = -1;
187 teb->o.odin.winmsg.time = -1;
188 if(msg->hwnd) {
189 teb->o.odin.nrOfMsgs = 1;
190 teb->o.odin.msgstate++; //odd -> next call to our PM window handler should dispatch the translated msg
191 memcpy(&teb->o.odin.msg, msg, sizeof(MSG));
192 }
193 if(os2msg.hwnd || os2msg.msg == WM_QUIT) {
194 memset(&teb->o.odin.os2msg, 0, sizeof(teb->o.odin.os2msg));
195 memset(&teb->o.odin.winmsg, 0, sizeof(teb->o.odin.winmsg));
196 return (LONG)WinDispatchMsg(teb->o.odin.hab, &os2msg);
197 }
198 //SvL: Don't dispatch messages sent by PostThreadMessage (correct??)
199 // Or WM_TIMER msgs with no window handle or timer proc
200 return 0;
201
202 }
203 else {//is this allowed?
204// dprintf(("WARNING: OSLibWinDispatchMsg: called with own message!"));
205 return SendMessageA(msg->hwnd, msg->message, msg->wParam, msg->lParam);
206 }
207}
208//******************************************************************************
209//******************************************************************************
210
211#ifdef ALTGR_HACK
212static void i_MostUglyAltGrHack(LPMSG pMsg)
213{
214 switch (pMsg->message)
215 {
216 case WINWM_KEYUP:
217 case WINWM_SYSKEYUP:
218 USHORT wWinScan = (pMsg->lParam & 0x00ff0000) >> 16;
219 if (wWinScan == WINSCAN_ALTRIGHT)
220 {
221 KeySetOverlayKeyState(VK_RMENU_W, KEYOVERLAYSTATE_DONTCARE);
222 KeySetOverlayKeyState(VK_MENU_W, KEYOVERLAYSTATE_DONTCARE);
223 }
224 break;
225 }
226}
227#else
228#define i_MostUglyAltGrHack(a)
229#endif
230
231BOOL OSLibWinGetMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
232 BOOL isUnicode)
233{
234 BOOL rc, eaten;
235 TEB *teb;
236 QMSG os2msg;
237 HWND hwndOS2 = 0;
238 ULONG filtermin, filtermax;
239
240 if(hwnd) {
241 hwndOS2 = Win32ToOS2Handle(hwnd);
242 if(hwndOS2 == NULL) {
243 memset(pMsg, 0, sizeof(MSG));
244 dprintf(("GetMsg: window %x NOT FOUND!", hwnd));
245 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
246 return TRUE;
247 }
248 }
249
250 teb = GetThreadTEB();
251 if(teb == NULL) {
252 DebugInt3();
253 return TRUE;
254 }
255
256 if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd))
257 {
258 dprintf(("Return queued WM_CHAR message hwnd=%x msg=%d wParam=%x lParam=%x", teb->o.odin.msgWCHAR.hwnd, teb->o.odin.msgWCHAR.message, teb->o.odin.msgWCHAR.wParam, teb->o.odin.msgWCHAR.lParam));
259 if(uMsgFilterMin) {
260 if(teb->o.odin.msgWCHAR.message < uMsgFilterMin)
261 goto continuegetmsg;
262 }
263 if(uMsgFilterMax) {
264 if(teb->o.odin.msgWCHAR.message > uMsgFilterMax)
265 goto continuegetmsg;
266 }
267 teb->o.odin.fTranslated = FALSE;
268 memcpy(pMsg, &teb->o.odin.msgWCHAR, sizeof(MSG));
269 teb->o.odin.os2msg.msg = 0;
270 teb->o.odin.os2msg.hwnd = 0;
271
272 // @@@PH verify this
273 // if this is a keyup or keydown message, we've got to
274 // call the keyboard hook here
275 // send keyboard messages to the registered hooks
276 switch (pMsg->message)
277 {
278 case WINWM_KEYDOWN:
279 case WINWM_KEYUP:
280 case WINWM_SYSKEYDOWN:
281 case WINWM_SYSKEYUP:
282 // only supposed to be called upon WM_KEYDOWN
283 // and WM_KEYUP according to docs.
284 if(ProcessKbdHook(pMsg, TRUE))
285 goto continuegetmsg;
286 break;
287 }
288
289 i_MostUglyAltGrHack(pMsg);
290
291 return (pMsg->message != WINWM_QUIT);
292 }
293
294continuegetmsg:
295 if(hwnd) {
296 filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
297 filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
298 if(filtermin > filtermax) {
299 ULONG tmp = filtermin;
300 filtermin = filtermax;
301 filtermax = filtermin;
302 }
303 do {
304 WinWaitMsg(teb->o.odin.hab, filtermin, filtermax);
305 rc = OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, PM_REMOVE_W, isUnicode);
306 }
307 while(rc == FALSE);
308
309 return (pMsg->message != WINWM_QUIT);
310 }
311 else
312 {
313 filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
314 filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
315 if(filtermin > filtermax) {
316 ULONG tmp = filtermin;
317 filtermin = filtermax;
318 filtermax = filtermin;
319 }
320 do {
321 eaten = FALSE;
322 rc = WinGetMsg(teb->o.odin.hab, &os2msg, 0, filtermin, filtermax);
323 if (os2msg.msg == WM_TIMER)
324 eaten = TIMER_HandleTimer(&os2msg);
325 } while (eaten);
326 }
327 if(OS2ToWinMsgTranslate((PVOID)teb, &os2msg, pMsg, isUnicode, MSG_REMOVE) == FALSE) {
328 //dispatch untranslated message immediately
329 WinDispatchMsg(teb->o.odin.hab, &os2msg);
330 //and get the next one
331 return OSLibWinGetMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, isUnicode);
332 }
333
334 memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
335 memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
336
337 // send keyboard messages to the registered hooks
338 switch (pMsg->message)
339 {
340 case WINWM_KEYDOWN:
341 case WINWM_KEYUP:
342 case WINWM_SYSKEYDOWN:
343 case WINWM_SYSKEYUP:
344 // only supposed to be called upon WM_KEYDOWN
345 // and WM_KEYUP according to docs.
346 if(ProcessKbdHook(pMsg, TRUE))
347 goto continuegetmsg;
348 break;
349 }
350
351 i_MostUglyAltGrHack(pMsg);
352
353 return rc;
354}
355
356
357//******************************************************************************
358//PeekMessage retrieves only messages associated with the window identified by the
359//hwnd parameter or any of its children as specified by the IsChild function, and within
360//the range of message values given by the uMsgFilterMin and uMsgFilterMax
361//parameters. If hwnd is NULL, PeekMessage retrieves messages for any window that
362//belongs to the current thread making the call. (PeekMessage does not retrieve
363//messages for windows that belong to other threads.) If hwnd is -1, PeekMessage only
364//returns messages with a hwnd value of NULL, as posted by the PostAppMessage
365//function. If uMsgFilterMin and uMsgFilterMax are both zero, PeekMessage returns all
366//available messages (no range filtering is performed).
367//TODO: Not working as specified right now!
368//******************************************************************************
369BOOL OSLibWinPeekMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
370 DWORD fRemove, BOOL isUnicode)
371{
372 BOOL rc, eaten;
373 TEB *teb;
374 QMSG os2msg;
375 HWND hwndOS2 = 0;
376
377 if(hwnd && hwnd != -1) {
378 hwndOS2 = Win32ToOS2Handle(hwnd);
379 if(hwndOS2 == NULL) {
380 dprintf(("PeekMsg: window %x NOT FOUND!", hwnd));
381 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
382 return FALSE;
383 }
384 }
385
386 teb = GetThreadTEB();
387 if(teb == NULL) {
388 DebugInt3();
389 return FALSE;
390 }
391
392 if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd))
393 {
394 dprintf(("Return queued WM_CHAR message hwnd=%x msg=%d wParam=%x lParam=%x", teb->o.odin.msgWCHAR.hwnd, teb->o.odin.msgWCHAR.message, teb->o.odin.msgWCHAR.wParam, teb->o.odin.msgWCHAR.lParam));
395 if(uMsgFilterMin) {
396 if(teb->o.odin.msgWCHAR.message < uMsgFilterMin)
397 goto continuepeekmsg;
398 }
399 if(uMsgFilterMax) {
400 if(teb->o.odin.msgWCHAR.message > uMsgFilterMax)
401 goto continuepeekmsg;
402 }
403
404 if(fRemove & PM_REMOVE_W) {
405 teb->o.odin.fTranslated = FALSE;
406 teb->o.odin.os2msg.msg = 0;
407 teb->o.odin.os2msg.hwnd = 0;
408 }
409 memcpy(pMsg, &teb->o.odin.msgWCHAR, sizeof(MSG));
410
411 // @@@PH verify this
412 // if this is a keyup or keydown message, we've got to
413 // call the keyboard hook here
414 // send keyboard messages to the registered hooks
415 switch (pMsg->message)
416 {
417 case WINWM_KEYDOWN:
418 case WINWM_KEYUP:
419 case WINWM_SYSKEYDOWN:
420 case WINWM_SYSKEYUP:
421 // only supposed to be called upon WM_KEYDOWN
422 // and WM_KEYUP according to docs.
423 if(ProcessKbdHook(pMsg, fRemove))
424 goto continuepeekmsg;
425 break;
426 }
427
428 return TRUE;
429 }
430
431continuepeekmsg:
432 do {
433 eaten = FALSE;
434 rc = WinPeekMsg(teb->o.odin.hab, &os2msg, hwndOS2, TranslateWinMsg(uMsgFilterMin, TRUE),
435 TranslateWinMsg(uMsgFilterMax, FALSE), (fRemove & PM_REMOVE_W) ? PM_REMOVE : PM_NOREMOVE);
436
437 if (rc && (fRemove & PM_REMOVE_W) && os2msg.msg == WM_TIMER) {
438 eaten = TIMER_HandleTimer(&os2msg);
439 }
440 }
441 while (eaten && rc);
442
443 if(rc == FALSE) {
444 return FALSE;
445 }
446
447 // @@@PH
448 // warning - OS2ToWinMsgTranslate might insert additional messages
449 // into the queue
450 if(OS2ToWinMsgTranslate((PVOID)teb, &os2msg, pMsg, isUnicode, (fRemove & PM_REMOVE_W) ? MSG_REMOVE : MSG_NOREMOVE) == FALSE)
451 {
452 //unused PM message; dispatch immediately and grab next one
453 dprintf2(("OSLibWinPeekMsg: Untranslated message; dispatched immediately"));
454 if(!(fRemove & PM_REMOVE_W)) {
455 rc = WinPeekMsg(teb->o.odin.hab, &os2msg, hwndOS2, TranslateWinMsg(uMsgFilterMin, TRUE),
456 TranslateWinMsg(uMsgFilterMax, FALSE), PM_REMOVE);
457 }
458 WinDispatchMsg(teb->o.odin.hab, &os2msg);
459 return OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax,
460 fRemove, isUnicode);
461 }
462 //TODO: This is not safe! There's no guarantee this message will be dispatched and it might overwrite a previous message
463 if(fRemove & PM_REMOVE_W) {
464 memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
465 memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
466 }
467
468 // send keyboard messages to the registered hooks
469 switch (pMsg->message)
470 {
471 case WINWM_KEYDOWN:
472 case WINWM_KEYUP:
473 case WINWM_SYSKEYDOWN:
474 case WINWM_SYSKEYUP:
475 // only supposed to be called upon WM_KEYDOWN
476 // and WM_KEYUP according to docs.
477 if(ProcessKbdHook(pMsg, fRemove))
478 goto continuepeekmsg;
479 break;
480 }
481
482 return rc;
483}
484//******************************************************************************
485//******************************************************************************
486ULONG OSLibWinQueryMsgTime()
487{
488 return WinQueryMsgTime(GetThreadHAB());
489}
490//******************************************************************************
491//******************************************************************************
492BOOL OSLibWinWaitMessage()
493{
494 return WinWaitMsg(GetThreadHAB(), 0, 0);
495}
496//******************************************************************************
497//TODO: QS_HOTKEY
498//******************************************************************************
499ULONG OSLibWinQueryQueueStatus()
500{
501 ULONG statusOS2, statusWin32 = 0;
502
503 statusOS2 = WinQueryQueueStatus(HWND_DESKTOP);
504
505 if(statusOS2 & QS_KEY)
506 statusWin32 |= QS_KEY_W;
507 if(statusOS2 & QS_MOUSEBUTTON)
508 statusWin32 |= QS_MOUSEBUTTON_W;
509 if(statusOS2 & QS_MOUSEMOVE)
510 statusWin32 |= QS_MOUSEMOVE_W;
511 if(statusOS2 & QS_TIMER)
512 statusWin32 |= QS_TIMER_W;
513 if(statusOS2 & QS_PAINT)
514 statusWin32 |= QS_PAINT_W;
515 if(statusOS2 & QS_POSTMSG)
516 statusWin32 |= QS_POSTMESSAGE_W;
517 if(statusOS2 & QS_SENDMSG)
518 statusWin32 |= QS_SENDMESSAGE_W;
519
520 return statusWin32;
521}
522//******************************************************************************
523//******************************************************************************
524BOOL OSLibWinInSendMessage()
525{
526 return WinInSendMsg(GetThreadHAB());
527}
528//******************************************************************************
529//******************************************************************************
530DWORD OSLibWinGetMessagePos()
531{
532 APIRET rc;
533 POINTL ptl;
534
535 rc = WinQueryMsgPos(GetThreadHAB(), &ptl);
536 if(!rc) {
537 return 0;
538 }
539 //convert to windows coordinates
540 return MAKEULONG(ptl.x,mapScreenY(ptl.y));
541}
542//******************************************************************************
543//******************************************************************************
544LONG OSLibWinGetMessageTime()
545{
546 return (LONG)WinQueryMsgTime(GetThreadHAB());
547}
548//******************************************************************************
549//******************************************************************************
550BOOL OSLibWinReplyMessage(ULONG result)
551{
552 return (BOOL)WinReplyMsg( NULLHANDLE, NULLHANDLE, HMQ_CURRENT, (MRESULT)result);
553}
554//******************************************************************************
555//******************************************************************************
556ULONG OSLibSendMessage(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode)
557{
558 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
559
560 if(NULL == packet)
561 {
562 dprintf(("user32::oslibmsg::OSLibSendMessage - allocated packet structure is NULL, heapmin=%d\n",
563 _sheapmin() ));
564
565 // PH: we cannot provide a correct returncode :(
566 DebugInt3();
567 return 0;
568 }
569
570 packet->wParam = wParam;
571 packet->lParam = lParam;
572
573 return (ULONG)WinSendMsg(hwnd, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), (MPARAM)packet);
574}
575//******************************************************************************
576//******************************************************************************
577ULONG OSLibWinBroadcastMsg(ULONG msg, ULONG wParam, ULONG lParam, BOOL fSend)
578{
579 return WinBroadcastMsg(HWND_DESKTOP, WIN32APP_POSTMSG+msg, (MPARAM)wParam, (MPARAM)lParam,
580 (fSend) ? BMSG_SEND : BMSG_POST);
581}
582//******************************************************************************
583//******************************************************************************
584BOOL OSLibPostMessage(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode)
585{
586 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
587
588 if (NULL == packet)
589 {
590 dprintf(("user32::oslibmsg::OSLibPostMessage - allocated packet structure is NULL, heapmin=%d\n",
591 _sheapmin() ));
592
593 // PH: we can provide a correct returncode
594 DebugInt3();
595 return FALSE;
596 }
597 packet->wParam = wParam;
598 packet->lParam = lParam;
599 return WinPostMsg(hwnd, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), (MPARAM)packet);
600}
601//******************************************************************************
602//Direct posting of messages that must remain invisible to the win32 app
603//******************************************************************************
604BOOL OSLibPostMessageDirect(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam)
605{
606 return WinPostMsg(hwnd, msg, (MPARAM)wParam, (MPARAM)lParam);
607}
608//******************************************************************************
609BOOL _System _O32_PostThreadMessage( DWORD, UINT, WPARAM, LPARAM );
610
611inline BOOL O32_PostThreadMessage(DWORD a, UINT b, WPARAM c, LPARAM d)
612{
613 BOOL yyrc;
614 USHORT sel = RestoreOS2FS();
615
616 yyrc = _O32_PostThreadMessage(a, b, c, d);
617 SetFS(sel);
618
619 return yyrc;
620}
621//******************************************************************************
622BOOL OSLibPostThreadMessage(ULONG threadid, UINT msg, WPARAM wParam, LPARAM lParam, BOOL fUnicode)
623{
624 TEB *teb = GetTEBFromThreadId(threadid);
625 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
626 BOOL ret;
627
628 if(NULL == packet)
629 {
630 dprintf(("user32::oslibmsg::OSLibPostMessage - allocated packet structure is NULL, heapmin=%d\n",
631 _sheapmin() ));
632
633 DebugInt3();
634 // PH: we can provide a correct returncode
635 return FALSE;
636 }
637
638 if(teb == NULL) {
639 dprintf(("OSLibPostThreadMessage: thread %x not found!", threadid));
640 return FALSE;
641 }
642 dprintf(("PostThreadMessageA %x %x %x %x -> hmq %x", threadid, msg, wParam, lParam, teb->o.odin.hmq));
643 packet->wParam = wParam;
644 packet->lParam = lParam;
645
646 ret = WinPostQueueMsg((HMQ)teb->o.odin.hmq, WIN32APP_POSTMSG+msg,
647 (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA),
648 (MPARAM)packet);
649
650 if(ret == FALSE)
651 {
652 SetLastError(ERROR_INVALID_PARAMETER_W);
653 return FALSE;
654 }
655 SetLastError(ERROR_SUCCESS_W);
656 return TRUE;
657}
658//******************************************************************************
659//******************************************************************************
660
Note: See TracBrowser for help on using the repository browser.