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

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

VT's codepage changes + combo bugfixes

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