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

Last change on this file since 8130 was 8130, checked in by sandervl, 23 years ago

comment update for PostQuitMessage

File size: 23.0 KB
Line 
1/* $Id: oslibmsg.cpp,v 1.55 2002-03-28 11:35:38 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 //NOTE: mp2 must always be zero or else we won't be able to distinguish
165 // between the WM_QUIT sent by us and the one sent by the window list!!
166 rc = WinPostQueueMsg(NULLHANDLE, WM_QUIT, MPFROMLONG(nExitCode), 0);
167 dprintf(("WinPostQueueMsg %d returned %d", nExitCode, rc));
168}
169//******************************************************************************
170//******************************************************************************
171LONG OSLibWinDispatchMsg(MSG *msg, BOOL isUnicode)
172{
173 TEB *teb;
174 QMSG os2msg;
175 LONG rc;
176
177 teb = GetThreadTEB();
178 if(teb == NULL) {
179 DebugInt3();
180 return FALSE;
181 }
182
183 //TODO: What to do if app changed msg? (translate)
184 // WinToOS2MsgTranslate(msg, &qmsg, isUnicode);
185
186 if(!memcmp(msg, &teb->o.odin.winmsg, sizeof(MSG)) || msg->hwnd == 0) {
187 memcpy(&os2msg, &teb->o.odin.os2msg, sizeof(QMSG));
188 teb->o.odin.os2msg.time = -1;
189 teb->o.odin.winmsg.time = -1;
190 if(msg->hwnd) {
191 teb->o.odin.nrOfMsgs = 1;
192 teb->o.odin.msgstate++; //odd -> next call to our PM window handler should dispatch the translated msg
193 memcpy(&teb->o.odin.msg, msg, sizeof(MSG));
194 }
195 if(os2msg.hwnd || os2msg.msg == WM_QUIT) {
196 memset(&teb->o.odin.os2msg, 0, sizeof(teb->o.odin.os2msg));
197 memset(&teb->o.odin.winmsg, 0, sizeof(teb->o.odin.winmsg));
198 return (LONG)WinDispatchMsg(teb->o.odin.hab, &os2msg);
199 }
200 //SvL: Don't dispatch messages sent by PostThreadMessage (correct??)
201 // Or WM_TIMER msgs with no window handle or timer proc
202 return 0;
203
204 }
205 else {//is this allowed?
206// dprintf(("WARNING: OSLibWinDispatchMsg: called with own message!"));
207 return SendMessageA(msg->hwnd, msg->message, msg->wParam, msg->lParam);
208 }
209}
210//******************************************************************************
211//******************************************************************************
212
213#ifdef ALTGR_HACK
214static void i_MostUglyAltGrHack(LPMSG pMsg)
215{
216 switch (pMsg->message)
217 {
218 case WINWM_KEYUP:
219 case WINWM_SYSKEYUP:
220 USHORT wWinScan = (pMsg->lParam & 0x00ff0000) >> 16;
221 if (wWinScan == WINSCAN_ALTRIGHT)
222 {
223 KeySetOverlayKeyState(VK_RMENU_W, KEYOVERLAYSTATE_DONTCARE);
224 KeySetOverlayKeyState(VK_MENU_W, KEYOVERLAYSTATE_DONTCARE);
225 }
226 break;
227 }
228}
229#else
230#define i_MostUglyAltGrHack(a)
231#endif
232
233BOOL OSLibWinGetMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
234 BOOL isUnicode)
235{
236 BOOL rc, eaten;
237 TEB *teb;
238 QMSG os2msg;
239 HWND hwndOS2 = 0;
240 ULONG filtermin, filtermax;
241
242 if(hwnd) {
243 hwndOS2 = Win32ToOS2Handle(hwnd);
244 if(hwndOS2 == NULL) {
245 memset(pMsg, 0, sizeof(MSG));
246 dprintf(("GetMsg: window %x NOT FOUND!", hwnd));
247 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
248 return TRUE;
249 }
250 }
251
252 teb = GetThreadTEB();
253 if(teb == NULL) {
254 DebugInt3();
255 return TRUE;
256 }
257
258 if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd))
259 {
260 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));
261 if(uMsgFilterMin) {
262 if(teb->o.odin.msgWCHAR.message < uMsgFilterMin)
263 goto continuegetmsg;
264 }
265 if(uMsgFilterMax) {
266 if(teb->o.odin.msgWCHAR.message > uMsgFilterMax)
267 goto continuegetmsg;
268 }
269 teb->o.odin.fTranslated = FALSE;
270 memcpy(pMsg, &teb->o.odin.msgWCHAR, sizeof(MSG));
271 teb->o.odin.os2msg.msg = 0;
272 teb->o.odin.os2msg.hwnd = 0;
273
274 // @@@PH verify this
275 // if this is a keyup or keydown message, we've got to
276 // call the keyboard hook here
277 // send keyboard messages to the registered hooks
278 switch (pMsg->message)
279 {
280 case WINWM_KEYDOWN:
281 case WINWM_KEYUP:
282 case WINWM_SYSKEYDOWN:
283 case WINWM_SYSKEYUP:
284 // only supposed to be called upon WM_KEYDOWN
285 // and WM_KEYUP according to docs.
286 if(ProcessKbdHook(pMsg, TRUE))
287 goto continuegetmsg;
288 break;
289 }
290
291 i_MostUglyAltGrHack(pMsg);
292
293 return (pMsg->message != WINWM_QUIT);
294 }
295
296continuegetmsg:
297 if(hwnd) {
298 filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
299 filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
300 if(filtermin > filtermax) {
301 ULONG tmp = filtermin;
302 filtermin = filtermax;
303 filtermax = filtermin;
304 }
305 do {
306 WinWaitMsg(teb->o.odin.hab, filtermin, filtermax);
307 rc = OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, PM_REMOVE_W, isUnicode);
308 }
309 while(rc == FALSE);
310
311 return (pMsg->message != WINWM_QUIT);
312 }
313 else
314 {
315 filtermin = TranslateWinMsg(uMsgFilterMin, TRUE);
316 filtermax = TranslateWinMsg(uMsgFilterMax, FALSE);
317 if(filtermin > filtermax) {
318 ULONG tmp = filtermin;
319 filtermin = filtermax;
320 filtermax = filtermin;
321 }
322 do {
323 eaten = FALSE;
324 rc = WinGetMsg(teb->o.odin.hab, &os2msg, 0, filtermin, filtermax);
325 if (os2msg.msg == WM_TIMER)
326 eaten = TIMER_HandleTimer(&os2msg);
327 if (os2msg.msg == WM_QUIT && ((ULONG)os2msg.mp2 != 0) ) {
328 // Don't return FALSE when the window list sends us
329 // a WM_QUIT message, improper killing can lead to
330 // application crashes.
331 // In the WM_QUIT handler in pmwindow we send a WM_CLOSE
332 // in this case. When the app calls PostQuitMessage (mp2 == 0),
333 // then we handle it the normal way
334 rc = 1;
335 }
336 } while (eaten);
337 }
338 if(OS2ToWinMsgTranslate((PVOID)teb, &os2msg, pMsg, isUnicode, MSG_REMOVE) == FALSE) {
339 //dispatch untranslated message immediately
340 WinDispatchMsg(teb->o.odin.hab, &os2msg);
341 //and get the next one
342 return OSLibWinGetMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax, isUnicode);
343 }
344
345 memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
346 memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
347
348 // send keyboard messages to the registered hooks
349 switch (pMsg->message)
350 {
351 case WINWM_KEYDOWN:
352 case WINWM_KEYUP:
353 case WINWM_SYSKEYDOWN:
354 case WINWM_SYSKEYUP:
355 // only supposed to be called upon WM_KEYDOWN
356 // and WM_KEYUP according to docs.
357 if(ProcessKbdHook(pMsg, TRUE))
358 goto continuegetmsg;
359 break;
360 }
361
362 i_MostUglyAltGrHack(pMsg);
363
364 return rc;
365}
366
367
368//******************************************************************************
369//PeekMessage retrieves only messages associated with the window identified by the
370//hwnd parameter or any of its children as specified by the IsChild function, and within
371//the range of message values given by the uMsgFilterMin and uMsgFilterMax
372//parameters. If hwnd is NULL, PeekMessage retrieves messages for any window that
373//belongs to the current thread making the call. (PeekMessage does not retrieve
374//messages for windows that belong to other threads.) If hwnd is -1, PeekMessage only
375//returns messages with a hwnd value of NULL, as posted by the PostAppMessage
376//function. If uMsgFilterMin and uMsgFilterMax are both zero, PeekMessage returns all
377//available messages (no range filtering is performed).
378//TODO: Not working as specified right now!
379//******************************************************************************
380BOOL OSLibWinPeekMsg(LPMSG pMsg, HWND hwnd, UINT uMsgFilterMin, UINT uMsgFilterMax,
381 DWORD fRemove, BOOL isUnicode)
382{
383 BOOL rc, eaten;
384 TEB *teb;
385 QMSG os2msg;
386 HWND hwndOS2 = 0;
387
388 if(hwnd && hwnd != -1) {
389 hwndOS2 = Win32ToOS2Handle(hwnd);
390 if(hwndOS2 == NULL) {
391 dprintf(("PeekMsg: window %x NOT FOUND!", hwnd));
392 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
393 return FALSE;
394 }
395 }
396
397 teb = GetThreadTEB();
398 if(teb == NULL) {
399 DebugInt3();
400 return FALSE;
401 }
402
403 if(teb->o.odin.fTranslated && (!hwnd || hwnd == teb->o.odin.msgWCHAR.hwnd))
404 {
405 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));
406 if(uMsgFilterMin) {
407 if(teb->o.odin.msgWCHAR.message < uMsgFilterMin)
408 goto continuepeekmsg;
409 }
410 if(uMsgFilterMax) {
411 if(teb->o.odin.msgWCHAR.message > uMsgFilterMax)
412 goto continuepeekmsg;
413 }
414
415 if(fRemove & PM_REMOVE_W) {
416 teb->o.odin.fTranslated = FALSE;
417 teb->o.odin.os2msg.msg = 0;
418 teb->o.odin.os2msg.hwnd = 0;
419 }
420 memcpy(pMsg, &teb->o.odin.msgWCHAR, sizeof(MSG));
421
422 // @@@PH verify this
423 // if this is a keyup or keydown message, we've got to
424 // call the keyboard hook here
425 // send keyboard messages to the registered hooks
426 switch (pMsg->message)
427 {
428 case WINWM_KEYDOWN:
429 case WINWM_KEYUP:
430 case WINWM_SYSKEYDOWN:
431 case WINWM_SYSKEYUP:
432 // only supposed to be called upon WM_KEYDOWN
433 // and WM_KEYUP according to docs.
434 if(ProcessKbdHook(pMsg, fRemove))
435 goto continuepeekmsg;
436 break;
437 }
438
439 return TRUE;
440 }
441
442continuepeekmsg:
443 do {
444 eaten = FALSE;
445 rc = WinPeekMsg(teb->o.odin.hab, &os2msg, hwndOS2, TranslateWinMsg(uMsgFilterMin, TRUE),
446 TranslateWinMsg(uMsgFilterMax, FALSE), (fRemove & PM_REMOVE_W) ? PM_REMOVE : PM_NOREMOVE);
447
448 if (rc && (fRemove & PM_REMOVE_W) && os2msg.msg == WM_TIMER) {
449 eaten = TIMER_HandleTimer(&os2msg);
450 }
451 }
452 while (eaten && rc);
453
454 if(rc == FALSE) {
455 return FALSE;
456 }
457
458 // @@@PH
459 // warning - OS2ToWinMsgTranslate might insert additional messages
460 // into the queue
461 if(OS2ToWinMsgTranslate((PVOID)teb, &os2msg, pMsg, isUnicode, (fRemove & PM_REMOVE_W) ? MSG_REMOVE : MSG_NOREMOVE) == FALSE)
462 {
463 //unused PM message; dispatch immediately and grab next one
464 dprintf2(("OSLibWinPeekMsg: Untranslated message; dispatched immediately"));
465 if(!(fRemove & PM_REMOVE_W)) {
466 rc = WinPeekMsg(teb->o.odin.hab, &os2msg, hwndOS2, TranslateWinMsg(uMsgFilterMin, TRUE),
467 TranslateWinMsg(uMsgFilterMax, FALSE), PM_REMOVE);
468 }
469 WinDispatchMsg(teb->o.odin.hab, &os2msg);
470 return OSLibWinPeekMsg(pMsg, hwnd, uMsgFilterMin, uMsgFilterMax,
471 fRemove, isUnicode);
472 }
473 //TODO: This is not safe! There's no guarantee this message will be dispatched and it might overwrite a previous message
474 if(fRemove & PM_REMOVE_W) {
475 memcpy(&teb->o.odin.os2msg, &os2msg, sizeof(QMSG));
476 memcpy(&teb->o.odin.winmsg, pMsg, sizeof(MSG));
477 }
478
479 // send keyboard messages to the registered hooks
480 switch (pMsg->message)
481 {
482 case WINWM_KEYDOWN:
483 case WINWM_KEYUP:
484 case WINWM_SYSKEYDOWN:
485 case WINWM_SYSKEYUP:
486 // only supposed to be called upon WM_KEYDOWN
487 // and WM_KEYUP according to docs.
488 if(ProcessKbdHook(pMsg, fRemove))
489 goto continuepeekmsg;
490 break;
491 }
492
493 return rc;
494}
495//******************************************************************************
496//******************************************************************************
497ULONG OSLibWinQueryMsgTime()
498{
499 return WinQueryMsgTime(GetThreadHAB());
500}
501//******************************************************************************
502//******************************************************************************
503BOOL OSLibWinWaitMessage()
504{
505 return WinWaitMsg(GetThreadHAB(), 0, 0);
506}
507//******************************************************************************
508//TODO: QS_HOTKEY
509//******************************************************************************
510ULONG OSLibWinQueryQueueStatus()
511{
512 ULONG statusOS2, statusWin32 = 0;
513
514 statusOS2 = WinQueryQueueStatus(HWND_DESKTOP);
515
516 if(statusOS2 & QS_KEY)
517 statusWin32 |= QS_KEY_W;
518 if(statusOS2 & QS_MOUSEBUTTON)
519 statusWin32 |= QS_MOUSEBUTTON_W;
520 if(statusOS2 & QS_MOUSEMOVE)
521 statusWin32 |= QS_MOUSEMOVE_W;
522 if(statusOS2 & QS_TIMER)
523 statusWin32 |= QS_TIMER_W;
524 if(statusOS2 & QS_PAINT)
525 statusWin32 |= QS_PAINT_W;
526 if(statusOS2 & QS_POSTMSG)
527 statusWin32 |= QS_POSTMESSAGE_W;
528 if(statusOS2 & QS_SENDMSG)
529 statusWin32 |= QS_SENDMESSAGE_W;
530
531 return statusWin32;
532}
533//******************************************************************************
534//******************************************************************************
535BOOL OSLibWinInSendMessage()
536{
537 return WinInSendMsg(GetThreadHAB());
538}
539//******************************************************************************
540//******************************************************************************
541DWORD OSLibWinGetMessagePos()
542{
543 APIRET rc;
544 POINTL ptl;
545
546 rc = WinQueryMsgPos(GetThreadHAB(), &ptl);
547 if(!rc) {
548 return 0;
549 }
550 //convert to windows coordinates
551 return MAKEULONG(ptl.x,mapScreenY(ptl.y));
552}
553//******************************************************************************
554//******************************************************************************
555LONG OSLibWinGetMessageTime()
556{
557 return (LONG)WinQueryMsgTime(GetThreadHAB());
558}
559//******************************************************************************
560//******************************************************************************
561BOOL OSLibWinReplyMessage(ULONG result)
562{
563 return (BOOL)WinReplyMsg( NULLHANDLE, NULLHANDLE, HMQ_CURRENT, (MRESULT)result);
564}
565//******************************************************************************
566//******************************************************************************
567ULONG OSLibSendMessage(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode)
568{
569 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
570
571 if(NULL == packet)
572 {
573 dprintf(("user32::oslibmsg::OSLibSendMessage - allocated packet structure is NULL, heapmin=%d\n",
574 _sheapmin() ));
575
576 // PH: we cannot provide a correct returncode :(
577 DebugInt3();
578 return 0;
579 }
580
581 packet->wParam = wParam;
582 packet->lParam = lParam;
583
584 return (ULONG)WinSendMsg(hwnd, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), (MPARAM)packet);
585}
586//******************************************************************************
587//******************************************************************************
588ULONG OSLibWinBroadcastMsg(ULONG msg, ULONG wParam, ULONG lParam, BOOL fSend)
589{
590 return WinBroadcastMsg(HWND_DESKTOP, WIN32APP_POSTMSG+msg, (MPARAM)wParam, (MPARAM)lParam,
591 (fSend) ? BMSG_SEND : BMSG_POST);
592}
593//******************************************************************************
594//******************************************************************************
595BOOL OSLibPostMessage(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam, BOOL fUnicode)
596{
597 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
598
599 if (NULL == packet)
600 {
601 dprintf(("user32::oslibmsg::OSLibPostMessage - allocated packet structure is NULL, heapmin=%d\n",
602 _sheapmin() ));
603
604 // PH: we can provide a correct returncode
605 DebugInt3();
606 return FALSE;
607 }
608 packet->wParam = wParam;
609 packet->lParam = lParam;
610 return WinPostMsg(hwnd, WIN32APP_POSTMSG+msg, (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA), (MPARAM)packet);
611}
612//******************************************************************************
613//Direct posting of messages that must remain invisible to the win32 app
614//******************************************************************************
615BOOL OSLibPostMessageDirect(HWND hwnd, ULONG msg, ULONG wParam, ULONG lParam)
616{
617 return WinPostMsg(hwnd, msg, (MPARAM)wParam, (MPARAM)lParam);
618}
619//******************************************************************************
620//******************************************************************************
621BOOL OSLibPostThreadMessage(ULONG threadid, UINT msg, WPARAM wParam, LPARAM lParam, BOOL fUnicode)
622{
623 TEB *teb = GetTEBFromThreadId(threadid);
624 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
625 BOOL ret;
626
627 if(NULL == packet)
628 {
629 dprintf(("user32::oslibmsg::OSLibPostMessage - allocated packet structure is NULL, heapmin=%d\n",
630 _sheapmin() ));
631
632 DebugInt3();
633 // PH: we can provide a correct returncode
634 return FALSE;
635 }
636
637 if(teb == NULL) {
638 dprintf(("OSLibPostThreadMessage: thread %x not found!", threadid));
639 return FALSE;
640 }
641 dprintf(("PostThreadMessageA %x %x %x %x -> hmq %x", threadid, msg, wParam, lParam, teb->o.odin.hmq));
642 packet->wParam = wParam;
643 packet->lParam = lParam;
644
645 ret = WinPostQueueMsg((HMQ)teb->o.odin.hmq, WIN32APP_POSTMSG+msg,
646 (MPARAM)((fUnicode) ? WIN32MSG_MAGICW : WIN32MSG_MAGICA),
647 (MPARAM)packet);
648
649 if(ret == FALSE)
650 {
651 SetLastError(ERROR_INVALID_PARAMETER_W);
652 return FALSE;
653 }
654 SetLastError(ERROR_SUCCESS_W);
655 return TRUE;
656}
657//******************************************************************************
658//******************************************************************************
659DWORD GetThreadMessageExtraInfo()
660{
661 TEB *teb;
662
663 teb = GetThreadTEB();
664 if(teb)
665 {
666 return teb->o.odin.dwMsgExtraInfo;
667 }
668 dprintf(("GetThreadMessageExtraInfo: teb == NULL!!"));
669 return 0;
670}
671//******************************************************************************
672//******************************************************************************
673DWORD SetThreadMessageExtraInfo(DWORD lParam)
674{
675 TEB *teb;
676
677 teb = GetThreadTEB();
678 if(teb)
679 {
680 teb->o.odin.dwMsgExtraInfo = lParam;
681 }
682 else dprintf(("SetThreadMessageExtraInfo: teb == NULL!!"));
683 return 0;
684}
685//******************************************************************************
686//******************************************************************************
Note: See TracBrowser for help on using the repository browser.