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

Last change on this file since 1046 was 1046, checked in by cbratschi, 26 years ago

WS_EX_* 3D frames for child windows

File size: 76.8 KB
Line 
1/* $Id: win32wbase.cpp,v 1.12 1999-09-25 15:10:00 cbratschi 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_3DFRAME(exStyle) \
50 ((exStyle & WS_EX_CLIENTEDGE) || (exStyle & WS_EX_STATICEDGE) || (exStyle & WS_EX_WINDOWEDGE))
51
52#define HAS_BORDER(style, exStyle) \
53 ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
54
55#define IS_OVERLAPPED(style) \
56 !(style & (WS_CHILD | WS_POPUP))
57
58//******************************************************************************
59//******************************************************************************
60Win32BaseWindow::Win32BaseWindow(DWORD objType) : GenericObject(&windows, objType)
61{
62 Init();
63}
64//******************************************************************************
65//******************************************************************************
66Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
67 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
68{
69 Init();
70 this->isUnicode = isUnicode;
71 CreateWindowExA(lpCreateStructA, classAtom);
72}
73//******************************************************************************
74//******************************************************************************
75void Win32BaseWindow::Init()
76{
77 isUnicode = FALSE;
78 fCreated = FALSE;
79 fFirstShow = TRUE;
80 fIsDialog = FALSE;
81
82 windowNameA = NULL;
83 windowNameW = NULL;
84 wndNameLength = 0;
85
86 userWindowLong = NULL;;
87 nrUserWindowLong = 0;
88
89 magic = WIN32PM_MAGIC;
90 OS2Hwnd = 0;
91 OS2HwndFrame = 0;
92 OS2HwndMenu = 0;
93 Win32Hwnd = 0;
94
95 if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
96 {
97 dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
98 DebugInt3();
99 }
100
101 posx = posy = 0;
102 width = height = 0;
103
104 dwExStyle = 0;
105 dwStyle = 0;
106 win32wndproc = 0;
107 hInstance = 0;
108 windowId = 0xFFFFFFFF; //default = -1
109 userData = 0;
110
111 hwndLinkAfter = HWND_BOTTOM;
112 flags = 0;
113 isIcon = FALSE;
114 lastHitTestVal = 0;
115 owner = NULL;
116 windowClass = 0;
117
118 acceltableResource = NULL;
119 iconResource = NULL;
120
121 EraseBkgndFlag = TRUE;
122 PSEraseFlag = FALSE;
123 SupressEraseFlag = FALSE;
124}
125//******************************************************************************
126//todo get rid of resources (menu, accel, icon etc)
127//******************************************************************************
128Win32BaseWindow::~Win32BaseWindow()
129{
130 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
131 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
132
133 if (isOwnDC())
134 releaseOwnDC (ownDC);
135
136 if(Win32Hwnd)
137 HwFreeWindowHandle(Win32Hwnd);
138
139 if(userWindowLong)
140 free(userWindowLong);
141 if(windowNameA) {
142 free(windowNameA);
143 windowNameA = NULL;
144 }
145 if(windowNameW) {
146 free(windowNameW);
147 windowNameW = NULL;
148 }
149}
150//******************************************************************************
151//******************************************************************************
152BOOL Win32BaseWindow::isChild()
153{
154 return (dwStyle & WS_CHILD) != 0;
155}
156//******************************************************************************
157//******************************************************************************
158BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
159{
160 char buffer[256];
161 INT sw = SW_SHOW;
162 POINT maxSize, maxPos, minTrack, maxTrack;
163
164 SetLastError(0);
165
166 /* Find the parent window */
167 if (cs->hwndParent)
168 {
169 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
170 if(!window) {
171 dprintf(("Bad parent %04x\n", cs->hwndParent ));
172 SetLastError(ERROR_INVALID_PARAMETER);
173 return FALSE;
174 }
175 /* Make sure parent is valid */
176 if (!window->IsWindow() )
177 {
178 dprintf(("Bad parent %04x\n", cs->hwndParent ));
179 SetLastError(ERROR_INVALID_PARAMETER);
180 return FALSE;
181 }
182 }
183 else
184 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
185 dprintf(("No parent for child window\n" ));
186 SetLastError(ERROR_INVALID_PARAMETER);
187 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
188 }
189
190 /* Find the window class */
191 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
192 if (!windowClass)
193 {
194 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
195 dprintf(("Bad class '%s'\n", buffer ));
196 SetLastError(ERROR_INVALID_PARAMETER);
197 return 0;
198 }
199
200 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
201 * with an atom as the class name, put some programs expect to have a *REAL* string in
202 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
203 */
204 if (!HIWORD(cs->lpszClass) ) {
205 if (isUnicode) {
206 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
207 }
208 else {
209 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
210 }
211 cs->lpszClass = buffer;
212 }
213
214 /* Fix the coordinates */
215 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
216 {
217// PDB *pdb = PROCESS_Current();
218
219 /* Never believe Microsoft's documentation... CreateWindowEx doc says
220 * that if an overlapped window is created with WS_VISIBLE style bit
221 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
222 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
223 * reveals that
224 *
225 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
226 * 2) it does not ignore the y parameter as the docs claim; instead, it
227 * uses it as second parameter to ShowWindow() unless y is either
228 * CW_USEDEFAULT or CW_USEDEFAULT16.
229 *
230 * The fact that we didn't do 2) caused bogus windows pop up when wine
231 * was running apps that were using this obscure feature. Example -
232 * calc.exe that comes with Win98 (only Win98, it's different from
233 * the one that comes with Win95 and NT)
234 */
235 if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) sw = cs->y;
236
237 /* We have saved cs->y, now we can trash it */
238#if 0
239 if ( !(cs->style & (WS_CHILD | WS_POPUP))
240 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
241 {
242 cs->x = pdb->env_db->startup_info->dwX;
243 cs->y = pdb->env_db->startup_info->dwY;
244 }
245#endif
246 cs->x = 0;
247 cs->y = 0;
248// }
249 }
250 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
251 {
252#if 0
253 PDB *pdb = PROCESS_Current();
254 if ( !(cs->style & (WS_CHILD | WS_POPUP))
255 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
256 {
257 cs->cx = pdb->env_db->startup_info->dwXSize;
258 cs->cy = pdb->env_db->startup_info->dwYSize;
259 }
260 else
261 {
262#endif
263 cs->cx = 600; /* FIXME */
264 cs->cy = 400;
265// }
266 }
267
268 if (cs->x < 0) cs->x = 0;
269 if (cs->y < 0) cs->y = 0;
270
271 //Allocate window words
272 nrUserWindowLong = windowClass->getExtraWndWords();
273 if(nrUserWindowLong) {
274 userWindowLong = (ULONG *)_smalloc(nrUserWindowLong);
275 memset(userWindowLong, 0, nrUserWindowLong);
276 }
277
278 if ((cs->style & WS_CHILD) && cs->hwndParent)
279 {
280 SetParent(cs->hwndParent);
281 owner = GetWindowFromHandle(cs->hwndParent);
282 if(owner == NULL)
283 {
284 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
285 return FALSE;
286 }
287 }
288 else
289 {
290 if (!cs->hwndParent) {
291 owner = NULL;
292 }
293 else
294 {
295 owner = GetWindowFromHandle(cs->hwndParent);
296 if(owner == NULL)
297 {
298 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
299 return FALSE;
300 }
301 }
302 }
303
304 setWindowProc(windowClass->getWindowProc());
305 hInstance = cs->hInstance;
306 dwStyle = cs->style & ~WS_VISIBLE;
307 dwExStyle = cs->dwExStyle;
308
309#if 1
310 //SvL: Messes up Z-order of dialog controls
311 hwndLinkAfter = HWND_TOP;
312#else
313 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
314 ? HWND_BOTTOM : HWND_TOP;
315#endif
316
317#if 0
318//TODO
319 /* Call the WH_CBT hook */
320
321 if (HOOK_IsHooked( WH_CBT ))
322 {
323 CBT_CREATEWNDA cbtc;
324 LRESULT ret;
325
326 cbtc.lpcs = cs;
327 cbtc.hwndInsertAfter = hwndLinkAfter;
328 ret = unicode ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc)
329 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc);
330 if (ret)
331 {
332 TRACE_(win)("CBT-hook returned 0\n");
333 wndPtr->pDriver->pFinalize(wndPtr);
334 retvalue = 0;
335 goto end;
336 }
337 }
338#endif
339
340 /* Increment class window counter */
341 windowClass->IncreaseWindowCount();
342
343 /* Correct the window style */
344 if (!(cs->style & WS_CHILD))
345 {
346 dwStyle |= WS_CLIPSIBLINGS;
347 if (!(cs->style & WS_POPUP))
348 {
349 dwStyle |= WS_CAPTION;
350 flags |= WIN_NEED_SIZE;
351 }
352 }
353 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
354
355 //TODO?
356#if 0
357 /* Get class or window DC if needed */
358 if (classPtr->style & CS_OWNDC) dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
359 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
360 else wndPtr->dce = NULL;
361#endif
362
363 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
364 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
365 {
366 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
367 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
368 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
369 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
370 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
371 }
372
373 if(cs->style & WS_CHILD)
374 {
375 if(cs->cx < 0) cs->cx = 0;
376 if(cs->cy < 0) cs->cy = 0;
377 }
378 else
379 {
380 if (cs->cx <= 0) cs->cx = 1;
381 if (cs->cy <= 0) cs->cy = 1;
382 }
383
384 rectWindow.left = cs->x;
385 rectWindow.top = cs->y;
386 rectWindow.right = cs->x + cs->cx;
387 rectWindow.bottom = cs->y + cs->cy;
388 rectClient = rectWindow;
389
390 DWORD dwOSWinStyle, dwOSFrameStyle;
391
392 OSLibWinConvertStyle(cs->style, cs->dwExStyle, &dwOSWinStyle, &dwOSFrameStyle);
393
394//CB: dwOSFrameStyle handled by OSLibWinConvertStyle
395// todo: subclass frame WM_PAINT -> call DrawEdge() if HAS_3DFRAME
396// OSLibWinCreateWindow: perhaps problems
397// shouldn't we always use a frame? -> no problems with scrollbars
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_NOMOVE) && !(wpos->flags & SWP_NOCLIENTMOVE))
1246 SendMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
1247
1248 if (!(wpos->flags & SWP_NOSIZE) && !(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) == -1) {
1368 dprintf(("WM_CREATE returned -1\n"));
1369 return(-1); //don't create window
1370 }
1371 NotifyParent(Msg, wParam, lParam);
1372
1373 return(0);
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) == -1) {
1409 dprintf(("WM_CREATE returned -1\n"));
1410 return(-1); //don't create window
1411 }
1412 NotifyParent(Msg, wParam, lParam);
1413
1414 return(0);
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) == -1) {
1447 dprintf(("WM_CREATE returned -1\n"));
1448 return(-1); //don't create window
1449 }
1450 NotifyParent(Msg, wParam, lParam);
1451
1452 return(0);
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
1523 dprintf(("SetMenu %x", hMenu));
1524 OS2HwndMenu = OSLibWinSetMenu(OS2HwndFrame, hMenu);
1525 if(OS2HwndMenu == 0) {
1526 dprintf(("Win32BaseWindow::SetMenu OS2HwndMenu == 0"));
1527 return FALSE;
1528 }
1529 return TRUE;
1530}
1531//******************************************************************************
1532//******************************************************************************
1533BOOL Win32BaseWindow::SetAccelTable(HACCEL hAccel)
1534{
1535 Win32Resource *winres = (Win32Resource *)hAccel;
1536 HANDLE accelhandle;
1537
1538 if(HIWORD(hAccel) == 0) {
1539 dprintf(("SetAccelTable: hAccel %x invalid", hAccel));
1540 SetLastError(ERROR_INVALID_PARAMETER);
1541 return FALSE;
1542 }
1543 acceltableResource = winres;
1544 accelhandle = OSLibWinSetAccelTable(OS2HwndFrame, winres->getOS2Handle(), winres->lockOS2Resource());
1545 winres->setOS2Handle(accelhandle);
1546 return(accelhandle != 0);
1547}
1548//******************************************************************************
1549//******************************************************************************
1550BOOL Win32BaseWindow::SetIcon(HICON hIcon)
1551{
1552 dprintf(("Win32BaseWindow::SetIcon %x", hIcon));
1553 if(OSLibWinSetIcon(OS2HwndFrame, hIcon) == TRUE) {
1554 SendInternalMessageA(WM_SETICON, hIcon, 0);
1555 return TRUE;
1556 }
1557 return FALSE;
1558}
1559//******************************************************************************
1560//******************************************************************************
1561BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
1562{
1563 ULONG showstate = 0;
1564
1565 dprintf(("ShowWindow %x", nCmdShow));
1566 if(fFirstShow) {
1567 if(isFrameWindow() && IS_OVERLAPPED(getStyle())) {
1568 SendMessageA(WM_SIZE, SIZE_RESTORED,
1569 MAKELONG(rectClient.right-rectClient.left,
1570 rectClient.bottom-rectClient.top));
1571 SendMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
1572
1573 }
1574 fFirstShow = FALSE;
1575 }
1576 switch(nCmdShow)
1577 {
1578 case SW_SHOW:
1579 case SW_SHOWDEFAULT: //todo
1580 showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
1581 break;
1582 case SW_HIDE:
1583 showstate = SWPOS_HIDE;
1584 break;
1585 case SW_RESTORE:
1586 showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
1587 break;
1588 case SW_MINIMIZE:
1589 showstate = SWPOS_MINIMIZE;
1590 break;
1591 case SW_SHOWMAXIMIZED:
1592 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
1593 break;
1594 case SW_SHOWMINIMIZED:
1595 showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
1596 break;
1597 case SW_SHOWMINNOACTIVE:
1598 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
1599 break;
1600 case SW_SHOWNA:
1601 showstate = SWPOS_SHOW;
1602 break;
1603 case SW_SHOWNOACTIVATE:
1604 showstate = SWPOS_SHOW;
1605 break;
1606 case SW_SHOWNORMAL:
1607 showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
1608 break;
1609 }
1610 return OSLibWinShowWindow(OS2HwndFrame, showstate);
1611}
1612//******************************************************************************
1613//******************************************************************************
1614BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
1615{
1616 BOOL rc = FALSE;
1617 Win32BaseWindow *window;
1618 HWND hParent = 0;
1619
1620 dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
1621
1622 if (fuFlags &
1623 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
1624 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
1625 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
1626 SWP_NOOWNERZORDER))
1627 {
1628 return FALSE;
1629 }
1630
1631 WINDOWPOS wpos;
1632 SWP swp, swpOld;
1633
1634 wpos.flags = fuFlags;
1635 wpos.cy = cy;
1636 wpos.cx = cx;
1637 wpos.x = x;
1638 wpos.y = y;
1639 wpos.hwndInsertAfter = hwndInsertAfter;
1640 wpos.hwnd = getWindowHandle();
1641
1642 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE)) {
1643 if (isChild())
1644 {
1645 hParent = getParent()->getOS2WindowHandle();
1646 OSLibWinQueryWindowPos(OS2Hwnd, &swpOld);
1647 } else
1648 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
1649 }
1650
1651 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
1652 if (swp.fl == 0)
1653 return TRUE;
1654
1655 if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
1656 {
1657 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
1658 swp.hwndInsertBehind = wndBehind->getOS2WindowHandle();
1659 }
1660 if (isFrameWindow())
1661 {
1662 POINT maxSize, maxPos, minTrack, maxTrack;
1663
1664 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
1665
1666 if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
1667 if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
1668 if (swp.cx < minTrack.x) swp.cx = minTrack.x;
1669 if (swp.cy < minTrack.y) swp.cy = minTrack.y;
1670 swp.hwnd = OS2HwndFrame;
1671 } else
1672 swp.hwnd = OS2Hwnd;
1673 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
1674
1675 rc = OSLibWinSetMultWindowPos(&swp, 1);
1676
1677 if (rc == FALSE)
1678 {
1679// SET_ERROR_LAST();
1680 }
1681 else
1682 {
1683 if (fuFlags & SWP_FRAMECHANGED_W)
1684 OSLibSendMessage (OS2HwndFrame, 0x42 /*WM_UPDATEFRAME*/, -1, 0);
1685 }
1686
1687 return (rc);
1688}
1689//******************************************************************************
1690//Also destroys all the child windows (destroy parent, destroy children)
1691//******************************************************************************
1692BOOL Win32BaseWindow::DestroyWindow()
1693{
1694 return OSLibWinDestroyWindow(OS2HwndFrame);
1695}
1696//******************************************************************************
1697//******************************************************************************
1698HWND Win32BaseWindow::GetParent()
1699{
1700 if(getParent()) {
1701 return getParent()->getWindowHandle();
1702 }
1703 else return 0;
1704}
1705//******************************************************************************
1706//******************************************************************************
1707HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
1708{
1709 HWND oldhwnd;
1710 Win32BaseWindow *newparent;
1711
1712 if(getParent()) {
1713 oldhwnd = getParent()->getWindowHandle();
1714 getParent()->RemoveChild(this);
1715 }
1716 else oldhwnd = 0;
1717
1718 if(hwndNewParent == 0) {//desktop window = parent
1719 setParent(NULL);
1720 OSLibWinSetParent(getOS2WindowHandle(), OSLIB_HWND_DESKTOP);
1721 return oldhwnd;
1722 }
1723 newparent = GetWindowFromHandle(hwndNewParent);
1724 if(newparent)
1725 {
1726 setParent(newparent);
1727 getParent()->AddChild(this);
1728 OSLibWinSetParent(getOS2WindowHandle(), getParent()->getOS2WindowHandle());
1729 return oldhwnd;
1730 }
1731 SetLastError(ERROR_INVALID_PARAMETER);
1732 return 0;
1733}
1734//******************************************************************************
1735//******************************************************************************
1736BOOL Win32BaseWindow::IsChild(HWND hwndParent)
1737{
1738 if(getParent()) {
1739 return getParent()->getWindowHandle() == hwndParent;
1740 }
1741 else return 0;
1742}
1743//******************************************************************************
1744//******************************************************************************
1745HWND Win32BaseWindow::GetTopWindow()
1746{
1747 return GetWindow(GW_CHILD);
1748}
1749//******************************************************************************
1750//Don't call WinUpdateWindow as that one also updates the child windows
1751//Also need to send WM_PAINT directly to the window procedure, which doesn't
1752//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
1753//******************************************************************************
1754BOOL Win32BaseWindow::UpdateWindow()
1755{
1756 RECT rect;
1757
1758 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
1759 {//update region not empty
1760 HDC hdc;
1761
1762 hdc = O32_GetDC(OS2Hwnd);
1763 if (isIcon)
1764 {
1765 SendInternalMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
1766 SendInternalMessageA(WM_PAINTICON, 0, 0);
1767 } else
1768 {
1769 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
1770 SendInternalMessageA(WM_PAINT, 0, 0);
1771 }
1772 O32_ReleaseDC(OS2Hwnd, hdc);
1773 }
1774 return TRUE;
1775}
1776//******************************************************************************
1777//******************************************************************************
1778BOOL Win32BaseWindow::IsIconic()
1779{
1780 return OSLibWinIsIconic(OS2Hwnd);
1781}
1782//******************************************************************************
1783//TODO:
1784//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
1785//the current process owns them.
1786//******************************************************************************
1787HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
1788 BOOL fUnicode)
1789{
1790 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
1791 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
1792
1793 if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
1794 (hwndChildAfter != 0 && !child) ||
1795 (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
1796 {
1797 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
1798 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1799 return 0;
1800 }
1801 if(hwndParent != OSLIB_HWND_DESKTOP)
1802 {//if the current process owns the window, just do a quick search
1803 child = (Win32BaseWindow *)parent->getFirstChild();
1804 if(hwndChildAfter != 0)
1805 {
1806 while(child)
1807 {
1808 if(child->getWindowHandle() == hwndChildAfter)
1809 {
1810 child = (Win32BaseWindow *)child->getNextChild();
1811 break;
1812 }
1813 child = (Win32BaseWindow *)child->getNextChild();
1814 }
1815 }
1816 while(child)
1817 {
1818 if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
1819 (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
1820 {
1821 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
1822 return child->getWindowHandle();
1823 }
1824 child = (Win32BaseWindow *)child->getNextChild();
1825 }
1826 }
1827 else {
1828 Win32BaseWindow *wnd;
1829 HWND henum, hwnd;
1830
1831 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
1832 hwnd = OSLibWinGetNextWindow(henum);
1833
1834 while(hwnd)
1835 {
1836 wnd = GetWindowFromOS2Handle(hwnd);
1837 if(wnd == NULL) {
1838 hwnd = OSLibWinQueryClientWindow(hwnd);
1839 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
1840 }
1841
1842 if(wnd) {
1843 LPVOID sharedmembase = (LPVOID)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_SHAREDMEM);
1844
1845 if(OSLibDosGetSharedMem(sharedmembase, MAX_HEAPSIZE, OSLIB_PAG_READ) != 0) {
1846 dprintf(("OSLibDosGetSharedMem returned error for %x", wnd));
1847 break;
1848 }
1849 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
1850 (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
1851 {
1852 OSLibWinEndEnumWindows(henum);
1853 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
1854 return wnd->getWindowHandle();
1855 }
1856 }
1857 hwnd = OSLibWinGetNextWindow(henum);
1858 }
1859 OSLibWinEndEnumWindows(henum);
1860 }
1861 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
1862 return 0;
1863}
1864//******************************************************************************
1865//TODO: not complete nor correct (distinction be tween top-level, top-most & child windows)
1866//******************************************************************************
1867HWND Win32BaseWindow::GetWindow(UINT uCmd)
1868{
1869 Win32BaseWindow *win32wnd;
1870 ULONG magic;
1871 ULONG getcmd = 0;
1872 HWND hwndRelated;
1873
1874 dprintf(("GetWindow %x %d NOT COMPLETE", getWindowHandle(), uCmd));
1875 switch(uCmd)
1876 {
1877 case GW_CHILD:
1878 getcmd = QWOS_TOP;
1879 break;
1880 case GW_HWNDFIRST:
1881 if(getParent()) {
1882 getcmd = QWOS_TOP; //top of child windows
1883 }
1884 else getcmd = QWOS_TOP; //TODO
1885 break;
1886 case GW_HWNDLAST:
1887 if(getParent()) {
1888 getcmd = QWOS_BOTTOM; //bottom of child windows
1889 }
1890 else getcmd = QWOS_BOTTOM; //TODO
1891 break;
1892 case GW_HWNDNEXT:
1893 getcmd = QWOS_NEXT;
1894 break;
1895 case GW_HWNDPREV:
1896 getcmd = QWOS_PREV;
1897 break;
1898 case GW_OWNER:
1899 if(owner) {
1900 return owner->getWindowHandle();
1901 }
1902 else return 0;
1903 }
1904 hwndRelated = OSLibWinQueryWindow(OS2Hwnd, getcmd);
1905 if(hwndRelated)
1906 {
1907 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32WNDPTR);
1908 magic = OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32PM_MAGIC);
1909 if(CheckMagicDword(magic) && win32wnd)
1910 {
1911 return win32wnd->getWindowHandle();
1912 }
1913 }
1914 return 0;
1915}
1916//******************************************************************************
1917//******************************************************************************
1918HWND Win32BaseWindow::SetActiveWindow()
1919{
1920 return OSLibWinSetActiveWindow(OS2Hwnd);
1921}
1922//******************************************************************************
1923//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
1924//******************************************************************************
1925BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
1926{
1927 return OSLibWinEnableWindow(OS2Hwnd, fEnable);
1928}
1929//******************************************************************************
1930//******************************************************************************
1931BOOL Win32BaseWindow::CloseWindow()
1932{
1933 return OSLibWinMinimizeWindow(OS2Hwnd);
1934}
1935//******************************************************************************
1936//******************************************************************************
1937HWND Win32BaseWindow::GetActiveWindow()
1938{
1939 HWND hwndActive;
1940 Win32BaseWindow *win32wnd;
1941 ULONG magic;
1942
1943 hwndActive = OSLibWinQueryActiveWindow();
1944
1945 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
1946 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
1947 if(CheckMagicDword(magic) && win32wnd)
1948 {
1949 return win32wnd->getWindowHandle();
1950 }
1951 return hwndActive;
1952}
1953//******************************************************************************
1954//******************************************************************************
1955BOOL Win32BaseWindow::IsWindowEnabled()
1956{
1957 return OSLibWinIsWindowEnabled(OS2Hwnd);
1958}
1959//******************************************************************************
1960//******************************************************************************
1961BOOL Win32BaseWindow::IsWindowVisible()
1962{
1963 return OSLibWinIsWindowVisible(OS2Hwnd);
1964}
1965//******************************************************************************
1966//******************************************************************************
1967BOOL Win32BaseWindow::GetWindowRect(PRECT pRect)
1968{
1969 return OSLibWinQueryWindowRect(OS2Hwnd, pRect, RELATIVE_TO_SCREEN);
1970}
1971//******************************************************************************
1972//******************************************************************************
1973BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
1974{
1975 if(fUnicode) {
1976 return (lstrcmpW(windowNameW, (LPWSTR)wndname) == 0);
1977 }
1978 else return (strcmp(windowNameA, wndname) == 0);
1979}
1980//******************************************************************************
1981//******************************************************************************
1982int Win32BaseWindow::GetWindowTextLength()
1983{
1984 return wndNameLength;
1985}
1986//******************************************************************************
1987//******************************************************************************
1988int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
1989{
1990 strncpy(lpsz, windowNameA, cch);
1991 return wndNameLength;
1992}
1993//******************************************************************************
1994//******************************************************************************
1995int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
1996{
1997 lstrcpynW((LPWSTR)lpsz, windowNameW, cch);
1998 return wndNameLength;
1999}
2000//******************************************************************************
2001//******************************************************************************
2002BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
2003{
2004 if(lpsz == NULL)
2005 return FALSE;
2006
2007 windowNameA = (LPSTR)_smalloc(strlen(lpsz)+1);
2008 strcpy(windowNameA, lpsz);
2009 windowNameW = (LPWSTR)_smalloc((strlen(lpsz)+1)*sizeof(WCHAR));
2010 lstrcpyAtoW(windowNameW, windowNameA);
2011 wndNameLength = strlen(windowNameA)+1; //including 0 terminator
2012
2013 if(OS2HwndFrame)
2014 return OSLibWinSetWindowText(OS2HwndFrame, (LPSTR)windowNameA);
2015
2016 return TRUE;
2017}
2018//******************************************************************************
2019//******************************************************************************
2020BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
2021{
2022 if(lpsz == NULL)
2023 return FALSE;
2024
2025 windowNameW = (LPWSTR)_smalloc((lstrlenW((LPWSTR)lpsz)+1)*sizeof(WCHAR));
2026 lstrcpyW(windowNameW, (LPWSTR)lpsz);
2027 windowNameA = (LPSTR)_smalloc(lstrlenW((LPWSTR)lpsz)+1);
2028 lstrcpyWtoA(windowNameA, windowNameW);
2029 wndNameLength = strlen(windowNameA)+1; //including 0 terminator
2030
2031 if(OS2HwndFrame)
2032 return OSLibWinSetWindowText(OS2HwndFrame, (LPSTR)windowNameA);
2033
2034 return TRUE;
2035}
2036//******************************************************************************
2037//******************************************************************************
2038LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value)
2039{
2040 LONG oldval;
2041
2042 switch(index) {
2043 case GWL_EXSTYLE:
2044 oldval = dwExStyle;
2045 setExStyle(value);
2046 return oldval;
2047 case GWL_STYLE:
2048 oldval = dwStyle;
2049 setStyle(value);
2050 return oldval;
2051 case GWL_WNDPROC:
2052 oldval = (LONG)getWindowProc();
2053 setWindowProc((WNDPROC)value);
2054 return oldval;
2055 case GWL_HINSTANCE:
2056 oldval = hInstance;
2057 hInstance = value;
2058 return oldval;
2059 case GWL_HWNDPARENT:
2060 return SetParent((HWND)value);
2061
2062 case GWL_ID:
2063 oldval = getWindowId();
2064 setWindowId(value);
2065 return oldval;
2066 case GWL_USERDATA:
2067 oldval = userData;
2068 userData = value;
2069 return oldval;
2070 default:
2071 if(index >= 0 && index/4 < nrUserWindowLong)
2072 {
2073 oldval = userWindowLong[index/4];
2074 userWindowLong[index/4] = value;
2075 return oldval;
2076 }
2077 SetLastError(ERROR_INVALID_PARAMETER);
2078 return 0;
2079 }
2080}
2081//******************************************************************************
2082//******************************************************************************
2083ULONG Win32BaseWindow::GetWindowLongA(int index)
2084{
2085 switch(index) {
2086 case GWL_EXSTYLE:
2087 return dwExStyle;
2088 case GWL_STYLE:
2089 return dwStyle;
2090 case GWL_WNDPROC:
2091 return (ULONG)getWindowProc();
2092 case GWL_HINSTANCE:
2093 return hInstance;
2094 case GWL_HWNDPARENT:
2095 if(getParent()) {
2096 return getParent()->getWindowHandle();
2097 }
2098 else return 0;
2099 case GWL_ID:
2100 return getWindowId();
2101 case GWL_USERDATA:
2102 return userData;
2103 default:
2104 if(index >= 0 && index/4 < nrUserWindowLong)
2105 {
2106 return userWindowLong[index/4];
2107 }
2108 SetLastError(ERROR_INVALID_PARAMETER);
2109 return 0;
2110 }
2111}
2112//******************************************************************************
2113//******************************************************************************
2114WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
2115{
2116 WORD oldval;
2117
2118 if(index >= 0 && index/4 < nrUserWindowLong)
2119 {
2120 oldval = ((WORD *)userWindowLong)[index/2];
2121 ((WORD *)userWindowLong)[index/2] = value;
2122 return oldval;
2123 }
2124 SetLastError(ERROR_INVALID_PARAMETER);
2125 return 0;
2126}
2127//******************************************************************************
2128//******************************************************************************
2129WORD Win32BaseWindow::GetWindowWord(int index)
2130{
2131 if(index >= 0 && index/4 < nrUserWindowLong)
2132 {
2133 return ((WORD *)userWindowLong)[index/2];
2134 }
2135 SetLastError(ERROR_INVALID_PARAMETER);
2136 return 0;
2137}
2138//******************************************************************************
2139//******************************************************************************
2140Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
2141{
2142 Win32BaseWindow *window;
2143
2144 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
2145 return window;
2146 }
2147 else return NULL;
2148}
2149//******************************************************************************
2150//******************************************************************************
2151Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
2152{
2153 Win32BaseWindow *win32wnd;
2154 DWORD magic;
2155
2156 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
2157 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
2158
2159 if(win32wnd && CheckMagicDword(magic)) {
2160 return win32wnd;
2161 }
2162 return 0;
2163}
2164//******************************************************************************
2165//******************************************************************************
2166HWND Win32BaseWindow::Win32ToOS2Handle(HWND hwnd)
2167{
2168 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
2169
2170 if(window) {
2171 return window->getOS2WindowHandle();
2172 }
2173 else return hwnd; //OS/2 window handle
2174}
2175//******************************************************************************
2176//******************************************************************************
2177HWND Win32BaseWindow::OS2ToWin32Handle(HWND hwnd)
2178{
2179 Win32BaseWindow *window = GetWindowFromOS2Handle(hwnd);
2180
2181 if(window) {
2182 return window->getWindowHandle();
2183 }
2184 else return hwnd; //OS/2 window handle
2185}
2186//******************************************************************************
2187//******************************************************************************
2188GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.