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

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

Misc window class changes/bugfixes

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