source: trunk/src/user32/win32wbase.cpp@ 1025

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

Control Z-order + changes for comctl32

File size: 77.0 KB
Line 
1/* $Id: win32wbase.cpp,v 1.8 1999-09-23 16:44:33 sandervl Exp $ */
2/*
3 * Win32 Window Base Class for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 *
8 * Parts based on Wine Windows code (windows\win.c)
9 *
10 * Copyright 1993, 1994 Alexandre Julliard
11 *
12 * TODO: Not thread/process safe
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17#include <os2win.h>
18#include <win.h>
19#include <stdlib.h>
20#include <string.h>
21#include <stdarg.h>
22#include <assert.h>
23#include <misc.h>
24#include <heapstring.h>
25#include <win32wbase.h>
26#include <winres.h>
27#include <spy.h>
28#include "wndmsg.h"
29#include "hooks.h"
30#include "oslibwin.h"
31#include "oslibutil.h"
32#include "oslibgdi.h"
33#include "oslibres.h"
34#include "oslibmenu.h"
35#include "oslibdos.h"
36#include "syscolor.h"
37#include "win32wndhandle.h"
38#include "heapshared.h"
39#include "dc.h"
40
41#define HAS_DLGFRAME(style,exStyle) \
42 (((exStyle) & WS_EX_DLGMODALFRAME) || \
43 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
44
45#define HAS_THICKFRAME(style) \
46 (((style) & WS_THICKFRAME) && \
47 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
48
49#define HAS_BORDER(style, exStyle) \
50 ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
51
52#define IS_OVERLAPPED(style) \
53 !(style & (WS_CHILD | WS_POPUP))
54
55//******************************************************************************
56//******************************************************************************
57Win32BaseWindow::Win32BaseWindow(DWORD objType) : GenericObject(&windows, objType)
58{
59 Init();
60}
61//******************************************************************************
62//******************************************************************************
63Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
64 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
65{
66 Init();
67 this->isUnicode = isUnicode;
68 CreateWindowExA(lpCreateStructA, classAtom);
69}
70//******************************************************************************
71//******************************************************************************
72void Win32BaseWindow::Init()
73{
74 isUnicode = FALSE;
75 fCreated = FALSE;
76 fFirstShow = TRUE;
77 fIsDialog = FALSE;
78
79 windowNameA = NULL;
80 windowNameW = NULL;
81 wndNameLength = 0;
82
83 userWindowLong = NULL;;
84 nrUserWindowLong = 0;
85
86 magic = WIN32PM_MAGIC;
87 OS2Hwnd = 0;
88 OS2HwndFrame = 0;
89 OS2HwndMenu = 0;
90 Win32Hwnd = 0;
91
92 if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
93 {
94 dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
95 DebugInt3();
96 }
97
98 posx = posy = 0;
99 width = height = 0;
100
101 dwExStyle = 0;
102 dwStyle = 0;
103 win32wndproc = 0;
104 hInstance = 0;
105 windowId = 0xFFFFFFFF; //default = -1
106 userData = 0;
107
108 hwndLinkAfter = HWND_BOTTOM;
109 flags = 0;
110 isIcon = FALSE;
111 lastHitTestVal = 0;
112 owner = NULL;
113 windowClass = 0;
114
115 acceltableResource = NULL;
116 menuResource = NULL;
117 iconResource = NULL;
118
119 EraseBkgndFlag = TRUE;
120 PSEraseFlag = FALSE;
121 SupressEraseFlag = FALSE;
122}
123//******************************************************************************
124//todo get rid of resources (menu, accel, icon etc)
125//******************************************************************************
126Win32BaseWindow::~Win32BaseWindow()
127{
128 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
129 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
130
131 if (isOwnDC())
132 releaseOwnDC (ownDC);
133
134 if(Win32Hwnd)
135 HwFreeWindowHandle(Win32Hwnd);
136
137 if(userWindowLong)
138 free(userWindowLong);
139 if(windowNameA) {
140 free(windowNameA);
141 windowNameA = NULL;
142 }
143 if(windowNameW) {
144 free(windowNameW);
145 windowNameW = NULL;
146 }
147}
148//******************************************************************************
149//******************************************************************************
150BOOL Win32BaseWindow::isChild()
151{
152 return (dwStyle & WS_CHILD) != 0;
153}
154//******************************************************************************
155//******************************************************************************
156BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
157{
158 char buffer[256];
159 INT sw = SW_SHOW;
160 POINT maxSize, maxPos, minTrack, maxTrack;
161
162 SetLastError(0);
163
164 /* Find the parent window */
165 if (cs->hwndParent)
166 {
167 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
168 if(!window) {
169 dprintf(("Bad parent %04x\n", cs->hwndParent ));
170 SetLastError(ERROR_INVALID_PARAMETER);
171 return FALSE;
172 }
173 /* Make sure parent is valid */
174 if (!window->IsWindow() )
175 {
176 dprintf(("Bad parent %04x\n", cs->hwndParent ));
177 SetLastError(ERROR_INVALID_PARAMETER);
178 return FALSE;
179 }
180 }
181 else
182 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
183 dprintf(("No parent for child window\n" ));
184 SetLastError(ERROR_INVALID_PARAMETER);
185 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
186 }
187
188 /* Find the window class */
189 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
190 if (!windowClass)
191 {
192 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
193 dprintf(("Bad class '%s'\n", buffer ));
194 SetLastError(ERROR_INVALID_PARAMETER);
195 return 0;
196 }
197
198 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
199 * with an atom as the class name, put some programs expect to have a *REAL* string in
200 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
201 */
202 if (!HIWORD(cs->lpszClass) ) {
203 if (isUnicode) {
204 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
205 }
206 else {
207 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
208 }
209 cs->lpszClass = buffer;
210 }
211
212 /* Fix the coordinates */
213 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
214 {
215// PDB *pdb = PROCESS_Current();
216
217 /* Never believe Microsoft's documentation... CreateWindowEx doc says
218 * that if an overlapped window is created with WS_VISIBLE style bit
219 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
220 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
221 * reveals that
222 *
223 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
224 * 2) it does not ignore the y parameter as the docs claim; instead, it
225 * uses it as second parameter to ShowWindow() unless y is either
226 * CW_USEDEFAULT or CW_USEDEFAULT16.
227 *
228 * The fact that we didn't do 2) caused bogus windows pop up when wine
229 * was running apps that were using this obscure feature. Example -
230 * calc.exe that comes with Win98 (only Win98, it's different from
231 * the one that comes with Win95 and NT)
232 */
233 if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) sw = cs->y;
234
235 /* We have saved cs->y, now we can trash it */
236#if 0
237 if ( !(cs->style & (WS_CHILD | WS_POPUP))
238 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
239 {
240 cs->x = pdb->env_db->startup_info->dwX;
241 cs->y = pdb->env_db->startup_info->dwY;
242 }
243#endif
244 cs->x = 0;
245 cs->y = 0;
246// }
247 }
248 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
249 {
250#if 0
251 PDB *pdb = PROCESS_Current();
252 if ( !(cs->style & (WS_CHILD | WS_POPUP))
253 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
254 {
255 cs->cx = pdb->env_db->startup_info->dwXSize;
256 cs->cy = pdb->env_db->startup_info->dwYSize;
257 }
258 else
259 {
260#endif
261 cs->cx = 600; /* FIXME */
262 cs->cy = 400;
263// }
264 }
265
266 if (cs->x < 0) cs->x = 0;
267 if (cs->y < 0) cs->y = 0;
268
269 //Allocate window words
270 nrUserWindowLong = windowClass->getExtraWndWords();
271 if(nrUserWindowLong) {
272 userWindowLong = (ULONG *)_smalloc(nrUserWindowLong);
273 memset(userWindowLong, 0, nrUserWindowLong);
274 }
275
276 if ((cs->style & WS_CHILD) && cs->hwndParent)
277 {
278 SetParent(cs->hwndParent);
279 owner = GetWindowFromHandle(cs->hwndParent);
280 if(owner == NULL)
281 {
282 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
283 return FALSE;
284 }
285 }
286 else
287 {
288 if (!cs->hwndParent) {
289 owner = NULL;
290 }
291 else
292 {
293 owner = GetWindowFromHandle(cs->hwndParent);
294 if(owner == NULL)
295 {
296 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
297 return FALSE;
298 }
299 }
300 }
301
302 setWindowProc(windowClass->getWindowProc());
303 hInstance = cs->hInstance;
304 dwStyle = cs->style & ~WS_VISIBLE;
305 dwExStyle = cs->dwExStyle;
306
307#if 1
308 //SvL: Messes up Z-order of dialog controls
309 hwndLinkAfter = HWND_TOP;
310#else
311 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
312 ? HWND_BOTTOM : HWND_TOP;
313#endif
314
315#if 0
316//TODO
317 /* Call the WH_CBT hook */
318
319 if (HOOK_IsHooked( WH_CBT ))
320 {
321 CBT_CREATEWNDA cbtc;
322 LRESULT ret;
323
324 cbtc.lpcs = cs;
325 cbtc.hwndInsertAfter = hwndLinkAfter;
326 ret = unicode ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc)
327 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc);
328 if (ret)
329 {
330 TRACE_(win)("CBT-hook returned 0\n");
331 wndPtr->pDriver->pFinalize(wndPtr);
332 retvalue = 0;
333 goto end;
334 }
335 }
336#endif
337
338 /* Increment class window counter */
339 windowClass->IncreaseWindowCount();
340
341 /* Correct the window style */
342 if (!(cs->style & WS_CHILD))
343 {
344 dwStyle |= WS_CLIPSIBLINGS;
345 if (!(cs->style & WS_POPUP))
346 {
347 dwStyle |= WS_CAPTION;
348 flags |= WIN_NEED_SIZE;
349 }
350 }
351 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
352
353 //TODO?
354#if 0
355 /* Get class or window DC if needed */
356 if (classPtr->style & CS_OWNDC) dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
357 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
358 else wndPtr->dce = NULL;
359#endif
360
361 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
362 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
363 {
364 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
365 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
366 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
367 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
368 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
369 }
370
371 if(cs->style & WS_CHILD)
372 {
373 if(cs->cx < 0) cs->cx = 0;
374 if(cs->cy < 0) cs->cy = 0;
375 }
376 else
377 {
378 if (cs->cx <= 0) cs->cx = 1;
379 if (cs->cy <= 0) cs->cy = 1;
380 }
381
382 rectWindow.left = cs->x;
383 rectWindow.top = cs->y;
384 rectWindow.right = cs->x + cs->cx;
385 rectWindow.bottom = cs->y + cs->cy;
386 rectClient = rectWindow;
387
388 DWORD dwOSWinStyle, dwOSFrameStyle;
389
390 OSLibWinConvertStyle(cs->style, cs->dwExStyle, &dwOSWinStyle, &dwOSFrameStyle);
391
392 //TODO: Test
393#if 1
394 if(cs->style & WS_CHILD) {
395 dwOSFrameStyle = 0;
396 }
397#endif
398
399 if(cs->lpszName)
400 {
401 if(isUnicode)
402 SetWindowTextW((LPWSTR)cs->lpszName);
403 else SetWindowTextA((LPSTR)cs->lpszName);
404 }
405
406 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
407 dwOSWinStyle, dwOSFrameStyle, (char *)windowNameA,
408 (owner) ? owner->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
409 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
410 &OS2HwndFrame);
411
412 if(OS2Hwnd == 0) {
413 dprintf(("Window creation failed!!"));
414 return FALSE;
415 }
416
417 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
418 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
419 return FALSE;
420 }
421 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
422 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
423 return FALSE;
424 }
425 //SvL: Need to store the shared memory base, or else other apps can map it into their memory space
426 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_SHAREDMEM, HeapGetSharedMemBase()) == FALSE) {
427 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
428 return FALSE;
429 }
430#if 0
431 if(OS2Hwnd != OS2HwndFrame) {
432 if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
433 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2HwndFrame));
434 return FALSE;
435 }
436 if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
437 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2HwndFrame));
438 return FALSE;
439 }
440 //SvL: Need to store the shared memory base, or else other apps can map it into their memory space
441 if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32PM_SHAREDMEM, HeapGetSharedMemBase()) == FALSE) {
442 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2HwndFrame));
443 return FALSE;
444 }
445 }
446#endif
447
448 fakeWinBase.hwndThis = OS2Hwnd;
449 fakeWinBase.pWindowClass = windowClass;
450// SetFakeOpen32();
451
452 /* Set the window menu */
453 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
454 {
455 if (cs->hMenu) SetMenu(cs->hMenu);
456 else
457 {
458 if (windowClass->getMenuNameA()) {
459 cs->hMenu = LoadMenuA(cs->hInstance, windowClass->getMenuNameA());
460 if (cs->hMenu) SetMenu(cs->hMenu );
461 }
462 }
463 }
464 else windowId = (UINT)cs->hMenu;
465
466 //Set icon from class
467 if(windowClass->getIcon())
468 SetIcon(windowClass->getIcon());
469
470 if(getParent()) {
471 SetWindowPos(getParent()->getWindowHandle(), rectClient.left, rectClient.top,
472 rectClient.right-rectClient.left,
473 rectClient.bottom-rectClient.top,
474 SWP_NOACTIVATE | SWP_NOZORDER);
475 }
476 else {
477 SetWindowPos(HWND_TOP, rectClient.left, rectClient.top,
478 rectClient.right-rectClient.left,
479 rectClient.bottom-rectClient.top,
480 SWP_NOACTIVATE);
481 }
482 //Get the client window rectangle
483 GetClientRect(Win32Hwnd, &rectClient);
484
485 /* Send the WM_CREATE message
486 * Perhaps we shouldn't allow width/height changes as well.
487 * See p327 in "Internals".
488 */
489 maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
490
491 fCreated = TRUE; //Allow WM_SIZE messages now
492 if(SendInternalMessage(WM_NCCREATE, 0, (LPARAM)cs) )
493 {
494 //doesn't work right, messes up client rectangle
495#if 0
496 SendNCCalcSize(FALSE, &rectWindow, NULL, NULL, 0, &rectClient );
497#endif
498 OffsetRect(&rectWindow, maxPos.x - rectWindow.left, maxPos.y - rectWindow.top);
499 dprintf(("Sending WM_CREATE"));
500 if( (SendInternalMessage(WM_CREATE, 0, (LPARAM)cs )) != -1 )
501 {
502 if(!(flags & WIN_NEED_SIZE)) {
503 SendMessageA(WM_SIZE, SIZE_RESTORED,
504 MAKELONG(rectClient.right-rectClient.left,
505 rectClient.bottom-rectClient.top));
506 SendMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
507 }
508 if (cs->style & WS_VISIBLE) ShowWindow( sw );
509
510#if 0
511 /* Call WH_SHELL hook */
512
513 if (!(dwStyle & WS_CHILD) && !owner)
514 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
515#endif
516 SetLastError(0);
517 return TRUE;
518 }
519 }
520 fCreated = FALSE;
521 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
522 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
523 DestroyWindow();
524 return FALSE;
525}
526#if 0
527/***********************************************************************
528 * WINPOS_MinMaximize
529 *
530 * Fill in lpRect and return additional flags to be used with SetWindowPos().
531 * This function assumes that 'cmd' is different from the current window
532 * state.
533 */
534UINT Win32BaseWindow::MinMaximize(UINT cmd, LPRECT lpRect )
535{
536 UINT swpFlags = 0;
537 POINT pt, size;
538 LPINTERNALPOS lpPos;
539
540 size.x = rectWindow.left; size.y = rectWindow.top;
541 lpPos = WINPOS_InitInternalPos( wndPtr, size, &rectWindow );
542
543 if (lpPos && !HOOK_CallHooks16(WH_CBT, HCBT_MINMAX, hwndSelf, cmd))
544 {
545 if( dwStyle & WS_MINIMIZE )
546 {
547 if( !SendInternalMessageA(WM_QUERYOPEN, 0, 0L ) )
548 return (SWP_NOSIZE | SWP_NOMOVE);
549 swpFlags |= SWP_NOCOPYBITS;
550 }
551 switch( cmd )
552 {
553 case SW_MINIMIZE:
554 if( dwStyle & WS_MAXIMIZE)
555 {
556 flags |= WIN_RESTORE_MAX;
557 dwStyle &= ~WS_MAXIMIZE;
558 }
559 else
560 flags &= ~WIN_RESTORE_MAX;
561 dwStyle |= WS_MINIMIZE;
562
563#if 0
564 if( flags & WIN_NATIVE )
565 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
566 swpFlags |= MINMAX_NOSWP;
567#endif
568
569 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
570
571 SetRect(lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
572 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
573 swpFlags |= SWP_NOCOPYBITS;
574 break;
575
576 case SW_MAXIMIZE:
577 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
578
579 if( dwStyle & WS_MINIMIZE )
580 {
581 if( flags & WIN_NATIVE )
582 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
583 swpFlags |= MINMAX_NOSWP;
584
585 WINPOS_ShowIconTitle( wndPtr, FALSE );
586 dwStyle &= ~WS_MINIMIZE;
587 }
588 dwStyle |= WS_MAXIMIZE;
589
590 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
591 size.x, size.y );
592 break;
593
594 case SW_RESTORE:
595 if( dwStyle & WS_MINIMIZE )
596 {
597 if( flags & WIN_NATIVE )
598 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
599 swpFlags |= MINMAX_NOSWP;
600
601 dwStyle &= ~WS_MINIMIZE;
602 WINPOS_ShowIconTitle( wndPtr, FALSE );
603
604 if( flags & WIN_RESTORE_MAX)
605 {
606 /* Restore to maximized position */
607 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
608 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
609 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
610 dwStyle |= WS_MAXIMIZE;
611 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
612 break;
613 }
614 }
615 else
616 if( !(dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
617 else dwStyle &= ~WS_MAXIMIZE;
618
619 /* Restore to normal position */
620
621 *lpRect = lpPos->rectNormal;
622 lpRect->right -= lpRect->left;
623 lpRect->bottom -= lpRect->top;
624
625 break;
626 }
627 } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
628 return swpFlags;
629}
630#endif
631/*******************************************************************
632 * GetMinMaxInfo
633 *
634 * Get the minimized and maximized information for a window.
635 */
636void Win32BaseWindow::GetMinMaxInfo(POINT *maxSize, POINT *maxPos,
637 POINT *minTrack, POINT *maxTrack )
638{
639 MINMAXINFO MinMax;
640 INT xinc, yinc;
641
642 /* Compute default values */
643
644 MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
645 MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
646 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
647 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
648 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
649 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
650
651 if (flags & WIN_MANAGED) xinc = yinc = 0;
652 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
653 {
654 xinc = GetSystemMetrics(SM_CXDLGFRAME);
655 yinc = GetSystemMetrics(SM_CYDLGFRAME);
656 }
657 else
658 {
659 xinc = yinc = 0;
660 if (HAS_THICKFRAME(dwStyle))
661 {
662 xinc += GetSystemMetrics(SM_CXFRAME);
663 yinc += GetSystemMetrics(SM_CYFRAME);
664 }
665 if (dwStyle & WS_BORDER)
666 {
667 xinc += GetSystemMetrics(SM_CXBORDER);
668 yinc += GetSystemMetrics(SM_CYBORDER);
669 }
670 }
671 MinMax.ptMaxSize.x += 2 * xinc;
672 MinMax.ptMaxSize.y += 2 * yinc;
673
674#if 0
675 lpPos = (LPINTERNALPOS)GetPropA( hwndSelf, atomInternalPos );
676 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
677 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
678 else
679 {
680#endif
681 MinMax.ptMaxPosition.x = -xinc;
682 MinMax.ptMaxPosition.y = -yinc;
683// }
684
685 SendInternalMessageA(WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
686
687 /* Some sanity checks */
688
689 dprintf(("GetMinMaxInfo: %ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
690 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
691 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
692 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
693 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y));
694 MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
695 MinMax.ptMinTrackSize.x );
696 MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
697 MinMax.ptMinTrackSize.y );
698
699 if (maxSize) *maxSize = MinMax.ptMaxSize;
700 if (maxPos) *maxPos = MinMax.ptMaxPosition;
701 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
702 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
703}
704/***********************************************************************
705 * WINPOS_SendNCCalcSize
706 *
707 * Send a WM_NCCALCSIZE message to a window.
708 * All parameters are read-only except newClientRect.
709 * oldWindowRect, oldClientRect and winpos must be non-NULL only
710 * when calcValidRect is TRUE.
711 */
712LONG Win32BaseWindow::SendNCCalcSize(BOOL calcValidRect, RECT *newWindowRect, RECT *oldWindowRect,
713 RECT *oldClientRect, WINDOWPOS *winpos,
714 RECT *newClientRect )
715{
716 NCCALCSIZE_PARAMS params;
717 WINDOWPOS winposCopy;
718 LONG result;
719
720 params.rgrc[0] = *newWindowRect;
721 if (calcValidRect)
722 {
723 winposCopy = *winpos;
724 params.rgrc[1] = *oldWindowRect;
725 params.rgrc[2] = *oldClientRect;
726 params.lppos = &winposCopy;
727 }
728 result = SendInternalMessageA(WM_NCCALCSIZE, calcValidRect,
729 (LPARAM)&params );
730 *newClientRect = params.rgrc[0];
731 return result;
732}
733//******************************************************************************
734//******************************************************************************
735ULONG Win32BaseWindow::MsgCreate(HWND hwndOS2, ULONG initParam)
736{
737 OS2Hwnd = hwndOS2;
738 return SendInternalMessageA(WM_CREATE, 0, initParam);
739}
740//******************************************************************************
741//******************************************************************************
742ULONG Win32BaseWindow::MsgQuit()
743{
744 return SendInternalMessageA(WM_QUIT, 0, 0);
745}
746//******************************************************************************
747//******************************************************************************
748ULONG Win32BaseWindow::MsgClose()
749{
750 if(SendInternalMessageA(WM_CLOSE, 0, 0) == 0) {
751 return 0; //app handles this message
752 }
753 delete this;
754 return 1;
755}
756//******************************************************************************
757//******************************************************************************
758ULONG Win32BaseWindow::MsgDestroy()
759{
760 ULONG rc;
761
762 rc = SendInternalMessageA(WM_DESTROY, 0, 0);
763 delete this;
764 return rc;
765}
766//******************************************************************************
767//******************************************************************************
768ULONG Win32BaseWindow::MsgEnable(BOOL fEnable)
769{
770 return SendInternalMessageA(WM_ENABLE, fEnable, 0);
771}
772//******************************************************************************
773//TODO: SW_PARENTCLOSING/OPENING flag (lParam)
774//******************************************************************************
775ULONG Win32BaseWindow::MsgShow(BOOL fShow)
776{
777 return SendInternalMessageA(WM_SHOWWINDOW, fShow, 0);
778}
779//******************************************************************************
780//******************************************************************************
781ULONG Win32BaseWindow::MsgPosChanging(LPARAM lp)
782{
783 dprintf(("MsgPosChanging"));
784#if 1
785 if(fCreated == FALSE) {
786 return 1;
787 }
788#endif
789 return SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, lp);
790}
791//******************************************************************************
792//******************************************************************************
793ULONG Win32BaseWindow::MsgPosChanged(LPARAM lp)
794{
795 dprintf(("MsgPosChanged"));
796#if 1
797 if(fCreated == FALSE) {
798 return 1;
799 }
800#endif
801 return SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, lp);
802}
803//******************************************************************************
804//******************************************************************************
805ULONG Win32BaseWindow::MsgMove(ULONG x, ULONG y)
806{
807 dprintf(("MsgMove to (%d,%d)", x, y));
808 if(fCreated == FALSE) {
809 return 1;
810 }
811
812 return SendInternalMessageA(WM_MOVE, 0, MAKELONG((USHORT)x, (USHORT)y));
813}
814//******************************************************************************
815//******************************************************************************
816ULONG Win32BaseWindow::MsgTimer(ULONG TimerID)
817{
818 // TODO: call TIMERPROC if not NULL
819 return SendInternalMessageA(WM_TIMER, TimerID, 0);
820}
821//******************************************************************************
822//******************************************************************************
823ULONG Win32BaseWindow::MsgCommand(ULONG cmd, ULONG Id, HWND hwnd)
824{
825 switch(cmd) {
826 case CMD_MENU:
827 return SendInternalMessageA(WM_COMMAND, MAKELONG(Id, 0), 0);
828 case CMD_CONTROL:
829 return 0; //todo
830 case CMD_ACCELERATOR:
831 dprintf(("accelerator command"));
832 return 0; //todo
833 }
834 return 0;
835}
836//******************************************************************************
837//******************************************************************************
838ULONG Win32BaseWindow::MsgHitTest(ULONG x, ULONG y)
839{
840 lastHitTestVal = SendInternalMessageA(WM_NCHITTEST, 0, MAKELONG((USHORT)x, (USHORT)y));
841 return 1; //TODO: May need to change this
842}
843//******************************************************************************
844//TODO: Send WM_NCCALCSIZE message here and correct size if necessary
845//******************************************************************************
846ULONG Win32BaseWindow::MsgSize(ULONG width, ULONG height, BOOL fMinimize, BOOL fMaximize)
847{
848 WORD fwSizeType = 0;
849
850 if(fCreated == FALSE) {//Solitaire crashes if it receives a WM_SIZE during CreateWindowEx (normal or our fault?)
851 return 1;
852 }
853
854 if(fMinimize) {
855 fwSizeType = SIZE_MINIMIZED;
856 }
857 else
858 if(fMaximize) {
859 fwSizeType = SIZE_MAXIMIZED;
860 }
861 else fwSizeType = SIZE_RESTORED;
862
863 return SendInternalMessageA(WM_SIZE, fwSizeType, MAKELONG((USHORT)width, (USHORT)height));
864}
865//******************************************************************************
866//******************************************************************************
867ULONG Win32BaseWindow::MsgActivate(BOOL fActivate, HWND hwnd)
868{
869 if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE)
870 {
871 if(!fActivate) {
872 return 1;
873 }
874 }
875 return SendInternalMessageA(WM_ACTIVATE, (fActivate) ? WA_ACTIVE : WA_INACTIVE, hwnd);
876}
877//******************************************************************************
878//******************************************************************************
879ULONG Win32BaseWindow::MsgSysCommand(ULONG win32sc, ULONG x, ULONG y)
880{
881 return SendInternalMessageA(WM_SYSCOMMAND, win32sc, MAKELONG((USHORT)x, (USHORT)y));
882}
883//******************************************************************************
884//TODO: virtual key & (possibly) scancode translation, extended keyboard bit & Unicode
885//******************************************************************************
886ULONG Win32BaseWindow::MsgChar(ULONG cmd, ULONG repeatcnt, ULONG scancode, ULONG vkey, ULONG keyflags)
887{
888 ULONG lParam = 0;
889
890 lParam = repeatcnt;
891 lParam |= (scancode << 16);
892 if(keyflags & KEY_ALTDOWN)
893 lParam |= (1<<29);
894 if(keyflags & KEY_PREVDOWN)
895 lParam |= (1<<30);
896 if(keyflags & KEY_UP)
897 lParam |= (1<<31);
898 if(keyflags & KEY_DEADKEY) {
899 dprintf(("WM_DEADCHAR: %x %x %08x", OS2Hwnd, cmd, lParam));
900 return SendInternalMessageA(WM_DEADCHAR, cmd, lParam);
901 }
902 else {
903 dprintf(("WM_CHAR: %x %x %08x", OS2Hwnd, cmd, lParam));
904 return SendInternalMessageA(WM_CHAR, cmd, lParam);
905 }
906}
907//******************************************************************************
908//******************************************************************************
909ULONG Win32BaseWindow::MsgKeyUp (ULONG repeatCount, ULONG scancode, ULONG virtualKey)
910{
911 ULONG lParam=0;
912
913 lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
914 lParam |= (scancode & 0x0FF) << 16; // bit 16-23, scancode
915 // bit 24, 1=extended key
916 // bit 25-28, reserved
917 lParam |= 0 << 29; // bit 29, key is released, always 0 for WM_KEYUP ?? <- conflict according to the MS docs
918 lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
919 lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
920
921 dprintf(("WM_KEYUP: vkey:(%x) param:(%x)", virtualKey, lParam));
922
923 return SendInternalMessageA (WM_KEYUP, virtualKey, lParam);
924}
925//******************************************************************************
926//******************************************************************************
927ULONG Win32BaseWindow::MsgKeyDown (ULONG repeatCount, ULONG scancode, ULONG virtualKey, BOOL keyWasPressed)
928{
929 ULONG lParam=0;
930
931 lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
932 lParam |= (scancode & 0x0FF) << 16; // bit 16-23, scancode
933 // bit 24, 1=extended key
934 // bit 25-28, reserved
935 // bit 29, key is pressed, always 0 for WM_KEYDOWN ?? <- conflict according to the MS docs
936 if (keyWasPressed)
937 lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
938 // bit 31, transition state, always 0 for WM_KEYDOWN
939
940 dprintf(("WM_KEYDOWN: vkey:(%x) param:(%x)", virtualKey, lParam));
941
942 return SendInternalMessageA (WM_KEYDOWN, virtualKey, lParam);
943}
944//******************************************************************************
945//******************************************************************************
946ULONG Win32BaseWindow::MsgSysKeyUp (ULONG repeatCount, ULONG scancode, ULONG virtualKey)
947{
948 ULONG lParam=0;
949
950 lParam = repeatCount & 0x0FFFF; // bit 0-15,repeatcount
951 lParam |= (scancode & 0x0FF) << 16; // bit 16-23, scancode
952 // bit 24, 1=extended key
953 // bit 25-28, reserved
954 lParam |= 0 << 29; // bit 29, key is released, always 0 for WM_KEYUP ?? <- conflict according to the MS docs
955 lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
956 lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
957
958 dprintf(("WM_SYSKEYUP: vkey:(%x) param:(%x)", virtualKey, lParam));
959
960 return SendInternalMessageA (WM_SYSKEYUP, virtualKey, lParam);
961}
962//******************************************************************************
963//******************************************************************************
964ULONG Win32BaseWindow::MsgSysKeyDown (ULONG repeatCount, ULONG scancode, ULONG virtualKey, BOOL keyWasPressed)
965{
966 ULONG lParam=0;
967
968 lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
969 lParam |= (scancode & 0x0FF) << 16; // bit 16-23, scancode
970 // bit 24, 1=extended key
971 // bit 25-28, reserved
972 // bit 29, key is pressed, always 0 for WM_KEYDOWN ?? <- conflict according to the MS docs
973 if (keyWasPressed)
974 lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
975 // bit 31, transition state, always 0 for WM_KEYDOWN
976
977 dprintf(("WM_SYSKEYDOWN: vkey:(%x) param:(%x)", virtualKey, lParam));
978
979 return SendInternalMessageA (WM_SYSKEYDOWN, virtualKey, lParam);
980}
981//******************************************************************************
982//******************************************************************************
983ULONG Win32BaseWindow::MsgSetFocus(HWND hwnd)
984{
985 if(hwnd == 0) {
986 //other app lost focus
987 SendInternalMessageA(WM_ACTIVATEAPP, TRUE, 0); //TODO: Need thread id from hwnd app
988 }
989 return SendInternalMessageA(WM_SETFOCUS, OS2ToWin32Handle (hwnd), 0);
990}
991//******************************************************************************
992//******************************************************************************
993ULONG Win32BaseWindow::MsgKillFocus(HWND hwnd)
994{
995 if(hwnd == 0) {
996 //other app lost focus
997 SendInternalMessageA(WM_ACTIVATEAPP, FALSE, 0); //TODO: Need thread id from hwnd app
998 }
999 return SendInternalMessageA(WM_KILLFOCUS, OS2ToWin32Handle (hwnd), 0);
1000}
1001//******************************************************************************
1002//******************************************************************************
1003//******************************************************************************
1004ULONG Win32BaseWindow::MsgButton(ULONG msg, ULONG ncx, ULONG ncy, ULONG clx, ULONG cly)
1005{
1006 ULONG win32msg;
1007 ULONG win32ncmsg;
1008
1009 dprintf(("MsgButton to (%d,%d)", ncx, ncy));
1010 switch(msg) {
1011 case BUTTON_LEFTDOWN:
1012 win32msg = WM_LBUTTONDOWN;
1013 win32ncmsg = WM_NCLBUTTONDOWN;
1014 break;
1015 case BUTTON_LEFTUP:
1016 win32msg = WM_LBUTTONUP;
1017 win32ncmsg = WM_NCLBUTTONUP;
1018 break;
1019 case BUTTON_LEFTDBLCLICK:
1020 win32msg = WM_LBUTTONDBLCLK;
1021 win32ncmsg = WM_NCLBUTTONDBLCLK;
1022 break;
1023 case BUTTON_RIGHTUP:
1024 win32msg = WM_RBUTTONUP;
1025 win32ncmsg = WM_NCRBUTTONUP;
1026 break;
1027 case BUTTON_RIGHTDOWN:
1028 win32msg = WM_RBUTTONDOWN;
1029 win32ncmsg = WM_NCRBUTTONDOWN;
1030 break;
1031 case BUTTON_RIGHTDBLCLICK:
1032 win32msg = WM_RBUTTONDBLCLK;
1033 win32ncmsg = WM_NCRBUTTONDBLCLK;
1034 break;
1035 case BUTTON_MIDDLEUP:
1036 win32msg = WM_MBUTTONUP;
1037 win32ncmsg = WM_NCMBUTTONUP;
1038 break;
1039 case BUTTON_MIDDLEDOWN:
1040 win32msg = WM_MBUTTONDOWN;
1041 win32ncmsg = WM_NCMBUTTONDOWN;
1042 break;
1043 case BUTTON_MIDDLEDBLCLICK:
1044 win32msg = WM_MBUTTONDBLCLK;
1045 win32ncmsg = WM_NCMBUTTONDBLCLK;
1046 break;
1047 default:
1048 dprintf(("Win32BaseWindow::Button: invalid msg!!!!"));
1049 return 1;
1050 }
1051 if(win32msg == WM_MBUTTONDBLCLK || win32msg == WM_RBUTTONDBLCLK || win32msg == WM_LBUTTONDBLCLK) {
1052 if(!(windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS)) {
1053 return 1;
1054 }
1055 }
1056 SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, win32ncmsg));
1057
1058 //WM_NC*BUTTON* is posted when the cursor is in a non-client area of the window
1059 if(lastHitTestVal != HTCLIENT) {
1060 SendInternalMessageA(win32ncmsg, lastHitTestVal, MAKELONG(ncx, ncy)); //TODO:
1061 }
1062 return SendInternalMessageA(win32msg, 0, MAKELONG(clx, cly));
1063}
1064//******************************************************************************
1065//******************************************************************************
1066ULONG Win32BaseWindow::MsgMouseMove(ULONG keystate, ULONG x, ULONG y)
1067{
1068 ULONG winstate = 0;
1069 ULONG setcursormsg = WM_MOUSEMOVE;
1070
1071 if(keystate & WMMOVE_LBUTTON)
1072 winstate |= MK_LBUTTON;
1073 if(keystate & WMMOVE_RBUTTON)
1074 winstate |= MK_RBUTTON;
1075 if(keystate & WMMOVE_MBUTTON)
1076 winstate |= MK_MBUTTON;
1077 if(keystate & WMMOVE_SHIFT)
1078 winstate |= MK_SHIFT;
1079 if(keystate & WMMOVE_CTRL)
1080 winstate |= MK_CONTROL;
1081
1082 if(lastHitTestVal != HTCLIENT) {
1083 setcursormsg = WM_NCMOUSEMOVE;
1084 }
1085 //TODO: hiword should be 0 if window enters menu mode (SDK docs)
1086 SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, setcursormsg));
1087
1088 //WM_NCMOUSEMOVE is posted when the cursor moves into a non-client area of the window
1089 if(lastHitTestVal != HTCLIENT) {
1090 SendInternalMessageA(WM_NCMOUSEMOVE, lastHitTestVal, MAKELONG(x, y));
1091 }
1092 return SendInternalMessageA(WM_MOUSEMOVE, keystate, MAKELONG(x, y));
1093}
1094//******************************************************************************
1095//******************************************************************************
1096ULONG Win32BaseWindow::MsgPaint(ULONG tmp1, BOOL select)
1097{
1098 if (select && isIcon)
1099 return SendInternalMessageA(WM_PAINTICON, 0, 0);
1100 else
1101 return SendInternalMessageA(WM_PAINT, 0, 0);
1102}
1103//******************************************************************************
1104//TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
1105// (or are we simply erasing too much here)
1106//******************************************************************************
1107ULONG Win32BaseWindow::MsgEraseBackGround(HDC hdc)
1108{
1109 ULONG rc;
1110 HDC hdcErase = hdc;
1111
1112 if (hdcErase == 0)
1113 hdcErase = O32_GetDC(OS2Hwnd);
1114
1115 if(isIcon)
1116 rc = SendInternalMessageA(WM_ICONERASEBKGND, hdcErase, 0);
1117 else
1118 rc = SendInternalMessageA(WM_ERASEBKGND, hdcErase, 0);
1119 if (hdc == 0)
1120 O32_ReleaseDC(OS2Hwnd, hdcErase);
1121 return (rc);
1122}
1123//******************************************************************************
1124//******************************************************************************
1125ULONG Win32BaseWindow::MsgSetText(LPSTR lpsz, LONG cch)
1126{
1127 if(isUnicode) {
1128 return SendInternalMessageW(WM_SETTEXT, 0, (LPARAM)lpsz);
1129 }
1130 else return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
1131}
1132//******************************************************************************
1133//TODO: in- or excluding terminating 0?
1134//******************************************************************************
1135ULONG Win32BaseWindow::MsgGetTextLength()
1136{
1137 return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
1138}
1139//******************************************************************************
1140//******************************************************************************
1141char *Win32BaseWindow::MsgGetText()
1142{
1143 if(isUnicode) {
1144 SendInternalMessageW(WM_GETTEXT, wndNameLength, (LPARAM)windowNameW);
1145 }
1146 else {
1147 SendInternalMessageA(WM_GETTEXT, wndNameLength, (LPARAM)windowNameA);
1148 }
1149 return windowNameA;
1150}
1151//******************************************************************************
1152//******************************************************************************
1153LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
1154{
1155 switch(Msg)
1156 {
1157 case WM_GETTEXTLENGTH:
1158 return wndNameLength;
1159
1160 case WM_GETTEXT: //TODO: SS_ICON controls
1161 strncpy((LPSTR)lParam, windowNameA, wParam);
1162 return min(wndNameLength, wParam);
1163
1164 case WM_SETTEXT:
1165 return 0;
1166
1167 case WM_SETREDRAW:
1168 if(wParam)
1169 SetWindowLongA (GWL_STYLE, GetWindowLongA (GWL_STYLE) | WS_VISIBLE);
1170 else SetWindowLongA (GWL_STYLE, GetWindowLongA (GWL_STYLE) & ~WS_VISIBLE);
1171
1172 return 0; //TODO
1173
1174 case WM_NCCREATE:
1175 return(TRUE);
1176
1177 //SvL: Set background color to default button color (not window (white))
1178 case WM_CTLCOLORBTN:
1179 SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE));
1180 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
1181 return GetSysColorBrush(COLOR_BTNFACE);
1182
1183 //SvL: Set background color to default dialog color if window is dialog
1184 case WM_CTLCOLORDLG:
1185 case WM_CTLCOLORSTATIC:
1186 if(IsDialog()) {
1187 SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE));
1188 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
1189 return GetSysColorBrush(COLOR_BTNFACE);
1190 }
1191 //no break
1192
1193 case WM_CTLCOLORMSGBOX:
1194 case WM_CTLCOLOREDIT:
1195 case WM_CTLCOLORLISTBOX:
1196 case WM_CTLCOLORSCROLLBAR:
1197 SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
1198 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
1199 return GetSysColorBrush(COLOR_BTNFACE);
1200
1201 case WM_PARENTNOTIFY:
1202 return 0;
1203
1204 case WM_MOUSEACTIVATE:
1205 {
1206 DWORD dwStyle = GetWindowLongA(GWL_STYLE);
1207 DWORD dwExStyle = GetWindowLongA(GWL_EXSTYLE);
1208 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1209 if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
1210 {
1211 if(getParent()) {
1212 LRESULT rc = getParent()->SendMessageA(WM_MOUSEACTIVATE, wParam, lParam );
1213 if(rc) return rc;
1214 }
1215 }
1216 return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
1217 }
1218 case WM_SETCURSOR:
1219 {
1220 DWORD dwStyle = GetWindowLongA(GWL_STYLE);
1221 DWORD dwExStyle = GetWindowLongA(GWL_EXSTYLE);
1222 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1223 if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
1224 {
1225 if(getParent()) {
1226 LRESULT rc = getParent()->SendMessageA(WM_SETCURSOR, wParam, lParam);
1227 if(rc) return rc;
1228 }
1229 }
1230 return 1;
1231 }
1232 case WM_MOUSEMOVE:
1233 return 0;
1234
1235 case WM_WINDOWPOSCHANGED:
1236 {
1237
1238/* undocumented SWP flags - from SDK 3.1 */
1239#define SWP_NOCLIENTSIZE 0x0800
1240#define SWP_NOCLIENTMOVE 0x1000
1241
1242 PWINDOWPOS wpos = (PWINDOWPOS)lParam;
1243 WPARAM wp = SIZE_RESTORED;
1244
1245 if (!(wpos->flags & SWP_NOCLIENTMOVE))
1246 SendMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
1247
1248 if (!(wpos->flags & SWP_NOCLIENTSIZE))
1249 {
1250 if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
1251 else if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
1252
1253 SendMessageA(WM_SIZE, wp, MAKELONG(rectClient.right - rectClient.left,
1254 rectClient.bottom - rectClient.top));
1255 }
1256 return 0;
1257 }
1258 case WM_ERASEBKGND:
1259 case WM_ICONERASEBKGND:
1260 {
1261 RECT rect;
1262 int rc;
1263
1264 if (!windowClass->getBackgroundBrush()) return 0;
1265
1266 rc = GetClipBox( (HDC)wParam, &rect );
1267 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
1268 FillRect( (HDC)wParam, &rect, windowClass->getBackgroundBrush());
1269
1270 return 1;
1271 }
1272 case WM_GETDLGCODE:
1273 return 0;
1274
1275 case WM_NCLBUTTONDOWN:
1276 case WM_NCLBUTTONUP:
1277 case WM_NCLBUTTONDBLCLK:
1278 case WM_NCRBUTTONUP:
1279 case WM_NCRBUTTONDOWN:
1280 case WM_NCRBUTTONDBLCLK:
1281 case WM_NCMBUTTONDOWN:
1282 case WM_NCMBUTTONUP:
1283 case WM_NCMBUTTONDBLCLK:
1284 return 0; //TODO: Send WM_SYSCOMMAND if required
1285
1286 case WM_NCHITTEST: //TODO: Calculate position of
1287 return HTCLIENT;
1288
1289 default:
1290 return 1;
1291 }
1292}
1293//******************************************************************************
1294//******************************************************************************
1295LRESULT Win32BaseWindow::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
1296{
1297 switch(Msg)
1298 {
1299 case WM_GETTEXTLENGTH:
1300 return wndNameLength;
1301
1302 case WM_GETTEXT: //TODO: SS_ICON controls
1303 lstrcpynW((LPWSTR)lParam, windowNameW, wParam);
1304 return min(wndNameLength, wParam);
1305
1306 default:
1307 return DefWindowProcA(Msg, wParam, lParam);
1308 }
1309}
1310//******************************************************************************
1311//******************************************************************************
1312LRESULT Win32BaseWindow::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1313{
1314 if(Msg != WM_GETDLGCODE && Msg != WM_ENTERIDLE) {//sent *very* often
1315 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1316 dprintf(("SendMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1317 }
1318
1319 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1320 return(0);
1321 }
1322 switch(Msg)
1323 {
1324 case WM_CREATE:
1325 {
1326 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
1327 dprintf(("WM_CREATE returned -1\n"));
1328 return(-1); //don't create window
1329 }
1330 NotifyParent(Msg, wParam, lParam);
1331
1332 return(0);
1333 }
1334 case WM_SETTEXT: //TODO: Nothing happens if passed to DefWindowProc
1335 return win32wndproc(getWindowHandle(), WM_SETTEXT, wParam, lParam);
1336
1337 case WM_LBUTTONDOWN:
1338 case WM_MBUTTONDOWN:
1339 case WM_RBUTTONDOWN:
1340 NotifyParent(Msg, wParam, lParam);
1341 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1342
1343 case WM_DESTROY:
1344 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1345 NotifyParent(Msg, wParam, lParam);
1346 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1347 default:
1348 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1349 }
1350}
1351//******************************************************************************
1352//******************************************************************************
1353LRESULT Win32BaseWindow::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
1354{
1355 if(Msg != WM_GETDLGCODE && Msg != WM_ENTERIDLE) {//sent *very* often
1356 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1357 dprintf(("SendMessageW %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1358 }
1359
1360 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1361 return(0);
1362 }
1363 switch(Msg)
1364 {
1365 case WM_CREATE:
1366 {
1367 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
1368 dprintf(("WM_CREATE returned FALSE\n"));
1369 return(0); //don't create window
1370 }
1371 NotifyParent(Msg, wParam, lParam);
1372
1373 return(1);
1374 }
1375 case WM_SETTEXT: //TODO: Nothing happens if passed to DefWindowProc
1376 return win32wndproc(getWindowHandle(), WM_SETTEXT, wParam, lParam);
1377
1378 case WM_LBUTTONDOWN:
1379 case WM_MBUTTONDOWN:
1380 case WM_RBUTTONDOWN:
1381 NotifyParent(Msg, wParam, lParam);
1382 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1383
1384 case WM_DESTROY:
1385 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1386 NotifyParent(Msg, wParam, lParam);
1387 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1388
1389 default:
1390 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1391 }
1392}
1393//******************************************************************************
1394//Called as a result of an OS/2 message
1395//******************************************************************************
1396LRESULT Win32BaseWindow::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1397{
1398 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1399 dprintf(("SendInternalMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1400
1401 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1402 return(0);
1403 }
1404 switch(Msg)
1405 {
1406 case WM_CREATE:
1407 {
1408 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
1409 dprintf(("WM_CREATE returned FALSE\n"));
1410 return(0); //don't create window
1411 }
1412 NotifyParent(Msg, wParam, lParam);
1413
1414 return(1);
1415 }
1416 case WM_LBUTTONDOWN:
1417 case WM_MBUTTONDOWN:
1418 case WM_RBUTTONDOWN:
1419 NotifyParent(Msg, wParam, lParam);
1420 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1421
1422 case WM_DESTROY:
1423 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1424 NotifyParent(Msg, wParam, lParam);
1425 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1426 default:
1427 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1428 }
1429}
1430//******************************************************************************
1431//Called as a result of an OS/2 message
1432//todo, unicode msgs (WM_SETTEXT etc)
1433//******************************************************************************
1434LRESULT Win32BaseWindow::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
1435{
1436 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1437 dprintf(("SendInternalMessageW %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1438
1439 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1440 return(0);
1441 }
1442 switch(Msg)
1443 {
1444 case WM_CREATE:
1445 {
1446 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
1447 dprintf(("WM_CREATE returned FALSE\n"));
1448 return(0); //don't create window
1449 }
1450 NotifyParent(Msg, wParam, lParam);
1451
1452 return(1);
1453 }
1454 case WM_LBUTTONDOWN:
1455 case WM_MBUTTONDOWN:
1456 case WM_RBUTTONDOWN:
1457 NotifyParent(Msg, wParam, lParam);
1458 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1459
1460 case WM_DESTROY:
1461 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1462 NotifyParent(Msg, wParam, lParam);
1463 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1464 default:
1465 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1466 }
1467}
1468//******************************************************************************
1469//******************************************************************************
1470BOOL Win32BaseWindow::PostMessageA(ULONG msg, WPARAM wParam, LPARAM lParam)
1471{
1472 return OSLibPostMessage(OS2Hwnd, WIN32APP_USERMSGBASE+msg, wParam, lParam);
1473}
1474//******************************************************************************
1475//******************************************************************************
1476BOOL Win32BaseWindow::PostMessageW(ULONG msg, WPARAM wParam, LPARAM lParam)
1477{
1478 return OSLibPostMessage(OS2Hwnd, WIN32APP_USERMSGBASE+msg, wParam, lParam);
1479}
1480//******************************************************************************
1481//TODO: do we need to inform the parent of the parent (etc) of the child window?
1482//******************************************************************************
1483void Win32BaseWindow::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
1484{
1485 Win32BaseWindow *window = this;
1486 Win32BaseWindow *parentwindow;
1487
1488 while(window)
1489 {
1490 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
1491 {
1492 /* Notify the parent window only */
1493 parentwindow = window->getParent();
1494 if(parentwindow) {
1495 if(Msg == WM_CREATE || Msg == WM_DESTROY) {
1496 parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), (LPARAM)window->getWindowHandle());
1497 }
1498 else parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), lParam );
1499 }
1500 }
1501 else break;
1502
1503 window = parentwindow;
1504 }
1505}
1506//******************************************************************************
1507//******************************************************************************
1508Win32BaseWindow *Win32BaseWindow::getTopParent()
1509{
1510 Win32BaseWindow *tmpWnd = this;
1511
1512 while( tmpWnd && (tmpWnd->getStyle() & WS_CHILD))
1513 {
1514 tmpWnd = tmpWnd->getParent();
1515 }
1516 return tmpWnd;
1517}
1518//******************************************************************************
1519//******************************************************************************
1520BOOL Win32BaseWindow::SetMenu(HMENU hMenu)
1521{
1522 PVOID menutemplate;
1523 Win32Resource *winres = (Win32Resource *)hMenu;
1524
1525 dprintf(("SetMenu %x", hMenu));
1526 if(HIWORD(winres) == 0) {
1527 dprintf(("Win32BaseWindow:: Win32Resource *winres == 0"));
1528 SetLastError(ERROR_INVALID_PARAMETER);
1529 return FALSE;
1530 }
1531 menutemplate = winres->lockOS2Resource();
1532 if(menutemplate == NULL)
1533 {
1534 dprintf(("Win32BaseWindow::SetMenu menutemplate == 0"));
1535 return FALSE;
1536 }
1537 OS2HwndMenu = OSLibWinCreateMenu(OS2HwndFrame, menutemplate);
1538 if(OS2HwndMenu == 0) {
1539 dprintf(("Win32BaseWindow::SetMenu OS2HwndMenu == 0"));
1540 return FALSE;
1541 }
1542 winres->setOS2Handle(OS2HwndMenu);
1543 menuResource = winres;
1544 return TRUE;
1545}
1546//******************************************************************************
1547//******************************************************************************
1548BOOL Win32BaseWindow::SetAccelTable(HACCEL hAccel)
1549{
1550 Win32Resource *winres = (Win32Resource *)hAccel;
1551 HANDLE accelhandle;
1552
1553 if(HIWORD(hAccel) == 0) {
1554 dprintf(("SetAccelTable: hAccel %x invalid", hAccel));
1555 SetLastError(ERROR_INVALID_PARAMETER);
1556 return FALSE;
1557 }
1558 acceltableResource = winres;
1559 accelhandle = OSLibWinSetAccelTable(OS2HwndFrame, winres->getOS2Handle(), winres->lockOS2Resource());
1560 winres->setOS2Handle(accelhandle);
1561 return(accelhandle != 0);
1562}
1563//******************************************************************************
1564//******************************************************************************
1565BOOL Win32BaseWindow::SetIcon(HICON hIcon)
1566{
1567 dprintf(("Win32BaseWindow::SetIcon %x", hIcon));
1568 if(OSLibWinSetIcon(OS2HwndFrame, hIcon) == TRUE) {
1569 SendInternalMessageA(WM_SETICON, hIcon, 0);
1570 return TRUE;
1571 }
1572 return FALSE;
1573}
1574//******************************************************************************
1575//******************************************************************************
1576BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
1577{
1578 ULONG showstate = 0;
1579
1580 dprintf(("ShowWindow %x", nCmdShow));
1581 if(fFirstShow) {
1582 if(isFrameWindow() && IS_OVERLAPPED(getStyle())) {
1583 SendMessageA(WM_SIZE, SIZE_RESTORED,
1584 MAKELONG(rectClient.right-rectClient.left,
1585 rectClient.bottom-rectClient.top));
1586 SendMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
1587
1588 }
1589 fFirstShow = FALSE;
1590 }
1591 switch(nCmdShow)
1592 {
1593 case SW_SHOW:
1594 case SW_SHOWDEFAULT: //todo
1595 showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
1596 break;
1597 case SW_HIDE:
1598 showstate = SWPOS_HIDE;
1599 break;
1600 case SW_RESTORE:
1601 showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
1602 break;
1603 case SW_MINIMIZE:
1604 showstate = SWPOS_MINIMIZE;
1605 break;
1606 case SW_SHOWMAXIMIZED:
1607 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
1608 break;
1609 case SW_SHOWMINIMIZED:
1610 showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
1611 break;
1612 case SW_SHOWMINNOACTIVE:
1613 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
1614 break;
1615 case SW_SHOWNA:
1616 showstate = SWPOS_SHOW;
1617 break;
1618 case SW_SHOWNOACTIVATE:
1619 showstate = SWPOS_SHOW;
1620 break;
1621 case SW_SHOWNORMAL:
1622 showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
1623 break;
1624 }
1625 return OSLibWinShowWindow(OS2HwndFrame, showstate);
1626}
1627//******************************************************************************
1628//******************************************************************************
1629BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
1630{
1631 BOOL rc = FALSE;
1632 Win32BaseWindow *window;
1633 HWND hParent = 0;
1634
1635 dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
1636
1637 if (fuFlags &
1638 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
1639 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
1640 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
1641 SWP_NOOWNERZORDER))
1642 {
1643 return FALSE;
1644 }
1645
1646 WINDOWPOS wpos;
1647 SWP swp, swpOld;
1648
1649 wpos.flags = fuFlags;
1650 wpos.cy = cy;
1651 wpos.cx = cx;
1652 wpos.x = x;
1653 wpos.y = y;
1654 wpos.hwndInsertAfter = hwndInsertAfter;
1655 wpos.hwnd = getWindowHandle();
1656
1657 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE)) {
1658 if (isChild())
1659 {
1660 hParent = getParent()->getOS2WindowHandle();
1661 OSLibWinQueryWindowPos(OS2Hwnd, &swpOld);
1662 } else
1663 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
1664 }
1665
1666 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
1667 if (swp.fl == 0)
1668 return TRUE;
1669
1670 if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
1671 {
1672 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
1673 swp.hwndInsertBehind = wndBehind->getOS2WindowHandle();
1674 }
1675 if (isFrameWindow())
1676 {
1677 POINT maxSize, maxPos, minTrack, maxTrack;
1678
1679 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
1680
1681 if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
1682 if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
1683 if (swp.cx < minTrack.x) swp.cx = minTrack.x;
1684 if (swp.cy < minTrack.y) swp.cy = minTrack.y;
1685 swp.hwnd = OS2HwndFrame;
1686 } else
1687 swp.hwnd = OS2Hwnd;
1688 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
1689
1690 rc = OSLibWinSetMultWindowPos(&swp, 1);
1691
1692 if (rc == FALSE)
1693 {
1694// SET_ERROR_LAST();
1695 }
1696 else
1697 {
1698 if (fuFlags & SWP_FRAMECHANGED_W)
1699 OSLibSendMessage (OS2HwndFrame, 0x42 /*WM_UPDATEFRAME*/, -1, 0);
1700 }
1701
1702 return (rc);
1703}
1704//******************************************************************************
1705//Also destroys all the child windows (destroy parent, destroy children)
1706//******************************************************************************
1707BOOL Win32BaseWindow::DestroyWindow()
1708{
1709 return OSLibWinDestroyWindow(OS2HwndFrame);
1710}
1711//******************************************************************************
1712//******************************************************************************
1713HWND Win32BaseWindow::GetParent()
1714{
1715 if(getParent()) {
1716 return getParent()->getWindowHandle();
1717 }
1718 else return 0;
1719}
1720//******************************************************************************
1721//******************************************************************************
1722HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
1723{
1724 HWND oldhwnd;
1725 Win32BaseWindow *newparent;
1726
1727 if(getParent()) {
1728 oldhwnd = getParent()->getWindowHandle();
1729 getParent()->RemoveChild(this);
1730 }
1731 else oldhwnd = 0;
1732
1733 if(hwndNewParent == 0) {//desktop window = parent
1734 setParent(NULL);
1735 OSLibWinSetParent(getOS2WindowHandle(), OSLIB_HWND_DESKTOP);
1736 return oldhwnd;
1737 }
1738 newparent = GetWindowFromHandle(hwndNewParent);
1739 if(newparent)
1740 {
1741 setParent(newparent);
1742 getParent()->AddChild(this);
1743 OSLibWinSetParent(getOS2WindowHandle(), getParent()->getOS2WindowHandle());
1744 return oldhwnd;
1745 }
1746 SetLastError(ERROR_INVALID_PARAMETER);
1747 return 0;
1748}
1749//******************************************************************************
1750//******************************************************************************
1751BOOL Win32BaseWindow::IsChild(HWND hwndParent)
1752{
1753 if(getParent()) {
1754 return getParent()->getWindowHandle() == hwndParent;
1755 }
1756 else return 0;
1757}
1758//******************************************************************************
1759//******************************************************************************
1760HWND Win32BaseWindow::GetTopWindow()
1761{
1762 return GetWindow(GW_CHILD);
1763}
1764//******************************************************************************
1765//Don't call WinUpdateWindow as that one also updates the child windows
1766//Also need to send WM_PAINT directly to the window procedure, which doesn't
1767//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
1768//******************************************************************************
1769BOOL Win32BaseWindow::UpdateWindow()
1770{
1771 RECT rect;
1772
1773 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
1774 {//update region not empty
1775 HDC hdc;
1776
1777 hdc = O32_GetDC(OS2Hwnd);
1778 if (isIcon)
1779 {
1780 SendInternalMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
1781 SendInternalMessageA(WM_PAINTICON, 0, 0);
1782 } else
1783 {
1784 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
1785 SendInternalMessageA(WM_PAINT, 0, 0);
1786 }
1787 O32_ReleaseDC(OS2Hwnd, hdc);
1788 }
1789 return TRUE;
1790}
1791//******************************************************************************
1792//******************************************************************************
1793BOOL Win32BaseWindow::IsIconic()
1794{
1795 return OSLibWinIsIconic(OS2Hwnd);
1796}
1797//******************************************************************************
1798//TODO:
1799//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
1800//the current process owns them.
1801//******************************************************************************
1802HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
1803 BOOL fUnicode)
1804{
1805 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
1806 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
1807
1808 if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
1809 (hwndChildAfter != 0 && !child) ||
1810 (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
1811 {
1812 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
1813 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1814 return 0;
1815 }
1816 if(hwndParent != OSLIB_HWND_DESKTOP)
1817 {//if the current process owns the window, just do a quick search
1818 child = (Win32BaseWindow *)parent->getFirstChild();
1819 if(hwndChildAfter != 0)
1820 {
1821 while(child)
1822 {
1823 if(child->getWindowHandle() == hwndChildAfter)
1824 {
1825 child = (Win32BaseWindow *)child->getNextChild();
1826 break;
1827 }
1828 child = (Win32BaseWindow *)child->getNextChild();
1829 }
1830 }
1831 while(child)
1832 {
1833 if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
1834 (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
1835 {
1836 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
1837 return child->getWindowHandle();
1838 }
1839 child = (Win32BaseWindow *)child->getNextChild();
1840 }
1841 }
1842 else {
1843 Win32BaseWindow *wnd;
1844 HWND henum, hwnd;
1845
1846 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
1847 hwnd = OSLibWinGetNextWindow(henum);
1848
1849 while(hwnd)
1850 {
1851 wnd = GetWindowFromOS2Handle(hwnd);
1852 if(wnd == NULL) {
1853 hwnd = OSLibWinQueryClientWindow(hwnd);
1854 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
1855 }
1856
1857 if(wnd) {
1858 LPVOID sharedmembase = (LPVOID)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_SHAREDMEM);
1859
1860 if(OSLibDosGetSharedMem(sharedmembase, MAX_HEAPSIZE, OSLIB_PAG_READ) != 0) {
1861 dprintf(("OSLibDosGetSharedMem returned error for %x", wnd));
1862 break;
1863 }
1864 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
1865 (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
1866 {
1867 OSLibWinEndEnumWindows(henum);
1868 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
1869 return wnd->getWindowHandle();
1870 }
1871 }
1872 hwnd = OSLibWinGetNextWindow(henum);
1873 }
1874 OSLibWinEndEnumWindows(henum);
1875 }
1876 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
1877 return 0;
1878}
1879//******************************************************************************
1880//TODO: not complete nor correct (distinction be tween top-level, top-most & child windows)
1881//******************************************************************************
1882HWND Win32BaseWindow::GetWindow(UINT uCmd)
1883{
1884 Win32BaseWindow *win32wnd;
1885 ULONG magic;
1886 ULONG getcmd = 0;
1887 HWND hwndRelated;
1888
1889 dprintf(("GetWindow %x %d NOT COMPLETE", getWindowHandle(), uCmd));
1890 switch(uCmd)
1891 {
1892 case GW_CHILD:
1893 getcmd = QWOS_TOP;
1894 break;
1895 case GW_HWNDFIRST:
1896 if(getParent()) {
1897 getcmd = QWOS_TOP; //top of child windows
1898 }
1899 else getcmd = QWOS_TOP; //TODO
1900 break;
1901 case GW_HWNDLAST:
1902 if(getParent()) {
1903 getcmd = QWOS_BOTTOM; //bottom of child windows
1904 }
1905 else getcmd = QWOS_BOTTOM; //TODO
1906 break;
1907 case GW_HWNDNEXT:
1908 getcmd = QWOS_NEXT;
1909 break;
1910 case GW_HWNDPREV:
1911 getcmd = QWOS_PREV;
1912 break;
1913 case GW_OWNER:
1914 if(owner) {
1915 return owner->getWindowHandle();
1916 }
1917 else return 0;
1918 }
1919 hwndRelated = OSLibWinQueryWindow(OS2Hwnd, getcmd);
1920 if(hwndRelated)
1921 {
1922 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32WNDPTR);
1923 magic = OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32PM_MAGIC);
1924 if(CheckMagicDword(magic) && win32wnd)
1925 {
1926 return win32wnd->getWindowHandle();
1927 }
1928 }
1929 return 0;
1930}
1931//******************************************************************************
1932//******************************************************************************
1933HWND Win32BaseWindow::SetActiveWindow()
1934{
1935 return OSLibWinSetActiveWindow(OS2Hwnd);
1936}
1937//******************************************************************************
1938//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
1939//******************************************************************************
1940BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
1941{
1942 return OSLibWinEnableWindow(OS2Hwnd, fEnable);
1943}
1944//******************************************************************************
1945//******************************************************************************
1946BOOL Win32BaseWindow::CloseWindow()
1947{
1948 return OSLibWinMinimizeWindow(OS2Hwnd);
1949}
1950//******************************************************************************
1951//******************************************************************************
1952HWND Win32BaseWindow::GetActiveWindow()
1953{
1954 HWND hwndActive;
1955 Win32BaseWindow *win32wnd;
1956 ULONG magic;
1957
1958 hwndActive = OSLibWinQueryActiveWindow();
1959
1960 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
1961 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
1962 if(CheckMagicDword(magic) && win32wnd)
1963 {
1964 return win32wnd->getWindowHandle();
1965 }
1966 return hwndActive;
1967}
1968//******************************************************************************
1969//******************************************************************************
1970BOOL Win32BaseWindow::IsWindowEnabled()
1971{
1972 return OSLibWinIsWindowEnabled(OS2Hwnd);
1973}
1974//******************************************************************************
1975//******************************************************************************
1976BOOL Win32BaseWindow::IsWindowVisible()
1977{
1978 return OSLibWinIsWindowVisible(OS2Hwnd);
1979}
1980//******************************************************************************
1981//******************************************************************************
1982BOOL Win32BaseWindow::GetWindowRect(PRECT pRect)
1983{
1984 return OSLibWinQueryWindowRect(OS2Hwnd, pRect, RELATIVE_TO_SCREEN);
1985}
1986//******************************************************************************
1987//******************************************************************************
1988BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
1989{
1990 if(fUnicode) {
1991 return (lstrcmpW(windowNameW, (LPWSTR)wndname) == 0);
1992 }
1993 else return (strcmp(windowNameA, wndname) == 0);
1994}
1995//******************************************************************************
1996//******************************************************************************
1997int Win32BaseWindow::GetWindowTextLength()
1998{
1999 return wndNameLength;
2000}
2001//******************************************************************************
2002//******************************************************************************
2003int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
2004{
2005 strncpy(lpsz, windowNameA, cch);
2006 return wndNameLength;
2007}
2008//******************************************************************************
2009//******************************************************************************
2010int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
2011{
2012 lstrcpynW((LPWSTR)lpsz, windowNameW, cch);
2013 return wndNameLength;
2014}
2015//******************************************************************************
2016//******************************************************************************
2017BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
2018{
2019 if(lpsz == NULL)
2020 return FALSE;
2021
2022 windowNameA = (LPSTR)_smalloc(strlen(lpsz)+1);
2023 strcpy(windowNameA, lpsz);
2024 windowNameW = (LPWSTR)_smalloc((strlen(lpsz)+1)*sizeof(WCHAR));
2025 lstrcpyAtoW(windowNameW, windowNameA);
2026 wndNameLength = strlen(windowNameA)+1; //including 0 terminator
2027
2028 if(OS2HwndFrame)
2029 return OSLibWinSetWindowText(OS2HwndFrame, (LPSTR)windowNameA);
2030
2031 return TRUE;
2032}
2033//******************************************************************************
2034//******************************************************************************
2035BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
2036{
2037 if(lpsz == NULL)
2038 return FALSE;
2039
2040 windowNameW = (LPWSTR)_smalloc((lstrlenW((LPWSTR)lpsz)+1)*sizeof(WCHAR));
2041 lstrcpyW(windowNameW, (LPWSTR)lpsz);
2042 windowNameA = (LPSTR)_smalloc(lstrlenW((LPWSTR)lpsz)+1);
2043 lstrcpyWtoA(windowNameA, windowNameW);
2044 wndNameLength = strlen(windowNameA)+1; //including 0 terminator
2045
2046 if(OS2HwndFrame)
2047 return OSLibWinSetWindowText(OS2HwndFrame, (LPSTR)windowNameA);
2048
2049 return TRUE;
2050}
2051//******************************************************************************
2052//******************************************************************************
2053LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value)
2054{
2055 LONG oldval;
2056
2057 switch(index) {
2058 case GWL_EXSTYLE:
2059 oldval = dwExStyle;
2060 setExStyle(value);
2061 return oldval;
2062 case GWL_STYLE:
2063 oldval = dwStyle;
2064 setStyle(value);
2065 return oldval;
2066 case GWL_WNDPROC:
2067 oldval = (LONG)getWindowProc();
2068 setWindowProc((WNDPROC)value);
2069 return oldval;
2070 case GWL_HINSTANCE:
2071 oldval = hInstance;
2072 hInstance = value;
2073 return oldval;
2074 case GWL_HWNDPARENT:
2075 return SetParent((HWND)value);
2076
2077 case GWL_ID:
2078 oldval = getWindowId();
2079 setWindowId(value);
2080 return oldval;
2081 case GWL_USERDATA:
2082 oldval = userData;
2083 userData = value;
2084 return oldval;
2085 default:
2086 if(index >= 0 && index/4 < nrUserWindowLong)
2087 {
2088 oldval = userWindowLong[index/4];
2089 userWindowLong[index/4] = value;
2090 return oldval;
2091 }
2092 SetLastError(ERROR_INVALID_PARAMETER);
2093 return 0;
2094 }
2095}
2096//******************************************************************************
2097//******************************************************************************
2098ULONG Win32BaseWindow::GetWindowLongA(int index)
2099{
2100 switch(index) {
2101 case GWL_EXSTYLE:
2102 return dwExStyle;
2103 case GWL_STYLE:
2104 return dwStyle;
2105 case GWL_WNDPROC:
2106 return (ULONG)getWindowProc();
2107 case GWL_HINSTANCE:
2108 return hInstance;
2109 case GWL_HWNDPARENT:
2110 if(getParent()) {
2111 return getParent()->getWindowHandle();
2112 }
2113 else return 0;
2114 case GWL_ID:
2115 return getWindowId();
2116 case GWL_USERDATA:
2117 return userData;
2118 default:
2119 if(index >= 0 && index/4 < nrUserWindowLong)
2120 {
2121 return userWindowLong[index/4];
2122 }
2123 SetLastError(ERROR_INVALID_PARAMETER);
2124 return 0;
2125 }
2126}
2127//******************************************************************************
2128//******************************************************************************
2129WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
2130{
2131 WORD oldval;
2132
2133 if(index >= 0 && index/4 < nrUserWindowLong)
2134 {
2135 oldval = ((WORD *)userWindowLong)[index/2];
2136 ((WORD *)userWindowLong)[index/2] = value;
2137 return oldval;
2138 }
2139 SetLastError(ERROR_INVALID_PARAMETER);
2140 return 0;
2141}
2142//******************************************************************************
2143//******************************************************************************
2144WORD Win32BaseWindow::GetWindowWord(int index)
2145{
2146 if(index >= 0 && index/4 < nrUserWindowLong)
2147 {
2148 return ((WORD *)userWindowLong)[index/2];
2149 }
2150 SetLastError(ERROR_INVALID_PARAMETER);
2151 return 0;
2152}
2153//******************************************************************************
2154//******************************************************************************
2155Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
2156{
2157 Win32BaseWindow *window;
2158
2159 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
2160 return window;
2161 }
2162 else return NULL;
2163}
2164//******************************************************************************
2165//******************************************************************************
2166Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
2167{
2168 Win32BaseWindow *win32wnd;
2169 DWORD magic;
2170
2171 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
2172 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
2173
2174 if(win32wnd && CheckMagicDword(magic)) {
2175 return win32wnd;
2176 }
2177 return 0;
2178}
2179//******************************************************************************
2180//******************************************************************************
2181HWND Win32BaseWindow::Win32ToOS2Handle(HWND hwnd)
2182{
2183 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
2184
2185 if(window) {
2186 return window->getOS2WindowHandle();
2187 }
2188 else return hwnd; //OS/2 window handle
2189}
2190//******************************************************************************
2191//******************************************************************************
2192HWND Win32BaseWindow::OS2ToWin32Handle(HWND hwnd)
2193{
2194 Win32BaseWindow *window = GetWindowFromOS2Handle(hwnd);
2195
2196 if(window) {
2197 return window->getWindowHandle();
2198 }
2199 else return hwnd; //OS/2 window handle
2200}
2201//******************************************************************************
2202//******************************************************************************
2203GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.