source: trunk/src/user32/new/win32wnd.cpp@ 319

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

Lots of changes/additions

File size: 39.6 KB
Line 
1/* $Id: win32wnd.cpp,v 1.5 1999-07-17 09:17:58 sandervl Exp $ */
2/*
3 * Win32 Window Code for OS/2
4 *
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * Parts based on Wine Windows code (windows\win.c)
9 *
10 * Copyright 1993, 1994 Alexandre Julliard
11 *
12 *
13 * Project Odin Software License can be found in LICENSE.TXT
14 *
15 */
16#include <os2win.h>
17#include <win.h>
18#include <stdlib.h>
19#include <string.h>
20#include <stdarg.h>
21#include <assert.h>
22#include <misc.h>
23#include <handlemanager.h>
24#include <win32wnd.h>
25#include <spy.h>
26#include "wndmsg.h"
27#include "hooks.h"
28#include <oslibwin.h>
29
30#define HAS_DLGFRAME(style,exStyle) \
31 (((exStyle) & WS_EX_DLGMODALFRAME) || \
32 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
33
34#define HAS_THICKFRAME(style) \
35 (((style) & WS_THICKFRAME) && \
36 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
37
38//******************************************************************************
39//******************************************************************************
40Win32Window::Win32Window(DWORD objType) : GenericObject(&windows, objType)
41{
42 Init();
43}
44//******************************************************************************
45//******************************************************************************
46Win32Window::Win32Window(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
47 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
48{
49 Init();
50 this->isUnicode = isUnicode;
51 CreateWindowExA(lpCreateStructA, classAtom);
52}
53//******************************************************************************
54//******************************************************************************
55void Win32Window::Init()
56{
57 isUnicode = FALSE;
58
59 windowName = NULL;
60 wndNameLength = 0;
61
62 windowText = NULL;;
63 wndTextLength = 0;
64
65 userWindowLong = NULL;;
66 nrUserWindowLong = 0;
67
68 magic = WIN32PM_MAGIC;
69 OS2Hwnd = 0;
70 OS2HwndFrame = 0;
71 OS2HwndMenu = 0;
72 Win32Hwnd = 0;
73
74 //CB: what does this code? Win32Hwnd is always 0!
75 if(HMHandleAllocate(&Win32Hwnd, (ULONG)this) != 0)
76 {
77 dprintf(("Win32Window::Init HMHandleAllocate failed!!"));
78 DebugInt3();
79 }
80 Win32Hwnd &= 0xFFFF;
81 Win32Hwnd |= 0x68000000;
82
83 posx = posy = 0;
84 width = height = 0;
85
86 dwExStyle = 0;
87 dwStyle = 0;
88 win32wndproc = 0;
89 hInstance = 0;
90 windowId = 0xFFFFFFFF; //default = -1
91 userData = 0;
92
93 hwndLinkAfter = HWND_BOTTOM;
94 flags = 0;
95 isIcon = FALSE;
96 owner = NULL;
97 windowClass = 0;
98}
99//******************************************************************************
100//******************************************************************************
101Win32Window::~Win32Window()
102{
103 if(Win32Hwnd)
104 HMHandleFree(Win32Hwnd);
105 if(windowName)
106 free(windowName);
107 if(windowText)
108 free(windowText);
109 if(userWindowLong)
110 free(userWindowLong);
111}
112//******************************************************************************
113//******************************************************************************
114BOOL Win32Window::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
115{
116 char buffer[256];
117 INT sw = SW_SHOW;
118 POINT maxSize, maxPos, minTrack, maxTrack;
119
120 SetLastError(0);
121
122 /* Find the parent window */
123 if (cs->hwndParent)
124 {
125 /* Make sure parent is valid */
126 if (!IsWindow( cs->hwndParent ))
127 {
128 dprintf(("Bad parent %04x\n", cs->hwndParent ));
129 SetLastError(ERROR_INVALID_PARAMETER);
130 return FALSE;
131 }
132 }
133 else
134 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
135 dprintf(("No parent for child window\n" ));
136 SetLastError(ERROR_INVALID_PARAMETER);
137 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
138 }
139
140 /* Find the window class */
141 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
142 if (!windowClass)
143 {
144 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
145 dprintf(("Bad class '%s'\n", buffer ));
146 return 0;
147 }
148
149 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
150 * with an atom as the class name, put some programs expect to have a *REAL* string in
151 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
152 */
153 if (!HIWORD(cs->lpszClass) ) {
154 if (isUnicode) {
155 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
156 }
157 else {
158 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
159 }
160 cs->lpszClass = buffer;
161 }
162
163 /* Fix the coordinates */
164 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
165 {
166// PDB *pdb = PROCESS_Current();
167
168 /* Never believe Microsoft's documentation... CreateWindowEx doc says
169 * that if an overlapped window is created with WS_VISIBLE style bit
170 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
171 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
172 * reveals that
173 *
174 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
175 * 2) it does not ignore the y parameter as the docs claim; instead, it
176 * uses it as second parameter to ShowWindow() unless y is either
177 * CW_USEDEFAULT or CW_USEDEFAULT16.
178 *
179 * The fact that we didn't do 2) caused bogus windows pop up when wine
180 * was running apps that were using this obscure feature. Example -
181 * calc.exe that comes with Win98 (only Win98, it's different from
182 * the one that comes with Win95 and NT)
183 */
184 if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) sw = cs->y;
185
186 /* We have saved cs->y, now we can trash it */
187#if 0
188 if ( !(cs->style & (WS_CHILD | WS_POPUP))
189 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
190 {
191 cs->x = pdb->env_db->startup_info->dwX;
192 cs->y = pdb->env_db->startup_info->dwY;
193 }
194#endif
195 cs->x = 0;
196 cs->y = 0;
197// }
198 }
199 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
200 {
201#if 0
202 PDB *pdb = PROCESS_Current();
203 if ( !(cs->style & (WS_CHILD | WS_POPUP))
204 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
205 {
206 cs->cx = pdb->env_db->startup_info->dwXSize;
207 cs->cy = pdb->env_db->startup_info->dwYSize;
208 }
209 else
210 {
211#endif
212 cs->cx = 600; /* FIXME */
213 cs->cy = 400;
214// }
215 }
216
217 //Allocate window words
218 nrUserWindowLong = windowClass->getExtraWndWords();
219 if(nrUserWindowLong) {
220 userWindowLong = (ULONG *)malloc(nrUserWindowLong);
221 memset(userWindowLong, 0, nrUserWindowLong);
222 }
223
224 if ((cs->style & WS_CHILD) && cs->hwndParent)
225 {
226 SetParent(cs->hwndParent);
227 }
228 else
229 {
230 if (!cs->hwndParent) {
231 owner = NULL;
232 }
233 else
234 {
235 owner = GetWindowFromHandle(cs->hwndParent);
236 if(owner == NULL)
237 {
238 dprintf(("HMHandleTranslateToOS2 couldn't find owner window %x!!!", cs->hwndParent));
239 return FALSE;
240 }
241 }
242 }
243
244 setWindowProc(windowClass->getWindowProc());
245 hInstance = cs->hInstance;
246 dwStyle = cs->style & ~WS_VISIBLE;
247 dwExStyle = cs->dwExStyle;
248
249 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
250 ? HWND_BOTTOM : HWND_TOP;
251
252#if 0
253//TODO
254 /* Call the WH_CBT hook */
255
256 if (HOOK_IsHooked( WH_CBT ))
257 {
258 CBT_CREATEWNDA cbtc;
259 LRESULT ret;
260
261 cbtc.lpcs = cs;
262 cbtc.hwndInsertAfter = hwndLinkAfter;
263 ret = unicode ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc)
264 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc);
265 if (ret)
266 {
267 TRACE_(win)("CBT-hook returned 0\n");
268 wndPtr->pDriver->pFinalize(wndPtr);
269 retvalue = 0;
270 goto end;
271 }
272 }
273#endif
274
275 /* Increment class window counter */
276 windowClass->IncreaseWindowCount();
277
278 /* Correct the window style */
279 if (!(cs->style & WS_CHILD))
280 {
281 dwStyle |= WS_CLIPSIBLINGS;
282 if (!(cs->style & WS_POPUP))
283 {
284 dwStyle |= WS_CAPTION;
285 flags |= WIN_NEED_SIZE;
286 }
287 }
288 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
289
290 //TODO?
291#if 0
292 /* Get class or window DC if needed */
293 if (classPtr->style & CS_OWNDC) dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
294 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
295 else wndPtr->dce = NULL;
296#endif
297
298 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
299 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
300 {
301 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
302 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
303 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
304 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
305 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
306 }
307
308 if(cs->style & WS_CHILD)
309 {
310 if(cs->cx < 0) cs->cx = 0;
311 if(cs->cy < 0) cs->cy = 0;
312 }
313 else
314 {
315 if (cs->cx <= 0) cs->cx = 1;
316 if (cs->cy <= 0) cs->cy = 1;
317 }
318
319 rectWindow.left = cs->x;
320 rectWindow.top = cs->y;
321 rectWindow.right = cs->x + cs->cx;
322 rectWindow.bottom = cs->y + cs->cy;
323 rectClient = rectWindow;
324
325 DWORD dwOSWinStyle, dwOSFrameStyle;
326
327 OSLibWinConvertStyle(cs->style, &dwOSWinStyle, &dwOSFrameStyle);
328
329 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : 0,
330 dwOSWinStyle, dwOSFrameStyle, (char *)cs->lpszName,
331 cs->x, cs->y, cs->cx, cs->cy,
332 (owner) ? owner->getOS2WindowHandle() : 0,
333 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE, &OS2HwndFrame);
334
335 if(OS2Hwnd == 0) {
336 dprintf(("Window creation failed!!"));
337 return FALSE;
338 }
339 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
340 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
341 return FALSE;
342 }
343 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
344 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
345 return FALSE;
346 }
347
348 /* Set the window menu */
349 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
350 {
351 if (cs->hMenu) SetMenu(cs->hMenu);
352 else
353 {
354 if (windowClass->getMenuNameA()) {
355 cs->hMenu = LoadMenuA(cs->hInstance, windowClass->getMenuNameA());
356 if (cs->hMenu) SetMenu(cs->hMenu );
357 }
358 }
359 }
360 else windowId = (UINT)cs->hMenu;
361
362 /* Send the WM_CREATE message
363 * Perhaps we shouldn't allow width/height changes as well.
364 * See p327 in "Internals".
365 */
366 maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
367
368 if(sendMessage(WM_NCCREATE, 0, (LPARAM)cs) )
369 {
370 SendNCCalcSize(FALSE, &rectWindow, NULL, NULL, 0, &rectClient );
371 OffsetRect(&rectWindow, maxPos.x - rectWindow.left,
372 maxPos.y - rectWindow.top);
373 dprintf(("Sending WM_CREATE"));
374 if( (sendMessage(WM_CREATE, 0, (LPARAM)cs )) != -1 )
375 {
376 /* Send the size messages */
377 dprintf(("Sent WM_CREATE"));
378
379 if (!(flags & WIN_NEED_SIZE))
380 {
381 /* send it anyway */
382 if (((rectClient.right-rectClient.left) <0)
383 ||((rectClient.bottom-rectClient.top)<0))
384 dprintf(("sending bogus WM_SIZE message 0x%08lx\n",
385 MAKELONG(rectClient.right-rectClient.left,
386 rectClient.bottom-rectClient.top)));
387 SendMessageA(WM_SIZE, SIZE_RESTORED,
388 MAKELONG(rectClient.right-rectClient.left,
389 rectClient.bottom-rectClient.top));
390 SendMessageA(WM_MOVE, 0,
391 MAKELONG( rectClient.left,
392 rectClient.top ) );
393 }
394
395#if 0
396 /* Show the window, maximizing or minimizing if needed */
397
398 if (dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
399 {
400 RECT16 newPos;
401 UINT16 swFlag = (dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
402 dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
403 WINPOS_MinMaximize(swFlag, &newPos );
404 swFlag = ((dwStyle & WS_CHILD) || GetActiveWindow())
405 ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
406 : SWP_NOZORDER | SWP_FRAMECHANGED;
407 SetWindowPos(0, newPos.left, newPos.top,
408 newPos.right, newPos.bottom, swFlag );
409 }
410#endif
411
412 if( dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
413 {
414 /* Notify the parent window only */
415
416 NotifyParent(WM_CREATE, 0, 0);
417 if( !IsWindow(Win32Hwnd) )
418 {
419 return FALSE;
420 }
421 }
422
423 if (cs->style & WS_VISIBLE) ShowWindow( sw );
424
425#if 0
426 /* Call WH_SHELL hook */
427
428 if (!(dwStyle & WS_CHILD) && !owner)
429 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
430#endif
431 return TRUE;
432 }
433 }
434 return FALSE;
435}
436#if 0
437/***********************************************************************
438 * WINPOS_MinMaximize
439 *
440 * Fill in lpRect and return additional flags to be used with SetWindowPos().
441 * This function assumes that 'cmd' is different from the current window
442 * state.
443 */
444UINT Win32Window::MinMaximize(UINT16 cmd, LPRECT16 lpRect )
445{
446 UINT swpFlags = 0;
447 POINT pt, size;
448 LPINTERNALPOS lpPos;
449
450 size.x = rectWindow.left; size.y = rectWindow.top;
451 lpPos = WINPOS_InitInternalPos( wndPtr, size, &rectWindow );
452
453 if (lpPos && !HOOK_CallHooks16(WH_CBT, HCBT_MINMAX, hwndSelf, cmd))
454 {
455 if( dwStyle & WS_MINIMIZE )
456 {
457 if( !SendMessageA(WM_QUERYOPEN, 0, 0L ) )
458 return (SWP_NOSIZE | SWP_NOMOVE);
459 swpFlags |= SWP_NOCOPYBITS;
460 }
461 switch( cmd )
462 {
463 case SW_MINIMIZE:
464 if( dwStyle & WS_MAXIMIZE)
465 {
466 flags |= WIN_RESTORE_MAX;
467 dwStyle &= ~WS_MAXIMIZE;
468 }
469 else
470 flags &= ~WIN_RESTORE_MAX;
471 dwStyle |= WS_MINIMIZE;
472
473#if 0
474 if( flags & WIN_NATIVE )
475 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
476 swpFlags |= MINMAX_NOSWP;
477#endif
478
479 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
480
481 SetRect(lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
482 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
483 swpFlags |= SWP_NOCOPYBITS;
484 break;
485
486 case SW_MAXIMIZE:
487 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
488 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
489 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
490
491 if( dwStyle & WS_MINIMIZE )
492 {
493 if( flags & WIN_NATIVE )
494 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
495 swpFlags |= MINMAX_NOSWP;
496
497 WINPOS_ShowIconTitle( wndPtr, FALSE );
498 dwStyle &= ~WS_MINIMIZE;
499 }
500 dwStyle |= WS_MAXIMIZE;
501
502 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
503 size.x, size.y );
504 break;
505
506 case SW_RESTORE:
507 if( dwStyle & WS_MINIMIZE )
508 {
509 if( flags & WIN_NATIVE )
510 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
511 swpFlags |= MINMAX_NOSWP;
512
513 dwStyle &= ~WS_MINIMIZE;
514 WINPOS_ShowIconTitle( wndPtr, FALSE );
515
516 if( flags & WIN_RESTORE_MAX)
517 {
518 /* Restore to maximized position */
519 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
520 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
521 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
522 dwStyle |= WS_MAXIMIZE;
523 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
524 break;
525 }
526 }
527 else
528 if( !(dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
529 else dwStyle &= ~WS_MAXIMIZE;
530
531 /* Restore to normal position */
532
533 *lpRect = lpPos->rectNormal;
534 lpRect->right -= lpRect->left;
535 lpRect->bottom -= lpRect->top;
536
537 break;
538 }
539 } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
540 return swpFlags;
541}
542#endif
543/*******************************************************************
544 * GetMinMaxInfo
545 *
546 * Get the minimized and maximized information for a window.
547 */
548void Win32Window::GetMinMaxInfo(POINT *maxSize, POINT *maxPos,
549 POINT *minTrack, POINT *maxTrack )
550{
551 MINMAXINFO MinMax;
552 INT xinc, yinc;
553
554 /* Compute default values */
555
556 MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
557 MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
558 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
559 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
560 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
561 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
562
563 if (flags & WIN_MANAGED) xinc = yinc = 0;
564 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
565 {
566 xinc = GetSystemMetrics(SM_CXDLGFRAME);
567 yinc = GetSystemMetrics(SM_CYDLGFRAME);
568 }
569 else
570 {
571 xinc = yinc = 0;
572 if (HAS_THICKFRAME(dwStyle))
573 {
574 xinc += GetSystemMetrics(SM_CXFRAME);
575 yinc += GetSystemMetrics(SM_CYFRAME);
576 }
577 if (dwStyle & WS_BORDER)
578 {
579 xinc += GetSystemMetrics(SM_CXBORDER);
580 yinc += GetSystemMetrics(SM_CYBORDER);
581 }
582 }
583 MinMax.ptMaxSize.x += 2 * xinc;
584 MinMax.ptMaxSize.y += 2 * yinc;
585
586#if 0
587 lpPos = (LPINTERNALPOS)GetPropA( hwndSelf, atomInternalPos );
588 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
589 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
590 else
591 {
592#endif
593 MinMax.ptMaxPosition.x = -xinc;
594 MinMax.ptMaxPosition.y = -yinc;
595// }
596
597 SendMessageA(WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
598
599 /* Some sanity checks */
600
601 dprintf(("GetMinMaxInfo: %ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
602 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
603 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
604 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
605 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y));
606 MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
607 MinMax.ptMinTrackSize.x );
608 MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
609 MinMax.ptMinTrackSize.y );
610
611 if (maxSize) *maxSize = MinMax.ptMaxSize;
612 if (maxPos) *maxPos = MinMax.ptMaxPosition;
613 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
614 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
615}
616/***********************************************************************
617 * WINPOS_SendNCCalcSize
618 *
619 * Send a WM_NCCALCSIZE message to a window.
620 * All parameters are read-only except newClientRect.
621 * oldWindowRect, oldClientRect and winpos must be non-NULL only
622 * when calcValidRect is TRUE.
623 */
624LONG Win32Window::SendNCCalcSize(BOOL calcValidRect,
625 RECT *newWindowRect, RECT *oldWindowRect,
626 RECT *oldClientRect, WINDOWPOS *winpos,
627 RECT *newClientRect )
628{
629 NCCALCSIZE_PARAMS params;
630 WINDOWPOS winposCopy;
631 LONG result;
632
633 params.rgrc[0] = *newWindowRect;
634 if (calcValidRect)
635 {
636 winposCopy = *winpos;
637 params.rgrc[1] = *oldWindowRect;
638 params.rgrc[2] = *oldClientRect;
639 params.lppos = &winposCopy;
640 }
641 result = SendMessageA(WM_NCCALCSIZE, calcValidRect,
642 (LPARAM)&params );
643 *newClientRect = params.rgrc[0];
644 return result;
645}
646//******************************************************************************
647//******************************************************************************
648ULONG Win32Window::MsgCreate(HWND hwndOS2, ULONG initParam)
649{
650 OS2Hwnd = hwndOS2;
651 return SendMessageA(WM_CREATE, 0, initParam);
652}
653//******************************************************************************
654//******************************************************************************
655ULONG Win32Window::MsgQuit()
656{
657 return SendMessageA(WM_QUIT, 0, 0);
658}
659//******************************************************************************
660//******************************************************************************
661ULONG Win32Window::MsgClose()
662{
663 return SendMessageA(WM_CLOSE, 0, 0);
664}
665//******************************************************************************
666//******************************************************************************
667ULONG Win32Window::MsgDestroy()
668{
669 ULONG rc;
670
671 rc = SendMessageA(WM_DESTROY, 0, 0);
672 delete this;
673 return rc;
674}
675//******************************************************************************
676//******************************************************************************
677ULONG Win32Window::MsgEnable(BOOL fEnable)
678{
679 return SendMessageA(WM_ENABLE, fEnable, 0);
680}
681//******************************************************************************
682//TODO: SW_PARENTCLOSING/OPENING flag (lParam)
683//******************************************************************************
684ULONG Win32Window::MsgShow(BOOL fShow)
685{
686 return SendMessageA(WM_SHOWWINDOW, fShow, 0);
687}
688//******************************************************************************
689//******************************************************************************
690ULONG Win32Window::MsgMove(ULONG xScreen, ULONG yScreen, ULONG xParent, ULONG yParent)
691{
692 return 0;
693}
694//******************************************************************************
695//TODO: Send WM_NCCALCSIZE message here and correct size if necessary
696//******************************************************************************
697ULONG Win32Window::MsgSize(ULONG width, ULONG height, BOOL fMinimize, BOOL fMaximize)
698{
699 WORD fwSizeType = 0;
700
701 if(fMinimize) {
702 fwSizeType = SIZE_MINIMIZED;
703 }
704 else
705 if(fMaximize) {
706 fwSizeType = SIZE_MAXIMIZED;
707 }
708 else fwSizeType = SIZE_RESTORED;
709
710 return SendMessageA(WM_SIZE, fwSizeType, MAKELONG((USHORT)width, (USHORT)height));
711}
712//******************************************************************************
713//******************************************************************************
714ULONG Win32Window::MsgActivate(BOOL fActivate, HWND hwnd)
715{
716 return SendMessageA(WM_ACTIVATE, (fActivate) ? WA_ACTIVE : WA_INACTIVE, hwnd);
717}
718//******************************************************************************
719//******************************************************************************
720ULONG Win32Window::MsgSetFocus(HWND hwnd)
721{
722 return SendMessageA(WM_SETFOCUS, hwnd, 0);
723}
724//******************************************************************************
725//******************************************************************************
726ULONG Win32Window::MsgKillFocus(HWND hwnd)
727{
728 return SendMessageA(WM_KILLFOCUS, hwnd, 0);
729}
730//******************************************************************************
731//******************************************************************************
732ULONG Win32Window::MsgButton(ULONG msg, ULONG x, ULONG y)
733{
734 ULONG win32msg;
735
736 switch(msg) {
737 case BUTTON_LEFTDOWN:
738 win32msg = WM_LBUTTONDOWN;
739 break;
740 case BUTTON_LEFTUP:
741 win32msg = WM_LBUTTONUP;
742 break;
743 case BUTTON_LEFTDBLCLICK:
744 win32msg = WM_LBUTTONDBLCLK;
745 break;
746 case BUTTON_RIGHTUP:
747 win32msg = WM_RBUTTONUP;
748 break;
749 case BUTTON_RIGHTDOWN:
750 win32msg = WM_RBUTTONDOWN;
751 break;
752 case BUTTON_RIGHTDBLCLICK:
753 win32msg = WM_RBUTTONDBLCLK;
754 break;
755 default:
756 dprintf(("Win32Window::Button: invalid msg!!!!"));
757 return 1;
758 }
759 return SendMessageA(win32msg, 0, MAKELONG(x, OS2TOWIN32POINT(height, y)));
760}
761//******************************************************************************
762//******************************************************************************
763ULONG Win32Window::MsgPaint(ULONG tmp1, ULONG tmp2)
764{
765 return SendMessageA(WM_PAINT, 0, 0);
766}
767//******************************************************************************
768//******************************************************************************
769ULONG Win32Window::MsgEraseBackGround(ULONG hps)
770{
771 return SendMessageA(WM_ERASEBKGND, hps, 0);
772}
773//******************************************************************************
774//******************************************************************************
775LRESULT Win32Window::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
776{
777 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
778 dprintf(("SendMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
779
780 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
781 return(0);
782 }
783 switch(Msg)
784 {
785 case WM_CREATE:
786 {
787 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
788 dprintf(("WM_NCCREATE returned FALSE\n"));
789 return(0); //don't create window
790 }
791 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
792 dprintf(("WM_CREATE returned FALSE\n"));
793 return(0); //don't create window
794 }
795 NotifyParent(Msg, wParam, lParam);
796
797 return(1);
798 }
799 case WM_LBUTTONDOWN:
800 case WM_MBUTTONDOWN:
801 case WM_RBUTTONDOWN:
802 NotifyParent(Msg, wParam, lParam);
803 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
804
805 case WM_DESTROY:
806 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
807 NotifyParent(Msg, wParam, lParam);
808 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
809 default:
810 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
811 }
812}
813//******************************************************************************
814//todo, unicode msgs
815//******************************************************************************
816LRESULT Win32Window::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
817{
818 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
819 dprintf(("SendMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
820
821 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
822 return(0);
823 }
824 switch(Msg)
825 {
826 case WM_CREATE:
827 {
828 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
829 dprintf(("WM_NCCREATE returned FALSE\n"));
830 return(0); //don't create window
831 }
832 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
833 dprintf(("WM_CREATE returned FALSE\n"));
834 return(0); //don't create window
835 }
836 NotifyParent(Msg, wParam, lParam);
837
838 return(1);
839 }
840 case WM_LBUTTONDOWN:
841 case WM_MBUTTONDOWN:
842 case WM_RBUTTONDOWN:
843 NotifyParent(Msg, wParam, lParam);
844 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
845
846 case WM_DESTROY:
847 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
848 NotifyParent(Msg, wParam, lParam);
849 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
850 default:
851 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
852 }
853}
854//******************************************************************************
855//******************************************************************************
856BOOL Win32Window::PostMessageA(ULONG msg, WPARAM wParam, LPARAM lParam)
857{
858 POSTMSG_PACKET *postmsg;
859
860 postmsg = (POSTMSG_PACKET *)malloc(sizeof(POSTMSG_PACKET));
861 if(postmsg == NULL) {
862 dprintf(("Win32Window::PostMessageA: malloc returned NULL!!"));
863 return 0;
864 }
865 postmsg->Msg = msg;
866 postmsg->wParam = wParam;
867 postmsg->lParam = lParam;
868 return OSLibPostMessage(OS2Hwnd, WM_WIN32_POSTMESSAGEA, (ULONG)postmsg, 0);
869}
870//******************************************************************************
871//******************************************************************************
872BOOL Win32Window::PostMessageW(ULONG msg, WPARAM wParam, LPARAM lParam)
873{
874 POSTMSG_PACKET *postmsg;
875
876 postmsg = (POSTMSG_PACKET *)malloc(sizeof(POSTMSG_PACKET));
877 if(postmsg == NULL) {
878 dprintf(("Win32Window::PostMessageW: malloc returned NULL!!"));
879 return 0;
880 }
881 postmsg->Msg = msg;
882 postmsg->wParam = wParam;
883 postmsg->lParam = lParam;
884 return OSLibPostMessage(OS2Hwnd, WM_WIN32_POSTMESSAGEW, (ULONG)postmsg, 0);
885}
886//******************************************************************************
887//TODO: do we need to inform the parent of the parent (etc) of the child window?
888//******************************************************************************
889void Win32Window::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
890{
891 Win32Window *window = this;
892 Win32Window *parentwindow;
893
894 while(window)
895 {
896 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
897 {
898 /* Notify the parent window only */
899 parentwindow = window->getParent();
900 if(parentwindow) {
901 if(Msg == WM_CREATE || Msg == WM_DESTROY) {
902 parentwindow->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), (LPARAM)window->getWindowHandle());
903 }
904 else parentwindow->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), lParam );
905 }
906 }
907 else break;
908
909 window = parentwindow;
910 }
911}
912//******************************************************************************
913//******************************************************************************
914BOOL Win32Window::SetMenu(ULONG hMenu)
915{
916 PVOID menutemplate;
917
918 if(HMHandleTranslateToOS2(hMenu, (PULONG)&menutemplate) == NO_ERROR)
919 {
920 OS2HwndMenu = OSLibWinCreateMenu(OS2HwndFrame, menutemplate);
921 if(OS2HwndMenu == 0) {
922 dprintf(("Win32Window::SetMenu OS2HwndMenu == 0"));
923 return FALSE;
924 }
925 }
926 dprintf(("Win32Window::SetMenu unknown hMenu (%x)", hMenu));
927 return FALSE;
928}
929//******************************************************************************
930//******************************************************************************
931BOOL Win32Window::ShowWindow(ULONG nCmdShow)
932{
933 ULONG showstate = 0;
934
935 switch(nCmdShow)
936 {
937 case SW_SHOW:
938 case SW_SHOWDEFAULT: //todo
939 showstate = SWPOS_SHOW;
940 break;
941 case SW_HIDE:
942 showstate = SWPOS_HIDE;
943 break;
944 case SW_MINIMIZE:
945 showstate = SWPOS_MINIMIZE;
946 break;
947 case SW_SHOWMAXIMIZED:
948 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW;
949 break;
950 case SW_SHOWMINIMIZED:
951 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
952 break;
953 case SW_SHOWMINNOACTIVE: //TODO
954 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
955 break;
956 case SW_SHOWNA: //TODO
957 showstate = SWPOS_SHOW;
958 break;
959 case SW_SHOWNOACTIVATE: //TODO
960 showstate = SWPOS_SHOW;
961 break;
962 case SW_SHOWNORMAL:
963 showstate = SWPOS_RESTORE;
964 break;
965 }
966 return OSLibWinShowWindow(OS2HwndFrame, showstate);
967}
968//******************************************************************************
969//******************************************************************************
970BOOL Win32Window::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
971{
972 Win32Window *window;
973 ULONG setstate = 0;
974
975 switch(hwndInsertAfter) {
976 case HWND_BOTTOM:
977 case HWND_TOP:
978 case HWND_TOPMOST:
979 case HWND_NOTOPMOST:
980 break;
981 default:
982 window = GetWindowFromHandle(hwndInsertAfter);
983 if(window) {
984 hwndInsertAfter = window->getOS2WindowHandle();
985 }
986 else {
987 dprintf(("Win32Window::SetWindowPos, unknown hwndInsertAfter %x", hwndInsertAfter));
988 hwndInsertAfter = 0;
989 }
990 break;
991
992 }
993 setstate = SWPOS_MOVE | SWPOS_SIZE | SWPOS_ACTIVATE | SWPOS_ZORDER;
994 if(fuFlags & SWP_DRAWFRAME)
995 setstate |= 0; //TODO
996 if(fuFlags & SWP_FRAMECHANGED)
997 setstate |= 0; //TODO
998 if(fuFlags & SWP_HIDEWINDOW)
999 setstate &= ~SWPOS_ZORDER;
1000 if(fuFlags & SWP_NOACTIVATE)
1001 setstate &= ~SWPOS_ACTIVATE;
1002 if(fuFlags & SWP_NOCOPYBITS)
1003 setstate |= 0; //TODO
1004 if(fuFlags & SWP_NOMOVE)
1005 setstate &= ~SWPOS_MOVE;
1006 if(fuFlags & SWP_NOSIZE)
1007 setstate &= ~SWPOS_SIZE;
1008 if(fuFlags & SWP_NOREDRAW)
1009 setstate |= SWPOS_NOREDRAW;
1010 if(fuFlags & SWP_NOZORDER)
1011 setstate &= ~SWPOS_ZORDER;
1012 if(fuFlags & SWP_SHOWWINDOW)
1013 setstate |= SWPOS_SHOW;
1014
1015 return OSLibWinSetWindowPos(OS2HwndFrame, hwndInsertAfter, x, y, cx, cy, setstate);
1016}
1017//******************************************************************************
1018//Also destroys all the child windows (destroy parent, destroy children)
1019//******************************************************************************
1020BOOL Win32Window::DestroyWindow()
1021{
1022 return OSLibWinDestroyWindow(OS2HwndFrame);
1023}
1024//******************************************************************************
1025//TODO:
1026//******************************************************************************
1027HWND Win32Window::SetActiveWindow()
1028{
1029 return O32_SetActiveWindow(OS2Hwnd);
1030}
1031//******************************************************************************
1032//******************************************************************************
1033HWND Win32Window::GetParent()
1034{
1035 if(getParent()) {
1036 return getParent()->getWindowHandle();
1037 }
1038 else return 0;
1039}
1040//******************************************************************************
1041//******************************************************************************
1042HWND Win32Window::SetParent(HWND hwndNewParent)
1043{
1044 HWND oldhwnd;
1045 Win32Window *newparent;
1046
1047 if(getParent()) {
1048 oldhwnd = getParent()->getWindowHandle();
1049 }
1050 else oldhwnd = 0;
1051
1052 if(hwndNewParent == 0) {//desktop window = parent
1053 setParent(NULL);
1054 OSLibWinSetParent(getOS2WindowHandle(), OSLIB_HWND_DESKTOP);
1055 return oldhwnd;
1056 }
1057 newparent = GetWindowFromHandle(hwndNewParent);
1058 if(newparent)
1059 {
1060 setParent(newparent);
1061 OSLibWinSetParent(getOS2WindowHandle(), getParent()->getOS2WindowHandle());
1062 return oldhwnd;
1063 }
1064 SetLastError(ERROR_INVALID_PARAMETER);
1065 return 0;
1066}
1067//******************************************************************************
1068//******************************************************************************
1069BOOL Win32Window::IsChild(HWND hwndParent)
1070{
1071 if(getParent()) {
1072 return getParent()->getWindowHandle() == hwndParent;
1073 }
1074 else return 0;
1075}
1076//******************************************************************************
1077//******************************************************************************
1078HWND Win32Window::GetTopWindow()
1079{
1080 HWND topchild;
1081
1082 topchild = OSLibWinQueryTopMostChildWindow(OS2HwndFrame);
1083 if(topchild)
1084 {
1085 return topchild;
1086 }
1087 else return 0;
1088}
1089//******************************************************************************
1090//Don't call WinUpdateWindow as that one also updates the child windows
1091//Also need to send WM_PAINT directly to the window procedure, which doesn't
1092//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
1093//******************************************************************************
1094BOOL Win32Window::UpdateWindow()
1095{
1096 RECTL rect;
1097
1098 if(OSLibWinQueryUpdateRect(OS2Hwnd, (PVOID)&rect))
1099 {//update region not empty
1100 SendMessageA((isIcon) ? WM_PAINTICON : WM_PAINT, 0, 0);
1101 }
1102 return TRUE;
1103}
1104//******************************************************************************
1105//******************************************************************************
1106BOOL Win32Window::IsIconic()
1107{
1108 return OSLibWinIsIconic(OS2HwndFrame);
1109}
1110//******************************************************************************
1111//******************************************************************************
1112LONG Win32Window::SetWindowLongA(int index, ULONG value)
1113{
1114 LONG oldval;
1115
1116 switch(index) {
1117 case GWL_EXSTYLE:
1118 oldval = dwExStyle;
1119 dwExStyle = value;
1120 return oldval;
1121 case GWL_STYLE:
1122 oldval = dwStyle;
1123 dwStyle = value;
1124 return oldval;
1125 case GWL_WNDPROC:
1126 oldval = (LONG)getWindowProc();
1127 setWindowProc((WNDPROC)value);
1128 return oldval;
1129 case GWL_HINSTANCE:
1130 oldval = hInstance;
1131 hInstance = value;
1132 return oldval;
1133 case GWL_HWNDPARENT:
1134 return SetParent((HWND)value);
1135
1136 case GWL_ID:
1137 oldval = getWindowId();
1138 setWindowId(value);
1139 return oldval;
1140 case GWL_USERDATA:
1141 oldval = userData;
1142 userData = value;
1143 return oldval;
1144 default:
1145 if(index >= 0 && index/4 < nrUserWindowLong)
1146 {
1147 oldval = userWindowLong[index/4];
1148 userWindowLong[index/4] = value;
1149 return oldval;
1150 }
1151 SetLastError(ERROR_INVALID_PARAMETER);
1152 return 0;
1153 }
1154}
1155//******************************************************************************
1156//******************************************************************************
1157ULONG Win32Window::GetWindowLongA(int index)
1158{
1159 switch(index) {
1160 case GWL_EXSTYLE:
1161 return dwExStyle;
1162 case GWL_STYLE:
1163 return dwStyle;
1164 case GWL_WNDPROC:
1165 return (ULONG)getWindowProc();
1166 case GWL_HINSTANCE:
1167 return hInstance;
1168 case GWL_HWNDPARENT:
1169 if(getParent()) {
1170 return getParent()->getWindowHandle();
1171 }
1172 else return 0;
1173 case GWL_ID:
1174 return getWindowId();
1175 case GWL_USERDATA:
1176 return userData;
1177 default:
1178 if(index >= 0 && index/4 < nrUserWindowLong)
1179 {
1180 return userWindowLong[index/4];
1181 }
1182 SetLastError(ERROR_INVALID_PARAMETER);
1183 return 0;
1184 }
1185}
1186//******************************************************************************
1187//******************************************************************************
1188WORD Win32Window::SetWindowWord(int index, WORD value)
1189{
1190 WORD oldval;
1191
1192 if(index >= 0 && index/4 < nrUserWindowLong)
1193 {
1194 oldval = ((WORD *)userWindowLong)[index/2];
1195 ((WORD *)userWindowLong)[index/2] = value;
1196 return oldval;
1197 }
1198 SetLastError(ERROR_INVALID_PARAMETER);
1199 return 0;
1200}
1201//******************************************************************************
1202//******************************************************************************
1203WORD Win32Window::GetWindowWord(int index)
1204{
1205 if(index >= 0 && index/4 < nrUserWindowLong)
1206 {
1207 return ((WORD *)userWindowLong)[index/2];
1208 }
1209 SetLastError(ERROR_INVALID_PARAMETER);
1210 return 0;
1211}
1212//******************************************************************************
1213//******************************************************************************
1214Win32Window *Win32Window::GetWindowFromHandle(HWND hwnd)
1215{
1216 Win32Window *window;
1217
1218 if(HIWORD(hwnd) != 0x6800) {
1219 return NULL;
1220 }
1221
1222 if(HMHandleTranslateToOS2(LOWORD(hwnd), (PULONG)&window) == NO_ERROR) {
1223 return window;
1224 }
1225 else return NULL;
1226}
1227//******************************************************************************
1228//******************************************************************************
1229GenericObject *Win32Window::windows = NULL;
Note: See TracBrowser for help on using the repository browser.