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

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

Menu changes

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