source: trunk/src/user32/pmwindow.cpp@ 2201

Last change on this file since 2201 was 2200, checked in by sandervl, 26 years ago

Message handling rewrite

File size: 17.6 KB
Line 
1/* $Id: pmwindow.cpp,v 1.69 1999-12-24 18:39:10 sandervl Exp $ */
2/*
3 * Win32 Window Managment Code for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_WIN
13#define INCL_GPI
14#define INCL_DEV /* Device Function definitions */
15#define INCL_GPICONTROL /* GPI control Functions */
16
17#include <os2wrap.h>
18#include <stdlib.h>
19#include <string.h>
20#include "win32type.h"
21#include <winconst.h>
22#include <wprocess.h>
23#include <misc.h>
24#include <win32wbase.h>
25#include <win32dlg.h>
26#include "win32wdesktop.h"
27#include "pmwindow.h"
28#include "oslibwin.h"
29#include "oslibutil.h"
30#include "oslibgdi.h"
31#include "oslibmsg.h"
32#include "dc.h"
33#include <thread.h>
34#include <wprocess.h>
35#include "caret.h"
36#include "timer.h"
37
38HMQ hmq = 0; /* Message queue handle */
39HAB hab = 0;
40
41RECTL desktopRectl = {0};
42ULONG ScreenWidth = 0;
43ULONG ScreenHeight = 0;
44ULONG ScreenBitsPerPel = 0;
45
46
47MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
48
49//******************************************************************************
50//Initialize PM; create hab, message queue and register special Win32 window classes
51//******************************************************************************
52BOOL InitPM()
53{
54 CLASSINFO FrameClassInfo;
55
56 hab = WinInitialize(0);
57 dprintf(("Winitialize returned %x", hab));
58 hmq = WinCreateMsgQueue(hab, 0);
59
60 if(!hab || !hmq)
61 {
62 UINT error;
63 //CB: only fail on real error
64 error = WinGetLastError(hab) & 0xFFFF; //error code
65 if (!hab || error != PMERR_MSG_QUEUE_ALREADY_EXISTS)
66 {
67 dprintf(("WinInitialize or WinCreateMsgQueue failed %x %x", hab, hmq));
68 dprintf((" Error = %x",error));
69 return(FALSE);
70 }
71 else
72 {
73 if(!hab) {
74 hab = WinQueryAnchorBlock(HWND_DESKTOP);
75 dprintf(("WinQueryAnchorBlock returned %x", hab));
76 }
77 if(!hmq) {
78 hmq = HMQ_CURRENT;
79 }
80 }
81 }
82 SetThreadHAB(hab);
83 dprintf(("InitPM: hmq = %x", hmq));
84 SetThreadMessageQueue(hmq);
85
86 if(!WinRegisterClass( /* Register window class */
87 hab, /* Anchor block handle */
88 (PSZ)WIN32_STDCLASS, /* Window class name */
89 (PFNWP)Win32WindowProc, /* Address of window procedure */
90// CS_SIZEREDRAW | CS_HITTEST | CS_MOVENOTIFY,
91 //CS_SIZEREDRAW | CS_HITTEST,
92 CS_HITTEST,
93 NROF_WIN32WNDBYTES)) {
94 dprintf(("WinRegisterClass Win32BaseWindow failed"));
95 return(FALSE);
96 }
97 if (!WinQueryClassInfo (hab, WC_FRAME, &FrameClassInfo)) {
98 dprintf (("WinQueryClassInfo WC_FRAME failed"));
99 return (FALSE);
100 }
101 FrameClassInfo.flClassStyle &= ~(CS_PUBLIC | CS_CLIPSIBLINGS);
102 if (!WinRegisterClass (hab,
103 WIN32_INNERFRAME,
104 FrameClassInfo.pfnWindowProc,
105 FrameClassInfo.flClassStyle,
106 FrameClassInfo.cbWindowData)) {
107 dprintf (("WinRegisterClass Win32InnerFrame failed"));
108 return (FALSE);
109 }
110
111 WinQueryWindowRect(HWND_DESKTOP, &desktopRectl);
112 ScreenWidth = desktopRectl.xRight;
113 ScreenHeight = desktopRectl.yTop;
114
115
116 HDC hdc; /* Device-context handle */
117 /* context data structure */
118 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
119 NULL, NULL, NULL};
120
121 /* create memory device context */
122 hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
123 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, (PLONG)&ScreenBitsPerPel);
124 DevCloseDC(hdc);
125
126 dprintf(("InitPM: Desktop (%d,%d)", ScreenWidth, ScreenHeight));
127 return OSLibInitMsgQueue();
128} /* End of main */
129//******************************************************************************
130//Win32 window message handler
131//******************************************************************************
132MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
133{
134 POSTMSG_PACKET *postmsg;
135 OSLIBPOINT point, ClientPoint;
136 Win32BaseWindow *win32wnd;
137 THDB *thdb;
138 APIRET rc;
139 MSG winMsg, *pWinMsg;
140
141 //Restore our FS selector
142 SetWin32TIB();
143
144 thdb = GetThreadTHDB();
145 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
146
147 if(!thdb || (msg != WM_CREATE && win32wnd == NULL)) {
148 dprintf(("Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
149 goto RunDefWndProc;
150 }
151
152 if((thdb->msgstate & 1) == 0)
153 {//message that was sent directly to our window proc handler; translate it here
154 QMSG qmsg;
155
156 qmsg.msg = msg;
157 qmsg.hwnd = hwnd;
158 qmsg.mp1 = mp1;
159 qmsg.mp2 = mp2;
160 qmsg.time = WinQueryMsgTime(thdb->hab);
161 WinQueryMsgPos(thdb->hab, &qmsg.ptl);
162 qmsg.reserved = 0;
163
164 if(OS2ToWinMsgTranslate((PVOID)thdb, &qmsg, &winMsg, FALSE, ODINMSG_NOEXTRAMSGS) == FALSE)
165 {//message was not translated
166 memset(&winMsg, 0, sizeof(MSG));
167 }
168 pWinMsg = &winMsg;
169 }
170 else {
171 pWinMsg = &thdb->msg;
172 thdb->msgstate++;
173 }
174
175 if(msg == WIN32APP_POSTMSG && (ULONG)mp1 == WIN32PM_MAGIC) {
176 //win32 app user message
177 return (MRESULT)win32wnd->PostMessage((POSTMSG_PACKET *)mp2);;
178 }
179 switch( msg )
180 {
181 //OS/2 msgs
182 case WM_CREATE:
183 {
184
185 if(thdb->newWindow == 0)
186 goto createfail;
187
188 //Processing is done in after WinCreateWindow returns
189 dprintf(("OS2: WM_CREATE %x", hwnd));
190 win32wnd = (Win32BaseWindow *)thdb->newWindow;
191 thdb->newWindow = 0;
192
193 if(win32wnd->MsgCreate(WinQueryWindow(hwnd, QW_PARENT), hwnd) == FALSE)
194 {
195 RestoreOS2TIB();
196 return (MRESULT)TRUE; //discontinue window creation
197 }
198 createfail:
199 RestoreOS2TIB();
200 return (MRESULT)FALSE;
201 }
202
203 case WM_QUIT:
204 dprintf(("OS2: WM_QUIT %x", hwnd));
205 if(win32wnd->MsgQuit()) {
206 goto RunDefWndProc;
207 }
208 break;
209
210 case WM_CLOSE:
211 dprintf(("OS2: WM_CLOSE %x", hwnd));
212 if(win32wnd->MsgClose()) {
213 goto RunDefWndProc;
214 }
215 break;
216
217 case WM_DESTROY:
218 dprintf(("OS2: WM_DESTROY %x", hwnd));
219 if(win32wnd->MsgDestroy()) {
220 goto RunDefWndProc;
221 }
222 break;
223
224 case WM_ENABLE:
225 dprintf(("OS2: WM_ENABLE %x", hwnd));
226 if(win32wnd->MsgEnable(SHORT1FROMMP(mp1))) {
227 goto RunDefWndProc;
228 }
229 break;
230
231 case WM_SHOW:
232 dprintf(("OS2: WM_SHOW %x %d", hwnd, mp1));
233 if(win32wnd->MsgShow((ULONG)mp1)) {
234 goto RunDefWndProc;
235 }
236 break;
237
238#if 1
239 case WM_ADJUSTWINDOWPOS:
240 {
241// PSWP pswp = (PSWP)mp1;
242
243// dprintf(("OS2: WM_ADJUSTWINDOWPOS %x %x %x (%d,%d) (%d,%d)", hwnd, pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
244 goto RunDefWndProc;
245 }
246#else
247 case WM_ADJUSTWINDOWPOS:
248 {
249 PSWP pswp = (PSWP)mp1;
250 SWP swpOld, swpNew;
251 WINDOWPOS wp;
252 ULONG parentHeight = 0;
253 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE, hwndAfter;
254
255 dprintf(("OS2: WM_ADJUSTWINDOWPOS %x %x %x (%d,%d) (%d,%d)", hwnd, pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
256
257 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) goto RunDefWndProc;;
258
259 //SvL: TODO: Workaround. Why is this happening?
260 // When this flag is set the coordinates are 0, even though SWP_SIZE & SWP_MOVE are set.
261// if ((pswp->fl & SWP_NOADJUST)) goto RunDefWndProc;
262
263 if(!win32wnd->CanReceiveSizeMsgs()) goto RunDefWndProc;;
264
265 WinQueryWindowPos(hwnd, &swpOld);
266
267 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
268 if (win32wnd->isChild()) {
269 if(win32wnd->getParent()) {
270 hParent = win32wnd->getParent()->getOS2WindowHandle();
271 }
272 else goto RunDefWndProc;;
273 }
274 }
275 hwndAfter = pswp->hwndInsertBehind;
276 hFrame = win32wnd->getOS2FrameWindowHandle();
277 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, hParent, hFrame);
278
279 wp.hwnd = win32wnd->getWindowHandle();
280 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
281 {
282 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
283 if(wndAfter) wp.hwndInsertAfter = wndAfter->getWindowHandle();
284 }
285 if(win32wnd->MsgPosChanging((LPARAM)&wp) == 0)
286 {//app or default window handler changed wp
287 dprintf(("OS2: WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
288 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
289 OSLibMapWINDOWPOStoSWP(&wp, &swpNew, &swpOld, hParent, hFrame);
290 dprintf(("%x (%d,%d), (%d,%d)", swpNew.fl, swpNew.x, swpNew.y, swpNew.cx, swpNew.cy));
291 swpNew.fl |= SWP_NOADJUST;
292 swpNew.hwndInsertBehind = hwndAfter;
293 swpNew.hwnd = hFrame;
294
295 WinSetMultWindowPos(GetThreadHAB(), &swpNew, 1);
296 return (MRESULT)0;
297 }
298 break;
299 }
300#endif
301
302 case WM_WINDOWPOSCHANGED:
303 {
304 win32wnd->MsgPosChanged((LPARAM)&thdb->wp);
305 goto RunDefWndProc;
306 }
307
308 case WM_ACTIVATE:
309 {
310 HWND hwndActivate = (HWND)mp2;
311 BOOL fMinimized = FALSE;
312
313 dprintf(("OS2: WM_ACTIVATE %x %x", hwnd, hwndActivate));
314 if(WinQueryWindowULong(hwndActivate, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
315 //another (non-win32) application's window
316 //set to NULL (allowed according to win32 SDK) to avoid problems
317 hwndActivate = NULL;
318 }
319 if(WinQueryWindowULong(hwnd, QWL_STYLE) & WS_MINIMIZED)
320 {
321 fMinimized = TRUE;
322 }
323
324 if(win32wnd->MsgActivate(SHORT1FROMMP(mp1), fMinimized, Win32BaseWindow::OS2ToWin32Handle(hwndActivate))) {
325 goto RunDefWndProc;
326 }
327 break;
328 }
329
330 case WM_SETFOCUS:
331 {
332 HWND hwndFocus = (HWND)mp1;
333
334 dprintf(("OS2: WM_SETFOCUS %x %x %d", win32wnd->getWindowHandle(), mp1, mp2));
335 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
336 //another (non-win32) application's window
337 //set to NULL (allowed according to win32 SDK) to avoid problems
338 hwndFocus = NULL;
339 }
340 if((ULONG)mp2 == TRUE) {
341 HWND hwndFocusWin32 = Win32BaseWindow::OS2ToWin32Handle(hwndFocus);
342 recreateCaret (hwndFocusWin32);
343 rc = win32wnd->MsgSetFocus(hwndFocusWin32);
344 }
345 else rc = win32wnd->MsgKillFocus(Win32BaseWindow::OS2ToWin32Handle(hwndFocus));
346 if(rc) {
347 goto RunDefWndProc;
348 }
349 break;
350 }
351
352 //**************************************************************************
353 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
354 //**************************************************************************
355 case WM_BUTTON1DOWN:
356 case WM_BUTTON1UP:
357 case WM_BUTTON1DBLCLK:
358 case WM_BUTTON2DOWN:
359 case WM_BUTTON2UP:
360 case WM_BUTTON2DBLCLK:
361 case WM_BUTTON3DOWN:
362 case WM_BUTTON3UP:
363 case WM_BUTTON3DBLCLK:
364 if(win32wnd->MsgButton(pWinMsg)) {
365 goto RunDefWndProc;
366 }
367 break;
368
369 case WM_BUTTON2MOTIONSTART:
370 case WM_BUTTON2MOTIONEND:
371 case WM_BUTTON2CLICK:
372 case WM_BUTTON1MOTIONSTART:
373 case WM_BUTTON1MOTIONEND:
374 case WM_BUTTON1CLICK:
375 case WM_BUTTON3MOTIONSTART:
376 case WM_BUTTON3MOTIONEND:
377 case WM_BUTTON3CLICK:
378 goto RunDefWndProc;
379
380 case WM_MOUSEMOVE:
381 {
382 //OS/2 Window coordinates -> Win32 Window coordinates
383 win32wnd->MsgMouseMove(pWinMsg);
384 break;
385 }
386
387 case WM_CONTROL:
388 case WM_COMMAND:
389 dprintf(("OS2: WM_COMMAND %x %x %x", hwnd, mp1, mp2));
390 win32wnd->DispatchMsg(pWinMsg);
391 //todo controls + accelerators
392 break;
393
394 case WM_SYSCOMMAND:
395 {
396 if(win32wnd->DispatchMsg(pWinMsg)) {
397 goto RunDefWndProc;
398 }
399 break;
400 }
401 case WM_CHAR:
402 {
403 win32wnd->DispatchMsg(pWinMsg);
404 break;
405 }
406
407 case WM_INITMENU:
408 win32wnd->MsgInitMenu(pWinMsg);
409 break;
410
411 case WM_TIMER:
412 win32wnd->DispatchMsg(pWinMsg);
413 goto RunDefWndProc;
414
415 case WM_MENUSELECT:
416 case WM_MENUEND:
417 case WM_NEXTMENU:
418 goto RunDefWndProc;
419
420 case WM_SETWINDOWPARAMS:
421 {
422 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
423
424 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
425 if(wndParams->fsStatus & WPM_TEXT) {
426 if(win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText)) {
427 goto RunDefWndProc;
428 }
429 }
430 goto RunDefWndProc;
431 }
432
433 case WM_QUERYWINDOWPARAMS:
434 {
435 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
436 ULONG textlen;
437 PSZ wintext;
438
439 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
440 {
441 if(wndpars->fsStatus & WPM_CCHTEXT)
442 wndpars->cchText = win32wnd->MsgGetTextLength();
443 if(wndpars->fsStatus & WPM_TEXT)
444 wndpars->pszText = win32wnd->MsgGetText();
445
446 wndpars->fsStatus = 0;
447 wndpars->cbCtlData = 0;
448 wndpars->cbPresParams = 0;
449 RestoreOS2TIB();
450 return (MRESULT)TRUE;
451 }
452 goto RunDefWndProc;
453 }
454
455 case WM_PAINT:
456 win32wnd->DispatchMsg(pWinMsg);
457 goto RunDefWndProc;
458
459 case WM_HITTEST:
460 // Only send this message if the window is enabled
461 if (WinIsWindowEnabled(hwnd))
462 {
463 if(win32wnd->MsgHitTest(pWinMsg)) {
464 goto RunDefWndProc;
465 }
466 }
467 else goto RunDefWndProc;
468
469 case WM_CONTEXTMENU:
470 {
471 win32wnd->DispatchMsg(pWinMsg);
472
473 RestoreOS2TIB();
474 return (MRESULT)TRUE;
475 }
476
477 case WM_ERASEBACKGROUND:
478 {
479 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
480 break;
481 }
482
483 case WM_SIZE:
484 {
485 dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp2)));
486 break;
487 }
488 case WM_MINMAXFRAME:
489 {
490 dprintf(("OS2: WM_MINMAXFRAME"));
491 break;
492 }
493 case WM_OWNERPOSCHANGE:
494 {
495 dprintf(("OS2: WM_OWNERPOSCHANGE"));
496 goto RunDefWndProc;
497 }
498
499 case WM_CALCVALIDRECTS:
500 {
501 dprintf(("OS2: WM_CALCVALIDRECTS"));
502 goto RunDefWndProc;
503 }
504
505 case WM_FOCUSCHANGE:
506 dprintf(("OS2: WM_FOCUSCHANGE %x", win32wnd->getWindowHandle()));
507 goto RunDefWndProc;
508
509 case WM_SYSCOLORCHANGE:
510 case WM_SYSVALUECHANGED:
511 case WM_SETSELECTION:
512 case WM_PPAINT:
513 case WM_PSETFOCUS:
514 case WM_PSYSCOLORCHANGE:
515 case WM_PSIZE:
516 case WM_PACTIVATE:
517 case WM_PCONTROL:
518 case WM_HELP:
519 case WM_APPTERMINATENOTIFY:
520 case WM_PRESPARAMCHANGED:
521 case WM_DRAWITEM:
522 case WM_MEASUREITEM:
523 case WM_CONTROLPOINTER:
524 case WM_QUERYDLGCODE:
525 case WM_SUBSTITUTESTRING:
526 case WM_MATCHMNEMONIC:
527 case WM_SAVEAPPLICATION:
528 case WM_SEMANTICEVENT:
529 default:
530 //dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
531 RestoreOS2TIB();
532 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
533 }
534 RestoreOS2TIB();
535 return (MRESULT)FALSE;
536
537RunDefWndProc:
538// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
539 RestoreOS2TIB();
540
541 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
542} /* End of Win32WindowProc */
543//******************************************************************************
544//******************************************************************************
545MRESULT EXPENTRY Win32SubclassWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
546{
547 Win32BaseWindow* win32wnd;
548
549 //Restore our FS selector
550 SetWin32TIB();
551
552 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
553
554 if (!win32wnd)
555 {
556 dprintf(("Invalid win32wnd pointer for subclassed window %x!!", hwnd));
557 goto RunDefWndProc;
558 }
559
560 switch (msg)
561 {
562 case WM_WINDOWPOSCHANGED:
563 {
564 PSWP pswp = (PSWP)mp1;
565 SWP swpOld = *(pswp + 1);
566 WINDOWPOS wp;
567 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE;
568
569 dprintf(("OS2Subclass: WM_WINDOWPOSCHANGED %x %x (%d,%d) (%d,%d)", hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
570 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) break;
571
572 hParent = hFrame = WinQueryWindow(hwnd, QW_PARENT);
573
574 OSLibMapSWPtoWINDOWPOS(pswp,&wp, &swpOld,hParent,hFrame);
575
576 win32wnd->setWindowRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
577 win32wnd->setClientRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
578 wp.x = swpOld.x;
579 wp.y = swpOld.y;
580 wp.cx = swpOld.cx;
581 wp.cy = swpOld.cy;
582
583 wp.hwnd = win32wnd->getWindowHandle();
584
585 win32wnd->MsgPosChanged((LPARAM)&wp);
586
587 goto RunOldWndProc;
588 }
589
590 default:
591 goto RunDefHandler;
592 }
593
594RunDefWndProc:
595 RestoreOS2TIB();
596 return WinDefWindowProc(hwnd,msg,mp1,mp2);
597
598RunOldWndProc:
599 RestoreOS2TIB();
600 return ((PFNWP)win32wnd->getOldWndProc())(hwnd,msg,mp1,mp2);
601
602RunDefHandler:
603 RestoreOS2TIB();
604 return Win32WindowProc(hwnd,msg,mp1,mp2);
605}
606
607PVOID SubclassWithDefHandler(HWND hwnd)
608{
609 return WinSubclassWindow(hwnd,Win32SubclassWindowProc);
610}
Note: See TracBrowser for help on using the repository browser.