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

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

Lots of message fixes

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