source: trunk/src/user32/new/win32wbase.cpp@ 2396

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

activated menu code

File size: 139.8 KB
Line 
1/* $Id: win32wbase.cpp,v 1.28 2000-01-10 17:18:09 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, 1996 Alexandre Julliard
11 * 1995 Alex Korobka
12 *
13 * TODO: Not thread/process safe
14 *
15 * Project Odin Software License can be found in LICENSE.TXT
16 *
17 */
18#include <os2win.h>
19#include <win.h>
20#include <stdlib.h>
21#include <string.h>
22#include <stdarg.h>
23#include <assert.h>
24#include <misc.h>
25#include <heapstring.h>
26#include <win32wbase.h>
27#include <winres.h>
28#include "wndmsg.h"
29#include "oslibwin.h"
30#include "oslibmsg.h"
31#include "oslibutil.h"
32#include "oslibgdi.h"
33#include "oslibres.h"
34#include "oslibdos.h"
35#include "syscolor.h"
36#include "win32wndhandle.h"
37#include "dc.h"
38#include "pmframe.h"
39#include "win32wdesktop.h"
40#include "pmwindow.h"
41#include "controls.h"
42#include <wprocess.h>
43#include "winmouse.h"
44#include <win\hook.h>
45#include <shellapi.h>
46#include <menu.h>
47#define INCL_TIMERWIN32
48#include "timer.h"
49
50#define SC_ABOUTWINE (SC_SCREENSAVE+1)
51#define SC_PUTMARK (SC_SCREENSAVE+2)
52
53#define HAS_DLGFRAME(style,exStyle) \
54 (((exStyle) & WS_EX_DLGMODALFRAME) || \
55 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
56
57#define HAS_THICKFRAME(style,exStyle) \
58 (((style) & WS_THICKFRAME) && \
59 !((exStyle) & WS_EX_DLGMODALFRAME) && \
60 !((style) & WS_CHILD))
61
62#define HAS_THINFRAME(style) \
63 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
64
65#define HAS_BIGFRAME(style,exStyle) \
66 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
67 ((exStyle) & WS_EX_DLGMODALFRAME))
68
69#define HAS_ANYFRAME(style,exStyle) \
70 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
71 ((exStyle) & WS_EX_DLGMODALFRAME) || \
72 !((style) & (WS_CHILD | WS_POPUP)))
73
74#define HAS_3DFRAME(exStyle) \
75 ((exStyle & WS_EX_CLIENTEDGE) || (exStyle & WS_EX_STATICEDGE) || (exStyle & WS_EX_WINDOWEDGE))
76
77#define HAS_BORDER(style, exStyle) \
78 ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
79
80#define IS_OVERLAPPED(style) \
81 !(style & (WS_CHILD | WS_POPUP))
82
83#define HAS_MENU() (!(getStyle() & WS_CHILD) && (GetMenu() != 0))
84
85/* bits in the dwKeyData */
86#define KEYDATA_ALT 0x2000
87#define KEYDATA_PREVSTATE 0x4000
88
89void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle);
90
91static fDestroyAll = FALSE;
92//For quick lookup of current process id
93static ULONG currentProcessId = -1;
94
95static HBITMAP hbitmapClose = 0;
96static HBITMAP hbitmapCloseD = 0;
97static HBITMAP hbitmapMinimize = 0;
98static HBITMAP hbitmapMinimizeD = 0;
99static HBITMAP hbitmapMaximize = 0;
100static HBITMAP hbitmapMaximizeD = 0;
101static HBITMAP hbitmapRestore = 0;
102static HBITMAP hbitmapRestoreD = 0;
103
104BYTE lpGrayMask[] = { 0xAA, 0xA0,
105 0x55, 0x50,
106 0xAA, 0xA0,
107 0x55, 0x50,
108 0xAA, 0xA0,
109 0x55, 0x50,
110 0xAA, 0xA0,
111 0x55, 0x50,
112 0xAA, 0xA0,
113 0x55, 0x50};
114
115//******************************************************************************
116//******************************************************************************
117Win32BaseWindow::Win32BaseWindow(DWORD objType) : GenericObject(&windows, objType)
118{
119 Init();
120}
121//******************************************************************************
122//******************************************************************************
123Win32BaseWindow::Win32BaseWindow(HWND os2Handle,VOID* win32WndProc) : GenericObject(&windows,OBJTYPE_WINDOW)
124{
125 Init();
126 OS2Hwnd = OS2HwndFrame = os2Handle;
127 dwStyle = WS_VISIBLE;
128 setWindowProc((WNDPROC)win32WndProc);
129 fIsSubclassedOS2Wnd = TRUE;
130 fFirstShow = FALSE;
131 fCreated = TRUE;
132
133 SetLastError(0);
134
135 //CB: replace by a secure method
136
137 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
138 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
139 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
140 return;
141 }
142 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
143 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
144 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
145 return;
146 }
147
148 OSLibWinQueryWindowRect(OS2Hwnd,&rectClient,RELATIVE_TO_WINDOW);
149 OSLibWinQueryWindowRect(OS2Hwnd,&rectWindow,RELATIVE_TO_SCREEN);
150
151 setOldWndProc(SubclassWithDefHandler(OS2Hwnd));
152}
153//******************************************************************************
154//******************************************************************************
155Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
156 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
157{
158 Init();
159 this->isUnicode = isUnicode;
160 CreateWindowExA(lpCreateStructA, classAtom);
161}
162//******************************************************************************
163//******************************************************************************
164void Win32BaseWindow::Init()
165{
166 isUnicode = FALSE;
167 fIsSubclassedOS2Wnd = FALSE;
168 fFirstShow = TRUE;
169 fIsDialog = FALSE;
170 fIsModalDialogOwner = FALSE;
171 OS2HwndModalDialog = 0;
172 fInternalMsg = FALSE;
173 fNoSizeMsg = FALSE;
174 fIsDestroyed = FALSE;
175 fDestroyWindowCalled = FALSE;
176 fCreated = FALSE;
177 fTaskList = FALSE;
178 fParentDC = FALSE;
179
180 windowNameA = NULL;
181 windowNameW = NULL;
182 wndNameLength = 0;
183
184 userWindowLong = NULL;;
185 nrUserWindowLong = 0;
186
187 magic = WIN32PM_MAGIC;
188 OS2Hwnd = 0;
189 OS2HwndFrame = 0;
190 hMenu = 0;
191 hSysMenu = 0;
192 Win32Hwnd = 0;
193
194 if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
195 {
196 dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
197 DebugInt3();
198 }
199
200 posx = posy = 0;
201 width = height = 0;
202
203 dwExStyle = 0;
204 dwStyle = 0;
205 win32wndproc = 0;
206 hInstance = 0;
207 windowId = 0xFFFFFFFF; //default = -1
208 userData = 0;
209 contextHelpId = 0;
210
211 pOldFrameProc = NULL;
212 borderWidth = 0;
213 borderHeight = 0;
214
215 hwndLinkAfter = HWND_BOTTOM;
216 flags = 0;
217 isIcon = FALSE;
218 lastHitTestVal = HTOS_NORMAL;
219 fIgnoreHitTest = FALSE;
220 owner = NULL;
221 windowClass = 0;
222
223 iconResource = NULL;
224
225 EraseBkgndFlag = TRUE;
226 PSEraseFlag = FALSE;
227 SuppressEraseFlag = FALSE;
228
229 horzScrollInfo = NULL;
230 vertScrollInfo = NULL;
231
232 ownDC = 0;
233 hWindowRegion = 0;
234
235 if(currentProcessId == -1)
236 {
237 currentProcessId = GetCurrentProcessId();
238 }
239 dwThreadId = GetCurrentThreadId();
240 dwProcessId = currentProcessId;
241}
242//******************************************************************************
243//todo get rid of resources (menu, icon etc)
244//******************************************************************************
245Win32BaseWindow::~Win32BaseWindow()
246{
247 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
248 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
249
250 if(!fDestroyAll && getParent() && getParent()->getFirstChild() == this && getNextChild() == NULL)
251 {
252 //if we're the last child that's being destroyed and our
253 //parent window was also destroyed, then we delete the parent object
254 if(getParent()->IsWindowDestroyed())
255 {
256 dprintf(("Last Child (%x) destroyed, get rid of our parent window (%x)", getWindowHandle(), getParent()->getWindowHandle()));
257 delete getParent();
258 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
259 }
260 }
261 else
262 if(fDestroyAll) {
263 dprintf(("Destroying window %x %s", getWindowHandle(), windowNameA));
264 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
265 }
266
267 if (isOwnDC())
268 releaseOwnDC (ownDC);
269
270 if(Win32Hwnd)
271 HwFreeWindowHandle(Win32Hwnd);
272
273 if(userWindowLong)
274 free(userWindowLong);
275 if(windowNameA) {
276 free(windowNameA);
277 windowNameA = NULL;
278 }
279 if(windowNameW) {
280 free(windowNameW);
281 windowNameW = NULL;
282 }
283 if(vertScrollInfo) {
284 free(vertScrollInfo);
285 vertScrollInfo = NULL;
286 }
287 if(horzScrollInfo) {
288 free(horzScrollInfo);
289 horzScrollInfo = NULL;
290 }
291}
292//******************************************************************************
293//******************************************************************************
294void Win32BaseWindow::DestroyAll()
295{
296 fDestroyAll = TRUE;
297 GenericObject::DestroyAll(windows);
298}
299//******************************************************************************
300//******************************************************************************
301BOOL Win32BaseWindow::isChild()
302{
303 return ((dwStyle & WS_CHILD) != 0);
304}
305//******************************************************************************
306//******************************************************************************
307BOOL Win32BaseWindow::IsWindowUnicode()
308{
309 dprintf2(("IsWindowUnicode %x %d", getWindowHandle(), WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W));
310 return (WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W);
311}
312//******************************************************************************
313//******************************************************************************
314BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
315{
316 char buffer[256];
317 POINT maxSize, maxPos, minTrack, maxTrack;
318
319#ifdef DEBUG
320 PrintWindowStyle(cs->style, cs->dwExStyle);
321#endif
322
323 sw = SW_SHOW;
324 SetLastError(0);
325
326 /* Find the parent window */
327 if (cs->hwndParent)
328 {
329 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
330 if(!window) {
331 dprintf(("Bad parent %04x\n", cs->hwndParent ));
332 SetLastError(ERROR_INVALID_PARAMETER);
333 return FALSE;
334 }
335 /* Make sure parent is valid */
336 if (!window->IsWindow() )
337 {
338 dprintf(("Bad parent %04x\n", cs->hwndParent ));
339 SetLastError(ERROR_INVALID_PARAMETER);
340 return FALSE;
341 }
342 }
343 else
344 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
345 dprintf(("No parent for child window\n" ));
346 SetLastError(ERROR_INVALID_PARAMETER);
347 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
348 }
349
350 /* Find the window class */
351 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
352 if (!windowClass)
353 {
354 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
355 dprintf(("Bad class '%s'\n", buffer ));
356 SetLastError(ERROR_INVALID_PARAMETER);
357 return 0;
358 }
359#ifdef DEBUG
360 if(HIWORD(cs->lpszClass))
361 {
362 char *astring;
363
364 if(isUnicode) astring = UnicodeToAsciiString((LPWSTR)cs->lpszClass);
365 else astring = (char *)cs->lpszClass;
366
367 dprintf(("Window class %s", astring));
368 if(isUnicode) FreeAsciiString(astring);
369 }
370 else dprintf(("Window class %x", cs->lpszClass));
371#endif
372
373 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
374 * with an atom as the class name, put some programs expect to have a *REAL* string in
375 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
376 */
377 if (!HIWORD(cs->lpszClass) ) {
378 if (isUnicode) {
379 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
380 }
381 else {
382 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
383 }
384 cs->lpszClass = buffer;
385 }
386
387 /* Fix the coordinates */
388 if ((cs->x == CW_USEDEFAULT) || (cs->x == CW_USEDEFAULT16))
389 {
390// PDB *pdb = PROCESS_Current();
391
392 /* Never believe Microsoft's documentation... CreateWindowEx doc says
393 * that if an overlapped window is created with WS_VISIBLE style bit
394 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
395 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
396 * reveals that
397 *
398 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
399 * 2) it does not ignore the y parameter as the docs claim; instead, it
400 * uses it as second parameter to ShowWindow() unless y is either
401 * CW_USEDEFAULT or CW_USEDEFAULT16.
402 *
403 * The fact that we didn't do 2) caused bogus windows pop up when wine
404 * was running apps that were using this obscure feature. Example -
405 * calc.exe that comes with Win98 (only Win98, it's different from
406 * the one that comes with Win95 and NT)
407 */
408 if ((cs->y != CW_USEDEFAULT) && (cs->y != CW_USEDEFAULT16)) sw = cs->y;
409
410 /* We have saved cs->y, now we can trash it */
411#if 0
412 if ( !(cs->style & (WS_CHILD | WS_POPUP))
413 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
414 {
415 cs->x = pdb->env_db->startup_info->dwX;
416 cs->y = pdb->env_db->startup_info->dwY;
417 }
418#endif
419 cs->x = 0;
420 cs->y = 0;
421// }
422 }
423 if ((cs->cx == CW_USEDEFAULT) || (cs->cx == CW_USEDEFAULT16))
424 {
425#if 0
426 PDB *pdb = PROCESS_Current();
427 if ( !(cs->style & (WS_CHILD | WS_POPUP))
428 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
429 {
430 cs->cx = pdb->env_db->startup_info->dwXSize;
431 cs->cy = pdb->env_db->startup_info->dwYSize;
432 }
433 else
434 {
435#endif
436 cs->cx = 600; /* FIXME */
437 cs->cy = 400;
438// }
439 }
440
441 if (cs->x < 0) cs->x = 0;
442 if (cs->y < 0) cs->y = 0;
443
444 //Allocate window words
445 nrUserWindowLong = windowClass->getExtraWndWords();
446 if(nrUserWindowLong) {
447 userWindowLong = (ULONG *)_smalloc(nrUserWindowLong);
448 memset(userWindowLong, 0, nrUserWindowLong);
449 }
450
451 if ((cs->style & WS_CHILD) && cs->hwndParent)
452 {
453 SetParent(cs->hwndParent);
454 owner = GetWindowFromHandle(cs->hwndParent);
455 if(owner == NULL)
456 {
457 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
458 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
459 return FALSE;
460 }
461 }
462 else
463 {
464 SetParent(0);
465 if (!cs->hwndParent || (cs->hwndParent == windowDesktop->getWindowHandle())) {
466 owner = NULL;
467 }
468 else
469 {
470 owner = GetWindowFromHandle(cs->hwndParent)->GetTopParent();
471 if(owner == NULL)
472 {
473 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
474 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
475 return FALSE;
476 }
477 }
478 }
479
480 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc(), WINPROC_GetProcType(windowClass->getWindowProc()), WIN_PROC_WINDOW);
481 hInstance = cs->hInstance;
482 dwStyle = cs->style & ~WS_VISIBLE;
483 dwExStyle = cs->dwExStyle;
484
485 hwndLinkAfter = HWND_TOP;
486 if(CONTROLS_IsControl(this, BUTTON_CONTROL) && ((dwStyle & 0x0f) == BS_GROUPBOX))
487 {
488 hwndLinkAfter = HWND_BOTTOM;
489 dwStyle |= WS_CLIPSIBLINGS;
490 }
491 else
492 if(CONTROLS_IsControl(this, STATIC_CONTROL) && !(dwStyle & WS_GROUP)) {
493 dwStyle |= WS_CLIPSIBLINGS;
494 }
495
496 /* Increment class window counter */
497 windowClass->IncreaseWindowCount();
498
499 if (HOOK_IsHooked( WH_CBT ))
500 {
501 CBT_CREATEWNDA cbtc;
502 LRESULT ret;
503
504 cbtc.lpcs = cs;
505 cbtc.hwndInsertAfter = hwndLinkAfter;
506 ret = HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc);
507 if(ret)
508 {
509 dprintf(("CBT-hook returned 0!!"));
510 SetLastError(ERROR_CAN_NOT_COMPLETE); //todo: wrong error
511 return FALSE;
512 }
513 }
514
515 /* Correct the window style */
516 if (!(cs->style & WS_CHILD))
517 {
518 dwStyle |= WS_CLIPSIBLINGS;
519 if (!(cs->style & WS_POPUP))
520 {
521 dwStyle |= WS_CAPTION;
522 flags |= WIN_NEED_SIZE;
523 }
524 }
525 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
526
527 if (cs->style & WS_HSCROLL)
528 {
529 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
530 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
531 horzScrollInfo->MaxVal = 100;
532 horzScrollInfo->flags = ESB_ENABLE_BOTH;
533 }
534
535 if (cs->style & WS_VSCROLL)
536 {
537 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
538 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
539 vertScrollInfo->MaxVal = 100;
540 vertScrollInfo->flags = ESB_ENABLE_BOTH;
541 }
542
543 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
544 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
545 {
546 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
547 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
548 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
549 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
550 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
551 }
552
553 if(cs->style & WS_CHILD)
554 {
555 if(cs->cx < 0) cs->cx = 0;
556 if(cs->cy < 0) cs->cy = 0;
557 }
558 else
559 {
560 if (cs->cx <= 0) cs->cx = 1;
561 if (cs->cy <= 0) cs->cy = 1;
562 }
563
564 if(((dwStyle & 0xC0000000) == WS_OVERLAPPED) && ((dwStyle & WS_CAPTION) == WS_CAPTION) && owner == NULL
565 && dwStyle & WS_SYSMENU)
566 {
567 fTaskList = TRUE;
568 }
569
570 DWORD dwOSWinStyle, dwOSFrameStyle;
571
572 OSLibWinConvertStyle(dwStyle, &dwExStyle, &dwOSWinStyle, &dwOSFrameStyle, &borderWidth, &borderHeight);
573
574 if(HIWORD(cs->lpszName))
575 {
576 if (!isUnicode)
577 {
578 wndNameLength = strlen(cs->lpszName);
579 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
580 strcpy(windowNameA,cs->lpszName);
581 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
582 lstrcpyAtoW(windowNameW,windowNameA);
583 windowNameA[wndNameLength] = 0;
584 windowNameW[wndNameLength] = 0;
585 }
586 else
587 {
588 wndNameLength = lstrlenW((LPWSTR)cs->lpszName);
589 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
590 lstrcpyWtoA(windowNameA,(LPWSTR)cs->lpszName);
591 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
592 lstrcpyW(windowNameW,(LPWSTR)cs->lpszName);
593 windowNameA[wndNameLength] = 0;
594 windowNameW[wndNameLength] = 0;
595 }
596 }
597
598 //copy pointer of CREATESTRUCT for usage in MsgCreate method
599 tmpcs = cs;
600
601 //Store our window object pointer in thread local memory, so PMWINDOW.CPP can retrieve it
602 THDB *thdb = GetThreadTHDB();
603
604 if(thdb == NULL) {
605 dprintf(("Window creation failed - thdb == NULL")); //this is VERY bad
606 ExitProcess(666);
607 return FALSE;
608 }
609
610 thdb->newWindow = (ULONG)this;
611
612 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
613 dwOSWinStyle,(char *)windowNameA,
614 (owner) ? owner->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
615 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
616 &OS2HwndFrame, 0, fTaskList);
617 if(OS2Hwnd == 0) {
618 dprintf(("Window creation failed!!"));
619 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
620 return FALSE;
621 }
622
623 SetLastError(0);
624 return TRUE;
625}
626//******************************************************************************
627//******************************************************************************
628BOOL Win32BaseWindow::MsgCreate(HWND hwndFrame, HWND hwndClient)
629{
630 POINT maxPos;
631 CREATESTRUCTA *cs = tmpcs; //pointer to CREATESTRUCT used in CreateWindowExA method
632
633 OS2Hwnd = hwndClient;
634 OS2HwndFrame = hwndFrame;
635
636 fNoSizeMsg = TRUE;
637
638 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
639 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
640 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
641 return FALSE;
642 }
643 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
644 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
645 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
646 return FALSE;
647 }
648
649 OSLibWinSetOwner(OS2Hwnd, OS2HwndFrame);
650
651 fakeWinBase.hwndThis = OS2Hwnd;
652 fakeWinBase.pWindowClass = windowClass;
653
654 //Set icon from class
655 if(windowClass->getIcon())
656 SetIcon(windowClass->getIcon());
657 /* Get class or window DC if needed */
658 if(windowClass->getStyle() & CS_OWNDC) {
659 dprintf(("Class with CS_OWNDC style"));
660// ownDC = GetWindowDC(getWindowHandle());
661 }
662 else
663 if (windowClass->getStyle() & CS_PARENTDC) {
664 dprintf(("WARNING: Class with CS_PARENTDC style!"));
665 fParentDC = TRUE;
666 ownDC = 0;
667 }
668 else
669 if (windowClass->getStyle() & CS_CLASSDC) {
670 dprintf(("WARNING: Class with CS_CLASSDC style!"));
671 ownDC = 0;
672 }
673 /* Set the window menu */
674 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
675 {
676 if (cs->hMenu) {
677 SetMenu(cs->hMenu);
678 }
679 else {
680 if (windowClass->getMenuNameA()) {
681 cs->hMenu = LoadMenuA(cs->hInstance, windowClass->getMenuNameA());
682 if (cs->hMenu) SetMenu(cs->hMenu );
683 }
684 }
685 }
686 else
687 {
688 setWindowId((DWORD)cs->hMenu);
689 }
690 hSysMenu = (dwStyle & WS_SYSMENU) ? MENU_GetSysMenu(Win32Hwnd,0):0;
691
692 // Subclass frame
693 pOldFrameProc = FrameSubclassFrameWindow(this);
694 //if (isChild()) FrameSetBorderSize(this,TRUE);
695
696 //preset rects
697 rectWindow.left = cs->x;
698 rectWindow.right = cs->x+cs->cx;
699 rectWindow.top = cs->y;
700 rectWindow.bottom = cs->y+cs->cy;
701 rectClient = rectWindow; //dummy client rect
702 if (getParent()) mapWin32Rect(getParent()->getOS2WindowHandle(),OSLIB_HWND_DESKTOP,&rectWindow);
703 /* Send the WM_CREATE message
704 * Perhaps we shouldn't allow width/height changes as well.
705 * See p327 in "Internals".
706 */
707 maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
708
709 //Note: Solitaire crashes when receiving WM_SIZE messages before WM_CREATE
710 //fNoSizeMsg = FALSE;
711 fCreated = TRUE;
712
713 if (SendInternalMessageA(WM_NCCREATE,0,(LPARAM)cs))
714 {
715 //update rect
716 rectWindow.left = cs->x;
717 rectWindow.right = cs->x+cs->cx;
718 rectWindow.top = cs->y;
719 rectWindow.bottom = cs->y+cs->cy;
720 if (getParent()) mapWin32Rect(getParent()->getOS2WindowHandle(),OSLIB_HWND_DESKTOP,&rectWindow);
721 OffsetRect(&rectWindow, maxPos.x - rectWindow.left, maxPos.y - rectWindow.top);
722 rectClient = rectWindow;
723 if (getParent()) mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2WindowHandle(),&rectClient);
724 //set the window size and update the client
725 SetWindowPos(hwndLinkAfter,rectClient.left,rectClient.top,rectClient.right-rectClient.left,rectClient.bottom-rectClient.top,SWP_NOACTIVATE | SWP_NOREDRAW | SWP_FRAMECHANGED);
726 fNoSizeMsg = FALSE;
727 if (cs->style & WS_VISIBLE) dwStyle |= WS_VISIBLE; //program could change position in WM_CREATE
728 if( (SendInternalMessageA(WM_CREATE, 0, (LPARAM)cs )) != -1 )
729 {
730 if(!(flags & WIN_NEED_SIZE)) {
731 SendInternalMessageA(WM_SIZE, SIZE_RESTORED,
732 MAKELONG(rectClient.right-rectClient.left,
733 rectClient.bottom-rectClient.top));
734 SendInternalMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
735 }
736
737 if( (getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
738 {
739 /* Notify the parent window only */
740 SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, getWindowId()), (LPARAM)getWindowHandle());
741 if(!::IsWindow(getWindowHandle()))
742 {
743 dprintf(("Createwindow: WM_PARENTNOTIFY destroyed window"));
744 goto end;
745 }
746 }
747
748 if (cs->style & WS_VISIBLE) ShowWindow(sw);
749
750 /* Call WH_SHELL hook */
751 if (!(getStyle() & WS_CHILD) && !owner)
752 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWCREATED, getWindowHandle(), 0 );
753
754 SetLastError(0);
755 return TRUE;
756 }
757 }
758 dprintf(("Window creation FAILED (NCCREATE cancelled creation)"));
759 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
760end:
761 return FALSE;
762}
763//******************************************************************************
764//******************************************************************************
765ULONG Win32BaseWindow::MsgQuit()
766{
767 return SendInternalMessageA(WM_QUIT, 0, 0);
768}
769//******************************************************************************
770//******************************************************************************
771ULONG Win32BaseWindow::MsgClose()
772{
773 return SendInternalMessageA(WM_CLOSE,0,0);
774}
775//******************************************************************************
776//******************************************************************************
777ULONG Win32BaseWindow::MsgDestroy()
778{
779 ULONG rc;
780 Win32BaseWindow *child;
781 HWND hwnd = getWindowHandle();
782
783 if (isSubclassedOS2Wnd) OSLibWinSubclassWindow(OS2Hwnd,pOldWndProc);
784
785 fIsDestroyed = TRUE;
786
787 if(fDestroyWindowCalled == FALSE)
788 {//this window was destroyed because DestroyWindow was called for it's parent
789 //so: send a WM_PARENTNOTIFY now as that hasn't happened yet
790 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
791 {
792 if(getParent())
793 {
794 /* Notify the parent window only */
795 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
796 }
797 else DebugInt3();
798 }
799 }
800 SendInternalMessageA(WM_DESTROY, 0, 0);
801 if(::IsWindow(hwnd) == FALSE) {
802 //object already destroyed, so return immediately
803 return 1;
804 }
805 SendInternalMessageA(WM_NCDESTROY, 0, 0);
806
807 TIMER_KillTimerFromWindow(OS2Hwnd);
808
809 if(getFirstChild() == NULL) {
810 delete this;
811 }
812 return 1;
813}
814//******************************************************************************
815//******************************************************************************
816ULONG Win32BaseWindow::MsgEnable(BOOL fEnable)
817{
818 if(fEnable) {
819 dwStyle &= ~WS_DISABLED;
820 }
821 else dwStyle |= WS_DISABLED;
822
823 return SendInternalMessageA(WM_ENABLE, fEnable, 0);
824}
825//******************************************************************************
826//TODO: SW_PARENTCLOSING/OPENING flag (lParam)
827//******************************************************************************
828ULONG Win32BaseWindow::MsgShow(BOOL fShow)
829{
830 if(fNoSizeMsg) {
831 return 1;
832 }
833
834 if(fShow) {
835 setStyle(getStyle() | WS_VISIBLE);
836 }
837 else setStyle(getStyle() & ~WS_VISIBLE);
838
839 return SendInternalMessageA(WM_SHOWWINDOW, fShow, 0);
840}
841//******************************************************************************
842//******************************************************************************
843ULONG Win32BaseWindow::MsgPosChanging(LPARAM lp)
844{
845 //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
846 // a WM_WINDOWPOSCHANGED msg -> crash)
847 if(fNoSizeMsg || fDestroyWindowCalled)
848 return 1;
849
850 return SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, lp);
851}
852//******************************************************************************
853//******************************************************************************
854ULONG Win32BaseWindow::MsgPosChanged(LPARAM lp)
855{
856 //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
857 // a WM_WINDOWPOSCHANGED msg -> crash)
858 if(fNoSizeMsg || fDestroyWindowCalled)
859 return 1;
860
861 return SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, lp);
862}
863//******************************************************************************
864//******************************************************************************
865#if 0
866ULONG Win32BaseWindow::MsgMinMax()
867{
868
869}
870#endif
871//******************************************************************************
872//******************************************************************************
873ULONG Win32BaseWindow::MsgScroll(ULONG msg, ULONG scrollCode, ULONG scrollPos)
874{
875 //According to the SDK docs, the scrollbar handle (lParam) is 0 when the standard
876 //window scrollbars send these messages
877 return SendInternalMessageA(msg, MAKELONG(scrollCode, scrollPos), 0);
878}
879//******************************************************************************
880//******************************************************************************
881ULONG Win32BaseWindow::MsgHitTest(MSG *msg)
882{
883 lastHitTestVal = SendInternalMessageA(WM_NCHITTEST,msg->wParam,msg->lParam);
884 dprintf2(("MsgHitTest returned %x", lastHitTestVal));
885
886 if (lastHitTestVal == HTERROR)
887 return HTOS_ERROR;
888
889#if 0 //CB: problems with groupboxes, internal handling is better
890 if (lastHitTestVal == HTTRANSPARENT)
891 return HTOS_TRANSPARENT;
892#endif
893
894 return HTOS_NORMAL;
895}
896//******************************************************************************
897//******************************************************************************
898ULONG Win32BaseWindow::MsgActivate(BOOL fActivate, BOOL fMinimized, HWND hwnd)
899{
900 ULONG rc, curprocid, procidhwnd = -1, threadidhwnd = 0;
901
902
903 //According to SDK docs, if app returns FALSE & window is being deactivated,
904 //default processing is cancelled
905 //TODO: According to Wine we should proceed anyway if window is sysmodal
906 if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
907 {
908 return 0;
909 }
910 rc = SendInternalMessageA(WM_ACTIVATE, MAKELONG((fActivate) ? WA_ACTIVE : WA_INACTIVE, fMinimized), hwnd);
911
912 curprocid = GetCurrentProcessId();
913 if(hwnd) {
914 threadidhwnd = GetWindowThreadProcessId(hwnd, &procidhwnd);
915 }
916
917 if(curprocid != procidhwnd && fActivate) {
918 SendInternalMessageA(WM_ACTIVATEAPP, 1, threadidhwnd);
919 }
920 return rc;
921}
922//******************************************************************************
923//TODO: Is this correct and complete?
924//Add print screen, break & numlock
925//******************************************************************************
926void Win32BaseWindow::setExtendedKey(ULONG virtualkey, ULONG *lParam)
927{
928 switch(virtualkey) {
929 case VK_DOWN:
930 case VK_UP:
931 case VK_PRIOR:
932 case VK_NEXT:
933 case VK_END:
934 case VK_DIVIDE:
935 case VK_DELETE:
936 case VK_EXECUTE: //Numeric enter key?
937 case VK_HOME:
938 case VK_INSERT:
939 case VK_RCONTROL:
940 case VK_RMENU: //is this the right alt???
941 *lParam = *lParam | (1<<24);
942 }
943}
944//******************************************************************************
945//******************************************************************************
946ULONG Win32BaseWindow::DispatchMsgA(MSG *msg)
947{
948 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
949}
950//******************************************************************************
951//******************************************************************************
952ULONG Win32BaseWindow::DispatchMsgW(MSG *msg)
953{
954 return SendInternalMessageW(msg->message, msg->wParam, msg->lParam);
955}
956//******************************************************************************
957//******************************************************************************
958ULONG Win32BaseWindow::MsgSetFocus(HWND hwnd)
959{
960 return SendInternalMessageA(WM_SETFOCUS, hwnd, 0);
961}
962//******************************************************************************
963//******************************************************************************
964ULONG Win32BaseWindow::MsgKillFocus(HWND hwnd)
965{
966 return SendInternalMessageA(WM_KILLFOCUS, hwnd, 0);
967}
968//******************************************************************************
969//******************************************************************************
970ULONG Win32BaseWindow::MsgButton(MSG *msg)
971{
972 BOOL fClick = FALSE;
973
974 dprintf(("MsgButton at (%d,%d)", msg->pt.x, msg->pt.y));
975 switch(msg->message) {
976 case WM_LBUTTONDBLCLK:
977 case WM_RBUTTONDBLCLK:
978 case WM_MBUTTONDBLCLK:
979 case WM_NCLBUTTONDBLCLK:
980 case WM_NCRBUTTONDBLCLK:
981 case WM_NCMBUTTONDBLCLK:
982 if (!(windowClass && windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS) && (msg->message != WM_NCLBUTTONDBLCLK))
983 {
984 msg->message = msg->message - (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN); //dblclick -> down
985 MsgButton(msg);
986 msg->message++; //button-up
987 return MsgButton(msg);
988 }
989 break;
990 case WM_LBUTTONDOWN:
991 case WM_RBUTTONDOWN:
992 case WM_MBUTTONDOWN:
993 case WM_NCLBUTTONDOWN:
994 case WM_NCRBUTTONDOWN:
995 case WM_NCMBUTTONDOWN:
996 fClick = TRUE;
997 break;
998 }
999
1000 if(ISMOUSE_CAPTURED())
1001 {
1002 if(DInputMouseHandler(getWindowHandle(), MOUSEMSG_BUTTON, msg->pt.x, msg->pt.y))
1003 return 0;
1004 }
1005
1006 if(fClick)
1007 {
1008 HWND hwndTop;
1009
1010 /* Activate the window if needed */
1011 if(isSubclassedOS2Wnd()) {
1012 Win32BaseWindow *parentwnd = GetWindowFromOS2FrameHandle(OSLibWinQueryWindow(OS2Hwnd, QWOS_PARENT));
1013 if(parentwnd) {
1014 hwndTop = (parentwnd->GetTopParent()) ? parentwnd->GetTopParent()->getWindowHandle() : 0;
1015 }
1016 else hwndTop = 0;
1017 }
1018 else hwndTop = (GetTopParent()) ? GetTopParent()->getWindowHandle() : 0;
1019
1020 HWND hwndActive = GetActiveWindow();
1021 if (hwndTop && (getWindowHandle() != hwndActive))
1022 {
1023 LONG ret = SendInternalMessageA(WM_MOUSEACTIVATE, hwndTop,
1024 MAKELONG( lastHitTestVal, msg->message) );
1025
1026#if 0
1027 if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
1028 eatMsg = TRUE;
1029#endif
1030 if(((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT))
1031 && hwndTop != GetForegroundWindow() )
1032 {
1033 ::SetActiveWindow(hwndTop);
1034 }
1035 }
1036 }
1037
1038 SendInternalMessageA(WM_SETCURSOR, getWindowHandle(), MAKELONG(lastHitTestVal, msg->message));
1039
1040 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1041}
1042//******************************************************************************
1043//******************************************************************************
1044ULONG Win32BaseWindow::MsgPaint(ULONG tmp1, BOOL select)
1045{
1046 if (select && isIcon)
1047 return SendInternalMessageA(WM_PAINTICON, 0, 0);
1048 else
1049 return SendInternalMessageA(WM_PAINT, 0, 0);
1050}
1051//******************************************************************************
1052//TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
1053// (or are we simply erasing too much here)
1054//******************************************************************************
1055ULONG Win32BaseWindow::MsgEraseBackGround(HDC hdc)
1056{
1057 ULONG rc;
1058 HDC hdcErase = hdc;
1059
1060 if (hdcErase == 0)
1061 hdcErase = O32_GetDC(OS2Hwnd);
1062
1063 if(isIcon)
1064 rc = SendInternalMessageA(WM_ICONERASEBKGND, hdcErase, 0);
1065 else
1066 rc = SendInternalMessageA(WM_ERASEBKGND, hdcErase, 0);
1067 if (hdc == 0)
1068 O32_ReleaseDC(OS2Hwnd, hdcErase);
1069 return (rc);
1070}
1071//******************************************************************************
1072//******************************************************************************
1073ULONG Win32BaseWindow::MsgMouseMove(MSG *msg)
1074{
1075 if(ISMOUSE_CAPTURED()) {
1076 if(DInputMouseHandler(getWindowHandle(), MOUSEMSG_MOVE, msg->pt.x, msg->pt.y))
1077 return 0;
1078 }
1079
1080 //TODO: hiword should be 0 if window enters menu mode (SDK docs)
1081 SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, msg->message));
1082
1083 //translated message == WM_(NC)MOUSEMOVE
1084 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1085}
1086//******************************************************************************
1087//TODO: Depending on menu type, we should send WM_INITMENU or WM_INITPOPUPMENU
1088//TODO: PM sends it for each submenu that gets activated; Windows only for the first
1089// submenu; once the menu bar is active, moving the cursor doesn't generate other
1090// WM_INITMENU msgs. Not really a problem, but might need to fix this later on.
1091//******************************************************************************
1092ULONG Win32BaseWindow::MsgInitMenu(MSG *msg)
1093{
1094 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1095}
1096//******************************************************************************
1097//******************************************************************************
1098ULONG Win32BaseWindow::MsgNCPaint()
1099{
1100 RECT rect;
1101
1102 if (GetOS2UpdateRect(OS2HwndFrame,&rect))
1103 {
1104 HRGN hrgn;
1105 ULONG rc;
1106 RECT client = rectClient;
1107
1108//CB: bug in dc.cpp!!!
1109 if ((rect.left == rect.right) || (rect.bottom == rect.top)) return 0;
1110 mapWin32Rect(getParent() ? getParent()->getOS2WindowHandle():OSLIB_HWND_DESKTOP,OS2HwndFrame,&client);
1111 if ((rect.left >= client.left) && (rect.left < client.right) &&
1112 (rect.right >= client.left) && (rect.right < client.right) &&
1113 (rect.top >= client.top) && (rect.top < client.bottom) &&
1114 (rect.bottom >= client.top) && (rect.bottom < client.bottom))
1115 return 0;
1116 hrgn = CreateRectRgnIndirect(&rect);
1117 if (!hrgn) return 0;
1118//CB: bug in GetDCEx with region!!!
1119 rc = SendInternalMessageA(WM_NCPAINT,/*hrgn*/0,0);
1120//dprintf(("CB: %d %d %d %d",rect.left,rect.top,rect.bottom,rect.right));
1121 DeleteObject(hrgn);
1122 //CB: todo: check if intersection with client
1123
1124 return rc;
1125 } else return 0;
1126}
1127//******************************************************************************
1128//******************************************************************************
1129ULONG Win32BaseWindow::MsgFormatFrame()
1130{
1131 RECT window = rectWindow,client = rectClient,rect;
1132 WINDOWPOS wndPos;
1133
1134 wndPos.hwnd = Win32Hwnd;
1135 wndPos.hwndInsertAfter = 0;
1136 rect = rectWindow;
1137 if (getParent()) mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2WindowHandle(),&rect);
1138 wndPos.x = rect.left;
1139 wndPos.y = rect.top;
1140 wndPos.cx = rect.right-rect.left;
1141 wndPos.cy = rect.bottom-rect.top;
1142 wndPos.flags = 0; //dummy
1143
1144 return SendNCCalcSize(TRUE,&window,&window,&client,&wndPos,&rectClient);
1145}
1146//******************************************************************************
1147//******************************************************************************
1148ULONG Win32BaseWindow::MsgSetText(LPSTR lpsz, LONG cch)
1149{
1150 return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
1151}
1152//******************************************************************************
1153//******************************************************************************
1154ULONG Win32BaseWindow::MsgGetTextLength()
1155{
1156 return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
1157}
1158//******************************************************************************
1159//******************************************************************************
1160char *Win32BaseWindow::MsgGetText()
1161{
1162 SendInternalMessageA(WM_GETTEXT, wndNameLength, (LPARAM)windowNameA);
1163 return windowNameA;
1164}
1165//******************************************************************************
1166//******************************************************************************
1167ULONG Win32BaseWindow::MsgContextMenu(ULONG x,ULONG y)
1168{
1169 return SendInternalMessageA(WM_CONTEXTMENU,Win32Hwnd,MAKELPARAM(x,y));
1170}
1171//******************************************************************************
1172//******************************************************************************
1173BOOL Win32BaseWindow::isMDIClient()
1174{
1175 return FALSE;
1176}
1177//******************************************************************************
1178//******************************************************************************
1179BOOL Win32BaseWindow::isMDIChild()
1180{
1181 return FALSE;
1182}
1183//******************************************************************************
1184//TODO: Not complete
1185//******************************************************************************
1186BOOL Win32BaseWindow::isFrameWindow()
1187{
1188// if(isMDIChild() || IsDialog() || (getParent() == NULL || getParent() == windowDesktop) && ((dwStyle & WS_CAPTION) == WS_CAPTION))
1189 if((dwStyle & WS_CAPTION) == WS_CAPTION || dwStyle & (WS_VSCROLL|WS_HSCROLL))
1190 return TRUE;
1191
1192 return FALSE;
1193}
1194//******************************************************************************
1195//******************************************************************************
1196SCROLLBAR_INFO *Win32BaseWindow::getScrollInfo(int nBar)
1197{
1198 switch(nBar)
1199 {
1200 case SB_HORZ:
1201 if (!horzScrollInfo)
1202 {
1203 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1204 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
1205 horzScrollInfo->MaxVal = 100;
1206 horzScrollInfo->flags = ESB_ENABLE_BOTH;
1207 }
1208 return horzScrollInfo;
1209
1210 case SB_VERT:
1211 if (!vertScrollInfo)
1212 {
1213 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1214 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
1215 vertScrollInfo->MaxVal = 100;
1216 vertScrollInfo->flags = ESB_ENABLE_BOTH;
1217 }
1218 return vertScrollInfo;
1219 }
1220
1221 return NULL;
1222}
1223//******************************************************************************
1224//******************************************************************************
1225LONG Win32BaseWindow::HandleNCActivate(WPARAM wParam)
1226{
1227 WORD wStateChange;
1228
1229 if( wParam ) wStateChange = !(flags & WIN_NCACTIVATED);
1230 else wStateChange = flags & WIN_NCACTIVATED;
1231
1232 if( wStateChange )
1233 {
1234 if (wParam) flags |= WIN_NCACTIVATED;
1235 else flags &= ~WIN_NCACTIVATED;
1236
1237 if(!(dwStyle & WS_MINIMIZE))
1238 DoNCPaint((HRGN)1,FALSE);
1239 }
1240
1241 return TRUE;
1242}
1243//******************************************************************************
1244//******************************************************************************
1245VOID Win32BaseWindow::TrackMinMaxBox(WORD wParam)
1246{
1247 MSG msg;
1248 HDC hdc;
1249 BOOL pressed = TRUE;
1250 UINT state;
1251
1252 if (wParam == HTMINBUTTON)
1253 {
1254 /* If the style is not present, do nothing */
1255 if (!(dwStyle & WS_MINIMIZEBOX))
1256 return;
1257 /* Check if the sysmenu item for minimize is there */
1258 state = GetMenuState(hSysMenu,SC_MINIMIZE,MF_BYCOMMAND);
1259 } else
1260 {
1261 /* If the style is not present, do nothing */
1262 if (!(dwStyle & WS_MAXIMIZEBOX))
1263 return;
1264 /* Check if the sysmenu item for maximize is there */
1265 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
1266 }
1267 SetCapture(Win32Hwnd);
1268 hdc = GetWindowDC(Win32Hwnd);
1269 if (wParam == HTMINBUTTON)
1270 DrawMinButton(hdc,TRUE,FALSE);
1271 else
1272 DrawMaxButton(hdc,TRUE,FALSE);
1273 do
1274 {
1275 BOOL oldstate = pressed;
1276
1277 GetMessageA(&msg,Win32Hwnd,0,0);
1278 pressed = (HandleNCHitTest(msg.pt) == wParam);
1279 if (pressed != oldstate)
1280 {
1281 if (wParam == HTMINBUTTON)
1282 DrawMinButton(hdc,pressed,FALSE);
1283 else
1284 DrawMaxButton(hdc,pressed,FALSE);
1285 }
1286 } while (msg.message != WM_LBUTTONUP);
1287 if (wParam == HTMINBUTTON)
1288 DrawMinButton(hdc,FALSE,FALSE);
1289 else
1290 DrawMaxButton(hdc,FALSE,FALSE);
1291 ReleaseCapture();
1292 ReleaseDC(Win32Hwnd,hdc);
1293 /* If the item minimize or maximize of the sysmenu are not there */
1294 /* or if the style is not present, do nothing */
1295 if ((!pressed) || (state == 0xFFFFFFFF))
1296 return;
1297 if (wParam == HTMINBUTTON)
1298 SendInternalMessageA(WM_SYSCOMMAND,SC_MINIMIZE,*(LPARAM*)&msg.pt);
1299 else
1300 SendInternalMessageA(WM_SYSCOMMAND,IsZoomed(Win32Hwnd) ? SC_RESTORE:SC_MAXIMIZE,*(LPARAM*)&msg.pt);
1301}
1302//******************************************************************************
1303//******************************************************************************
1304VOID Win32BaseWindow::TrackCloseButton(WORD wParam)
1305{
1306 MSG msg;
1307 HDC hdc;
1308 BOOL pressed = TRUE;
1309 UINT state;
1310
1311 if (hSysMenu == 0)
1312 return;
1313 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1314 /* If the item close of the sysmenu is disabled or not there do nothing */
1315 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
1316 return;
1317 hdc = GetWindowDC(Win32Hwnd);
1318 SetCapture(Win32Hwnd);
1319 DrawCloseButton(hdc,TRUE,FALSE);
1320 do
1321 {
1322 BOOL oldstate = pressed;
1323
1324 GetMessageA(&msg,Win32Hwnd,0,0);
1325 pressed = (HandleNCHitTest(msg.pt) == wParam);
1326 if (pressed != oldstate)
1327 DrawCloseButton(hdc, pressed, FALSE);
1328 } while (msg.message != WM_LBUTTONUP);
1329 DrawCloseButton(hdc,FALSE,FALSE);
1330 ReleaseCapture();
1331 ReleaseDC(Win32Hwnd,hdc);
1332 if (!pressed) return;
1333 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,*(LPARAM*)&msg.pt);
1334}
1335//******************************************************************************
1336//******************************************************************************
1337VOID Win32BaseWindow::TrackScrollBar(WPARAM wParam,POINT pt)
1338{
1339 INT scrollbar;
1340 MSG msg;
1341
1342 if ((wParam & 0xfff0) == SC_HSCROLL)
1343 {
1344 if ((wParam & 0x0f) != HTHSCROLL) return;
1345 scrollbar = SB_HORZ;
1346 } else /* SC_VSCROLL */
1347 {
1348 if ((wParam & 0x0f) != HTVSCROLL) return;
1349 scrollbar = SB_VERT;
1350 }
1351
1352 pt.x -= rectWindow.left;
1353 pt.y -= rectWindow.top;
1354 SCROLL_HandleScrollEvent(Win32Hwnd,0,MAKELONG(pt.x,pt.y),scrollbar,WM_LBUTTONDOWN);
1355 if (GetCapture() != Win32Hwnd) return;
1356 do
1357 {
1358 GetMessageA(&msg,Win32Hwnd,0,0);
1359 switch(msg.message)
1360 {
1361 case WM_LBUTTONUP:
1362 case WM_MOUSEMOVE:
1363 pt.x = msg.pt.x-rectWindow.left;
1364 pt.y = msg.pt.y-rectWindow.top;
1365 msg.lParam = MAKELONG(pt.x,pt.y);
1366 case WM_SYSTIMER:
1367 SCROLL_HandleScrollEvent(Win32Hwnd,msg.wParam,msg.lParam,scrollbar,msg.message);
1368 break;
1369
1370 default:
1371 TranslateMessage(&msg);
1372 DispatchMessageA(&msg);
1373 break;
1374 }
1375 if (!IsWindow())
1376 {
1377 ReleaseCapture();
1378 break;
1379 }
1380 } while (msg.message != WM_LBUTTONUP);
1381}
1382//******************************************************************************
1383//******************************************************************************
1384LONG Win32BaseWindow::HandleNCLButtonDown(WPARAM wParam,LPARAM lParam)
1385{
1386 switch(wParam) /* Hit test */
1387 {
1388 case HTCAPTION:
1389 SetActiveWindow();
1390 if (GetActiveWindow() == Win32Hwnd)
1391 SendInternalMessageA(WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
1392 break;
1393
1394 case HTSYSMENU:
1395 if(dwStyle & WS_SYSMENU )
1396 {
1397 if( !(dwStyle & WS_MINIMIZE) )
1398 {
1399 HDC hDC = GetWindowDC(Win32Hwnd);
1400 DrawSysButton(hDC,TRUE);
1401 ReleaseDC(Win32Hwnd,hDC);
1402 }
1403 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
1404 }
1405 break;
1406
1407 case HTMENU:
1408 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU,lParam);
1409 break;
1410
1411 case HTHSCROLL:
1412 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
1413 break;
1414
1415 case HTVSCROLL:
1416 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
1417 break;
1418
1419 case HTMINBUTTON:
1420 case HTMAXBUTTON:
1421 TrackMinMaxBox(wParam);
1422 break;
1423
1424 case HTCLOSE:
1425 TrackCloseButton(wParam);
1426 break;
1427
1428 case HTLEFT:
1429 case HTRIGHT:
1430 case HTTOP:
1431 case HTTOPLEFT:
1432 case HTTOPRIGHT:
1433 case HTBOTTOM:
1434 case HTBOTTOMLEFT:
1435 case HTBOTTOMRIGHT:
1436 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
1437 SendInternalMessageA(WM_SYSCOMMAND,SC_SIZE+wParam-2,lParam);
1438 break;
1439 case HTBORDER:
1440 break;
1441 }
1442
1443 return 0;
1444}
1445//******************************************************************************
1446//******************************************************************************
1447BOOL Win32BaseWindow::WindowNeedsWMBorder()
1448{
1449 if (!(dwStyle & WS_CHILD) &&
1450 //Options.managed && //CB: to check
1451 !(dwExStyle & WS_EX_TOOLWINDOW) &&
1452 ( ((dwStyle & WS_CAPTION) == WS_CAPTION) ||
1453 (dwStyle & WS_THICKFRAME)))
1454 return TRUE;
1455 if (dwExStyle & WS_EX_TRAYWINDOW)
1456 return TRUE;
1457 return FALSE;
1458}
1459//******************************************************************************
1460//******************************************************************************
1461VOID Win32BaseWindow::AdjustRectOuter(LPRECT rect,BOOL menu)
1462{
1463 if(dwStyle & WS_ICONIC) return;
1464
1465 /* Decide if the window will be managed (see CreateWindowEx) */
1466 //if (!WindowNeedsWMBorder()) //CB: check Options.managed
1467 {
1468 if (HAS_THICKFRAME(dwStyle,dwExStyle ))
1469 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
1470 else
1471 if (HAS_DLGFRAME( dwStyle, dwExStyle ))
1472 InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
1473 else
1474 if (HAS_THINFRAME( dwStyle ))
1475 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
1476
1477 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1478 {
1479 if (dwExStyle & WS_EX_TOOLWINDOW)
1480 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
1481 else
1482 rect->top -= GetSystemMetrics(SM_CYCAPTION);
1483 }
1484 }
1485
1486 if (menu)
1487 rect->top -= GetSystemMetrics(SM_CYMENU);
1488}
1489//******************************************************************************
1490//******************************************************************************
1491VOID Win32BaseWindow::AdjustRectInner(LPRECT rect)
1492{
1493 if(dwStyle & WS_ICONIC) return;
1494
1495 if (dwExStyle & WS_EX_CLIENTEDGE)
1496 InflateRect (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
1497
1498 if (dwExStyle & WS_EX_STATICEDGE)
1499 InflateRect (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
1500
1501 if (dwStyle & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
1502 if (dwStyle & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
1503}
1504//******************************************************************************
1505//******************************************************************************
1506LONG Win32BaseWindow::HandleNCCalcSize(BOOL calcValidRects,RECT *winRect)
1507{
1508 RECT tmpRect = { 0, 0, 0, 0 },*clientRect;
1509 LONG result = WVR_ALIGNTOP | WVR_ALIGNLEFT;
1510 UINT style;
1511
1512 if (!calcValidRects) return 0;
1513
1514 style = (UINT) GetClassLongA(Win32Hwnd,GCL_STYLE);
1515
1516 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
1517 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
1518
1519 clientRect = &((NCCALCSIZE_PARAMS*)winRect)->rgrc[2];
1520 *clientRect = rectWindow;
1521 if (getParent()) mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2WindowHandle(),clientRect);
1522
1523 if(!(dwStyle & WS_MINIMIZE))
1524 {
1525 AdjustRectOuter(&tmpRect,FALSE);
1526
1527 clientRect->left -= tmpRect.left;
1528 clientRect->top -= tmpRect.top;
1529 clientRect->right -= tmpRect.right;
1530 clientRect->bottom -= tmpRect.bottom;
1531
1532 if (HAS_MENU())
1533 {
1534 clientRect->top +=
1535 MENU_GetMenuBarHeight(Win32Hwnd,
1536 winRect->right - winRect->left,
1537 -tmpRect.left, -tmpRect.top ) + 1;
1538 }
1539
1540 SetRect (&tmpRect, 0, 0, 0, 0);
1541 AdjustRectInner(&tmpRect);
1542 clientRect->left -= tmpRect.left;
1543 clientRect->top -= tmpRect.top;
1544 clientRect->right -= tmpRect.right;
1545 clientRect->bottom -= tmpRect.bottom;
1546 }
1547
1548 return result;
1549}
1550//******************************************************************************
1551//******************************************************************************
1552LONG Win32BaseWindow::HandleNCHitTest(POINT pt)
1553{
1554 RECT rect = rectWindow;
1555
1556 if (!PtInRect(&rect,pt)) return HTNOWHERE;
1557
1558 if (dwStyle & WS_MINIMIZE) return HTCAPTION;
1559
1560 if (!(flags & WIN_MANAGED))
1561 {
1562 /* Check borders */
1563 if (HAS_THICKFRAME(dwStyle,dwExStyle))
1564 {
1565 InflateRect(&rect,-GetSystemMetrics(SM_CXFRAME),-GetSystemMetrics(SM_CYFRAME));
1566 if (!PtInRect(&rect,pt))
1567 {
1568 /* Check top sizing border */
1569 if (pt.y < rect.top)
1570 {
1571 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
1572 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
1573 return HTTOP;
1574 }
1575 /* Check bottom sizing border */
1576 if (pt.y >= rect.bottom)
1577 {
1578 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
1579 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
1580 return HTBOTTOM;
1581 }
1582 /* Check left sizing border */
1583 if (pt.x < rect.left)
1584 {
1585 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
1586 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
1587 return HTLEFT;
1588 }
1589 /* Check right sizing border */
1590 if (pt.x >= rect.right)
1591 {
1592 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
1593 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
1594 return HTRIGHT;
1595 }
1596 }
1597 } else /* No thick frame */
1598 {
1599 if (HAS_DLGFRAME(dwStyle,dwExStyle))
1600 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
1601 else if (HAS_THINFRAME(dwStyle ))
1602 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
1603 if (!PtInRect( &rect, pt )) return HTBORDER;
1604 }
1605
1606 /* Check caption */
1607
1608 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1609 {
1610 if (dwExStyle & WS_EX_TOOLWINDOW)
1611 rect.top += GetSystemMetrics(SM_CYSMCAPTION)-1;
1612 else
1613 rect.top += GetSystemMetrics(SM_CYCAPTION)-1;
1614 if (!PtInRect(&rect,pt))
1615 {
1616 /* Check system menu */
1617 if(dwStyle & WS_SYSMENU)
1618 {
1619 /* Check if there is an user icon */
1620 HICON hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICONSM);
1621 if(!hIcon) hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICON);
1622
1623 /* If there is an icon associated with the window OR */
1624 /* If there is no hIcon specified and this is not a modal dialog, */
1625 /* there is a system menu icon. */
1626 if((hIcon != 0) || (!(dwStyle & DS_MODALFRAME)))
1627 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1628 }
1629 if (pt.x < rect.left) return HTSYSMENU;
1630
1631 /* Check close button */
1632 if (dwStyle & WS_SYSMENU)
1633 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1634 if (pt.x > rect.right) return HTCLOSE;
1635
1636 /* Check maximize box */
1637 /* In win95 there is automatically a Maximize button when there is a minimize one*/
1638 if ((dwStyle & WS_MAXIMIZEBOX)|| (dwStyle & WS_MINIMIZEBOX))
1639 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1640 if (pt.x > rect.right) return HTMAXBUTTON;
1641
1642 /* Check minimize box */
1643 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
1644 if ((dwStyle & WS_MINIMIZEBOX)||(dwStyle & WS_MAXIMIZEBOX))
1645 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1646
1647 if (pt.x > rect.right) return HTMINBUTTON;
1648 return HTCAPTION;
1649 }
1650 }
1651 }
1652
1653 /* Check client area */
1654
1655 ScreenToClient(Win32Hwnd,&pt);
1656 getClientRect(&rect);
1657 if (PtInRect(&rect,pt)) return HTCLIENT;
1658
1659 /* Check vertical scroll bar */
1660
1661 if (dwStyle & WS_VSCROLL)
1662 {
1663 rect.right += GetSystemMetrics(SM_CXVSCROLL);
1664 if (PtInRect( &rect, pt )) return HTVSCROLL;
1665 }
1666
1667 /* Check horizontal scroll bar */
1668
1669 if (dwStyle & WS_HSCROLL)
1670 {
1671 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
1672 if (PtInRect( &rect, pt ))
1673 {
1674 /* Check size box */
1675 if ((dwStyle & WS_VSCROLL) &&
1676 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
1677 return (dwStyle & WS_CHILD) ? HTSIZE:HTBOTTOMRIGHT;
1678 return HTHSCROLL;
1679 }
1680 }
1681
1682 /* Check menu bar */
1683
1684 if (HAS_MENU())
1685 {
1686 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
1687 return HTMENU;
1688 }
1689
1690 /* Should never get here */
1691 return HTERROR;
1692}
1693
1694//******************************************************************************
1695//******************************************************************************
1696VOID Win32BaseWindow::GetInsideRect(RECT *rect)
1697{
1698 rect->top = rect->left = 0;
1699 rect->right = rectWindow.right - rectWindow.left;
1700 rect->bottom = rectWindow.bottom - rectWindow.top;
1701
1702 if ((dwStyle & WS_ICONIC) || (flags & WIN_MANAGED)) return;
1703
1704 /* Remove frame from rectangle */
1705 if (HAS_THICKFRAME(dwStyle,dwExStyle))
1706 {
1707 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
1708 }
1709 else if (HAS_DLGFRAME(dwStyle,dwExStyle ))
1710 {
1711 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
1712 }
1713 else if (HAS_THINFRAME(dwStyle))
1714 {
1715 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
1716 }
1717
1718 /* We have additional border information if the window
1719 * is a child (but not an MDI child) */
1720 if ( (dwStyle & WS_CHILD) &&
1721 ( (dwExStyle & WS_EX_MDICHILD) == 0 ) )
1722 {
1723 if (dwExStyle & WS_EX_CLIENTEDGE)
1724 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
1725
1726 if (dwExStyle & WS_EX_STATICEDGE)
1727 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
1728 }
1729}
1730//******************************************************************************
1731//******************************************************************************
1732VOID Win32BaseWindow::DrawFrame(HDC hdc,RECT *rect,BOOL dlgFrame,BOOL active)
1733{
1734 INT width, height;
1735 HBRUSH oldBrush;
1736
1737 if (dlgFrame)
1738 {
1739 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1740 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1741 } else
1742 {
1743 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1744 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1745 }
1746
1747 oldBrush = SelectObject(hdc,GetSysColorBrush(active ? COLOR_ACTIVEBORDER:COLOR_INACTIVEBORDER));
1748
1749 /* Draw frame */
1750
1751 PatBlt(hdc,rect->left,rect->top,rect->right-rect->left,height,PATCOPY);
1752 PatBlt(hdc,rect->left,rect->top,width,rect->bottom-rect->top,PATCOPY);
1753 PatBlt(hdc,rect->left,rect->bottom-1,rect->right-rect->left,-height,PATCOPY);
1754 PatBlt(hdc,rect->right-1,rect->top,-width,rect->bottom-rect->top,PATCOPY);
1755 SelectObject(hdc,oldBrush);
1756
1757 InflateRect(rect,-width,-height);
1758}
1759//******************************************************************************
1760//******************************************************************************
1761BOOL Win32BaseWindow::DrawSysButton(HDC hdc,BOOL down)
1762{
1763 if(!(flags & WIN_MANAGED))
1764 {
1765 HICON hIcon;
1766 RECT rect;
1767
1768 GetInsideRect(&rect);
1769
1770 hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICONSM);
1771 if(!hIcon) hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICON);
1772
1773 /* If there is no hIcon specified or this is not a modal dialog, */
1774 /* get the default one. */
1775 if(hIcon == 0)
1776 if (!(dwStyle & DS_MODALFRAME))
1777 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_ODINICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
1778
1779 if (hIcon)
1780 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1781 GetSystemMetrics(SM_CXSMICON),
1782 GetSystemMetrics(SM_CYSMICON),
1783 0, 0, DI_NORMAL);
1784
1785 return (hIcon != 0);
1786 }
1787 return FALSE;
1788}
1789//******************************************************************************
1790//******************************************************************************
1791BOOL Win32BaseWindow::GetSysPopupPos(RECT* rect)
1792{
1793 if(hSysMenu)
1794 {
1795 if(dwStyle & WS_MINIMIZE )
1796 *rect = rectWindow;
1797 else
1798 {
1799 GetInsideRect(rect );
1800 OffsetRect( rect, rectWindow.left, rectWindow.top);
1801 if ((dwStyle & WS_CHILD) && getParent())
1802 ClientToScreen(getParent()->getWindowHandle(), (POINT *)rect );
1803 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
1804 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
1805 }
1806 return TRUE;
1807 }
1808 return FALSE;
1809}
1810//******************************************************************************
1811//******************************************************************************
1812BOOL Win32BaseWindow::DrawGrayButton(HDC hdc,int x,int y)
1813{
1814 HBITMAP hMaskBmp;
1815 HDC hdcMask = CreateCompatibleDC (0);
1816 HBRUSH hOldBrush;
1817 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
1818
1819 if(hMaskBmp == 0)
1820 return FALSE;
1821
1822 SelectObject (hdcMask, hMaskBmp);
1823
1824 /* Draw the grayed bitmap using the mask */
1825 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
1826 BitBlt (hdc, x, y, 12, 10,
1827 hdcMask, 0, 0, 0xB8074A);
1828
1829 /* Clean up */
1830 SelectObject (hdc, hOldBrush);
1831 DeleteObject(hMaskBmp);
1832 DeleteDC (hdcMask);
1833
1834 return TRUE;
1835}
1836//******************************************************************************
1837//******************************************************************************
1838VOID Win32BaseWindow::DrawCloseButton(HDC hdc,BOOL down,BOOL bGrayed)
1839{
1840 RECT rect;
1841 HDC hdcMem;
1842
1843 if( !(flags & WIN_MANAGED) )
1844 {
1845 BITMAP bmp;
1846 HBITMAP hBmp, hOldBmp;
1847
1848 GetInsideRect(&rect);
1849
1850 hdcMem = CreateCompatibleDC( hdc );
1851 hBmp = down ? hbitmapCloseD : hbitmapClose;
1852 hOldBmp = SelectObject (hdcMem, hBmp);
1853 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1854
1855 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1856 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1857 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1858
1859 if(bGrayed)
1860 DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1861 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1862
1863 SelectObject (hdcMem, hOldBmp);
1864 DeleteDC (hdcMem);
1865 }
1866}
1867//******************************************************************************
1868//******************************************************************************
1869VOID Win32BaseWindow::DrawMaxButton(HDC hdc,BOOL down,BOOL bGrayed)
1870{
1871 RECT rect;
1872 HDC hdcMem;
1873
1874 if( !(flags & WIN_MANAGED))
1875 {
1876 BITMAP bmp;
1877 HBITMAP hBmp,hOldBmp;
1878
1879 GetInsideRect(&rect);
1880 hdcMem = CreateCompatibleDC( hdc );
1881 hBmp = IsZoomed(Win32Hwnd) ?
1882 (down ? hbitmapRestoreD : hbitmapRestore ) :
1883 (down ? hbitmapMaximizeD: hbitmapMaximize);
1884 hOldBmp=SelectObject( hdcMem, hBmp );
1885 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1886
1887 if (dwStyle & WS_SYSMENU)
1888 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1889
1890 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1891 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1892 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1893
1894 if(bGrayed)
1895 DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1896 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1897
1898
1899 SelectObject (hdcMem, hOldBmp);
1900 DeleteDC( hdcMem );
1901 }
1902}
1903//******************************************************************************
1904//******************************************************************************
1905VOID Win32BaseWindow::DrawMinButton(HDC hdc,BOOL down,BOOL bGrayed)
1906{
1907 RECT rect;
1908 HDC hdcMem;
1909
1910 if( !(flags & WIN_MANAGED))
1911
1912 {
1913 BITMAP bmp;
1914 HBITMAP hBmp,hOldBmp;
1915
1916 GetInsideRect(&rect);
1917
1918 hdcMem = CreateCompatibleDC( hdc );
1919 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1920 hOldBmp= SelectObject( hdcMem, hBmp );
1921 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1922
1923 if (dwStyle & WS_SYSMENU)
1924 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1925
1926 /* In win 95 there is always a Maximize box when there is a Minimize one */
1927 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
1928 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1929
1930 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1931 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1932 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1933
1934 if(bGrayed)
1935 DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1936 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1937
1938
1939 SelectObject (hdcMem, hOldBmp);
1940 DeleteDC( hdcMem );
1941 }
1942}
1943//******************************************************************************
1944//******************************************************************************
1945VOID Win32BaseWindow::DrawCaption(HDC hdc,RECT *rect,BOOL active)
1946{
1947 RECT r = *rect;
1948 char buffer[256];
1949 HPEN hPrevPen;
1950
1951 if (flags & WIN_MANAGED) return;
1952
1953 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1954 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1955 LineTo( hdc, r.right, r.bottom - 1 );
1956 SelectObject( hdc, hPrevPen );
1957 r.bottom--;
1958
1959 if (SYSCOLOR_GetUseWinColors())
1960 {
1961 COLORREF startColor = GetSysColor(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION),endColor = GetSysColor(active ? COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION);
1962
1963 if (startColor == endColor)
1964 FillRect(hdc,&r,GetSysColorBrush(startColor));
1965 else
1966 {
1967 INT rDiff = GetRValue(endColor)-GetRValue(startColor);
1968 INT gDiff = GetGValue(endColor)-GetGValue(startColor);
1969 INT bDiff = GetBValue(endColor)-GetBValue(startColor);
1970 INT steps = MAX(MAX(abs(rDiff),abs(gDiff)),abs(bDiff));
1971 INT w = r.right-r.left;
1972 RECT r2;
1973
1974 if (w < steps) steps = w;
1975 r2.left = r2.right = r.left;
1976 r2.top = r.top;
1977 r2.bottom = r.bottom;
1978 for (INT x = 0;x <= steps;x++)
1979 {
1980 COLORREF color = RGB(GetRValue(startColor)+rDiff*x/steps,GetGValue(startColor)+gDiff*x/steps,GetBValue(startColor)+bDiff*x/steps);
1981 HBRUSH brush = CreateSolidBrush(color);
1982
1983 r2.left = r2.right;
1984 r2.right = r.left+w*x/steps;
1985 FillRect(hdc,&r2,brush);
1986 DeleteObject(brush);
1987 }
1988 }
1989 } else FillRect(hdc,&r,GetSysColorBrush(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION));
1990
1991 if (!hbitmapClose)
1992 {
1993 if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
1994 hbitmapCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
1995 hbitmapMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
1996 hbitmapMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
1997 hbitmapMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
1998 hbitmapMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
1999 hbitmapRestore = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
2000 hbitmapRestoreD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
2001 }
2002
2003 if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW))
2004 {
2005 if (DrawSysButton(hdc,FALSE))
2006 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
2007 }
2008
2009 if (dwStyle & WS_SYSMENU)
2010 {
2011 UINT state;
2012
2013 /* Go get the sysmenu */
2014 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2015
2016 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
2017 DrawCloseButton(hdc, FALSE,
2018 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
2019 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
2020
2021 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
2022 {
2023 /* In win95 the two buttons are always there */
2024 /* But if the menu item is not in the menu they're disabled*/
2025
2026 DrawMaxButton(hdc, FALSE, (!(dwStyle & WS_MAXIMIZEBOX)));
2027 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2028
2029 DrawMinButton(hdc, FALSE, (!(dwStyle & WS_MINIMIZEBOX)));
2030 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2031 }
2032 }
2033
2034 if (GetWindowTextA(buffer, sizeof(buffer) ))
2035 {
2036 NONCLIENTMETRICSA nclm;
2037 HFONT hFont, hOldFont;
2038 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
2039 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
2040 if (dwExStyle & WS_EX_TOOLWINDOW)
2041 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
2042 else
2043 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
2044 hOldFont = SelectObject (hdc, hFont);
2045 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
2046 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
2047 SetBkMode( hdc, TRANSPARENT );
2048 r.left += 2;
2049 DrawTextA( hdc, buffer, -1, &r,
2050 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
2051 DeleteObject (SelectObject (hdc, hOldFont));
2052 }
2053}
2054//******************************************************************************
2055//******************************************************************************
2056VOID Win32BaseWindow::DoNCPaint(HRGN clip,BOOL suppress_menupaint)
2057{
2058 BOOL active = flags & WIN_NCACTIVATED;
2059 HDC hdc;
2060 RECT rect,rectClip,rfuzz;
2061
2062 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
2063 the call to GetDCEx implying that it is allowed not to use it either.
2064 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
2065 will cause clipRgn to be deleted after ReleaseDC().
2066 Now, how is the "system" supposed to tell what happened?
2067 */
2068
2069 if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
2070 ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
2071
2072 rect.top = rect.left = 0;
2073 rect.right = rectWindow.right - rectWindow.left;
2074 rect.bottom = rectWindow.bottom - rectWindow.top;
2075
2076 if( clip > 1 )
2077 GetRgnBox( clip, &rectClip );
2078 else
2079 {
2080 clip = 0;
2081 rectClip = rect;
2082 }
2083
2084 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
2085
2086 if(!(flags & WIN_MANAGED))
2087 {
2088 if (HAS_BIGFRAME( dwStyle, dwExStyle))
2089 {
2090 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
2091 }
2092 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
2093 DrawFrame(hdc, &rect, FALSE, active );
2094 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
2095 DrawFrame( hdc, &rect, TRUE, active );
2096 else if (HAS_THINFRAME( dwStyle ))
2097 {
2098 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
2099 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
2100 }
2101
2102 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
2103 {
2104 RECT r = rect;
2105 if (dwExStyle & WS_EX_TOOLWINDOW)
2106 {
2107 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
2108 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
2109 }
2110 else
2111 {
2112 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
2113 rect.top += GetSystemMetrics(SM_CYCAPTION);
2114 }
2115 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
2116 DrawCaption(hdc, &r, active);
2117 }
2118 }
2119 if (HAS_MENU())
2120 {
2121 RECT r = rect;
2122 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
2123
2124 rect.top += MENU_DrawMenuBar( hdc, &r, Win32Hwnd, suppress_menupaint ) + 1;
2125 }
2126
2127 if (dwExStyle & WS_EX_CLIENTEDGE)
2128 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
2129
2130 if (dwExStyle & WS_EX_STATICEDGE)
2131 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
2132
2133 /* Draw the scroll-bars */
2134 if (dwStyle & WS_VSCROLL)
2135 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_VERT,TRUE,TRUE);
2136 if (dwStyle & WS_HSCROLL)
2137 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_HORZ,TRUE,TRUE);
2138
2139 /* Draw the "size-box" */
2140 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
2141 {
2142 RECT r = rect;
2143 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
2144 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
2145 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
2146 if (!(dwStyle & WS_CHILD))
2147 {
2148 POINT p1,p2;
2149 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
2150 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
2151 HPEN oldPen = SelectObject(hdc,penDark);
2152 INT x;
2153
2154 p1.x = r.right-1;
2155 p1.y = r.bottom;
2156 p2.x = r.right;
2157 p2.y = r.bottom-1;
2158 for (x = 0;x < 3;x++)
2159 {
2160 SelectObject(hdc,penDark);
2161 MoveToEx(hdc,p1.x,p1.y,NULL);
2162 LineTo(hdc,p2.x,p2.y);
2163 p1.x--;
2164 p2.y--;
2165 MoveToEx(hdc,p1.x,p1.y,NULL);
2166 LineTo(hdc,p2.x,p2.y);
2167 SelectObject(hdc,penWhite);
2168 p1.x--;
2169 p2.y--;
2170 MoveToEx(hdc,p1.x,p1.y,NULL);
2171 LineTo(hdc,p2.x,p2.y);
2172 p1.x -= 2;
2173 p2.y -= 2;
2174 }
2175
2176 SelectObject(hdc,oldPen);
2177 }
2178 }
2179
2180 ReleaseDC(Win32Hwnd,hdc);
2181}
2182//******************************************************************************
2183//******************************************************************************
2184LONG Win32BaseWindow::HandleNCPaint(HRGN clip)
2185{
2186//CB: ignore it for now (SetWindowPos in WM_CREATE)
2187// if (!(dwStyle & WS_VISIBLE)) return 0;
2188
2189 if (dwStyle & WS_MINIMIZE) return 0;
2190
2191 DoNCPaint(clip,FALSE);
2192
2193 return 0;
2194}
2195/***********************************************************************
2196 * NC_HandleNCLButtonDblClk
2197 *
2198 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2199 */
2200LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
2201{
2202 /*
2203 * if this is an icon, send a restore since we are handling
2204 * a double click
2205 */
2206 if (dwStyle & WS_MINIMIZE)
2207 {
2208 SendInternalMessageA(WM_SYSCOMMAND,SC_RESTORE,lParam);
2209 return 0;
2210 }
2211
2212 switch(wParam) /* Hit test */
2213 {
2214 case HTCAPTION:
2215 /* stop processing if WS_MAXIMIZEBOX is missing */
2216 if (dwStyle & WS_MAXIMIZEBOX)
2217 SendInternalMessageA(WM_SYSCOMMAND,
2218 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2219 lParam);
2220 break;
2221
2222 case HTSYSMENU:
2223 if (!(GetClassWord(Win32Hwnd,GCW_STYLE) & CS_NOCLOSE))
2224 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
2225 break;
2226
2227 case HTHSCROLL:
2228 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
2229 break;
2230
2231 case HTVSCROLL:
2232 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
2233 break;
2234 }
2235
2236 return 0;
2237}
2238/***********************************************************************
2239 * NC_HandleSysCommand
2240 *
2241 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2242 *
2243 * TODO: Not done (see #if 0)
2244 */
2245LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam,POINT *pt32)
2246{
2247 UINT uCommand = wParam & 0xFFF0;
2248
2249/* //CB: don't need this, perhaps recycle for menus
2250 if ((getStyle() & WS_CHILD) && (uCommand != SC_KEYMENU))
2251 ScreenToClient(getParent()->getWindowHandle(), pt32 );
2252*/
2253 switch (uCommand)
2254 {
2255
2256 case SC_SIZE:
2257 {
2258 DWORD flags = 0;
2259
2260 switch ((wParam & 0xF)+2)
2261 {
2262 case HTLEFT:
2263 flags = TFOS_LEFT;
2264 break;
2265
2266 case HTRIGHT:
2267 flags = TFOS_RIGHT;
2268 break;
2269
2270 case HTTOP:
2271 flags = TFOS_TOP;
2272 break;
2273
2274 case HTTOPLEFT:
2275 flags = TFOS_TOP | TFOS_LEFT;
2276 break;
2277
2278 case HTTOPRIGHT:
2279 flags = TFOS_TOP | TFOS_RIGHT;
2280 break;
2281
2282 case HTBOTTOM:
2283 flags = TFOS_BOTTOM;
2284 break;
2285
2286 case HTBOTTOMLEFT:
2287 flags = TFOS_BOTTOM | TFOS_LEFT;
2288 break;
2289
2290 case HTBOTTOMRIGHT:
2291 flags = TFOS_BOTTOM | TFOS_RIGHT;
2292 break;
2293 }
2294 if (flags) FrameTrackFrame(this,flags);
2295 break;
2296 }
2297
2298 case SC_MOVE:
2299 FrameTrackFrame(this,TFOS_MOVE);
2300 break;
2301
2302 case SC_MINIMIZE:
2303 ShowWindow(SW_MINIMIZE);
2304 break;
2305
2306 case SC_MAXIMIZE:
2307 ShowWindow(SW_MAXIMIZE);
2308 break;
2309
2310 case SC_RESTORE:
2311 ShowWindow(SW_RESTORE);
2312 break;
2313
2314 case SC_CLOSE:
2315 return SendInternalMessageA(WM_CLOSE,0,0);
2316
2317 case SC_VSCROLL:
2318 case SC_HSCROLL:
2319 TrackScrollBar(wParam,*pt32);
2320 break;
2321
2322 case SC_MOUSEMENU:
2323 MENU_TrackMouseMenuBar(Win32Hwnd,wParam & 0x000F,*pt32);
2324 break;
2325
2326 case SC_KEYMENU:
2327 MENU_TrackKbdMenuBar(Win32Hwnd,wParam,pt32->x);
2328 break;
2329
2330 case SC_TASKLIST:
2331 WinExec("taskman.exe",SW_SHOWNORMAL);
2332 break;
2333
2334 case SC_SCREENSAVE:
2335 if (wParam == SC_ABOUTWINE)
2336 ShellAboutA(Win32Hwnd,"Odin","Odin alpha release compiled with IBM VAC++",0);
2337 else
2338 if (wParam == SC_PUTMARK)
2339 dprintf(("Mark requested by user\n"));
2340 break;
2341
2342 case SC_HOTKEY:
2343 case SC_ARRANGE:
2344 case SC_NEXTWINDOW:
2345 case SC_PREVWINDOW:
2346 break;
2347 }
2348 return 0;
2349}
2350//******************************************************************************
2351//******************************************************************************
2352LRESULT Win32BaseWindow::DefWndControlColor(UINT ctlType, HDC hdc)
2353{
2354 //SvL: Set background color to default button color (not window (white))
2355 if(ctlType == CTLCOLOR_BTN)
2356 {
2357 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
2358 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
2359 return GetSysColorBrush(COLOR_BTNFACE);
2360 }
2361 //SvL: Set background color to default dialog color if window is dialog
2362 if((ctlType == CTLCOLOR_DLG || ctlType == CTLCOLOR_STATIC) && IsDialog()) {
2363 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
2364 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
2365 return GetSysColorBrush(COLOR_BTNFACE);
2366 }
2367
2368 if( ctlType == CTLCOLOR_SCROLLBAR)
2369 {
2370 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
2371 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
2372 SetTextColor( hdc, GetSysColor(COLOR_3DFACE));
2373 SetBkColor( hdc, bk);
2374
2375//TODO?
2376#if 0
2377 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
2378 * we better use 0x55aa bitmap brush to make scrollbar's background
2379 * look different from the window background.
2380 */
2381 if (bk == GetSysColor(COLOR_WINDOW)) {
2382 return CACHE_GetPattern55AABrush();
2383 }
2384#endif
2385 UnrealizeObject( hb );
2386 return (LRESULT)hb;
2387 }
2388
2389 SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
2390
2391 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
2392 {
2393 SetBkColor( hdc, GetSysColor(COLOR_WINDOW) );
2394 }
2395 else
2396 {
2397 SetBkColor( hdc, GetSysColor(COLOR_3DFACE) );
2398 return (LRESULT)GetSysColorBrush(COLOR_3DFACE);
2399 }
2400 return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
2401}
2402//******************************************************************************
2403//******************************************************************************
2404LRESULT Win32BaseWindow::DefWndPrint(HDC hdc,ULONG uFlags)
2405{
2406 /*
2407 * Visibility flag.
2408 */
2409 if ( (uFlags & PRF_CHECKVISIBLE) &&
2410 !IsWindowVisible() )
2411 return 0;
2412
2413 /*
2414 * Unimplemented flags.
2415 */
2416 if ( (uFlags & PRF_CHILDREN) ||
2417 (uFlags & PRF_OWNED) ||
2418 (uFlags & PRF_NONCLIENT) )
2419 {
2420 dprintf(("WM_PRINT message with unsupported flags\n"));
2421 }
2422
2423 /*
2424 * Background
2425 */
2426 if ( uFlags & PRF_ERASEBKGND)
2427 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
2428
2429 /*
2430 * Client area
2431 */
2432 if ( uFlags & PRF_CLIENT)
2433 SendInternalMessageA(WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
2434
2435
2436 return 0;
2437}
2438//******************************************************************************
2439//******************************************************************************
2440LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
2441{
2442 switch(Msg)
2443 {
2444 case WM_CLOSE:
2445 dprintf(("DefWindowProcA: WM_CLOSE %x", getWindowHandle()));
2446 DestroyWindow();
2447 return 0;
2448
2449 case WM_GETTEXTLENGTH:
2450 return wndNameLength;
2451
2452 case WM_GETTEXT:
2453 if (!lParam || !wParam) return 0;
2454 if (!windowNameA) ((LPSTR)lParam)[0] = 0;
2455 else lstrcpynA((LPSTR)lParam, windowNameA, wParam);
2456 return min(wndNameLength, wParam);
2457
2458 case WM_SETTEXT:
2459 {
2460 LPCSTR lpsz = (LPCSTR)lParam;
2461
2462 if(windowNameA) free(windowNameA);
2463 if(windowNameW) free(windowNameW);
2464
2465 if (lParam)
2466 {
2467 wndNameLength = strlen(lpsz);
2468 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
2469 strcpy(windowNameA, lpsz);
2470 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
2471 lstrcpyAtoW(windowNameW, windowNameA);
2472 }
2473 else
2474 {
2475 windowNameA = NULL;
2476 windowNameW = NULL;
2477 wndNameLength = 0;
2478 }
2479 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, lParam));
2480 if (dwStyle & WS_CAPTION)
2481 {
2482 //CB: optimize!
2483 HandleNCPaint(0);
2484 }
2485/* //CB: endless loop in trackbar.exe -> to fix
2486 if(OS2HwndFrame && (dwStyle & WS_CAPTION) == WS_CAPTION)
2487 return OSLibWinSetWindowText(OS2HwndFrame,(LPSTR)windowNameA);
2488*/
2489 return TRUE;
2490 }
2491
2492 case WM_SETREDRAW:
2493 {
2494 if (wParam)
2495 {
2496 setStyle(getStyle() | WS_VISIBLE);
2497 OSLibWinEnableWindowUpdate(OS2HwndFrame,TRUE);
2498 } else
2499 {
2500 if (getStyle() & WS_VISIBLE)
2501 {
2502 setStyle(getStyle() & ~WS_VISIBLE);
2503 OSLibWinEnableWindowUpdate(OS2HwndFrame,FALSE);
2504 }
2505 }
2506 return 0;
2507 }
2508
2509 case WM_NCPAINT:
2510 return HandleNCPaint((HRGN)wParam);
2511
2512 case WM_NCACTIVATE:
2513 return HandleNCActivate(wParam);
2514
2515 case WM_NCCREATE:
2516 return(TRUE);
2517
2518 case WM_NCDESTROY:
2519 return 0;
2520
2521 case WM_NCCALCSIZE:
2522 return HandleNCCalcSize((BOOL)wParam,(RECT*)lParam);
2523
2524 case WM_CTLCOLORMSGBOX:
2525 case WM_CTLCOLOREDIT:
2526 case WM_CTLCOLORLISTBOX:
2527 case WM_CTLCOLORBTN:
2528 case WM_CTLCOLORDLG:
2529 case WM_CTLCOLORSTATIC:
2530 case WM_CTLCOLORSCROLLBAR:
2531 return DefWndControlColor(Msg - WM_CTLCOLORMSGBOX, (HDC)wParam);
2532
2533 case WM_CTLCOLOR:
2534 return DefWndControlColor(HIWORD(lParam), (HDC)wParam);
2535
2536 case WM_VKEYTOITEM:
2537 case WM_CHARTOITEM:
2538 return -1;
2539
2540 case WM_PARENTNOTIFY:
2541 return 0;
2542
2543 case WM_MOUSEACTIVATE:
2544 {
2545 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
2546 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
2547 {
2548 if(getParent()) {
2549 LRESULT rc = getParent()->SendInternalMessageA(WM_MOUSEACTIVATE, wParam, lParam );
2550 if(rc) return rc;
2551 }
2552 }
2553 return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
2554 }
2555
2556 case WM_ACTIVATE:
2557 return 0;
2558
2559 case WM_SETCURSOR:
2560 {
2561 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
2562 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
2563 {
2564 if(getParent()) {
2565 LRESULT rc = getParent()->SendInternalMessageA(WM_SETCURSOR, wParam, lParam);
2566 if(rc) return rc;
2567 }
2568 }
2569 if (wParam == Win32Hwnd)
2570 {
2571 HCURSOR hCursor;
2572
2573 switch(LOWORD(lParam))
2574 {
2575 case HTCLIENT:
2576 hCursor = windowClass ? windowClass->getCursor():LoadCursorA(0,IDC_ARROWA);
2577 break;
2578
2579 case HTLEFT:
2580 case HTRIGHT:
2581 hCursor = LoadCursorA(0,IDC_SIZEWEA);
2582 break;
2583
2584 case HTTOP:
2585 case HTBOTTOM:
2586 hCursor = LoadCursorA(0,IDC_SIZENSA);
2587 break;
2588
2589 case HTTOPLEFT:
2590 case HTBOTTOMRIGHT:
2591 hCursor = LoadCursorA(0,IDC_SIZENWSEA);
2592 break;
2593
2594 case HTTOPRIGHT:
2595 case HTBOTTOMLEFT:
2596 hCursor = LoadCursorA(0,IDC_SIZENESWA);
2597 break;
2598
2599 default:
2600 hCursor = LoadCursorA(0,IDC_ARROWA);
2601 break;
2602 }
2603
2604 if (hCursor)
2605 {
2606 SetCursor(hCursor);
2607 return 1;
2608 } else return 0;
2609 } else return 0;
2610 }
2611
2612 case WM_MOUSEMOVE:
2613 return 0;
2614
2615 case WM_WINDOWPOSCHANGED:
2616 {
2617
2618/* undocumented SWP flags - from SDK 3.1 */
2619#define SWP_NOCLIENTSIZE 0x0800
2620#define SWP_NOCLIENTMOVE 0x1000
2621
2622 PWINDOWPOS wpos = (PWINDOWPOS)lParam;
2623 WPARAM wp = SIZE_RESTORED;
2624
2625 if (!(wpos->flags & SWP_NOMOVE) && !(wpos->flags & SWP_NOCLIENTMOVE))
2626 SendInternalMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
2627
2628 if (!(wpos->flags & SWP_NOSIZE) && !(wpos->flags & SWP_NOCLIENTSIZE))
2629 {
2630 if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
2631 else if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
2632
2633 SendInternalMessageA(WM_SIZE, wp, MAKELONG(rectClient.right - rectClient.left,
2634 rectClient.bottom - rectClient.top));
2635 }
2636 return 0;
2637 }
2638 case WM_WINDOWPOSCHANGING:
2639 return HandleWindowPosChanging((WINDOWPOS *)lParam);
2640
2641 case WM_ERASEBKGND:
2642 case WM_ICONERASEBKGND:
2643 {
2644 RECT rect;
2645 int rc;
2646
2647 if (!windowClass || !windowClass->getBackgroundBrush()) return 0;
2648
2649 rc = GetClipBox( (HDC)wParam, &rect );
2650 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
2651 {
2652 HBRUSH hBrush = windowClass->getBackgroundBrush();
2653
2654 if (hBrush <= (HBRUSH)(SYSCOLOR_GetLastColor()+1)) hBrush = GetSysColorBrush(hBrush-1);
2655
2656 FillRect( (HDC)wParam, &rect, hBrush);
2657 }
2658
2659 return 1;
2660 }
2661
2662 case WM_PRINT:
2663 return DefWndPrint(wParam,lParam);
2664
2665 case WM_PAINTICON:
2666 case WM_PAINT:
2667 {
2668 PAINTSTRUCT ps;
2669 HDC hdc = BeginPaint(getWindowHandle(), &ps );
2670 if( hdc )
2671 {
2672 if( (getStyle() & WS_MINIMIZE) && getWindowClass()->getIcon())
2673 {
2674 int x = (rectWindow.right - rectWindow.left - GetSystemMetrics(SM_CXICON))/2;
2675 int y = (rectWindow.bottom - rectWindow.top - GetSystemMetrics(SM_CYICON))/2;
2676 dprintf(("Painting class icon: vis rect=(%i,%i - %i,%i)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom ));
2677 DrawIcon(hdc, x, y, getWindowClass()->getIcon() );
2678 }
2679 EndPaint(getWindowHandle(), &ps );
2680 }
2681 return 0;
2682 }
2683
2684 case WM_GETDLGCODE:
2685 return 0;
2686
2687 case WM_NCLBUTTONDOWN:
2688 return HandleNCLButtonDown(wParam,lParam);
2689
2690 case WM_LBUTTONDBLCLK:
2691 case WM_NCLBUTTONDBLCLK:
2692 return HandleNCLButtonDblClk(wParam,lParam);
2693
2694 case WM_NCRBUTTONDOWN:
2695 case WM_NCRBUTTONDBLCLK:
2696 case WM_NCMBUTTONDOWN:
2697 case WM_NCMBUTTONDBLCLK:
2698 if (lastHitTestVal == HTERROR) MessageBeep(MB_ICONEXCLAMATION);
2699 return 0;
2700
2701 case WM_NCRBUTTONUP:
2702 case WM_NCMBUTTONUP:
2703 return 0;
2704
2705 case WM_NCHITTEST:
2706 {
2707 POINT point;
2708
2709 point.x = (SHORT)LOWORD(lParam);
2710 point.y = (SHORT)HIWORD(lParam);
2711
2712 return HandleNCHitTest(point);
2713 }
2714
2715 case WM_SYSCOMMAND:
2716 {
2717 POINT point;
2718
2719 point.x = LOWORD(lParam);
2720 point.y = HIWORD(lParam);
2721 return HandleSysCommand(wParam,&point);
2722 }
2723
2724 case WM_SYSKEYDOWN:
2725 if(wParam == VK_F4) /* try to close the window */
2726 {
2727 Win32BaseWindow *window = GetTopParent();
2728 if(window && !(window->getClass()->getStyle() & CS_NOCLOSE))
2729 PostMessageA(getWindowHandle(), WM_SYSCOMMAND, SC_CLOSE, 0);
2730 }
2731
2732 Win32BaseWindow *siblingWindow;
2733 HWND sibling;
2734 char nameBuffer [40], mnemonic;
2735 int nameLength;
2736
2737 GetWindowTextA (nameBuffer, 40);
2738
2739 // search all sibling to see it this key is their mnemonic
2740 sibling = GetWindow (GW_HWNDFIRST);
2741 while (sibling != 0) {
2742 siblingWindow = GetWindowFromHandle (sibling);
2743 nameLength = siblingWindow->GetWindowTextA (nameBuffer, 40);
2744
2745 // find the siblings mnemonic
2746 mnemonic = '\0';
2747 for (int i=0 ; i<nameLength ; i++) {
2748 if (nameBuffer [i] == '&') {
2749 mnemonic = nameBuffer [i+1];
2750 if ((mnemonic >= 'a') && (mnemonic <= 'z'))
2751 mnemonic -= 32; // make it uppercase
2752 break; // stop searching
2753 }
2754 }
2755
2756 // key matches siblings mnemonic, send mouseclick
2757 if (mnemonic == (char) wParam) {
2758 siblingWindow->SendInternalMessageA (BM_CLICK, 0, 0);
2759 }
2760
2761 sibling = siblingWindow->GetNextWindow (GW_HWNDNEXT);
2762 }
2763
2764 return 0;
2765
2766 case WM_SHOWWINDOW:
2767 if (!lParam) return 0; /* sent from ShowWindow */
2768 if (!(dwStyle & WS_POPUP) || !owner) return 0;
2769 if ((dwStyle & WS_VISIBLE) && wParam) return 0;
2770 else if (!(dwStyle & WS_VISIBLE) && !wParam) return 0;
2771 ShowWindow(wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
2772 return 0;
2773
2774 case WM_CANCELMODE:
2775 if (getParent() == windowDesktop) EndMenu();
2776 if (GetCapture() == Win32Hwnd) ReleaseCapture();
2777 return 0;
2778
2779 case WM_DROPOBJECT:
2780 return DRAG_FILE;
2781
2782 case WM_QUERYDROPOBJECT:
2783 if (dwExStyle & WS_EX_ACCEPTFILES) return 1;
2784 return 0;
2785
2786 case WM_QUERYDRAGICON:
2787 {
2788 HICON hIcon = windowClass->getCursor();
2789 UINT len;
2790
2791 if(hIcon) return (LRESULT)hIcon;
2792 for(len = 1; len < 64; len++)
2793 {
2794 hIcon = LoadIconA(hInstance,MAKEINTRESOURCEA(len));
2795 if(hIcon)
2796 return (LRESULT)hIcon;
2797 }
2798 return (LRESULT)LoadIconA(0,IDI_APPLICATIONA);
2799 }
2800
2801 case WM_QUERYOPEN:
2802 case WM_QUERYENDSESSION:
2803 return 1;
2804
2805 case WM_NOTIFYFORMAT:
2806 if (IsWindowUnicode()) return NFR_UNICODE;
2807 else return NFR_ANSI;
2808
2809 case WM_SETICON:
2810 case WM_GETICON:
2811 {
2812 LRESULT result = 0;
2813 if (!windowClass) return result;
2814 int index = GCL_HICON;
2815
2816 if (wParam == ICON_SMALL)
2817 index = GCL_HICONSM;
2818
2819 result = windowClass->getClassLongA(index);
2820
2821 if (Msg == WM_SETICON)
2822 windowClass->setClassLongA(index, lParam);
2823
2824 return result;
2825 }
2826
2827 case WM_NOTIFY:
2828 return 0; //comctl32 controls expect this
2829
2830 default:
2831 if(Msg > WM_USER) {
2832 return 0;
2833 }
2834 return 1; //CB: shouldn't this be 0?
2835 }
2836}
2837//******************************************************************************
2838//******************************************************************************
2839LRESULT Win32BaseWindow::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
2840{
2841 switch(Msg)
2842 {
2843 case WM_GETTEXTLENGTH:
2844 return wndNameLength;
2845
2846 case WM_GETTEXT:
2847 if (!lParam || !wParam) return 0;
2848 if (!windowNameW) ((LPWSTR)lParam)[0] = 0;
2849 else lstrcpynW((LPWSTR)lParam,windowNameW,wParam);
2850 return min(wndNameLength,wParam);
2851
2852 case WM_SETTEXT:
2853 {
2854 LPWSTR lpsz = (LPWSTR)lParam;
2855
2856 if(windowNameA) free(windowNameA);
2857 if(windowNameW) free(windowNameW);
2858
2859 if (lParam)
2860 {
2861 wndNameLength = lstrlenW(lpsz);
2862 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
2863 lstrcpyWtoA(windowNameA,lpsz);
2864 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
2865 lstrcpyW(windowNameW,lpsz);
2866 }
2867 else
2868 {
2869 windowNameA = NULL;
2870 windowNameW = NULL;
2871 wndNameLength = 0;
2872 }
2873
2874 if(OS2HwndFrame && (dwStyle & WS_CAPTION) == WS_CAPTION)
2875 return OSLibWinSetWindowText(OS2HwndFrame,(LPSTR)windowNameA);
2876
2877 return TRUE;
2878 }
2879
2880 default:
2881 return DefWindowProcA(Msg, wParam, lParam);
2882 }
2883}
2884//******************************************************************************
2885//******************************************************************************
2886LRESULT Win32BaseWindow::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
2887{
2888 //if the destination window is created by this process & thread, call window proc directly
2889 if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
2890 return SendInternalMessageA(Msg, wParam, lParam);
2891 }
2892 //otherwise use WinSendMsg to send it to the right process/thread
2893 return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, FALSE);
2894}
2895//******************************************************************************
2896//******************************************************************************
2897LRESULT Win32BaseWindow::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
2898{
2899 //if the destination window is created by this process & thread, call window proc directly
2900 if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
2901 return SendInternalMessageW(Msg, wParam, lParam);
2902 }
2903 //otherwise use WinSendMsg to send it to the right process/thread
2904 return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, TRUE);
2905}
2906//******************************************************************************
2907//Called as a result of an OS/2 message or called from a class method
2908//******************************************************************************
2909LRESULT Win32BaseWindow::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
2910{
2911 LRESULT rc;
2912 BOOL fInternalMsgBackup = fInternalMsg;
2913
2914 DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, FALSE, TRUE);
2915
2916 CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, FALSE);
2917
2918 fInternalMsg = TRUE;
2919 switch(Msg)
2920 {
2921 case WM_CREATE:
2922 {
2923 if(CallWindowProcA(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
2924 dprintf(("WM_CREATE returned -1\n"));
2925 rc = -1; //don't create window
2926 break;
2927 }
2928 rc = 0;
2929 break;
2930 }
2931 case WM_LBUTTONDOWN:
2932 case WM_MBUTTONDOWN:
2933 case WM_RBUTTONDOWN:
2934 {
2935 if (getParent())
2936 {
2937 POINTS pt = MAKEPOINTS(lParam);
2938 POINT point;
2939
2940 point.x = pt.x;
2941 point.y = pt.y;
2942 mapWin32Point(OS2Hwnd,getParent()->getOS2WindowHandle(),(OSLIBPOINT*)&point);
2943 NotifyParent(Msg,wParam,MAKELPARAM(point.x,point.y));
2944 }
2945 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
2946 break;
2947 }
2948
2949 case WM_DESTROY:
2950 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
2951 break;
2952
2953 default:
2954 rc = CallWindowProcA(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
2955 break;
2956 }
2957 fInternalMsg = fInternalMsgBackup;
2958 return rc;
2959}
2960//******************************************************************************
2961//Called as a result of an OS/2 message or called from a class method
2962//******************************************************************************
2963LRESULT Win32BaseWindow::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
2964{
2965 LRESULT rc;
2966 BOOL fInternalMsgBackup = fInternalMsg;
2967
2968 DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, TRUE, TRUE);
2969
2970 CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, TRUE);
2971
2972 fInternalMsg = TRUE;
2973 switch(Msg)
2974 {
2975 case WM_CREATE:
2976 {
2977 if(CallWindowProcW(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
2978 dprintf(("WM_CREATE returned -1\n"));
2979 rc = -1; //don't create window
2980 break;
2981 }
2982 rc = 0;
2983 break;
2984 }
2985 case WM_LBUTTONDOWN:
2986 case WM_MBUTTONDOWN:
2987 case WM_RBUTTONDOWN:
2988 NotifyParent(Msg, wParam, lParam);
2989 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
2990 break;
2991
2992 case WM_DESTROY:
2993 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
2994 break;
2995 default:
2996 rc = CallWindowProcW(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
2997 break;
2998 }
2999 fInternalMsg = fInternalMsgBackup;
3000 return rc;
3001}
3002//******************************************************************************
3003//******************************************************************************
3004void Win32BaseWindow::CallWindowHookProc(ULONG hooktype, ULONG Msg, WPARAM wParam, LPARAM lParam, BOOL fUnicode)
3005{
3006 CWPSTRUCT cwp;
3007
3008 cwp.lParam = lParam;
3009 cwp.wParam = wParam;
3010 cwp.message = Msg;
3011 cwp.hwnd = getWindowHandle();
3012
3013 switch(hooktype) {
3014 case WH_CALLWNDPROC:
3015 if(fUnicode) {
3016 HOOK_CallHooksW(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
3017 }
3018 else HOOK_CallHooksA(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
3019 break;
3020 }
3021}
3022//******************************************************************************
3023//******************************************************************************
3024//******************************************************************************
3025//TODO: Do this more efficiently
3026//******************************************************************************
3027LRESULT Win32BaseWindow::BroadcastMessageA(int type, UINT msg, WPARAM wParam, LPARAM lParam)
3028{
3029 Win32BaseWindow *window;
3030 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
3031
3032 dprintf(("BroadCastMessageA %x %x %x", msg, wParam, lParam, GetFS()));
3033
3034 for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
3035 window = GetWindowFromHandle(hwnd++);
3036 if(window) {
3037 if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
3038 {
3039
3040 if(type == BROADCAST_SEND) {
3041 window->SendInternalMessageA(msg, wParam, lParam);
3042 }
3043 else PostMessageA(window->getWindowHandle(), msg, wParam, lParam);
3044 }
3045 }
3046 }
3047 return 0;
3048}
3049//******************************************************************************
3050//TODO: Do this more efficiently
3051//******************************************************************************
3052LRESULT Win32BaseWindow::BroadcastMessageW(int type, UINT msg, WPARAM wParam, LPARAM lParam)
3053{
3054 Win32BaseWindow *window;
3055 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
3056
3057 dprintf(("BroadCastMessageW %x %x %x", msg, wParam, lParam));
3058
3059 for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
3060 window = GetWindowFromHandle(hwnd++);
3061 if(window) {
3062 if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
3063 {
3064
3065 if(type == BROADCAST_SEND) {
3066 window->SendInternalMessageW(msg, wParam, lParam);
3067 }
3068 else PostMessageW(window->getWindowHandle(), msg, wParam, lParam);
3069 }
3070 }
3071 }
3072 return 0;
3073}
3074//******************************************************************************
3075//******************************************************************************
3076void Win32BaseWindow::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
3077{
3078 Win32BaseWindow *window = this;
3079 Win32BaseWindow *parentwindow;
3080
3081 while(window)
3082 {
3083 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
3084 {
3085 /* Notify the parent window only */
3086 parentwindow = window->getParent();
3087 if(parentwindow) {
3088 parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, getWindowId()), lParam );
3089 }
3090 }
3091 else break;
3092
3093 window = parentwindow;
3094 }
3095}
3096//******************************************************************************
3097//******************************************************************************
3098BOOL Win32BaseWindow::SetIcon(HICON hIcon)
3099{
3100 dprintf(("Win32BaseWindow::SetIcon %x", hIcon));
3101 if(OSLibWinSetIcon(OS2HwndFrame, hIcon) == TRUE) {
3102//TODO: Wine does't send these. Correct?
3103// SendInternalMessageA(WM_SETICON, ICON_BIG, hIcon);
3104 return TRUE;
3105 }
3106 return FALSE;
3107}
3108//******************************************************************************
3109//******************************************************************************
3110BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
3111{
3112 ULONG showstate = 0;
3113 HWND hWinAfter;
3114
3115 dprintf(("ShowWindow %x %x", getWindowHandle(), nCmdShow));
3116#if 1
3117 if (flags & WIN_NEED_SIZE)
3118 {
3119 /* should happen only in CreateWindowEx() */
3120 int wParam = SIZE_RESTORED;
3121
3122 flags &= ~WIN_NEED_SIZE;
3123 if (dwStyle & WS_MAXIMIZE)
3124 wParam = SIZE_MAXIMIZED;
3125 else
3126 if (dwStyle & WS_MINIMIZE)
3127 wParam = SIZE_MINIMIZED;
3128
3129 SendInternalMessageA(WM_SIZE, wParam,
3130 MAKELONG(rectClient.right-rectClient.left,
3131 rectClient.bottom-rectClient.top));
3132 SendInternalMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
3133 }
3134#else
3135 if(fFirstShow) {
3136 if(isFrameWindow() && IS_OVERLAPPED(getStyle()) && !isChild()) {
3137 SendInternalMessageA(WM_SIZE, SIZE_RESTORED,
3138 MAKELONG(rectClient.right-rectClient.left,
3139 rectClient.bottom-rectClient.top));
3140 SendInternalMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
3141
3142 }
3143 fFirstShow = FALSE;
3144 }
3145#endif
3146 switch(nCmdShow)
3147 {
3148 case SW_SHOW:
3149 case SW_SHOWDEFAULT: //todo
3150 showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
3151 break;
3152 case SW_HIDE:
3153 showstate = SWPOS_HIDE;
3154 break;
3155 case SW_RESTORE:
3156 showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
3157 break;
3158 case SW_MINIMIZE:
3159 showstate = SWPOS_MINIMIZE;
3160 break;
3161 case SW_SHOWMAXIMIZED:
3162 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
3163 break;
3164 case SW_SHOWMINIMIZED:
3165 showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
3166 break;
3167 case SW_SHOWMINNOACTIVE:
3168 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
3169 break;
3170 case SW_SHOWNA:
3171 showstate = SWPOS_SHOW;
3172 break;
3173 case SW_SHOWNOACTIVATE:
3174 showstate = SWPOS_SHOW;
3175 break;
3176 case SW_SHOWNORMAL:
3177 showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
3178 break;
3179 }
3180
3181 /* We can't activate a child window (WINE) */
3182 if(getStyle() & WS_CHILD)
3183 showstate &= ~SWPOS_ACTIVATE;
3184
3185 if(showstate & SWPOS_SHOW) {
3186 setStyle(getStyle() | WS_VISIBLE);
3187 }
3188 else setStyle(getStyle() & ~WS_VISIBLE);
3189
3190 BOOL rc = OSLibWinShowWindow(OS2HwndFrame, showstate);
3191
3192 return rc;
3193}
3194//******************************************************************************
3195//******************************************************************************
3196BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
3197{
3198 BOOL rc = FALSE;
3199 Win32BaseWindow *window;
3200 HWND hParent = 0;
3201
3202 dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
3203
3204 if (fuFlags &
3205 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
3206 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
3207 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
3208 SWP_NOOWNERZORDER))
3209 {
3210 return FALSE;
3211 }
3212
3213 WINDOWPOS wpos;
3214 SWP swp, swpOld;
3215
3216 wpos.flags = fuFlags;
3217 wpos.cy = cy;
3218 wpos.cx = cx;
3219 wpos.x = x;
3220 wpos.y = y;
3221 wpos.hwndInsertAfter = hwndInsertAfter;
3222 wpos.hwnd = getWindowHandle();
3223
3224 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE))
3225 {
3226 if (isChild())
3227 {
3228 Win32BaseWindow *windowParent = getParent();
3229 if(windowParent) {
3230 hParent = getParent()->getOS2WindowHandle();
3231 }
3232 else dprintf(("WARNING: Win32BaseWindow::SetWindowPos window %x is child but has no parent!!", getWindowHandle()));
3233 }
3234 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
3235 }
3236
3237 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
3238 if (swp.fl == 0)
3239 return TRUE;
3240
3241// if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
3242 if ((swp.hwndInsertBehind > HWNDOS_BOTTOM))
3243 {
3244 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
3245 if(wndBehind) {
3246 swp.hwndInsertBehind = wndBehind->getOS2FrameWindowHandle();
3247 }
3248 else {
3249 dprintf(("ERROR: SetWindowPos: hwndInsertBehind %x invalid!",swp.hwndInsertBehind));
3250 swp.hwndInsertBehind = 0;
3251 }
3252 }
3253//CB: todo
3254 #if 0
3255 if (isFrameWindow())
3256 {
3257 if (!isChild())
3258 {
3259 POINT maxSize, maxPos, minTrack, maxTrack;
3260
3261 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
3262
3263 if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
3264 if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
3265 if (swp.cx < minTrack.x) swp.cx = minTrack.x;
3266 if (swp.cy < minTrack.y) swp.cy = minTrack.y;
3267 }
3268 swp.hwnd = OS2HwndFrame;
3269 }
3270 else
3271#endif
3272 swp.hwnd = OS2HwndFrame;
3273
3274 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
3275
3276 rc = OSLibWinSetMultWindowPos(&swp, 1);
3277
3278 if (rc == FALSE)
3279 {
3280 dprintf(("OSLibWinSetMultWindowPos failed! Error %x",OSLibWinGetLastError()));
3281 }
3282
3283 if (fuFlags == SWP_FRAMECHANGED)
3284 {
3285 //CB: optimize: if frame size has changed not necessary!
3286 FrameUpdateFrame(this,0);
3287 }
3288
3289 return (rc);
3290}
3291//******************************************************************************
3292//TODO: WPF_RESTOREMAXIMIZED
3293//******************************************************************************
3294BOOL Win32BaseWindow::SetWindowPlacement(WINDOWPLACEMENT *winpos)
3295{
3296 if(isFrameWindow())
3297 {
3298 // Set the minimized position
3299 if (winpos->flags & WPF_SETMINPOSITION)
3300 {
3301 OSLibSetWindowMinPos(OS2HwndFrame, winpos->ptMinPosition.x, winpos->ptMinPosition.y);
3302 }
3303
3304 //TODO: Max position
3305
3306 // Set the new restore position.
3307 OSLibSetWindowRestoreRect(OS2HwndFrame, &winpos->rcNormalPosition);
3308 }
3309
3310 return ShowWindow(winpos->showCmd);
3311}
3312//******************************************************************************
3313//Also destroys all the child windows (destroy children first, parent last)
3314//******************************************************************************
3315BOOL Win32BaseWindow::DestroyWindow()
3316{
3317 /* Call hooks */
3318 if(HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, getWindowHandle(), 0L))
3319 {
3320 return FALSE;
3321 }
3322
3323 if(!(getStyle() & WS_CHILD) && getOwner() == NULL)
3324 {
3325 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWDESTROYED, getWindowHandle(), 0L);
3326 /* FIXME: clean up palette - see "Internals" p.352 */
3327 }
3328
3329 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
3330 {
3331 if(getParent())
3332 {
3333 /* Notify the parent window only */
3334 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
3335 if( !::IsWindow(getWindowHandle()) )
3336 {
3337 return TRUE;
3338 }
3339 }
3340 else DebugInt3();
3341 }
3342 fDestroyWindowCalled = TRUE;
3343 return OSLibWinDestroyWindow(OS2HwndFrame);
3344}
3345//******************************************************************************
3346//******************************************************************************
3347Win32BaseWindow *Win32BaseWindow::getParent()
3348{
3349 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::GetParent();
3350 return ((ULONG)wndparent == (ULONG)windowDesktop) ? NULL : wndparent;
3351}
3352//******************************************************************************
3353//******************************************************************************
3354HWND Win32BaseWindow::GetParent()
3355{
3356 Win32BaseWindow *wndparent;
3357
3358 if ((!(getStyle() & (WS_POPUP|WS_CHILD))))
3359 {
3360 return 0;
3361 }
3362 wndparent = ((getStyle() & WS_CHILD) ? getParent() : getOwner());
3363
3364 return (wndparent) ? wndparent->getWindowHandle() : 0;
3365}
3366//******************************************************************************
3367//******************************************************************************
3368HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
3369{
3370 HWND oldhwnd;
3371 Win32BaseWindow *newparent;
3372
3373 if(getParent()) {
3374 oldhwnd = getParent()->getWindowHandle();
3375 getParent()->RemoveChild(this);
3376 }
3377 else oldhwnd = 0;
3378
3379 newparent = GetWindowFromHandle(hwndNewParent);
3380 if(newparent)
3381 {
3382 setParent(newparent);
3383 getParent()->AddChild(this);
3384 OSLibWinSetParent(getOS2FrameWindowHandle(), getParent()->getOS2WindowHandle());
3385 return oldhwnd;
3386 }
3387 else {
3388 setParent(windowDesktop);
3389 windowDesktop->AddChild(this);
3390 OSLibWinSetParent(getOS2FrameWindowHandle(), OSLIB_HWND_DESKTOP);
3391 return oldhwnd;
3392 }
3393}
3394//******************************************************************************
3395//******************************************************************************
3396BOOL Win32BaseWindow::IsChild(HWND hwndParent)
3397{
3398 if(getParent()) {
3399 return getParent()->getWindowHandle() == hwndParent;
3400 }
3401 else return 0;
3402}
3403//******************************************************************************
3404//******************************************************************************
3405HWND Win32BaseWindow::GetTopWindow()
3406{
3407 return GetWindow(GW_CHILD);
3408}
3409//******************************************************************************
3410// Get the top-level parent for a child window.
3411//******************************************************************************
3412Win32BaseWindow *Win32BaseWindow::GetTopParent()
3413{
3414 Win32BaseWindow *window = this;
3415
3416 while(window && (window->getStyle() & WS_CHILD))
3417 {
3418 window = window->getParent();
3419 }
3420 return window;
3421}
3422//******************************************************************************
3423//Don't call WinUpdateWindow as that one also updates the child windows
3424//Also need to send WM_PAINT directly to the window procedure, which doesn't
3425//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
3426//******************************************************************************
3427BOOL Win32BaseWindow::UpdateWindow()
3428{
3429 RECT rect;
3430
3431 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
3432 {//update region not empty
3433 HDC hdc;
3434
3435 hdc = O32_GetDC(OS2Hwnd);
3436 if (isIcon)
3437 {
3438 SendInternalMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
3439 SendInternalMessageA(WM_PAINTICON, 0, 0);
3440 }
3441 else
3442 {
3443 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
3444 SendInternalMessageA(WM_PAINT, 0, 0);
3445 }
3446 O32_ReleaseDC(OS2Hwnd, hdc);
3447 }
3448 return TRUE;
3449}
3450//******************************************************************************
3451//******************************************************************************
3452BOOL Win32BaseWindow::IsIconic()
3453{
3454 return OSLibWinIsIconic(OS2Hwnd);
3455}
3456//******************************************************************************
3457//TODO: Should not enumerate children that are created during the enumeration!
3458//******************************************************************************
3459BOOL Win32BaseWindow::EnumChildWindows(WNDENUMPROC lpfn, LPARAM lParam)
3460{
3461 BOOL rc = TRUE;
3462 HWND hwnd;
3463 Win32BaseWindow *prevchild = 0, *child = 0;
3464
3465 dprintf(("EnumChildWindows of %x parameter %x %x (%x)", getWindowHandle(), lpfn, lParam, getFirstChild()));
3466 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3467 {
3468 dprintf(("EnumChildWindows: enumerating child %x", child->getWindowHandle()));
3469 hwnd = child->getWindowHandle();
3470 if(child->getOwner()) {
3471 continue; //shouldn't have an owner (Wine)
3472 }
3473 if(lpfn(hwnd, lParam) == FALSE)
3474 {
3475 rc = FALSE;
3476 break;
3477 }
3478 //check if the window still exists
3479 if(!::IsWindow(hwnd))
3480 {
3481 child = prevchild;
3482 continue;
3483 }
3484 if(child->getFirstChild() != NULL)
3485 {
3486 dprintf(("EnumChildWindows: Enumerate children of %x", child->getWindowHandle()));
3487 if(child->EnumChildWindows(lpfn, lParam) == FALSE)
3488 {
3489 rc = FALSE;
3490 break;
3491 }
3492 }
3493 prevchild = child;
3494 }
3495 return rc;
3496}
3497//******************************************************************************
3498//Enumerate first-level children only and check thread id
3499//******************************************************************************
3500BOOL Win32BaseWindow::EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
3501{
3502 Win32BaseWindow *child = 0;
3503 ULONG tid, pid;
3504 BOOL rc;
3505 HWND hwnd;
3506
3507 dprintf(("EnumThreadWindows %x %x %x", dwThreadId, lpfn, lParam));
3508
3509 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3510 {
3511 OSLibWinQueryWindowProcess(child->getOS2WindowHandle(), &pid, &tid);
3512
3513 if(dwThreadId == tid) {
3514 dprintf2(("EnumThreadWindows: Found Window %x", child->getWindowHandle()));
3515 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
3516 break;
3517 }
3518 }
3519 }
3520 return TRUE;
3521}
3522//******************************************************************************
3523//Enumerate first-level children only
3524//******************************************************************************
3525BOOL Win32BaseWindow::EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
3526{
3527 Win32BaseWindow *child = 0;
3528 BOOL rc;
3529 HWND hwnd;
3530
3531 dprintf(("EnumWindows %x %x", lpfn, lParam));
3532
3533 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3534 {
3535 hwnd = child->getWindowHandle();
3536
3537 dprintf2(("EnumWindows: Found Window %x", child->getWindowHandle()));
3538 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
3539 break;
3540 }
3541 }
3542 return TRUE;
3543}
3544//******************************************************************************
3545//******************************************************************************
3546Win32BaseWindow *Win32BaseWindow::FindWindowById(int id)
3547{
3548 for (Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3549 {
3550 if (child->getWindowId() == id)
3551 {
3552 return child;
3553 }
3554 }
3555 return 0;
3556}
3557//******************************************************************************
3558//TODO:
3559//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
3560//the current process owns them.
3561//******************************************************************************
3562HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
3563 BOOL fUnicode)
3564{
3565 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
3566 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
3567
3568 if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
3569 (hwndChildAfter != 0 && !child) ||
3570 (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
3571 {
3572 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
3573 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
3574 return 0;
3575 }
3576 if(hwndParent != OSLIB_HWND_DESKTOP)
3577 {//if the current process owns the window, just do a quick search
3578 child = (Win32BaseWindow *)parent->getFirstChild();
3579 if(hwndChildAfter != 0)
3580 {
3581 while(child)
3582 {
3583 if(child->getWindowHandle() == hwndChildAfter)
3584 {
3585 child = (Win32BaseWindow *)child->getNextChild();
3586 break;
3587 }
3588 child = (Win32BaseWindow *)child->getNextChild();
3589 }
3590 }
3591 while(child)
3592 {
3593 if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
3594 (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
3595 {
3596 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
3597 return child->getWindowHandle();
3598 }
3599 child = (Win32BaseWindow *)child->getNextChild();
3600 }
3601 }
3602 else {
3603 Win32BaseWindow *wnd;
3604 HWND henum, hwnd;
3605
3606 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
3607 hwnd = OSLibWinGetNextWindow(henum);
3608
3609 while(hwnd)
3610 {
3611 wnd = GetWindowFromOS2Handle(hwnd);
3612 if(wnd == NULL) {
3613 hwnd = OSLibWinQueryClientWindow(hwnd);
3614 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
3615 if(!hwnd) wnd = GetWindowFromOS2FrameHandle(hwnd);
3616 }
3617
3618 if(wnd) {
3619 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
3620 (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
3621 {
3622 OSLibWinEndEnumWindows(henum);
3623 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
3624 return wnd->getWindowHandle();
3625 }
3626 }
3627 hwnd = OSLibWinGetNextWindow(henum);
3628 }
3629 OSLibWinEndEnumWindows(henum);
3630 }
3631 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
3632 return 0;
3633}
3634//******************************************************************************
3635//******************************************************************************
3636HWND Win32BaseWindow::GetWindow(UINT uCmd)
3637{
3638 HWND hwndRelated = 0;
3639 Win32BaseWindow *window;
3640
3641 switch(uCmd)
3642 {
3643 case GW_HWNDFIRST:
3644 if(getParent()) {
3645 window = (Win32BaseWindow *)getParent()->getFirstChild();
3646 hwndRelated = window->getWindowHandle();
3647 }
3648 break;
3649
3650 case GW_HWNDLAST:
3651 if(!getParent())
3652 {
3653 goto end;
3654 }
3655
3656 window = this;
3657 while(window->getNextChild())
3658 {
3659 window = (Win32BaseWindow *)window->getNextChild();
3660 }
3661 hwndRelated = window->getWindowHandle();
3662 break;
3663
3664 case GW_HWNDNEXT:
3665 window = (Win32BaseWindow *)getNextChild();
3666 if(window) {
3667 hwndRelated = window->getWindowHandle();
3668 }
3669 break;
3670
3671 case GW_HWNDPREV:
3672 if(!getParent())
3673 {
3674 goto end;
3675 }
3676 window = (Win32BaseWindow *)(getParent()->getFirstChild()); /* First sibling */
3677 if(window == this)
3678 {
3679 hwndRelated = 0; /* First in list */
3680 goto end;
3681 }
3682 while(window->getNextChild())
3683 {
3684 if (window->getNextChild() == this)
3685 {
3686 hwndRelated = window->getWindowHandle();
3687 goto end;
3688 }
3689 window = (Win32BaseWindow *)window->getNextChild();
3690 }
3691 break;
3692
3693 case GW_OWNER:
3694 if(getOwner()) {
3695 hwndRelated = getOwner()->getWindowHandle();
3696 }
3697 break;
3698
3699 case GW_CHILD:
3700 if(getFirstChild()) {
3701 hwndRelated = ((Win32BaseWindow *)getFirstChild())->getWindowHandle();
3702 }
3703 break;
3704 }
3705end:
3706 dprintf(("GetWindow %x %d returned %x", getWindowHandle(), uCmd, hwndRelated));
3707 return hwndRelated;
3708}
3709//******************************************************************************
3710//******************************************************************************
3711HWND Win32BaseWindow::SetActiveWindow()
3712{
3713 HWND hwndActive;
3714 Win32BaseWindow *win32wnd;
3715 ULONG magic;
3716
3717 hwndActive = OSLibWinSetActiveWindow(OS2HwndFrame);
3718 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
3719 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
3720 if(CheckMagicDword(magic) && win32wnd)
3721 {
3722 return win32wnd->getWindowHandle();
3723 }
3724 return 0;
3725}
3726//******************************************************************************
3727//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
3728//******************************************************************************
3729BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
3730{
3731 return OSLibWinEnableWindow(OS2HwndFrame, fEnable);
3732}
3733//******************************************************************************
3734//******************************************************************************
3735BOOL Win32BaseWindow::CloseWindow()
3736{
3737 return OSLibWinMinimizeWindow(OS2HwndFrame);
3738}
3739//******************************************************************************
3740//******************************************************************************
3741HWND Win32BaseWindow::GetActiveWindow()
3742{
3743 HWND hwndActive;
3744 Win32BaseWindow *win32wnd;
3745 ULONG magic;
3746
3747 hwndActive = OSLibWinQueryActiveWindow();
3748
3749 return OS2ToWin32Handle(hwndActive);
3750}
3751//******************************************************************************
3752//******************************************************************************
3753BOOL Win32BaseWindow::IsWindowEnabled()
3754{
3755 return OSLibWinIsWindowEnabled(OS2HwndFrame);
3756}
3757//******************************************************************************
3758//******************************************************************************
3759BOOL Win32BaseWindow::IsWindowVisible()
3760{
3761#if 1
3762 return (dwStyle & WS_VISIBLE) == WS_VISIBLE;
3763#else
3764 return OSLibWinIsWindowVisible(OS2HwndFrame);
3765#endif
3766}
3767//******************************************************************************
3768//******************************************************************************
3769BOOL Win32BaseWindow::GetWindowRect(PRECT pRect)
3770{
3771 return OSLibWinQueryWindowRect(OS2HwndFrame, pRect, RELATIVE_TO_SCREEN);
3772}
3773//******************************************************************************
3774//******************************************************************************
3775BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
3776{
3777 INT len = GetWindowTextLength();
3778 BOOL res;
3779
3780 if (wndname == NULL)
3781 return (len == 0);
3782
3783 len++;
3784 if (fUnicode)
3785 {
3786 WCHAR *text = (WCHAR*)malloc(len*sizeof(WCHAR));
3787
3788 GetWindowTextW(text,len);
3789 res = (lstrcmpW(text,(LPWSTR)wndname) == 0);
3790 free(text);
3791 } else
3792 {
3793 CHAR *text = (CHAR*)malloc(len*sizeof(CHAR));
3794
3795 GetWindowTextA(text,len);
3796 res = (strcmp(text,wndname) == 0);
3797 free(text);
3798 }
3799
3800 return res;
3801}
3802//******************************************************************************
3803//******************************************************************************
3804CHAR *Win32BaseWindow::getWindowNamePtrA()
3805{
3806 INT len = GetWindowTextLength();
3807 CHAR *text;
3808
3809 if (len == 0) return NULL;
3810 len++;
3811 text = (CHAR*)malloc(len*sizeof(CHAR));
3812 GetWindowTextA(text,len);
3813
3814 return text;
3815}
3816//******************************************************************************
3817//******************************************************************************
3818WCHAR *Win32BaseWindow::getWindowNamePtrW()
3819{
3820 INT len = GetWindowTextLength();
3821 WCHAR *text;
3822
3823 if (len == 0) return NULL;
3824 len++;
3825 text = (WCHAR*)malloc(len*sizeof(WCHAR));
3826 GetWindowTextW(text,len);
3827
3828 return text;
3829}
3830//******************************************************************************
3831//******************************************************************************
3832VOID Win32BaseWindow::freeWindowNamePtr(PVOID namePtr)
3833{
3834 if (namePtr) free(namePtr);
3835}
3836//******************************************************************************
3837//******************************************************************************
3838int Win32BaseWindow::GetWindowTextLength()
3839{
3840 return SendInternalMessageA(WM_GETTEXTLENGTH,0,0);
3841}
3842//******************************************************************************
3843//******************************************************************************
3844int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
3845{
3846 return SendInternalMessageA(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
3847}
3848//******************************************************************************
3849//******************************************************************************
3850int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
3851{
3852 return SendInternalMessageW(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
3853}
3854//******************************************************************************
3855//******************************************************************************
3856BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
3857{
3858 return SendInternalMessageA(WM_SETTEXT,0,(LPARAM)lpsz);
3859}
3860//******************************************************************************
3861//******************************************************************************
3862BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
3863{
3864 return SendInternalMessageW(WM_SETTEXT,0,(LPARAM)lpsz);
3865}
3866//******************************************************************************
3867//******************************************************************************
3868VOID Win32BaseWindow::updateWindowStyle(DWORD oldExStyle,DWORD oldStyle)
3869{
3870 if(IsWindowDestroyed()) return;
3871
3872 //CB: todo: dwExStyle, creating new frame controls, destroy not used controls, WS_VISIBLE, WS_CHILD, ...
3873 // write test cases
3874 if ((dwStyle & 0xFFFF0000) != (oldStyle & 0xFFFF0000))
3875 {
3876 //dprintf(("updateWindowStyle: %x %x",oldStyle,dwStyle));
3877 OSLibSetWindowStyle(OS2HwndFrame, dwStyle, fTaskList);
3878 }
3879}
3880//******************************************************************************
3881//******************************************************************************
3882LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value, BOOL fUnicode)
3883{
3884 LONG oldval;
3885
3886 dprintf2(("SetWindowLong%c %x %d %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
3887 switch(index) {
3888 case GWL_EXSTYLE:
3889 {
3890 STYLESTRUCT ss;
3891
3892 if(dwExStyle == value)
3893 return value;
3894
3895 ss.styleOld = dwExStyle;
3896 ss.styleNew = value;
3897 dprintf(("SetWindowLong GWL_EXSTYLE %x old %x new style %x", getWindowHandle(), dwExStyle, value));
3898 SendInternalMessageA(WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
3899 setExStyle(ss.styleNew);
3900 updateWindowStyle(ss.styleOld,getStyle());
3901 SendInternalMessageA(WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
3902 return ss.styleOld;
3903 }
3904 case GWL_STYLE:
3905 {
3906 STYLESTRUCT ss;
3907
3908 if(dwStyle == value)
3909 return value;
3910
3911 value &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way (WINE) */
3912 ss.styleOld = getStyle();
3913 ss.styleNew = value | (ss.styleOld & (WS_VISIBLE | WS_CHILD));
3914 dprintf(("SetWindowLong GWL_STYLE %x old %x new style %x", getWindowHandle(), ss.styleOld, ss.styleNew));
3915 SendInternalMessageA(WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
3916 setStyle(ss.styleNew);
3917 updateWindowStyle(dwExStyle,ss.styleOld);
3918 SendInternalMessageA(WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
3919#ifdef DEBUG
3920 PrintWindowStyle(ss.styleNew, 0);
3921#endif
3922 return ss.styleOld;
3923 }
3924 case GWL_WNDPROC:
3925 oldval = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3926 //WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A, WIN_PROC_WINDOW);
3927 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, WINPROC_GetProcType(win32wndproc), WIN_PROC_WINDOW);
3928 return oldval;
3929 case GWL_HINSTANCE:
3930 oldval = hInstance;
3931 hInstance = value;
3932 return oldval;
3933 case GWL_HWNDPARENT:
3934 return SetParent((HWND)value);
3935 case GWL_ID:
3936 oldval = getWindowId();
3937 setWindowId(value);
3938 return oldval;
3939 case GWL_USERDATA:
3940 oldval = userData;
3941 userData = value;
3942 return oldval;
3943 default:
3944 if(index >= 0 && index/4 < nrUserWindowLong)
3945 {
3946 oldval = userWindowLong[index/4];
3947 userWindowLong[index/4] = value;
3948 return oldval;
3949 }
3950 SetLastError(ERROR_INVALID_PARAMETER);
3951 return 0;
3952 }
3953}
3954//******************************************************************************
3955//******************************************************************************
3956ULONG Win32BaseWindow::GetWindowLongA(int index, BOOL fUnicode)
3957{
3958 ULONG value;
3959
3960 switch(index) {
3961 case GWL_EXSTYLE:
3962 value = dwExStyle;
3963 break;
3964 case GWL_STYLE:
3965 value = dwStyle;
3966 break;
3967 case GWL_WNDPROC:
3968 value = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3969 break;
3970 case GWL_HINSTANCE:
3971 value = hInstance;
3972 break;
3973 case GWL_HWNDPARENT:
3974 if(getParent()) {
3975 value = getParent()->getWindowHandle();
3976 }
3977 else value = 0;
3978 break;
3979 case GWL_ID:
3980 value = getWindowId();
3981 break;
3982 case GWL_USERDATA:
3983 value = userData;
3984 break;
3985 default:
3986 if(index >= 0 && index/4 < nrUserWindowLong)
3987 {
3988 value = userWindowLong[index/4];
3989 break;
3990 }
3991 SetLastError(ERROR_INVALID_PARAMETER);
3992 return 0;
3993 }
3994 dprintf2(("GetWindowLongA %x %d %x", getWindowHandle(), index, value));
3995 return value;
3996}
3997//******************************************************************************
3998//******************************************************************************
3999WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
4000{
4001 WORD oldval;
4002
4003 if(index >= 0 && index/4 < nrUserWindowLong)
4004 {
4005 oldval = ((WORD *)userWindowLong)[index/2];
4006 ((WORD *)userWindowLong)[index/2] = value;
4007 return oldval;
4008 }
4009 SetLastError(ERROR_INVALID_PARAMETER);
4010 return 0;
4011}
4012//******************************************************************************
4013//******************************************************************************
4014WORD Win32BaseWindow::GetWindowWord(int index)
4015{
4016 if(index >= 0 && index/4 < nrUserWindowLong)
4017 {
4018 return ((WORD *)userWindowLong)[index/2];
4019 }
4020 SetLastError(ERROR_INVALID_PARAMETER);
4021 return 0;
4022}
4023//******************************************************************************
4024//******************************************************************************
4025void Win32BaseWindow::setWindowId(DWORD id)
4026{
4027 windowId = id;
4028 dprintf(("Set window ID to %x", id));
4029 OSLibSetWindowID(OS2HwndFrame, id);
4030}
4031//******************************************************************************
4032//******************************************************************************
4033Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
4034{
4035 Win32BaseWindow *window;
4036
4037 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
4038 return window;
4039 }
4040// dprintf2(("Win32BaseWindow::GetWindowFromHandle: not a win32 window %x", hwnd));
4041 return NULL;
4042}
4043//******************************************************************************
4044//******************************************************************************
4045Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
4046{
4047 Win32BaseWindow *win32wnd;
4048 DWORD magic;
4049
4050 if(hwnd == OSLIB_HWND_DESKTOP)
4051 {
4052 return windowDesktop;
4053 }
4054
4055 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
4056 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
4057
4058 if(win32wnd && CheckMagicDword(magic)) {
4059 return win32wnd;
4060 }
4061// dprintf2(("Win32BaseWindow::GetWindowFromOS2Handle: not an Odin os2 window %x", hwnd));
4062 return 0;
4063}
4064//******************************************************************************
4065//******************************************************************************
4066Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
4067{
4068 return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
4069}
4070//******************************************************************************
4071//******************************************************************************
4072HWND Win32BaseWindow::Win32ToOS2Handle(HWND hwnd)
4073{
4074 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
4075
4076 if(window) {
4077 return window->getOS2WindowHandle();
4078 }
4079// dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
4080 return hwnd;
4081}
4082//******************************************************************************
4083//******************************************************************************
4084HWND Win32BaseWindow::Win32ToOS2FrameHandle(HWND hwnd)
4085{
4086 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
4087
4088 if(window) {
4089 return window->getOS2FrameWindowHandle();
4090 }
4091// dprintf2(("Win32BaseWindow::Win32ToOS2FrameHandle: not a win32 window %x", hwnd));
4092 return hwnd;
4093}
4094//******************************************************************************
4095//******************************************************************************
4096HWND Win32BaseWindow::OS2ToWin32Handle(HWND hwnd)
4097{
4098 Win32BaseWindow *window = GetWindowFromOS2Handle(hwnd);
4099
4100 if(window) {
4101 return window->getWindowHandle();
4102 }
4103 window = GetWindowFromOS2FrameHandle(hwnd);
4104 if(window) {
4105 return window->getWindowHandle();
4106 }
4107// dprintf2(("Win32BaseWindow::OS2ToWin32Handle: not a win32 window %x", hwnd));
4108 return 0;
4109// else return hwnd; //OS/2 window handle
4110}
4111//******************************************************************************
4112// GetNextDlgTabItem32 (USER32.276)
4113//******************************************************************************
4114HWND Win32BaseWindow::getNextDlgTabItem(HWND hwndCtrl, BOOL fPrevious)
4115{
4116 Win32BaseWindow *child, *nextchild, *lastchild;
4117 HWND retvalue;
4118
4119 if (hwndCtrl)
4120 {
4121 child = GetWindowFromHandle(hwndCtrl);
4122 if (!child)
4123 {
4124 retvalue = 0;
4125 goto END;
4126 }
4127 /* Make sure hwndCtrl is a top-level child */
4128 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
4129 {
4130 child = child->getParent();
4131 if(child == NULL) break;
4132 }
4133
4134 if (!child || (child->getParent() != this))
4135 {
4136 retvalue = 0;
4137 goto END;
4138 }
4139 }
4140 else
4141 {
4142 /* No ctrl specified -> start from the beginning */
4143 child = (Win32BaseWindow *)getFirstChild();
4144 if (!child)
4145 {
4146 retvalue = 0;
4147 goto END;
4148 }
4149
4150 if (!fPrevious)
4151 {
4152 while (child->getNextChild())
4153 {
4154 child = (Win32BaseWindow *)child->getNextChild();
4155 }
4156 }
4157 }
4158
4159 lastchild = child;
4160 nextchild = (Win32BaseWindow *)child->getNextChild();
4161 while (TRUE)
4162 {
4163 if (!nextchild) nextchild = (Win32BaseWindow *)getFirstChild();
4164
4165 if (child == nextchild) break;
4166
4167 if ((nextchild->getStyle() & WS_TABSTOP) && (nextchild->getStyle() & WS_VISIBLE) &&
4168 !(nextchild->getStyle() & WS_DISABLED))
4169 {
4170 lastchild = nextchild;
4171 if (!fPrevious) break;
4172 }
4173 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
4174 }
4175 retvalue = lastchild->getWindowHandle();
4176
4177END:
4178 return retvalue;
4179}
4180//******************************************************************************
4181//******************************************************************************
4182HWND Win32BaseWindow::getNextDlgGroupItem(HWND hwndCtrl, BOOL fPrevious)
4183{
4184 Win32BaseWindow *child, *nextchild, *lastchild;
4185 HWND retvalue;
4186
4187 if (hwndCtrl)
4188 {
4189 child = GetWindowFromHandle(hwndCtrl);
4190 if (!child)
4191 {
4192 retvalue = 0;
4193 goto END;
4194 }
4195 /* Make sure hwndCtrl is a top-level child */
4196 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
4197 {
4198 child = child->getParent();
4199 if(child == NULL) break;
4200 }
4201
4202 if (!child || (child->getParent() != this))
4203 {
4204 retvalue = 0;
4205 goto END;
4206 }
4207 }
4208 else
4209 {
4210 /* No ctrl specified -> start from the beginning */
4211 child = (Win32BaseWindow *)getFirstChild();
4212 if (!child)
4213 {
4214 retvalue = 0;
4215 goto END;
4216 }
4217
4218 if (fPrevious)
4219 {
4220 while (child->getNextChild())
4221 {
4222 child = (Win32BaseWindow *)child->getNextChild();
4223 }
4224 }
4225 }
4226
4227 lastchild = child;
4228 nextchild = (Win32BaseWindow *)child->getNextChild();
4229 while (TRUE)
4230 {
4231 if (!nextchild || (nextchild->getStyle() & WS_GROUP))
4232 {
4233 /* Wrap-around to the beginning of the group */
4234 Win32BaseWindow *pWndTemp;
4235
4236 nextchild = (Win32BaseWindow *)getFirstChild();
4237
4238 for(pWndTemp = nextchild;pWndTemp;pWndTemp = (Win32BaseWindow *)pWndTemp->getNextChild())
4239 {
4240 if (pWndTemp->getStyle() & WS_GROUP)
4241 nextchild = pWndTemp;
4242
4243 if (pWndTemp == child)
4244 break;
4245 }
4246
4247 }
4248 if (nextchild == child)
4249 break;
4250
4251 if ((nextchild->getStyle() & WS_VISIBLE) && !(nextchild->getStyle() & WS_DISABLED))
4252 {
4253 lastchild = nextchild;
4254
4255 if (!fPrevious)
4256 break;
4257 }
4258
4259 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
4260 }
4261 retvalue = lastchild->getWindowHandle();
4262END:
4263 return retvalue;
4264}
4265//******************************************************************************
4266//******************************************************************************
4267#ifdef DEBUG
4268void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle)
4269{
4270 char style[256] = "";
4271 char exstyle[256] = "";
4272
4273 /* Window styles */
4274 if(dwStyle & WS_CHILD)
4275 strcat(style, "WS_CHILD ");
4276 if(dwStyle & WS_POPUP)
4277 strcat(style, "WS_POPUP ");
4278 if(dwStyle & WS_VISIBLE)
4279 strcat(style, "WS_VISIBLE ");
4280 if(dwStyle & WS_DISABLED)
4281 strcat(style, "WS_DISABLED ");
4282 if(dwStyle & WS_CLIPSIBLINGS)
4283 strcat(style, "WS_CLIPSIBLINGS ");
4284 if(dwStyle & WS_CLIPCHILDREN)
4285 strcat(style, "WS_CLIPCHILDREN ");
4286 if(dwStyle & WS_MAXIMIZE)
4287 strcat(style, "WS_MAXIMIZE ");
4288 if(dwStyle & WS_MINIMIZE)
4289 strcat(style, "WS_MINIMIZE ");
4290 if(dwStyle & WS_GROUP)
4291 strcat(style, "WS_GROUP ");
4292 if(dwStyle & WS_TABSTOP)
4293 strcat(style, "WS_TABSTOP ");
4294
4295 if((dwStyle & WS_CAPTION) == WS_CAPTION)
4296 strcat(style, "WS_CAPTION ");
4297 if(dwStyle & WS_DLGFRAME)
4298 strcat(style, "WS_DLGFRAME ");
4299 if(dwStyle & WS_BORDER)
4300 strcat(style, "WS_BORDER ");
4301
4302 if(dwStyle & WS_VSCROLL)
4303 strcat(style, "WS_VSCROLL ");
4304 if(dwStyle & WS_HSCROLL)
4305 strcat(style, "WS_HSCROLL ");
4306 if(dwStyle & WS_SYSMENU)
4307 strcat(style, "WS_SYSMENU ");
4308 if(dwStyle & WS_THICKFRAME)
4309 strcat(style, "WS_THICKFRAME ");
4310 if(dwStyle & WS_MINIMIZEBOX)
4311 strcat(style, "WS_MINIMIZEBOX ");
4312 if(dwStyle & WS_MAXIMIZEBOX)
4313 strcat(style, "WS_MAXIMIZEBOX ");
4314
4315 if(dwExStyle & WS_EX_DLGMODALFRAME)
4316 strcat(exstyle, "WS_EX_DLGMODALFRAME ");
4317 if(dwExStyle & WS_EX_ACCEPTFILES)
4318 strcat(exstyle, "WS_EX_ACCEPTFILES ");
4319 if(dwExStyle & WS_EX_NOPARENTNOTIFY)
4320 strcat(exstyle, "WS_EX_NOPARENTNOTIFY ");
4321 if(dwExStyle & WS_EX_TOPMOST)
4322 strcat(exstyle, "WS_EX_TOPMOST ");
4323 if(dwExStyle & WS_EX_TRANSPARENT)
4324 strcat(exstyle, "WS_EX_TRANSPARENT ");
4325
4326 if(dwExStyle & WS_EX_MDICHILD)
4327 strcat(exstyle, "WS_EX_MDICHILD ");
4328 if(dwExStyle & WS_EX_TOOLWINDOW)
4329 strcat(exstyle, "WS_EX_TOOLWINDOW ");
4330 if(dwExStyle & WS_EX_WINDOWEDGE)
4331 strcat(exstyle, "WS_EX_WINDOWEDGE ");
4332 if(dwExStyle & WS_EX_CLIENTEDGE)
4333 strcat(exstyle, "WS_EX_CLIENTEDGE ");
4334 if(dwExStyle & WS_EX_CONTEXTHELP)
4335 strcat(exstyle, "WS_EX_CONTEXTHELP ");
4336 if(dwExStyle & WS_EX_RIGHT)
4337 strcat(exstyle, "WS_EX_RIGHT ");
4338 if(dwExStyle & WS_EX_LEFT)
4339 strcat(exstyle, "WS_EX_LEFT ");
4340 if(dwExStyle & WS_EX_RTLREADING)
4341 strcat(exstyle, "WS_EX_RTLREADING ");
4342 if(dwExStyle & WS_EX_LTRREADING)
4343 strcat(exstyle, "WS_EX_LTRREADING ");
4344 if(dwExStyle & WS_EX_LEFTSCROLLBAR)
4345 strcat(exstyle, "WS_EX_LEFTSCROLLBAR ");
4346 if(dwExStyle & WS_EX_RIGHTSCROLLBAR)
4347 strcat(exstyle, "WS_EX_RIGHTSCROLLBAR ");
4348 if(dwExStyle & WS_EX_CONTROLPARENT)
4349 strcat(exstyle, "WS_EX_CONTROLPARENT ");
4350 if(dwExStyle & WS_EX_STATICEDGE)
4351 strcat(exstyle, "WS_EX_STATICEDGE ");
4352 if(dwExStyle & WS_EX_APPWINDOW)
4353 strcat(exstyle, "WS_EX_APPWINDOW ");
4354
4355 dprintf(("Window style: %x %s", dwStyle, style));
4356 dprintf(("Window exStyle: %x %s (FS = %x)", dwExStyle, exstyle, GetFS()));
4357}
4358#endif
4359//******************************************************************************
4360//******************************************************************************
4361
4362GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.