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

Last change on this file since 1000 was 1000, checked in by dengert, 26 years ago

erase background/paint stuff enhanced

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