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

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

* empty log message *

File size: 139.6 KB
Line 
1/* $Id: win32wbase.cpp,v 1.25 2000-01-08 16:47:48 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 "oslibmenu.h"
35#include "oslibdos.h"
36#include "syscolor.h"
37#include "win32wndhandle.h"
38#include "dc.h"
39#include "pmframe.h"
40#include "win32wdesktop.h"
41#include "pmwindow.h"
42#include "controls.h"
43#include <wprocess.h>
44#include "winmouse.h"
45#include <win\hook.h>
46#define INCL_TIMERWIN32
47#include "timer.h"
48
49#define HAS_DLGFRAME(style,exStyle) \
50 (((exStyle) & WS_EX_DLGMODALFRAME) || \
51 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
52
53#define HAS_THICKFRAME(style,exStyle) \
54 (((style) & WS_THICKFRAME) && \
55 !((exStyle) & WS_EX_DLGMODALFRAME))
56
57#define HAS_THINFRAME(style) \
58 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
59
60#define HAS_BIGFRAME(style,exStyle) \
61 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
62 ((exStyle) & WS_EX_DLGMODALFRAME))
63
64#define HAS_ANYFRAME(style,exStyle) \
65 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
66 ((exStyle) & WS_EX_DLGMODALFRAME) || \
67 !((style) & (WS_CHILD | WS_POPUP)))
68
69#define HAS_3DFRAME(exStyle) \
70 ((exStyle & WS_EX_CLIENTEDGE) || (exStyle & WS_EX_STATICEDGE) || (exStyle & WS_EX_WINDOWEDGE))
71
72#define HAS_BORDER(style, exStyle) \
73 ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
74
75#define IS_OVERLAPPED(style) \
76 !(style & (WS_CHILD | WS_POPUP))
77
78#define HAS_MENU(w) (!((w)->getStyle() & WS_CHILD) && ((w)->getWindowId() != 0))
79
80/* bits in the dwKeyData */
81#define KEYDATA_ALT 0x2000
82#define KEYDATA_PREVSTATE 0x4000
83
84void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle);
85
86static fDestroyAll = FALSE;
87//For quick lookup of current process id
88static ULONG currentProcessId = -1;
89
90static HBITMAP hbitmapClose = 0;
91static HBITMAP hbitmapCloseD = 0;
92static HBITMAP hbitmapMinimize = 0;
93static HBITMAP hbitmapMinimizeD = 0;
94static HBITMAP hbitmapMaximize = 0;
95static HBITMAP hbitmapMaximizeD = 0;
96static HBITMAP hbitmapRestore = 0;
97static HBITMAP hbitmapRestoreD = 0;
98
99BYTE lpGrayMask[] = { 0xAA, 0xA0,
100 0x55, 0x50,
101 0xAA, 0xA0,
102 0x55, 0x50,
103 0xAA, 0xA0,
104 0x55, 0x50,
105 0xAA, 0xA0,
106 0x55, 0x50,
107 0xAA, 0xA0,
108 0x55, 0x50};
109
110//******************************************************************************
111//******************************************************************************
112Win32BaseWindow::Win32BaseWindow(DWORD objType) : GenericObject(&windows, objType)
113{
114 Init();
115}
116//******************************************************************************
117//******************************************************************************
118Win32BaseWindow::Win32BaseWindow(HWND os2Handle,VOID* win32WndProc) : GenericObject(&windows,OBJTYPE_WINDOW)
119{
120 Init();
121 OS2Hwnd = OS2HwndFrame = os2Handle;
122 dwStyle = WS_VISIBLE;
123 setWindowProc((WNDPROC)win32WndProc);
124 fIsSubclassedOS2Wnd = TRUE;
125 fFirstShow = FALSE;
126 fCreated = TRUE;
127
128 SetLastError(0);
129
130 //CB: replace by a secure method
131
132 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
133 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
134 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
135 return;
136 }
137 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
138 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
139 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
140 return;
141 }
142
143 OSLibWinQueryWindowRect(OS2Hwnd,&rectClient,RELATIVE_TO_WINDOW);
144 OSLibWinQueryWindowRect(OS2Hwnd,&rectWindow,RELATIVE_TO_SCREEN);
145
146 setOldWndProc(SubclassWithDefHandler(OS2Hwnd));
147}
148//******************************************************************************
149//******************************************************************************
150Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
151 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
152{
153 Init();
154 this->isUnicode = isUnicode;
155 CreateWindowExA(lpCreateStructA, classAtom);
156}
157//******************************************************************************
158//******************************************************************************
159void Win32BaseWindow::Init()
160{
161 isUnicode = FALSE;
162 fIsSubclassedOS2Wnd = FALSE;
163 fFirstShow = TRUE;
164 fIsDialog = FALSE;
165 fIsModalDialogOwner = FALSE;
166 OS2HwndModalDialog = 0;
167 fInternalMsg = FALSE;
168 fNoSizeMsg = FALSE;
169 fIsDestroyed = FALSE;
170 fDestroyWindowCalled = FALSE;
171 fCreated = FALSE;
172 fTaskList = FALSE;
173 fParentDC = FALSE;
174
175 windowNameA = NULL;
176 windowNameW = NULL;
177 wndNameLength = 0;
178
179 userWindowLong = NULL;;
180 nrUserWindowLong = 0;
181
182 magic = WIN32PM_MAGIC;
183 OS2Hwnd = 0;
184 OS2HwndFrame = 0;
185 OS2HwndMenu = 0;
186 Win32Hwnd = 0;
187
188 if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
189 {
190 dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
191 DebugInt3();
192 }
193
194 posx = posy = 0;
195 width = height = 0;
196
197 dwExStyle = 0;
198 dwStyle = 0;
199 win32wndproc = 0;
200 hInstance = 0;
201 windowId = 0xFFFFFFFF; //default = -1
202 userData = 0;
203 contextHelpId = 0;
204
205 pOldFrameProc = NULL;
206 borderWidth = 0;
207 borderHeight = 0;
208
209 hwndLinkAfter = HWND_BOTTOM;
210 flags = 0;
211 isIcon = FALSE;
212 lastHitTestVal = HTOS_NORMAL;
213 fIgnoreHitTest = FALSE;
214 owner = NULL;
215 windowClass = 0;
216
217 iconResource = NULL;
218
219 EraseBkgndFlag = TRUE;
220 PSEraseFlag = FALSE;
221 SuppressEraseFlag = FALSE;
222
223 horzScrollInfo = NULL;
224 vertScrollInfo = NULL;
225 hwndHorzScroll = 0;
226 hwndVertScroll = 0;
227
228 ownDC = 0;
229 hWindowRegion = 0;
230
231 if(currentProcessId == -1)
232 {
233 currentProcessId = GetCurrentProcessId();
234 }
235 dwThreadId = GetCurrentThreadId();
236 dwProcessId = currentProcessId;
237}
238//******************************************************************************
239//todo get rid of resources (menu, icon etc)
240//******************************************************************************
241Win32BaseWindow::~Win32BaseWindow()
242{
243 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
244 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
245
246 if(!fDestroyAll && getParent() && getParent()->getFirstChild() == this && getNextChild() == NULL)
247 {
248 //if we're the last child that's being destroyed and our
249 //parent window was also destroyed, then we delete the parent object
250 if(getParent()->IsWindowDestroyed())
251 {
252 dprintf(("Last Child (%x) destroyed, get rid of our parent window (%x)", getWindowHandle(), getParent()->getWindowHandle()));
253 delete getParent();
254 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
255 }
256 }
257 else
258 if(fDestroyAll) {
259 dprintf(("Destroying window %x %s", getWindowHandle(), windowNameA));
260 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
261 }
262
263 if (isOwnDC())
264 releaseOwnDC (ownDC);
265
266 if(Win32Hwnd)
267 HwFreeWindowHandle(Win32Hwnd);
268
269 if(userWindowLong)
270 free(userWindowLong);
271 if(windowNameA) {
272 free(windowNameA);
273 windowNameA = NULL;
274 }
275 if(windowNameW) {
276 free(windowNameW);
277 windowNameW = NULL;
278 }
279 if(vertScrollInfo) {
280 free(vertScrollInfo);
281 vertScrollInfo = NULL;
282 }
283 if(horzScrollInfo) {
284 free(horzScrollInfo);
285 horzScrollInfo = NULL;
286 }
287}
288//******************************************************************************
289//******************************************************************************
290void Win32BaseWindow::DestroyAll()
291{
292 fDestroyAll = TRUE;
293 GenericObject::DestroyAll(windows);
294}
295//******************************************************************************
296//******************************************************************************
297BOOL Win32BaseWindow::isChild()
298{
299 return ((dwStyle & WS_CHILD) != 0);
300}
301//******************************************************************************
302//******************************************************************************
303BOOL Win32BaseWindow::IsWindowUnicode()
304{
305 dprintf2(("IsWindowUnicode %x %d", getWindowHandle(), WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W));
306 return (WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W);
307}
308//******************************************************************************
309//******************************************************************************
310BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
311{
312 char buffer[256];
313 POINT maxSize, maxPos, minTrack, maxTrack;
314
315#ifdef DEBUG
316 PrintWindowStyle(cs->style, cs->dwExStyle);
317#endif
318
319 sw = SW_SHOW;
320 SetLastError(0);
321
322 /* Find the parent window */
323 if (cs->hwndParent)
324 {
325 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
326 if(!window) {
327 dprintf(("Bad parent %04x\n", cs->hwndParent ));
328 SetLastError(ERROR_INVALID_PARAMETER);
329 return FALSE;
330 }
331 /* Make sure parent is valid */
332 if (!window->IsWindow() )
333 {
334 dprintf(("Bad parent %04x\n", cs->hwndParent ));
335 SetLastError(ERROR_INVALID_PARAMETER);
336 return FALSE;
337 }
338 }
339 else
340 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
341 dprintf(("No parent for child window\n" ));
342 SetLastError(ERROR_INVALID_PARAMETER);
343 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
344 }
345
346 /* Find the window class */
347 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
348 if (!windowClass)
349 {
350 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
351 dprintf(("Bad class '%s'\n", buffer ));
352 SetLastError(ERROR_INVALID_PARAMETER);
353 return 0;
354 }
355#ifdef DEBUG
356 if(HIWORD(cs->lpszClass))
357 {
358 char *astring;
359
360 if(isUnicode) astring = UnicodeToAsciiString((LPWSTR)cs->lpszClass);
361 else astring = (char *)cs->lpszClass;
362
363 dprintf(("Window class %s", astring));
364 if(isUnicode) FreeAsciiString(astring);
365 }
366 else dprintf(("Window class %x", cs->lpszClass));
367#endif
368
369 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
370 * with an atom as the class name, put some programs expect to have a *REAL* string in
371 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
372 */
373 if (!HIWORD(cs->lpszClass) ) {
374 if (isUnicode) {
375 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
376 }
377 else {
378 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
379 }
380 cs->lpszClass = buffer;
381 }
382
383 /* Fix the coordinates */
384 if ((cs->x == CW_USEDEFAULT) || (cs->x == CW_USEDEFAULT16))
385 {
386// PDB *pdb = PROCESS_Current();
387
388 /* Never believe Microsoft's documentation... CreateWindowEx doc says
389 * that if an overlapped window is created with WS_VISIBLE style bit
390 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
391 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
392 * reveals that
393 *
394 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
395 * 2) it does not ignore the y parameter as the docs claim; instead, it
396 * uses it as second parameter to ShowWindow() unless y is either
397 * CW_USEDEFAULT or CW_USEDEFAULT16.
398 *
399 * The fact that we didn't do 2) caused bogus windows pop up when wine
400 * was running apps that were using this obscure feature. Example -
401 * calc.exe that comes with Win98 (only Win98, it's different from
402 * the one that comes with Win95 and NT)
403 */
404 if ((cs->y != CW_USEDEFAULT) && (cs->y != CW_USEDEFAULT16)) sw = cs->y;
405
406 /* We have saved cs->y, now we can trash it */
407#if 0
408 if ( !(cs->style & (WS_CHILD | WS_POPUP))
409 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
410 {
411 cs->x = pdb->env_db->startup_info->dwX;
412 cs->y = pdb->env_db->startup_info->dwY;
413 }
414#endif
415 cs->x = 0;
416 cs->y = 0;
417// }
418 }
419 if ((cs->cx == CW_USEDEFAULT) || (cs->cx == CW_USEDEFAULT16))
420 {
421#if 0
422 PDB *pdb = PROCESS_Current();
423 if ( !(cs->style & (WS_CHILD | WS_POPUP))
424 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
425 {
426 cs->cx = pdb->env_db->startup_info->dwXSize;
427 cs->cy = pdb->env_db->startup_info->dwYSize;
428 }
429 else
430 {
431#endif
432 cs->cx = 600; /* FIXME */
433 cs->cy = 400;
434// }
435 }
436
437 if (cs->x < 0) cs->x = 0;
438 if (cs->y < 0) cs->y = 0;
439
440 //Allocate window words
441 nrUserWindowLong = windowClass->getExtraWndWords();
442 if(nrUserWindowLong) {
443 userWindowLong = (ULONG *)_smalloc(nrUserWindowLong);
444 memset(userWindowLong, 0, nrUserWindowLong);
445 }
446
447 if ((cs->style & WS_CHILD) && cs->hwndParent)
448 {
449 SetParent(cs->hwndParent);
450 owner = GetWindowFromHandle(cs->hwndParent);
451 if(owner == NULL)
452 {
453 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
454 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
455 return FALSE;
456 }
457 }
458 else
459 {
460 SetParent(0);
461 if (!cs->hwndParent || (cs->hwndParent == windowDesktop->getWindowHandle())) {
462 owner = NULL;
463 }
464 else
465 {
466 owner = GetWindowFromHandle(cs->hwndParent)->GetTopParent();
467 if(owner == NULL)
468 {
469 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
470 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
471 return FALSE;
472 }
473 }
474 }
475
476 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc(), WINPROC_GetProcType(windowClass->getWindowProc()), WIN_PROC_WINDOW);
477 hInstance = cs->hInstance;
478 dwStyle = cs->style & ~WS_VISIBLE;
479 dwExStyle = cs->dwExStyle;
480
481 hwndLinkAfter = HWND_TOP;
482 if(CONTROLS_IsControl(this, BUTTON_CONTROL) && ((dwStyle & 0x0f) == BS_GROUPBOX))
483 {
484 hwndLinkAfter = HWND_BOTTOM;
485 dwStyle |= WS_CLIPSIBLINGS;
486 }
487 else
488 if(CONTROLS_IsControl(this, STATIC_CONTROL) && !(dwStyle & WS_GROUP)) {
489 dwStyle |= WS_CLIPSIBLINGS;
490 }
491
492 /* Increment class window counter */
493 windowClass->IncreaseWindowCount();
494
495 if (HOOK_IsHooked( WH_CBT ))
496 {
497 CBT_CREATEWNDA cbtc;
498 LRESULT ret;
499
500 cbtc.lpcs = cs;
501 cbtc.hwndInsertAfter = hwndLinkAfter;
502 ret = HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc);
503 if(ret)
504 {
505 dprintf(("CBT-hook returned 0!!"));
506 SetLastError(ERROR_CAN_NOT_COMPLETE); //todo: wrong error
507 return FALSE;
508 }
509 }
510
511 /* Correct the window style */
512 if (!(cs->style & WS_CHILD))
513 {
514 dwStyle |= WS_CLIPSIBLINGS;
515 if (!(cs->style & WS_POPUP))
516 {
517 dwStyle |= WS_CAPTION;
518 flags |= WIN_NEED_SIZE;
519 }
520 }
521 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
522
523 if (cs->style & WS_HSCROLL)
524 {
525 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
526 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
527 horzScrollInfo->MaxVal = 100;
528 horzScrollInfo->flags = ESB_ENABLE_BOTH;
529 }
530
531 if (cs->style & WS_VSCROLL)
532 {
533 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
534 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
535 vertScrollInfo->MaxVal = 100;
536 vertScrollInfo->flags = ESB_ENABLE_BOTH;
537 }
538
539 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
540 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
541 {
542 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
543 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
544 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
545 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
546 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
547 }
548
549 if(cs->style & WS_CHILD)
550 {
551 if(cs->cx < 0) cs->cx = 0;
552 if(cs->cy < 0) cs->cy = 0;
553 }
554 else
555 {
556 if (cs->cx <= 0) cs->cx = 1;
557 if (cs->cy <= 0) cs->cy = 1;
558 }
559
560 if(((dwStyle & 0xC0000000) == WS_OVERLAPPED) && ((dwStyle & WS_CAPTION) == WS_CAPTION) && owner == NULL
561 && dwStyle & WS_SYSMENU)
562 {
563 fTaskList = TRUE;
564 }
565
566 DWORD dwOSWinStyle, dwOSFrameStyle;
567
568 OSLibWinConvertStyle(dwStyle, &dwExStyle, &dwOSWinStyle, &dwOSFrameStyle, &borderWidth, &borderHeight);
569
570 if(HIWORD(cs->lpszName))
571 {
572 if (!isUnicode)
573 {
574 wndNameLength = strlen(cs->lpszName);
575 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
576 strcpy(windowNameA,cs->lpszName);
577 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
578 lstrcpyAtoW(windowNameW,windowNameA);
579 windowNameA[wndNameLength] = 0;
580 windowNameW[wndNameLength] = 0;
581 }
582 else
583 {
584 wndNameLength = lstrlenW((LPWSTR)cs->lpszName);
585 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
586 lstrcpyWtoA(windowNameA,(LPWSTR)cs->lpszName);
587 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
588 lstrcpyW(windowNameW,(LPWSTR)cs->lpszName);
589 windowNameA[wndNameLength] = 0;
590 windowNameW[wndNameLength] = 0;
591 }
592 }
593
594 //copy pointer of CREATESTRUCT for usage in MsgCreate method
595 tmpcs = cs;
596
597 //Store our window object pointer in thread local memory, so PMWINDOW.CPP can retrieve it
598 THDB *thdb = GetThreadTHDB();
599
600 if(thdb == NULL) {
601 dprintf(("Window creation failed - thdb == NULL")); //this is VERY bad
602 ExitProcess(666);
603 return FALSE;
604 }
605
606 thdb->newWindow = (ULONG)this;
607
608 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
609 dwOSWinStyle,(char *)windowNameA,
610 (owner) ? owner->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
611 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
612 &OS2HwndFrame, 0, fTaskList);
613 if(OS2Hwnd == 0) {
614 dprintf(("Window creation failed!!"));
615 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
616 return FALSE;
617 }
618
619 SetLastError(0);
620 return TRUE;
621}
622//******************************************************************************
623//******************************************************************************
624BOOL Win32BaseWindow::MsgCreate(HWND hwndFrame, HWND hwndClient)
625{
626 POINT maxPos;
627 CREATESTRUCTA *cs = tmpcs; //pointer to CREATESTRUCT used in CreateWindowExA method
628
629 OS2Hwnd = hwndClient;
630 OS2HwndFrame = hwndFrame;
631
632 fNoSizeMsg = TRUE;
633
634 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
635 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
636 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
637 return FALSE;
638 }
639 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
640 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
641 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
642 return FALSE;
643 }
644
645 OSLibWinSetOwner(OS2Hwnd, OS2HwndFrame);
646
647 //FrameGetScrollBarHandles(this,dwStyle & WS_HSCROLL,dwStyle & WS_VSCROLL);
648 //subclassScrollBars(dwStyle & WS_HSCROLL,dwStyle & WS_VSCROLL);
649
650 fakeWinBase.hwndThis = OS2Hwnd;
651 fakeWinBase.pWindowClass = windowClass;
652
653 //Set icon from class
654 if(windowClass->getIcon())
655 SetIcon(windowClass->getIcon());
656 /* Get class or window DC if needed */
657 if(windowClass->getStyle() & CS_OWNDC) {
658 dprintf(("Class with CS_OWNDC style"));
659// ownDC = GetWindowDC(getWindowHandle());
660 }
661 else
662 if (windowClass->getStyle() & CS_PARENTDC) {
663 dprintf(("WARNING: Class with CS_PARENTDC style!"));
664 fParentDC = TRUE;
665 ownDC = 0;
666 }
667 else
668 if (windowClass->getStyle() & CS_CLASSDC) {
669 dprintf(("WARNING: Class with CS_CLASSDC style!"));
670 ownDC = 0;
671 }
672 /* Set the window menu */
673 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
674 {
675#if 0 //CB: todo
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#endif
686 }
687 else
688 {
689 setWindowId((DWORD)cs->hMenu);
690 }
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//******************************************************************************
1225VOID Win32BaseWindow::subclassScrollBars(BOOL subHorz,BOOL subVert)
1226{
1227 SCROLL_SubclassScrollBars(subHorz ? hwndHorzScroll:0,subVert ? hwndVertScroll:0);
1228}
1229//******************************************************************************
1230//******************************************************************************
1231BOOL Win32BaseWindow::showScrollBars(BOOL changeHorz,BOOL changeVert,BOOL fShow)
1232{
1233 BOOL rc = TRUE;
1234 DWORD flags = 0;
1235
1236 if (fShow)
1237 {
1238 BOOL createHorz = FALSE,createVert = FALSE;
1239 BOOL showHorz = FALSE,showVert = FALSE;
1240
1241 if (changeHorz)
1242 {
1243 if (!hwndHorzScroll)
1244 createHorz = TRUE;
1245 else
1246 showHorz = TRUE;
1247 }
1248
1249 if (changeVert)
1250 {
1251 if (!hwndVertScroll)
1252 createVert = TRUE;
1253 else
1254 showVert = TRUE;
1255 }
1256
1257 if (createHorz || createVert)
1258 {
1259 if (createHorz && !horzScrollInfo)
1260 {
1261 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1262 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
1263 horzScrollInfo->MaxVal = 100;
1264 horzScrollInfo->flags = ESB_ENABLE_BOTH;
1265 }
1266
1267 if (createVert && !vertScrollInfo)
1268 {
1269 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1270 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
1271 vertScrollInfo->MaxVal = 100;
1272 vertScrollInfo->flags = ESB_ENABLE_BOTH;
1273 }
1274
1275 rc = FrameCreateScrollBars(this,createHorz,createVert,FALSE,&flags);
1276
1277 if (!rc) return FALSE;
1278 if (createHorz) dwStyle |= WS_HSCROLL;
1279 if (createVert) dwStyle |= WS_VSCROLL;
1280 }
1281
1282 if (showVert || showHorz)
1283 {
1284 DWORD newFlags;
1285
1286 rc = FrameShowScrollBars(this,showHorz,showVert,fShow,FALSE,&newFlags);
1287 flags |= newFlags;
1288 if (rc)
1289 {
1290 if (showHorz) dwStyle |= WS_HSCROLL;
1291 if (showVert) dwStyle |= WS_VSCROLL;
1292 }
1293 }
1294
1295 if (flags) FrameUpdateFrame(this,flags);
1296 } else
1297 {
1298 rc = FrameShowScrollBars(this,changeHorz && hwndHorzScroll,changeVert && hwndVertScroll,fShow,TRUE);
1299
1300 if (rc)
1301 {
1302 if (changeHorz) dwStyle &= ~WS_HSCROLL;
1303 if (changeVert) dwStyle &= ~WS_VSCROLL;
1304 }
1305 }
1306
1307 return rc;
1308}
1309//******************************************************************************
1310//******************************************************************************
1311LONG Win32BaseWindow::HandleNCActivate(WPARAM wParam)
1312{
1313 WORD wStateChange;
1314
1315 if( wParam ) wStateChange = !(flags & WIN_NCACTIVATED);
1316 else wStateChange = flags & WIN_NCACTIVATED;
1317
1318 if( wStateChange )
1319 {
1320 if (wParam) flags |= WIN_NCACTIVATED;
1321 else flags &= ~WIN_NCACTIVATED;
1322
1323 if(!(dwStyle & WS_MINIMIZE))
1324 DoNCPaint((HRGN)1,FALSE);
1325 }
1326
1327 return TRUE;
1328}
1329//******************************************************************************
1330//******************************************************************************
1331VOID Win32BaseWindow::TrackMinMaxBox(WORD wParam)
1332{
1333 MSG msg;
1334 HDC hdc;
1335 BOOL pressed = TRUE;
1336 UINT state;
1337
1338 if (wParam == HTMINBUTTON)
1339 {
1340 /* If the style is not present, do nothing */
1341 if (!(dwStyle & WS_MINIMIZEBOX))
1342 return;
1343 /* Check if the sysmenu item for minimize is there */
1344#if 0 //CB: todo
1345 state = GetMenuState(hSysMenu,SC_MINIMIZE,MF_BYCOMMAND);
1346#endif
1347 } else
1348 {
1349 /* If the style is not present, do nothing */
1350 if (!(dwStyle & WS_MAXIMIZEBOX))
1351 return;
1352 /* Check if the sysmenu item for maximize is there */
1353#if 0 //CB: todo
1354 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
1355#endif
1356 }
1357 SetCapture(Win32Hwnd);
1358 hdc = GetWindowDC(Win32Hwnd);
1359 if (wParam == HTMINBUTTON)
1360 DrawMinButton(hdc,TRUE,FALSE);
1361 else
1362 DrawMaxButton(hdc,TRUE,FALSE);
1363 do
1364 {
1365 BOOL oldstate = pressed;
1366
1367 GetMessageA(&msg,Win32Hwnd,0,0);
1368 pressed = (HandleNCHitTest(msg.pt) == wParam);
1369 if (pressed != oldstate)
1370 {
1371 if (wParam == HTMINBUTTON)
1372 DrawMinButton(hdc,pressed,FALSE);
1373 else
1374 DrawMaxButton(hdc,pressed,FALSE);
1375 }
1376 } while (msg.message != WM_LBUTTONUP);
1377 if (wParam == HTMINBUTTON)
1378 DrawMinButton(hdc,FALSE,FALSE);
1379 else
1380 DrawMaxButton(hdc,FALSE,FALSE);
1381 ReleaseCapture();
1382 ReleaseDC(Win32Hwnd,hdc);
1383 /* If the item minimize or maximize of the sysmenu are not there */
1384 /* or if the style is not present, do nothing */
1385 if ((!pressed) || (state == 0xFFFFFFFF))
1386 return;
1387 if (wParam == HTMINBUTTON)
1388 SendInternalMessageA(WM_SYSCOMMAND,SC_MINIMIZE,*(LPARAM*)&msg.pt);
1389 else
1390 SendInternalMessageA(WM_SYSCOMMAND,IsZoomed(Win32Hwnd) ? SC_RESTORE:SC_MAXIMIZE,*(LPARAM*)&msg.pt);
1391}
1392//******************************************************************************
1393//******************************************************************************
1394VOID Win32BaseWindow::TrackCloseButton(WORD wParam)
1395{
1396 MSG msg;
1397 HDC hdc;
1398 BOOL pressed = TRUE;
1399 UINT state;
1400
1401#if 0 //CB: todo
1402 if (hSysMenu == 0)
1403 return;
1404 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1405#else
1406state = 0;
1407#endif
1408 /* If the item close of the sysmenu is disabled or not there do nothing */
1409 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
1410 return;
1411 hdc = GetWindowDC(Win32Hwnd);
1412 SetCapture(Win32Hwnd);
1413 DrawCloseButton(hdc,TRUE,FALSE);
1414 do
1415 {
1416 BOOL oldstate = pressed;
1417
1418 GetMessageA(&msg,Win32Hwnd,0,0);
1419 pressed = (HandleNCHitTest(msg.pt) == wParam);
1420 if (pressed != oldstate)
1421 DrawCloseButton(hdc, pressed, FALSE);
1422 } while (msg.message != WM_LBUTTONUP);
1423 DrawCloseButton(hdc,FALSE,FALSE);
1424 ReleaseCapture();
1425 ReleaseDC(Win32Hwnd,hdc);
1426 if (!pressed) return;
1427 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,*(LPARAM*)&msg.pt);
1428}
1429//******************************************************************************
1430//******************************************************************************
1431LONG Win32BaseWindow::HandleNCLButtonDown(WPARAM wParam,LPARAM lParam)
1432{
1433 switch(wParam) /* Hit test */
1434 {
1435 case HTCAPTION:
1436 SetActiveWindow();
1437 if (GetActiveWindow() == Win32Hwnd)
1438 SendInternalMessageA(WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
1439 break;
1440
1441 case HTSYSMENU:
1442 if(dwStyle & WS_SYSMENU )
1443 {
1444 if( !(dwStyle & WS_MINIMIZE) )
1445 {
1446 HDC hDC = GetWindowDC(Win32Hwnd);
1447 DrawSysButton(hDC,TRUE);
1448 ReleaseDC(Win32Hwnd,hDC);
1449 }
1450 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
1451 }
1452 break;
1453
1454 case HTMENU:
1455 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU,lParam);
1456 break;
1457
1458 case HTHSCROLL:
1459 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
1460 break;
1461
1462 case HTVSCROLL:
1463 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
1464 break;
1465
1466 case HTMINBUTTON:
1467 case HTMAXBUTTON:
1468 TrackMinMaxBox(wParam);
1469 break;
1470
1471 case HTCLOSE:
1472 TrackCloseButton(wParam);
1473 break;
1474
1475 case HTLEFT:
1476 case HTRIGHT:
1477 case HTTOP:
1478 case HTTOPLEFT:
1479 case HTTOPRIGHT:
1480 case HTBOTTOM:
1481 case HTBOTTOMLEFT:
1482 case HTBOTTOMRIGHT:
1483 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
1484 SendInternalMessageA(WM_SYSCOMMAND,SC_SIZE+wParam-2,lParam);
1485 break;
1486 case HTBORDER:
1487 break;
1488 }
1489
1490 return 0;
1491}
1492//******************************************************************************
1493//******************************************************************************
1494BOOL Win32BaseWindow::WindowNeedsWMBorder()
1495{
1496 if (!(dwStyle & WS_CHILD) &&
1497 //Options.managed && //CB: to check
1498 !(dwExStyle & WS_EX_TOOLWINDOW) &&
1499 ( ((dwStyle & WS_CAPTION) == WS_CAPTION) ||
1500 (dwStyle & WS_THICKFRAME)))
1501 return TRUE;
1502 if (dwExStyle & WS_EX_TRAYWINDOW)
1503 return TRUE;
1504 return FALSE;
1505}
1506//******************************************************************************
1507//******************************************************************************
1508VOID Win32BaseWindow::AdjustRectOuter(LPRECT rect,BOOL menu)
1509{
1510 if(dwStyle & WS_ICONIC) return;
1511
1512 /* Decide if the window will be managed (see CreateWindowEx) */
1513 //if (!WindowNeedsWMBorder()) //CB: check Options.managed
1514 {
1515 if (HAS_THICKFRAME(dwStyle,dwExStyle ))
1516 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
1517 else
1518 if (HAS_DLGFRAME( dwStyle, dwExStyle ))
1519 InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
1520 else
1521 if (HAS_THINFRAME( dwStyle ))
1522 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
1523
1524 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1525 {
1526 if (dwExStyle & WS_EX_TOOLWINDOW)
1527 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
1528 else
1529 rect->top -= GetSystemMetrics(SM_CYCAPTION);
1530 }
1531 }
1532
1533 if (menu)
1534 rect->top -= GetSystemMetrics(SM_CYMENU);
1535}
1536//******************************************************************************
1537//******************************************************************************
1538VOID Win32BaseWindow::AdjustRectInner(LPRECT rect)
1539{
1540 if(dwStyle & WS_ICONIC) return;
1541
1542 if (dwExStyle & WS_EX_CLIENTEDGE)
1543 InflateRect (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
1544
1545 if (dwExStyle & WS_EX_STATICEDGE)
1546 InflateRect (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
1547
1548 if (dwStyle & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
1549 if (dwStyle & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
1550}
1551//******************************************************************************
1552//******************************************************************************
1553LONG Win32BaseWindow::HandleNCCalcSize(BOOL calcValidRects,RECT *winRect)
1554{
1555 RECT tmpRect = { 0, 0, 0, 0 },*clientRect;
1556 LONG result = WVR_ALIGNTOP | WVR_ALIGNLEFT;
1557 UINT style;
1558
1559 if (!calcValidRects) return 0;
1560
1561 style = (UINT) GetClassLongA(Win32Hwnd,GCL_STYLE);
1562
1563 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
1564 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
1565
1566 clientRect = &((NCCALCSIZE_PARAMS*)winRect)->rgrc[2];
1567 *clientRect = rectWindow;
1568 if (getParent()) mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2WindowHandle(),clientRect);
1569
1570 if(!(dwStyle & WS_MINIMIZE))
1571 {
1572 AdjustRectOuter(&tmpRect,FALSE); //CB: todo: menu
1573
1574 clientRect->left -= tmpRect.left;
1575 clientRect->top -= tmpRect.top;
1576 clientRect->right -= tmpRect.right;
1577 clientRect->bottom -= tmpRect.bottom;
1578
1579 if (HAS_MENU(this))
1580 {
1581#if 0 //CB: todo
1582 winRect->top +=
1583 MENU_GetMenuBarHeight(Win32Hwnd,
1584 winRect->right - winRect->left,
1585 -tmpRect.left, -tmpRect.top ) + 1;
1586#endif
1587 }
1588
1589 SetRect (&tmpRect, 0, 0, 0, 0);
1590 AdjustRectInner(&tmpRect);
1591 clientRect->left -= tmpRect.left;
1592 clientRect->top -= tmpRect.top;
1593 clientRect->right -= tmpRect.right;
1594 clientRect->bottom -= tmpRect.bottom;
1595 }
1596
1597 return result;
1598}
1599//******************************************************************************
1600//******************************************************************************
1601LONG Win32BaseWindow::HandleNCHitTest(POINT pt)
1602{
1603 RECT rect = rectWindow;
1604
1605 if (!PtInRect(&rect,pt)) return HTNOWHERE;
1606
1607 if (dwStyle & WS_MINIMIZE) return HTCAPTION;
1608
1609 if (!(flags & WIN_MANAGED))
1610 {
1611 /* Check borders */
1612 if (HAS_THICKFRAME(dwStyle,dwExStyle))
1613 {
1614 InflateRect(&rect,-GetSystemMetrics(SM_CXFRAME),-GetSystemMetrics(SM_CYFRAME));
1615 if (!PtInRect(&rect,pt))
1616 {
1617 /* Check top sizing border */
1618 if (pt.y < rect.top)
1619 {
1620 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
1621 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
1622 return HTTOP;
1623 }
1624 /* Check bottom sizing border */
1625 if (pt.y >= rect.bottom)
1626 {
1627 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
1628 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
1629 return HTBOTTOM;
1630 }
1631 /* Check left sizing border */
1632 if (pt.x < rect.left)
1633 {
1634 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
1635 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
1636 return HTLEFT;
1637 }
1638 /* Check right sizing border */
1639 if (pt.x >= rect.right)
1640 {
1641 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
1642 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
1643 return HTRIGHT;
1644 }
1645 }
1646 } else /* No thick frame */
1647 {
1648 if (HAS_DLGFRAME(dwStyle,dwExStyle))
1649 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
1650 else if (HAS_THINFRAME(dwStyle ))
1651 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
1652 if (!PtInRect( &rect, pt )) return HTBORDER;
1653 }
1654
1655 /* Check caption */
1656
1657 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1658 {
1659 if (dwExStyle & WS_EX_TOOLWINDOW)
1660 rect.top += GetSystemMetrics(SM_CYSMCAPTION)-1;
1661 else
1662 rect.top += GetSystemMetrics(SM_CYCAPTION)-1;
1663 if (!PtInRect(&rect,pt))
1664 {
1665 /* Check system menu */
1666 if(dwStyle & WS_SYSMENU)
1667 {
1668 /* Check if there is an user icon */
1669 HICON hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICONSM);
1670 if(!hIcon) hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICON);
1671
1672 /* If there is an icon associated with the window OR */
1673 /* If there is no hIcon specified and this is not a modal dialog, */
1674 /* there is a system menu icon. */
1675 if((hIcon != 0) || (!(dwStyle & DS_MODALFRAME)))
1676 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1677 }
1678 if (pt.x < rect.left) return HTSYSMENU;
1679
1680 /* Check close button */
1681 if (dwStyle & WS_SYSMENU)
1682 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1683 if (pt.x > rect.right) return HTCLOSE;
1684
1685 /* Check maximize box */
1686 /* In win95 there is automatically a Maximize button when there is a minimize one*/
1687 if ((dwStyle & WS_MAXIMIZEBOX)|| (dwStyle & WS_MINIMIZEBOX))
1688 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1689 if (pt.x > rect.right) return HTMAXBUTTON;
1690
1691 /* Check minimize box */
1692 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
1693 if ((dwStyle & WS_MINIMIZEBOX)||(dwStyle & WS_MAXIMIZEBOX))
1694 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1695
1696 if (pt.x > rect.right) return HTMINBUTTON;
1697 return HTCAPTION;
1698 }
1699 }
1700 }
1701
1702 /* Check client area */
1703
1704 ScreenToClient(Win32Hwnd,&pt);
1705 getClientRect(&rect);
1706 if (PtInRect(&rect,pt)) return HTCLIENT;
1707
1708 /* Check vertical scroll bar */
1709
1710 if (dwStyle & WS_VSCROLL)
1711 {
1712 rect.right += GetSystemMetrics(SM_CXVSCROLL);
1713 if (PtInRect( &rect, pt )) return HTVSCROLL;
1714 }
1715
1716 /* Check horizontal scroll bar */
1717
1718 if (dwStyle & WS_HSCROLL)
1719 {
1720 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
1721 if (PtInRect( &rect, pt ))
1722 {
1723 /* Check size box */
1724 if ((dwStyle & WS_VSCROLL) &&
1725 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
1726 return (dwStyle & WS_CHILD) ? HTSIZE:HTBOTTOMRIGHT;
1727 return HTHSCROLL;
1728 }
1729 }
1730
1731 /* Check menu bar */
1732
1733 if (HAS_MENU(this))
1734 {
1735 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
1736 return HTMENU;
1737 }
1738
1739 /* Should never get here */
1740 return HTERROR;
1741}
1742
1743//******************************************************************************
1744//******************************************************************************
1745VOID Win32BaseWindow::GetInsideRect(RECT *rect)
1746{
1747 rect->top = rect->left = 0;
1748 rect->right = rectWindow.right - rectWindow.left;
1749 rect->bottom = rectWindow.bottom - rectWindow.top;
1750
1751 if ((dwStyle & WS_ICONIC) || (flags & WIN_MANAGED)) return;
1752
1753 /* Remove frame from rectangle */
1754 if (HAS_THICKFRAME(dwStyle,dwExStyle))
1755 {
1756 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
1757 }
1758 else if (HAS_DLGFRAME(dwStyle,dwExStyle ))
1759 {
1760 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
1761 }
1762 else if (HAS_THINFRAME(dwStyle))
1763 {
1764 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
1765 }
1766
1767 /* We have additional border information if the window
1768 * is a child (but not an MDI child) */
1769 if ( (dwStyle & WS_CHILD) &&
1770 ( (dwExStyle & WS_EX_MDICHILD) == 0 ) )
1771 {
1772 if (dwExStyle & WS_EX_CLIENTEDGE)
1773 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
1774
1775 if (dwExStyle & WS_EX_STATICEDGE)
1776 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
1777 }
1778}
1779//******************************************************************************
1780//******************************************************************************
1781VOID Win32BaseWindow::DrawFrame(HDC hdc,RECT *rect,BOOL dlgFrame,BOOL active)
1782{
1783 INT width, height;
1784 HBRUSH oldBrush;
1785
1786 if (dlgFrame)
1787 {
1788 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1789 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1790 } else
1791 {
1792 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1793 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1794 }
1795
1796 oldBrush = SelectObject(hdc,GetSysColorBrush(active ? COLOR_ACTIVEBORDER:COLOR_INACTIVEBORDER));
1797
1798 /* Draw frame */
1799
1800 PatBlt(hdc,rect->left,rect->top,rect->right-rect->left,height,PATCOPY);
1801 PatBlt(hdc,rect->left,rect->top,width,rect->bottom-rect->top,PATCOPY);
1802 PatBlt(hdc,rect->left,rect->bottom-1,rect->right-rect->left,-height,PATCOPY);
1803 PatBlt(hdc,rect->right-1,rect->top,-width,rect->bottom-rect->top,PATCOPY);
1804 SelectObject(hdc,oldBrush);
1805
1806 InflateRect(rect,-width,-height);
1807}
1808//******************************************************************************
1809//******************************************************************************
1810BOOL Win32BaseWindow::DrawSysButton(HDC hdc,BOOL down)
1811{
1812 if(!(flags & WIN_MANAGED))
1813 {
1814 HICON hIcon;
1815 RECT rect;
1816
1817 GetInsideRect(&rect);
1818
1819 hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICONSM);
1820 if(!hIcon) hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICON);
1821
1822 /* If there is no hIcon specified or this is not a modal dialog, */
1823 /* get the default one. */
1824 if(hIcon == 0)
1825 if (!(dwStyle & DS_MODALFRAME))
1826 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
1827
1828 if (hIcon)
1829 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1830 GetSystemMetrics(SM_CXSMICON),
1831 GetSystemMetrics(SM_CYSMICON),
1832 0, 0, DI_NORMAL);
1833
1834 return (hIcon != 0);
1835 }
1836 return FALSE;
1837}
1838//******************************************************************************
1839//******************************************************************************
1840BOOL Win32BaseWindow::DrawGrayButton(HDC hdc,int x,int y)
1841{
1842 HBITMAP hMaskBmp;
1843 HDC hdcMask = CreateCompatibleDC (0);
1844 HBRUSH hOldBrush;
1845 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
1846
1847 if(hMaskBmp == 0)
1848 return FALSE;
1849
1850 SelectObject (hdcMask, hMaskBmp);
1851
1852 /* Draw the grayed bitmap using the mask */
1853 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
1854 BitBlt (hdc, x, y, 12, 10,
1855 hdcMask, 0, 0, 0xB8074A);
1856
1857 /* Clean up */
1858 SelectObject (hdc, hOldBrush);
1859 DeleteObject(hMaskBmp);
1860 DeleteDC (hdcMask);
1861
1862 return TRUE;
1863}
1864//******************************************************************************
1865//******************************************************************************
1866VOID Win32BaseWindow::DrawCloseButton(HDC hdc,BOOL down,BOOL bGrayed)
1867{
1868 RECT rect;
1869 HDC hdcMem;
1870
1871 if( !(flags & WIN_MANAGED) )
1872 {
1873 BITMAP bmp;
1874 HBITMAP hBmp, hOldBmp;
1875
1876 GetInsideRect(&rect);
1877
1878 hdcMem = CreateCompatibleDC( hdc );
1879 hBmp = down ? hbitmapCloseD : hbitmapClose;
1880 hOldBmp = SelectObject (hdcMem, hBmp);
1881 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1882
1883 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1884 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1885 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1886
1887 if(bGrayed)
1888 DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1889 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1890
1891 SelectObject (hdcMem, hOldBmp);
1892 DeleteDC (hdcMem);
1893 }
1894}
1895//******************************************************************************
1896//******************************************************************************
1897VOID Win32BaseWindow::DrawMaxButton(HDC hdc,BOOL down,BOOL bGrayed)
1898{
1899 RECT rect;
1900 HDC hdcMem;
1901
1902 if( !(flags & WIN_MANAGED))
1903 {
1904 BITMAP bmp;
1905 HBITMAP hBmp,hOldBmp;
1906
1907 GetInsideRect(&rect);
1908 hdcMem = CreateCompatibleDC( hdc );
1909 hBmp = IsZoomed(Win32Hwnd) ?
1910 (down ? hbitmapRestoreD : hbitmapRestore ) :
1911 (down ? hbitmapMaximizeD: hbitmapMaximize);
1912 hOldBmp=SelectObject( hdcMem, hBmp );
1913 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1914
1915 if (dwStyle & WS_SYSMENU)
1916 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1917
1918 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1919 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1920 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1921
1922 if(bGrayed)
1923 DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1924 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1925
1926
1927 SelectObject (hdcMem, hOldBmp);
1928 DeleteDC( hdcMem );
1929 }
1930}
1931//******************************************************************************
1932//******************************************************************************
1933VOID Win32BaseWindow::DrawMinButton(HDC hdc,BOOL down,BOOL bGrayed)
1934{
1935 RECT rect;
1936 HDC hdcMem;
1937
1938 if( !(flags & WIN_MANAGED))
1939
1940 {
1941 BITMAP bmp;
1942 HBITMAP hBmp,hOldBmp;
1943
1944 GetInsideRect(&rect);
1945
1946 hdcMem = CreateCompatibleDC( hdc );
1947 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1948 hOldBmp= SelectObject( hdcMem, hBmp );
1949 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1950
1951 if (dwStyle & WS_SYSMENU)
1952 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1953
1954 /* In win 95 there is always a Maximize box when there is a Minimize one */
1955 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
1956 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1957
1958 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1959 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1960 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1961
1962 if(bGrayed)
1963 DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1964 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1965
1966
1967 SelectObject (hdcMem, hOldBmp);
1968 DeleteDC( hdcMem );
1969 }
1970}
1971//******************************************************************************
1972//******************************************************************************
1973VOID Win32BaseWindow::DrawCaption(HDC hdc,RECT *rect,BOOL active)
1974{
1975 RECT r = *rect;
1976 char buffer[256];
1977 HPEN hPrevPen;
1978 HMENU hSysMenu;
1979
1980 if (flags & WIN_MANAGED) return;
1981
1982 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1983 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1984 LineTo( hdc, r.right, r.bottom - 1 );
1985 SelectObject( hdc, hPrevPen );
1986 r.bottom--;
1987
1988 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
1989
1990 if (!hbitmapClose)
1991 {
1992 if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
1993 hbitmapCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
1994 hbitmapMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
1995 hbitmapMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
1996 hbitmapMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
1997 hbitmapMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
1998 hbitmapRestore = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
1999 hbitmapRestoreD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
2000 }
2001
2002 if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW))
2003 {
2004 if (DrawSysButton(hdc,FALSE))
2005 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
2006 }
2007
2008 if (dwStyle & WS_SYSMENU)
2009 {
2010 UINT state;
2011#if 0 //CB: todo
2012 /* Go get the sysmenu */
2013 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2014#else
2015state = 0;
2016#endif
2017 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
2018 DrawCloseButton(hdc, FALSE,
2019 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
2020 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
2021
2022 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
2023 {
2024 /* In win95 the two buttons are always there */
2025 /* But if the menu item is not in the menu they're disabled*/
2026
2027 DrawMaxButton(hdc, FALSE, (!(dwStyle & WS_MAXIMIZEBOX)));
2028 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2029
2030 DrawMinButton(hdc, FALSE, (!(dwStyle & WS_MINIMIZEBOX)));
2031 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2032 }
2033 }
2034
2035 if (GetWindowTextA(buffer, sizeof(buffer) ))
2036 {
2037 NONCLIENTMETRICSA nclm;
2038 HFONT hFont, hOldFont;
2039 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
2040 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
2041 if (dwExStyle & WS_EX_TOOLWINDOW)
2042 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
2043 else
2044 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
2045 hOldFont = SelectObject (hdc, hFont);
2046 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
2047 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
2048 SetBkMode( hdc, TRANSPARENT );
2049 r.left += 2;
2050 DrawTextA( hdc, buffer, -1, &r,
2051 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
2052 DeleteObject (SelectObject (hdc, hOldFont));
2053 }
2054}
2055//******************************************************************************
2056//******************************************************************************
2057VOID Win32BaseWindow::DoNCPaint(HRGN clip,BOOL suppress_menupaint)
2058{
2059 BOOL active = flags & WIN_NCACTIVATED;
2060 HDC hdc;
2061 RECT rect,rectClip,rfuzz;
2062
2063 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
2064 the call to GetDCEx implying that it is allowed not to use it either.
2065 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
2066 will cause clipRgn to be deleted after ReleaseDC().
2067 Now, how is the "system" supposed to tell what happened?
2068 */
2069
2070 if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
2071 ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
2072
2073 rect.top = rect.left = 0;
2074 rect.right = rectWindow.right - rectWindow.left;
2075 rect.bottom = rectWindow.bottom - rectWindow.top;
2076
2077 if( clip > 1 )
2078 GetRgnBox( clip, &rectClip );
2079 else
2080 {
2081 clip = 0;
2082 rectClip = rect;
2083 }
2084
2085 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
2086
2087 if(!(flags & WIN_MANAGED))
2088 {
2089 if (HAS_BIGFRAME( dwStyle, dwExStyle))
2090 {
2091 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
2092 }
2093 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
2094 DrawFrame(hdc, &rect, FALSE, active );
2095 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
2096 DrawFrame( hdc, &rect, TRUE, active );
2097 else if (HAS_THINFRAME( dwStyle ))
2098 {
2099 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
2100 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
2101 }
2102
2103 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
2104 {
2105 RECT r = rect;
2106 if (dwExStyle & WS_EX_TOOLWINDOW)
2107 {
2108 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
2109 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
2110 }
2111 else
2112 {
2113 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
2114 rect.top += GetSystemMetrics(SM_CYCAPTION);
2115 }
2116 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
2117 DrawCaption(hdc, &r, active);
2118 }
2119 }
2120#if 0 //CB: todo
2121 if (HAS_MENU(wndPtr))
2122 {
2123 RECT r = rect;
2124 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
2125
2126 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
2127 }
2128#endif
2129
2130 if (dwExStyle & WS_EX_CLIENTEDGE)
2131 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
2132
2133 if (dwExStyle & WS_EX_STATICEDGE)
2134 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
2135
2136 /* Draw the scroll-bars */
2137#if 0 //CB: todo
2138 if (dwStyle & WS_VSCROLL)
2139 SCROLL_DrawScrollBar(hwnd,hdc,SB_VERT,TRUE,TRUE);
2140 if (wndPtr->dwStyle & WS_HSCROLL)
2141 SCROLL_DrawScrollBar(hwnd,hdc,SB_HORZ,TRUE,TRUE);
2142#endif
2143 /* Draw the "size-box" */
2144 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
2145 {
2146 RECT r = rect;
2147 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
2148 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
2149 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
2150 if (!(dwStyle & WS_CHILD))
2151 {
2152 POINT p1,p2;
2153 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
2154 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
2155 HPEN oldPen = SelectObject(hdc,penDark);
2156 INT x;
2157
2158 p1.x = r.right-1;
2159 p1.y = r.bottom;
2160 p2.x = r.right;
2161 p2.y = r.bottom-1;
2162 for (x = 0;x < 3;x++)
2163 {
2164 SelectObject(hdc,penDark);
2165 MoveToEx(hdc,p1.x,p1.y,NULL);
2166 LineTo(hdc,p2.x,p2.y);
2167 p1.x--;
2168 p2.y--;
2169 MoveToEx(hdc,p1.x,p1.y,NULL);
2170 LineTo(hdc,p2.x,p2.y);
2171 SelectObject(hdc,penWhite);
2172 p1.x--;
2173 p2.y--;
2174 MoveToEx(hdc,p1.x,p1.y,NULL);
2175 LineTo(hdc,p2.x,p2.y);
2176 p1.x -= 2;
2177 p2.y -= 2;
2178 }
2179
2180 SelectObject(hdc,oldPen);
2181 }
2182 }
2183
2184 ReleaseDC(Win32Hwnd,hdc);
2185}
2186//******************************************************************************
2187//******************************************************************************
2188LONG Win32BaseWindow::HandleNCPaint(HRGN clip)
2189{
2190//CB: ignore it for now (SetWindowPos in WM_CREATE)
2191// if (!(dwStyle & WS_VISIBLE)) return 0;
2192
2193 if (dwStyle & WS_MINIMIZE) return 0;
2194
2195 DoNCPaint(clip,FALSE);
2196
2197 return 0;
2198}
2199/***********************************************************************
2200 * NC_HandleNCLButtonDblClk
2201 *
2202 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2203 */
2204LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
2205{
2206 /*
2207 * if this is an icon, send a restore since we are handling
2208 * a double click
2209 */
2210 if (dwStyle & WS_MINIMIZE)
2211 {
2212 SendInternalMessageA(WM_SYSCOMMAND,SC_RESTORE,lParam);
2213 return 0;
2214 }
2215
2216 switch(wParam) /* Hit test */
2217 {
2218 case HTCAPTION:
2219 /* stop processing if WS_MAXIMIZEBOX is missing */
2220 if (dwStyle & WS_MAXIMIZEBOX)
2221 SendInternalMessageA(WM_SYSCOMMAND,
2222 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2223 lParam);
2224 break;
2225
2226 case HTSYSMENU:
2227 if (!(GetClassWord(Win32Hwnd,GCW_STYLE) & CS_NOCLOSE))
2228 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
2229 break;
2230
2231 case HTHSCROLL:
2232 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
2233 break;
2234
2235 case HTVSCROLL:
2236 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
2237 break;
2238 }
2239
2240 return 0;
2241}
2242/***********************************************************************
2243 * NC_HandleSysCommand
2244 *
2245 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2246 *
2247 * TODO: Not done (see #if 0)
2248 */
2249LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam, POINT *pt32)
2250{
2251 UINT uCommand = wParam & 0xFFF0;
2252
2253 if ((getStyle() & WS_CHILD) && (uCommand != SC_KEYMENU))
2254 ScreenToClient(getParent()->getWindowHandle(), pt32 );
2255
2256 switch (uCommand)
2257 {
2258
2259 case SC_SIZE:
2260 {
2261 DWORD flags = 0;
2262
2263 switch ((wParam & 0xF)+2)
2264 {
2265 case HTLEFT:
2266 flags = TFOS_LEFT;
2267 break;
2268
2269 case HTRIGHT:
2270 flags = TFOS_RIGHT;
2271 break;
2272
2273 case HTTOP:
2274 flags = TFOS_TOP;
2275 break;
2276
2277 case HTTOPLEFT:
2278 flags = TFOS_TOP | TFOS_LEFT;
2279 break;
2280
2281 case HTTOPRIGHT:
2282 flags = TFOS_TOP | TFOS_RIGHT;
2283 break;
2284
2285 case HTBOTTOM:
2286 flags = TFOS_BOTTOM;
2287 break;
2288
2289 case HTBOTTOMLEFT:
2290 flags = TFOS_BOTTOM | TFOS_LEFT;
2291 break;
2292
2293 case HTBOTTOMRIGHT:
2294 flags = TFOS_BOTTOM | TFOS_RIGHT;
2295 break;
2296 }
2297 if (flags) FrameTrackFrame(this,flags);
2298 break;
2299 }
2300
2301 case SC_MOVE:
2302 FrameTrackFrame(this,TFOS_MOVE);
2303 break;
2304
2305 case SC_MINIMIZE:
2306 ShowWindow(SW_MINIMIZE);
2307 break;
2308
2309 case SC_MAXIMIZE:
2310 ShowWindow(SW_MAXIMIZE);
2311 break;
2312
2313 case SC_RESTORE:
2314 ShowWindow(SW_RESTORE);
2315 break;
2316
2317 case SC_CLOSE:
2318 return SendInternalMessageA(WM_CLOSE, 0, 0);
2319
2320#if 0
2321 case SC_VSCROLL:
2322 case SC_HSCROLL:
2323 NC_TrackScrollBar( hwnd, wParam, pt32 );
2324 break;
2325
2326 case SC_MOUSEMENU:
2327 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2328 break;
2329
2330 case SC_KEYMENU:
2331 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2332 break;
2333
2334 case SC_TASKLIST:
2335 WinExec( "taskman.exe", SW_SHOWNORMAL );
2336 break;
2337
2338 case SC_SCREENSAVE:
2339 if (wParam == SC_ABOUTWINE)
2340 ShellAboutA(hwnd, "Odin", ODIN_RELEASE_INFO, 0);
2341 else
2342 if (wParam == SC_PUTMARK)
2343 dprintf(("Mark requested by user\n"));
2344 break;
2345#endif
2346 case SC_HOTKEY:
2347 case SC_ARRANGE:
2348 case SC_NEXTWINDOW:
2349 case SC_PREVWINDOW:
2350 break;
2351 }
2352 return 0;
2353}
2354//******************************************************************************
2355//******************************************************************************
2356LRESULT Win32BaseWindow::DefWndControlColor(UINT ctlType, HDC hdc)
2357{
2358 //SvL: Set background color to default button color (not window (white))
2359 if(ctlType == CTLCOLOR_BTN)
2360 {
2361 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
2362 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
2363 return GetSysColorBrush(COLOR_BTNFACE);
2364 }
2365 //SvL: Set background color to default dialog color if window is dialog
2366 if((ctlType == CTLCOLOR_DLG || ctlType == CTLCOLOR_STATIC) && IsDialog()) {
2367 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
2368 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
2369 return GetSysColorBrush(COLOR_BTNFACE);
2370 }
2371
2372 if( ctlType == CTLCOLOR_SCROLLBAR)
2373 {
2374 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
2375 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
2376 SetTextColor( hdc, GetSysColor(COLOR_3DFACE));
2377 SetBkColor( hdc, bk);
2378
2379//TODO?
2380#if 0
2381 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
2382 * we better use 0x55aa bitmap brush to make scrollbar's background
2383 * look different from the window background.
2384 */
2385 if (bk == GetSysColor(COLOR_WINDOW)) {
2386 return CACHE_GetPattern55AABrush();
2387 }
2388#endif
2389 UnrealizeObject( hb );
2390 return (LRESULT)hb;
2391 }
2392
2393 SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
2394
2395 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
2396 {
2397 SetBkColor( hdc, GetSysColor(COLOR_WINDOW) );
2398 }
2399 else
2400 {
2401 SetBkColor( hdc, GetSysColor(COLOR_3DFACE) );
2402 return (LRESULT)GetSysColorBrush(COLOR_3DFACE);
2403 }
2404 return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
2405}
2406//******************************************************************************
2407//******************************************************************************
2408LRESULT Win32BaseWindow::DefWndPrint(HDC hdc,ULONG uFlags)
2409{
2410 /*
2411 * Visibility flag.
2412 */
2413 if ( (uFlags & PRF_CHECKVISIBLE) &&
2414 !IsWindowVisible() )
2415 return 0;
2416
2417 /*
2418 * Unimplemented flags.
2419 */
2420 if ( (uFlags & PRF_CHILDREN) ||
2421 (uFlags & PRF_OWNED) ||
2422 (uFlags & PRF_NONCLIENT) )
2423 {
2424 dprintf(("WM_PRINT message with unsupported flags\n"));
2425 }
2426
2427 /*
2428 * Background
2429 */
2430 if ( uFlags & PRF_ERASEBKGND)
2431 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
2432
2433 /*
2434 * Client area
2435 */
2436 if ( uFlags & PRF_CLIENT)
2437 SendInternalMessageA(WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
2438
2439
2440 return 0;
2441}
2442//******************************************************************************
2443//******************************************************************************
2444LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
2445{
2446 switch(Msg)
2447 {
2448 case WM_CLOSE:
2449 dprintf(("DefWindowProcA: WM_CLOSE %x", getWindowHandle()));
2450 DestroyWindow();
2451 return 0;
2452
2453 case WM_GETTEXTLENGTH:
2454 return wndNameLength;
2455
2456 case WM_GETTEXT:
2457 if (!lParam || !wParam) return 0;
2458 if (!windowNameA) ((LPSTR)lParam)[0] = 0;
2459 else lstrcpynA((LPSTR)lParam, windowNameA, wParam);
2460 return min(wndNameLength, wParam);
2461
2462 case WM_SETTEXT:
2463 {
2464 LPCSTR lpsz = (LPCSTR)lParam;
2465
2466 if(windowNameA) free(windowNameA);
2467 if(windowNameW) free(windowNameW);
2468
2469 if (lParam)
2470 {
2471 wndNameLength = strlen(lpsz);
2472 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
2473 strcpy(windowNameA, lpsz);
2474 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
2475 lstrcpyAtoW(windowNameW, windowNameA);
2476 }
2477 else
2478 {
2479 windowNameA = NULL;
2480 windowNameW = NULL;
2481 wndNameLength = 0;
2482 }
2483 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, lParam));
2484 if (dwStyle & WS_CAPTION)
2485 {
2486 //CB: optimize!
2487 HandleNCPaint(0);
2488 }
2489/* //CB: endless loop in trackbar.exe -> to fix
2490 if(OS2HwndFrame && (dwStyle & WS_CAPTION) == WS_CAPTION)
2491 return OSLibWinSetWindowText(OS2HwndFrame,(LPSTR)windowNameA);
2492*/
2493 return TRUE;
2494 }
2495
2496 case WM_SETREDRAW:
2497 {
2498 if (wParam)
2499 {
2500 setStyle(getStyle() | WS_VISIBLE);
2501 OSLibWinEnableWindowUpdate(OS2HwndFrame,TRUE);
2502 } else
2503 {
2504 if (getStyle() & WS_VISIBLE)
2505 {
2506 setStyle(getStyle() & ~WS_VISIBLE);
2507 OSLibWinEnableWindowUpdate(OS2HwndFrame,FALSE);
2508 }
2509 }
2510 return 0;
2511 }
2512
2513 case WM_NCPAINT:
2514 return HandleNCPaint((HRGN)wParam);
2515
2516 case WM_NCACTIVATE:
2517 return HandleNCActivate(wParam);
2518
2519 case WM_NCCREATE:
2520 return(TRUE);
2521
2522 case WM_NCDESTROY:
2523 return 0;
2524
2525 case WM_NCCALCSIZE:
2526 return HandleNCCalcSize((BOOL)wParam,(RECT*)lParam);
2527
2528 case WM_CTLCOLORMSGBOX:
2529 case WM_CTLCOLOREDIT:
2530 case WM_CTLCOLORLISTBOX:
2531 case WM_CTLCOLORBTN:
2532 case WM_CTLCOLORDLG:
2533 case WM_CTLCOLORSTATIC:
2534 case WM_CTLCOLORSCROLLBAR:
2535 return DefWndControlColor(Msg - WM_CTLCOLORMSGBOX, (HDC)wParam);
2536
2537 case WM_CTLCOLOR:
2538 return DefWndControlColor(HIWORD(lParam), (HDC)wParam);
2539
2540 case WM_VKEYTOITEM:
2541 case WM_CHARTOITEM:
2542 return -1;
2543
2544 case WM_PARENTNOTIFY:
2545 return 0;
2546
2547 case WM_MOUSEACTIVATE:
2548 {
2549 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
2550 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
2551 {
2552 if(getParent()) {
2553 LRESULT rc = getParent()->SendInternalMessageA(WM_MOUSEACTIVATE, wParam, lParam );
2554 if(rc) return rc;
2555 }
2556 }
2557 return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
2558 }
2559
2560 case WM_ACTIVATE:
2561 return 0;
2562
2563 case WM_SETCURSOR:
2564 {
2565 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
2566 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
2567 {
2568 if(getParent()) {
2569 LRESULT rc = getParent()->SendInternalMessageA(WM_SETCURSOR, wParam, lParam);
2570 if(rc) return rc;
2571 }
2572 }
2573 if (wParam == Win32Hwnd)
2574 {
2575 HCURSOR hCursor;
2576
2577 switch(LOWORD(lParam))
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 = windowClass ? windowClass->getCursor():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::SetMenu(HMENU hMenu)
3099{
3100
3101 dprintf(("SetMenu %x", hMenu));
3102 OS2HwndMenu = OSLibWinSetMenu(OS2HwndFrame, hMenu);
3103 if(OS2HwndMenu == 0) {
3104 dprintf(("Win32BaseWindow::SetMenu OS2HwndMenu == 0"));
3105 return FALSE;
3106 }
3107 return TRUE;
3108}
3109//******************************************************************************
3110//******************************************************************************
3111BOOL Win32BaseWindow::SetIcon(HICON hIcon)
3112{
3113 dprintf(("Win32BaseWindow::SetIcon %x", hIcon));
3114 if(OSLibWinSetIcon(OS2HwndFrame, hIcon) == TRUE) {
3115//TODO: Wine does't send these. Correct?
3116// SendInternalMessageA(WM_SETICON, ICON_BIG, hIcon);
3117 return TRUE;
3118 }
3119 return FALSE;
3120}
3121//******************************************************************************
3122//******************************************************************************
3123BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
3124{
3125 ULONG showstate = 0;
3126 HWND hWinAfter;
3127
3128 dprintf(("ShowWindow %x %x", getWindowHandle(), nCmdShow));
3129#if 1
3130 if (flags & WIN_NEED_SIZE)
3131 {
3132 /* should happen only in CreateWindowEx() */
3133 int wParam = SIZE_RESTORED;
3134
3135 flags &= ~WIN_NEED_SIZE;
3136 if (dwStyle & WS_MAXIMIZE)
3137 wParam = SIZE_MAXIMIZED;
3138 else
3139 if (dwStyle & WS_MINIMIZE)
3140 wParam = SIZE_MINIMIZED;
3141
3142 SendInternalMessageA(WM_SIZE, wParam,
3143 MAKELONG(rectClient.right-rectClient.left,
3144 rectClient.bottom-rectClient.top));
3145 SendInternalMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
3146 }
3147#else
3148 if(fFirstShow) {
3149 if(isFrameWindow() && IS_OVERLAPPED(getStyle()) && !isChild()) {
3150 SendInternalMessageA(WM_SIZE, SIZE_RESTORED,
3151 MAKELONG(rectClient.right-rectClient.left,
3152 rectClient.bottom-rectClient.top));
3153 SendInternalMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
3154
3155 }
3156 fFirstShow = FALSE;
3157 }
3158#endif
3159 switch(nCmdShow)
3160 {
3161 case SW_SHOW:
3162 case SW_SHOWDEFAULT: //todo
3163 showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
3164 break;
3165 case SW_HIDE:
3166 showstate = SWPOS_HIDE;
3167 break;
3168 case SW_RESTORE:
3169 showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
3170 break;
3171 case SW_MINIMIZE:
3172 showstate = SWPOS_MINIMIZE;
3173 break;
3174 case SW_SHOWMAXIMIZED:
3175 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
3176 break;
3177 case SW_SHOWMINIMIZED:
3178 showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
3179 break;
3180 case SW_SHOWMINNOACTIVE:
3181 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
3182 break;
3183 case SW_SHOWNA:
3184 showstate = SWPOS_SHOW;
3185 break;
3186 case SW_SHOWNOACTIVATE:
3187 showstate = SWPOS_SHOW;
3188 break;
3189 case SW_SHOWNORMAL:
3190 showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
3191 break;
3192 }
3193
3194 /* We can't activate a child window (WINE) */
3195 if(getStyle() & WS_CHILD)
3196 showstate &= ~SWPOS_ACTIVATE;
3197
3198 if(showstate & SWPOS_SHOW) {
3199 setStyle(getStyle() | WS_VISIBLE);
3200 }
3201 else setStyle(getStyle() & ~WS_VISIBLE);
3202
3203 BOOL rc = OSLibWinShowWindow(OS2HwndFrame, showstate);
3204
3205 return rc;
3206}
3207//******************************************************************************
3208//******************************************************************************
3209BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
3210{
3211 BOOL rc = FALSE;
3212 Win32BaseWindow *window;
3213 HWND hParent = 0;
3214
3215 dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
3216
3217 if (fuFlags &
3218 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
3219 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
3220 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
3221 SWP_NOOWNERZORDER))
3222 {
3223 return FALSE;
3224 }
3225
3226 WINDOWPOS wpos;
3227 SWP swp, swpOld;
3228
3229 wpos.flags = fuFlags;
3230 wpos.cy = cy;
3231 wpos.cx = cx;
3232 wpos.x = x;
3233 wpos.y = y;
3234 wpos.hwndInsertAfter = hwndInsertAfter;
3235 wpos.hwnd = getWindowHandle();
3236
3237 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE))
3238 {
3239 if (isChild())
3240 {
3241 Win32BaseWindow *windowParent = getParent();
3242 if(windowParent) {
3243 hParent = getParent()->getOS2WindowHandle();
3244 }
3245 else dprintf(("WARNING: Win32BaseWindow::SetWindowPos window %x is child but has no parent!!", getWindowHandle()));
3246 }
3247 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
3248 }
3249
3250 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
3251 if (swp.fl == 0)
3252 return TRUE;
3253
3254// if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
3255 if ((swp.hwndInsertBehind > HWNDOS_BOTTOM))
3256 {
3257 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
3258 if(wndBehind) {
3259 swp.hwndInsertBehind = wndBehind->getOS2FrameWindowHandle();
3260 }
3261 else {
3262 dprintf(("ERROR: SetWindowPos: hwndInsertBehind %x invalid!",swp.hwndInsertBehind));
3263 swp.hwndInsertBehind = 0;
3264 }
3265 }
3266//CB: todo
3267 #if 0
3268 if (isFrameWindow())
3269 {
3270 if (!isChild())
3271 {
3272 POINT maxSize, maxPos, minTrack, maxTrack;
3273
3274 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
3275
3276 if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
3277 if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
3278 if (swp.cx < minTrack.x) swp.cx = minTrack.x;
3279 if (swp.cy < minTrack.y) swp.cy = minTrack.y;
3280 }
3281 swp.hwnd = OS2HwndFrame;
3282 }
3283 else
3284#endif
3285 swp.hwnd = OS2HwndFrame;
3286
3287 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
3288
3289 rc = OSLibWinSetMultWindowPos(&swp, 1);
3290
3291 if (rc == FALSE)
3292 {
3293 dprintf(("OSLibWinSetMultWindowPos failed! Error %x",OSLibWinGetLastError()));
3294 }
3295
3296 if (fuFlags == SWP_FRAMECHANGED)
3297 {
3298 //CB: optimize: if frame size has changed not necessary!
3299 FrameUpdateFrame(this,0);
3300 }
3301
3302 return (rc);
3303}
3304//******************************************************************************
3305//TODO: WPF_RESTOREMAXIMIZED
3306//******************************************************************************
3307BOOL Win32BaseWindow::SetWindowPlacement(WINDOWPLACEMENT *winpos)
3308{
3309 if(isFrameWindow())
3310 {
3311 // Set the minimized position
3312 if (winpos->flags & WPF_SETMINPOSITION)
3313 {
3314 OSLibSetWindowMinPos(OS2HwndFrame, winpos->ptMinPosition.x, winpos->ptMinPosition.y);
3315 }
3316
3317 //TODO: Max position
3318
3319 // Set the new restore position.
3320 OSLibSetWindowRestoreRect(OS2HwndFrame, &winpos->rcNormalPosition);
3321 }
3322
3323 return ShowWindow(winpos->showCmd);
3324}
3325//******************************************************************************
3326//Also destroys all the child windows (destroy children first, parent last)
3327//******************************************************************************
3328BOOL Win32BaseWindow::DestroyWindow()
3329{
3330 /* Call hooks */
3331 if(HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, getWindowHandle(), 0L))
3332 {
3333 return FALSE;
3334 }
3335
3336 if(!(getStyle() & WS_CHILD) && getOwner() == NULL)
3337 {
3338 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWDESTROYED, getWindowHandle(), 0L);
3339 /* FIXME: clean up palette - see "Internals" p.352 */
3340 }
3341
3342 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
3343 {
3344 if(getParent())
3345 {
3346 /* Notify the parent window only */
3347 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
3348 if( !::IsWindow(getWindowHandle()) )
3349 {
3350 return TRUE;
3351 }
3352 }
3353 else DebugInt3();
3354 }
3355 fDestroyWindowCalled = TRUE;
3356 return OSLibWinDestroyWindow(OS2HwndFrame);
3357}
3358//******************************************************************************
3359//******************************************************************************
3360Win32BaseWindow *Win32BaseWindow::getParent()
3361{
3362 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::GetParent();
3363 return ((ULONG)wndparent == (ULONG)windowDesktop) ? NULL : wndparent;
3364}
3365//******************************************************************************
3366//******************************************************************************
3367HWND Win32BaseWindow::GetParent()
3368{
3369 Win32BaseWindow *wndparent;
3370
3371 if ((!(getStyle() & (WS_POPUP|WS_CHILD))))
3372 {
3373 return 0;
3374 }
3375 wndparent = ((getStyle() & WS_CHILD) ? getParent() : getOwner());
3376
3377 return (wndparent) ? wndparent->getWindowHandle() : 0;
3378}
3379//******************************************************************************
3380//******************************************************************************
3381HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
3382{
3383 HWND oldhwnd;
3384 Win32BaseWindow *newparent;
3385
3386 if(getParent()) {
3387 oldhwnd = getParent()->getWindowHandle();
3388 getParent()->RemoveChild(this);
3389 }
3390 else oldhwnd = 0;
3391
3392 newparent = GetWindowFromHandle(hwndNewParent);
3393 if(newparent)
3394 {
3395 setParent(newparent);
3396 getParent()->AddChild(this);
3397 OSLibWinSetParent(getOS2FrameWindowHandle(), getParent()->getOS2WindowHandle());
3398 return oldhwnd;
3399 }
3400 else {
3401 setParent(windowDesktop);
3402 windowDesktop->AddChild(this);
3403 OSLibWinSetParent(getOS2FrameWindowHandle(), OSLIB_HWND_DESKTOP);
3404 return oldhwnd;
3405 }
3406}
3407//******************************************************************************
3408//******************************************************************************
3409BOOL Win32BaseWindow::IsChild(HWND hwndParent)
3410{
3411 if(getParent()) {
3412 return getParent()->getWindowHandle() == hwndParent;
3413 }
3414 else return 0;
3415}
3416//******************************************************************************
3417//******************************************************************************
3418HWND Win32BaseWindow::GetTopWindow()
3419{
3420 return GetWindow(GW_CHILD);
3421}
3422//******************************************************************************
3423// Get the top-level parent for a child window.
3424//******************************************************************************
3425Win32BaseWindow *Win32BaseWindow::GetTopParent()
3426{
3427 Win32BaseWindow *window = this;
3428
3429 while(window && (window->getStyle() & WS_CHILD))
3430 {
3431 window = window->getParent();
3432 }
3433 return window;
3434}
3435//******************************************************************************
3436//Don't call WinUpdateWindow as that one also updates the child windows
3437//Also need to send WM_PAINT directly to the window procedure, which doesn't
3438//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
3439//******************************************************************************
3440BOOL Win32BaseWindow::UpdateWindow()
3441{
3442 RECT rect;
3443
3444 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
3445 {//update region not empty
3446 HDC hdc;
3447
3448 hdc = O32_GetDC(OS2Hwnd);
3449 if (isIcon)
3450 {
3451 SendInternalMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
3452 SendInternalMessageA(WM_PAINTICON, 0, 0);
3453 }
3454 else
3455 {
3456 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
3457 SendInternalMessageA(WM_PAINT, 0, 0);
3458 }
3459 O32_ReleaseDC(OS2Hwnd, hdc);
3460 }
3461 return TRUE;
3462}
3463//******************************************************************************
3464//******************************************************************************
3465BOOL Win32BaseWindow::IsIconic()
3466{
3467 return OSLibWinIsIconic(OS2Hwnd);
3468}
3469//******************************************************************************
3470//TODO: Should not enumerate children that are created during the enumeration!
3471//******************************************************************************
3472BOOL Win32BaseWindow::EnumChildWindows(WNDENUMPROC lpfn, LPARAM lParam)
3473{
3474 BOOL rc = TRUE;
3475 HWND hwnd;
3476 Win32BaseWindow *prevchild = 0, *child = 0;
3477
3478 dprintf(("EnumChildWindows of %x parameter %x %x (%x)", getWindowHandle(), lpfn, lParam, getFirstChild()));
3479 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3480 {
3481 dprintf(("EnumChildWindows: enumerating child %x", child->getWindowHandle()));
3482 hwnd = child->getWindowHandle();
3483 if(child->getOwner()) {
3484 continue; //shouldn't have an owner (Wine)
3485 }
3486 if(lpfn(hwnd, lParam) == FALSE)
3487 {
3488 rc = FALSE;
3489 break;
3490 }
3491 //check if the window still exists
3492 if(!::IsWindow(hwnd))
3493 {
3494 child = prevchild;
3495 continue;
3496 }
3497 if(child->getFirstChild() != NULL)
3498 {
3499 dprintf(("EnumChildWindows: Enumerate children of %x", child->getWindowHandle()));
3500 if(child->EnumChildWindows(lpfn, lParam) == FALSE)
3501 {
3502 rc = FALSE;
3503 break;
3504 }
3505 }
3506 prevchild = child;
3507 }
3508 return rc;
3509}
3510//******************************************************************************
3511//Enumerate first-level children only and check thread id
3512//******************************************************************************
3513BOOL Win32BaseWindow::EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
3514{
3515 Win32BaseWindow *child = 0;
3516 ULONG tid, pid;
3517 BOOL rc;
3518 HWND hwnd;
3519
3520 dprintf(("EnumThreadWindows %x %x %x", dwThreadId, lpfn, lParam));
3521
3522 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3523 {
3524 OSLibWinQueryWindowProcess(child->getOS2WindowHandle(), &pid, &tid);
3525
3526 if(dwThreadId == tid) {
3527 dprintf2(("EnumThreadWindows: Found Window %x", child->getWindowHandle()));
3528 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
3529 break;
3530 }
3531 }
3532 }
3533 return TRUE;
3534}
3535//******************************************************************************
3536//Enumerate first-level children only
3537//******************************************************************************
3538BOOL Win32BaseWindow::EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
3539{
3540 Win32BaseWindow *child = 0;
3541 BOOL rc;
3542 HWND hwnd;
3543
3544 dprintf(("EnumWindows %x %x", lpfn, lParam));
3545
3546 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3547 {
3548 hwnd = child->getWindowHandle();
3549
3550 dprintf2(("EnumWindows: Found Window %x", child->getWindowHandle()));
3551 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
3552 break;
3553 }
3554 }
3555 return TRUE;
3556}
3557//******************************************************************************
3558//******************************************************************************
3559Win32BaseWindow *Win32BaseWindow::FindWindowById(int id)
3560{
3561 for (Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3562 {
3563 if (child->getWindowId() == id)
3564 {
3565 return child;
3566 }
3567 }
3568 return 0;
3569}
3570//******************************************************************************
3571//TODO:
3572//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
3573//the current process owns them.
3574//******************************************************************************
3575HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
3576 BOOL fUnicode)
3577{
3578 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
3579 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
3580
3581 if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
3582 (hwndChildAfter != 0 && !child) ||
3583 (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
3584 {
3585 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
3586 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
3587 return 0;
3588 }
3589 if(hwndParent != OSLIB_HWND_DESKTOP)
3590 {//if the current process owns the window, just do a quick search
3591 child = (Win32BaseWindow *)parent->getFirstChild();
3592 if(hwndChildAfter != 0)
3593 {
3594 while(child)
3595 {
3596 if(child->getWindowHandle() == hwndChildAfter)
3597 {
3598 child = (Win32BaseWindow *)child->getNextChild();
3599 break;
3600 }
3601 child = (Win32BaseWindow *)child->getNextChild();
3602 }
3603 }
3604 while(child)
3605 {
3606 if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
3607 (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
3608 {
3609 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
3610 return child->getWindowHandle();
3611 }
3612 child = (Win32BaseWindow *)child->getNextChild();
3613 }
3614 }
3615 else {
3616 Win32BaseWindow *wnd;
3617 HWND henum, hwnd;
3618
3619 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
3620 hwnd = OSLibWinGetNextWindow(henum);
3621
3622 while(hwnd)
3623 {
3624 wnd = GetWindowFromOS2Handle(hwnd);
3625 if(wnd == NULL) {
3626 hwnd = OSLibWinQueryClientWindow(hwnd);
3627 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
3628 if(!hwnd) wnd = GetWindowFromOS2FrameHandle(hwnd);
3629 }
3630
3631 if(wnd) {
3632 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
3633 (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
3634 {
3635 OSLibWinEndEnumWindows(henum);
3636 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
3637 return wnd->getWindowHandle();
3638 }
3639 }
3640 hwnd = OSLibWinGetNextWindow(henum);
3641 }
3642 OSLibWinEndEnumWindows(henum);
3643 }
3644 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
3645 return 0;
3646}
3647//******************************************************************************
3648//******************************************************************************
3649HWND Win32BaseWindow::GetWindow(UINT uCmd)
3650{
3651 HWND hwndRelated = 0;
3652 Win32BaseWindow *window;
3653
3654 switch(uCmd)
3655 {
3656 case GW_HWNDFIRST:
3657 if(getParent()) {
3658 window = (Win32BaseWindow *)getParent()->getFirstChild();
3659 hwndRelated = window->getWindowHandle();
3660 }
3661 break;
3662
3663 case GW_HWNDLAST:
3664 if(!getParent())
3665 {
3666 goto end;
3667 }
3668
3669 window = this;
3670 while(window->getNextChild())
3671 {
3672 window = (Win32BaseWindow *)window->getNextChild();
3673 }
3674 hwndRelated = window->getWindowHandle();
3675 break;
3676
3677 case GW_HWNDNEXT:
3678 window = (Win32BaseWindow *)getNextChild();
3679 if(window) {
3680 hwndRelated = window->getWindowHandle();
3681 }
3682 break;
3683
3684 case GW_HWNDPREV:
3685 if(!getParent())
3686 {
3687 goto end;
3688 }
3689 window = (Win32BaseWindow *)(getParent()->getFirstChild()); /* First sibling */
3690 if(window == this)
3691 {
3692 hwndRelated = 0; /* First in list */
3693 goto end;
3694 }
3695 while(window->getNextChild())
3696 {
3697 if (window->getNextChild() == this)
3698 {
3699 hwndRelated = window->getWindowHandle();
3700 goto end;
3701 }
3702 window = (Win32BaseWindow *)window->getNextChild();
3703 }
3704 break;
3705
3706 case GW_OWNER:
3707 if(getOwner()) {
3708 hwndRelated = getOwner()->getWindowHandle();
3709 }
3710 break;
3711
3712 case GW_CHILD:
3713 if(getFirstChild()) {
3714 hwndRelated = ((Win32BaseWindow *)getFirstChild())->getWindowHandle();
3715 }
3716 break;
3717 }
3718end:
3719 dprintf(("GetWindow %x %d returned %x", getWindowHandle(), uCmd, hwndRelated));
3720 return hwndRelated;
3721}
3722//******************************************************************************
3723//******************************************************************************
3724HWND Win32BaseWindow::SetActiveWindow()
3725{
3726 HWND hwndActive;
3727 Win32BaseWindow *win32wnd;
3728 ULONG magic;
3729
3730 hwndActive = OSLibWinSetActiveWindow(OS2HwndFrame);
3731 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
3732 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
3733 if(CheckMagicDword(magic) && win32wnd)
3734 {
3735 return win32wnd->getWindowHandle();
3736 }
3737 return 0;
3738}
3739//******************************************************************************
3740//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
3741//******************************************************************************
3742BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
3743{
3744 return OSLibWinEnableWindow(OS2HwndFrame, fEnable);
3745}
3746//******************************************************************************
3747//******************************************************************************
3748BOOL Win32BaseWindow::CloseWindow()
3749{
3750 return OSLibWinMinimizeWindow(OS2HwndFrame);
3751}
3752//******************************************************************************
3753//******************************************************************************
3754HWND Win32BaseWindow::GetActiveWindow()
3755{
3756 HWND hwndActive;
3757 Win32BaseWindow *win32wnd;
3758 ULONG magic;
3759
3760 hwndActive = OSLibWinQueryActiveWindow();
3761
3762 return OS2ToWin32Handle(hwndActive);
3763}
3764//******************************************************************************
3765//******************************************************************************
3766BOOL Win32BaseWindow::IsWindowEnabled()
3767{
3768 return OSLibWinIsWindowEnabled(OS2HwndFrame);
3769}
3770//******************************************************************************
3771//******************************************************************************
3772BOOL Win32BaseWindow::IsWindowVisible()
3773{
3774#if 1
3775 return (dwStyle & WS_VISIBLE) == WS_VISIBLE;
3776#else
3777 return OSLibWinIsWindowVisible(OS2HwndFrame);
3778#endif
3779}
3780//******************************************************************************
3781//******************************************************************************
3782BOOL Win32BaseWindow::GetWindowRect(PRECT pRect)
3783{
3784 return OSLibWinQueryWindowRect(OS2HwndFrame, pRect, RELATIVE_TO_SCREEN);
3785}
3786//******************************************************************************
3787//******************************************************************************
3788BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
3789{
3790 INT len = GetWindowTextLength();
3791 BOOL res;
3792
3793 if (wndname == NULL)
3794 return (len == 0);
3795
3796 len++;
3797 if (fUnicode)
3798 {
3799 WCHAR *text = (WCHAR*)malloc(len*sizeof(WCHAR));
3800
3801 GetWindowTextW(text,len);
3802 res = (lstrcmpW(text,(LPWSTR)wndname) == 0);
3803 free(text);
3804 } else
3805 {
3806 CHAR *text = (CHAR*)malloc(len*sizeof(CHAR));
3807
3808 GetWindowTextA(text,len);
3809 res = (strcmp(text,wndname) == 0);
3810 free(text);
3811 }
3812
3813 return res;
3814}
3815//******************************************************************************
3816//******************************************************************************
3817CHAR *Win32BaseWindow::getWindowNamePtrA()
3818{
3819 INT len = GetWindowTextLength();
3820 CHAR *text;
3821
3822 if (len == 0) return NULL;
3823 len++;
3824 text = (CHAR*)malloc(len*sizeof(CHAR));
3825 GetWindowTextA(text,len);
3826
3827 return text;
3828}
3829//******************************************************************************
3830//******************************************************************************
3831WCHAR *Win32BaseWindow::getWindowNamePtrW()
3832{
3833 INT len = GetWindowTextLength();
3834 WCHAR *text;
3835
3836 if (len == 0) return NULL;
3837 len++;
3838 text = (WCHAR*)malloc(len*sizeof(WCHAR));
3839 GetWindowTextW(text,len);
3840
3841 return text;
3842}
3843//******************************************************************************
3844//******************************************************************************
3845VOID Win32BaseWindow::freeWindowNamePtr(PVOID namePtr)
3846{
3847 if (namePtr) free(namePtr);
3848}
3849//******************************************************************************
3850//******************************************************************************
3851int Win32BaseWindow::GetWindowTextLength()
3852{
3853 return SendInternalMessageA(WM_GETTEXTLENGTH,0,0);
3854}
3855//******************************************************************************
3856//******************************************************************************
3857int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
3858{
3859 return SendInternalMessageA(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
3860}
3861//******************************************************************************
3862//******************************************************************************
3863int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
3864{
3865 return SendInternalMessageW(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
3866}
3867//******************************************************************************
3868//******************************************************************************
3869BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
3870{
3871 return SendInternalMessageA(WM_SETTEXT,0,(LPARAM)lpsz);
3872}
3873//******************************************************************************
3874//******************************************************************************
3875BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
3876{
3877 return SendInternalMessageW(WM_SETTEXT,0,(LPARAM)lpsz);
3878}
3879//******************************************************************************
3880//******************************************************************************
3881VOID Win32BaseWindow::updateWindowStyle(DWORD oldExStyle,DWORD oldStyle)
3882{
3883 if(IsWindowDestroyed()) return;
3884
3885 //CB: todo: dwExStyle, creating new frame controls, destroy not used controls, WS_VISIBLE, WS_CHILD, ...
3886 // write test cases
3887 if ((dwStyle & 0xFFFF0000) != (oldStyle & 0xFFFF0000))
3888 {
3889 //dprintf(("updateWindowStyle: %x %x",oldStyle,dwStyle));
3890 OSLibSetWindowStyle(OS2HwndFrame, dwStyle, fTaskList);
3891 }
3892}
3893//******************************************************************************
3894//******************************************************************************
3895LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value, BOOL fUnicode)
3896{
3897 LONG oldval;
3898
3899 dprintf2(("SetWindowLong%c %x %d %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
3900 switch(index) {
3901 case GWL_EXSTYLE:
3902 {
3903 STYLESTRUCT ss;
3904
3905 if(dwExStyle == value)
3906 return value;
3907
3908 ss.styleOld = dwExStyle;
3909 ss.styleNew = value;
3910 dprintf(("SetWindowLong GWL_EXSTYLE %x old %x new style %x", getWindowHandle(), dwExStyle, value));
3911 SendInternalMessageA(WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
3912 setExStyle(ss.styleNew);
3913 updateWindowStyle(ss.styleOld,getStyle());
3914 SendInternalMessageA(WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
3915 return ss.styleOld;
3916 }
3917 case GWL_STYLE:
3918 {
3919 STYLESTRUCT ss;
3920
3921 if(dwStyle == value)
3922 return value;
3923
3924 value &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way (WINE) */
3925 ss.styleOld = getStyle();
3926 ss.styleNew = value | (ss.styleOld & (WS_VISIBLE | WS_CHILD));
3927 dprintf(("SetWindowLong GWL_STYLE %x old %x new style %x", getWindowHandle(), ss.styleOld, ss.styleNew));
3928 SendInternalMessageA(WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
3929 setStyle(ss.styleNew);
3930 updateWindowStyle(dwExStyle,ss.styleOld);
3931 SendInternalMessageA(WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
3932#ifdef DEBUG
3933 PrintWindowStyle(ss.styleNew, 0);
3934#endif
3935 return ss.styleOld;
3936 }
3937 case GWL_WNDPROC:
3938 oldval = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3939 //WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A, WIN_PROC_WINDOW);
3940 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, WINPROC_GetProcType(win32wndproc), WIN_PROC_WINDOW);
3941 return oldval;
3942 case GWL_HINSTANCE:
3943 oldval = hInstance;
3944 hInstance = value;
3945 return oldval;
3946 case GWL_HWNDPARENT:
3947 return SetParent((HWND)value);
3948 case GWL_ID:
3949 oldval = getWindowId();
3950 setWindowId(value);
3951 return oldval;
3952 case GWL_USERDATA:
3953 oldval = userData;
3954 userData = value;
3955 return oldval;
3956 default:
3957 if(index >= 0 && index/4 < nrUserWindowLong)
3958 {
3959 oldval = userWindowLong[index/4];
3960 userWindowLong[index/4] = value;
3961 return oldval;
3962 }
3963 SetLastError(ERROR_INVALID_PARAMETER);
3964 return 0;
3965 }
3966}
3967//******************************************************************************
3968//******************************************************************************
3969ULONG Win32BaseWindow::GetWindowLongA(int index, BOOL fUnicode)
3970{
3971 ULONG value;
3972
3973 switch(index) {
3974 case GWL_EXSTYLE:
3975 value = dwExStyle;
3976 break;
3977 case GWL_STYLE:
3978 value = dwStyle;
3979 break;
3980 case GWL_WNDPROC:
3981 value = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3982 break;
3983 case GWL_HINSTANCE:
3984 value = hInstance;
3985 break;
3986 case GWL_HWNDPARENT:
3987 if(getParent()) {
3988 value = getParent()->getWindowHandle();
3989 }
3990 else value = 0;
3991 break;
3992 case GWL_ID:
3993 value = getWindowId();
3994 break;
3995 case GWL_USERDATA:
3996 value = userData;
3997 break;
3998 default:
3999 if(index >= 0 && index/4 < nrUserWindowLong)
4000 {
4001 value = userWindowLong[index/4];
4002 break;
4003 }
4004 SetLastError(ERROR_INVALID_PARAMETER);
4005 return 0;
4006 }
4007 dprintf2(("GetWindowLongA %x %d %x", getWindowHandle(), index, value));
4008 return value;
4009}
4010//******************************************************************************
4011//******************************************************************************
4012WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
4013{
4014 WORD oldval;
4015
4016 if(index >= 0 && index/4 < nrUserWindowLong)
4017 {
4018 oldval = ((WORD *)userWindowLong)[index/2];
4019 ((WORD *)userWindowLong)[index/2] = value;
4020 return oldval;
4021 }
4022 SetLastError(ERROR_INVALID_PARAMETER);
4023 return 0;
4024}
4025//******************************************************************************
4026//******************************************************************************
4027WORD Win32BaseWindow::GetWindowWord(int index)
4028{
4029 if(index >= 0 && index/4 < nrUserWindowLong)
4030 {
4031 return ((WORD *)userWindowLong)[index/2];
4032 }
4033 SetLastError(ERROR_INVALID_PARAMETER);
4034 return 0;
4035}
4036//******************************************************************************
4037//******************************************************************************
4038void Win32BaseWindow::setWindowId(DWORD id)
4039{
4040 windowId = id;
4041 dprintf(("Set window ID to %x", id));
4042 OSLibSetWindowID(OS2HwndFrame, id);
4043}
4044//******************************************************************************
4045//******************************************************************************
4046Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
4047{
4048 Win32BaseWindow *window;
4049
4050 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
4051 return window;
4052 }
4053// dprintf2(("Win32BaseWindow::GetWindowFromHandle: not a win32 window %x", hwnd));
4054 return NULL;
4055}
4056//******************************************************************************
4057//******************************************************************************
4058Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
4059{
4060 Win32BaseWindow *win32wnd;
4061 DWORD magic;
4062
4063 if(hwnd == OSLIB_HWND_DESKTOP)
4064 {
4065 return windowDesktop;
4066 }
4067
4068 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
4069 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
4070
4071 if(win32wnd && CheckMagicDword(magic)) {
4072 return win32wnd;
4073 }
4074// dprintf2(("Win32BaseWindow::GetWindowFromOS2Handle: not an Odin os2 window %x", hwnd));
4075 return 0;
4076}
4077//******************************************************************************
4078//******************************************************************************
4079Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
4080{
4081 return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
4082}
4083//******************************************************************************
4084//******************************************************************************
4085HWND Win32BaseWindow::Win32ToOS2Handle(HWND hwnd)
4086{
4087 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
4088
4089 if(window) {
4090 return window->getOS2WindowHandle();
4091 }
4092// dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
4093 return hwnd;
4094}
4095//******************************************************************************
4096//******************************************************************************
4097HWND Win32BaseWindow::Win32ToOS2FrameHandle(HWND hwnd)
4098{
4099 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
4100
4101 if(window) {
4102 return window->getOS2FrameWindowHandle();
4103 }
4104// dprintf2(("Win32BaseWindow::Win32ToOS2FrameHandle: not a win32 window %x", hwnd));
4105 return hwnd;
4106}
4107//******************************************************************************
4108//******************************************************************************
4109HWND Win32BaseWindow::OS2ToWin32Handle(HWND hwnd)
4110{
4111 Win32BaseWindow *window = GetWindowFromOS2Handle(hwnd);
4112
4113 if(window) {
4114 return window->getWindowHandle();
4115 }
4116 window = GetWindowFromOS2FrameHandle(hwnd);
4117 if(window) {
4118 return window->getWindowHandle();
4119 }
4120// dprintf2(("Win32BaseWindow::OS2ToWin32Handle: not a win32 window %x", hwnd));
4121 return 0;
4122// else return hwnd; //OS/2 window handle
4123}
4124//******************************************************************************
4125// GetNextDlgTabItem32 (USER32.276)
4126//******************************************************************************
4127HWND Win32BaseWindow::getNextDlgTabItem(HWND hwndCtrl, BOOL fPrevious)
4128{
4129 Win32BaseWindow *child, *nextchild, *lastchild;
4130 HWND retvalue;
4131
4132 if (hwndCtrl)
4133 {
4134 child = GetWindowFromHandle(hwndCtrl);
4135 if (!child)
4136 {
4137 retvalue = 0;
4138 goto END;
4139 }
4140 /* Make sure hwndCtrl is a top-level child */
4141 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
4142 {
4143 child = child->getParent();
4144 if(child == NULL) break;
4145 }
4146
4147 if (!child || (child->getParent() != this))
4148 {
4149 retvalue = 0;
4150 goto END;
4151 }
4152 }
4153 else
4154 {
4155 /* No ctrl specified -> start from the beginning */
4156 child = (Win32BaseWindow *)getFirstChild();
4157 if (!child)
4158 {
4159 retvalue = 0;
4160 goto END;
4161 }
4162
4163 if (!fPrevious)
4164 {
4165 while (child->getNextChild())
4166 {
4167 child = (Win32BaseWindow *)child->getNextChild();
4168 }
4169 }
4170 }
4171
4172 lastchild = child;
4173 nextchild = (Win32BaseWindow *)child->getNextChild();
4174 while (TRUE)
4175 {
4176 if (!nextchild) nextchild = (Win32BaseWindow *)getFirstChild();
4177
4178 if (child == nextchild) break;
4179
4180 if ((nextchild->getStyle() & WS_TABSTOP) && (nextchild->getStyle() & WS_VISIBLE) &&
4181 !(nextchild->getStyle() & WS_DISABLED))
4182 {
4183 lastchild = nextchild;
4184 if (!fPrevious) break;
4185 }
4186 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
4187 }
4188 retvalue = lastchild->getWindowHandle();
4189
4190END:
4191 return retvalue;
4192}
4193//******************************************************************************
4194//******************************************************************************
4195HWND Win32BaseWindow::getNextDlgGroupItem(HWND hwndCtrl, BOOL fPrevious)
4196{
4197 Win32BaseWindow *child, *nextchild, *lastchild;
4198 HWND retvalue;
4199
4200 if (hwndCtrl)
4201 {
4202 child = GetWindowFromHandle(hwndCtrl);
4203 if (!child)
4204 {
4205 retvalue = 0;
4206 goto END;
4207 }
4208 /* Make sure hwndCtrl is a top-level child */
4209 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
4210 {
4211 child = child->getParent();
4212 if(child == NULL) break;
4213 }
4214
4215 if (!child || (child->getParent() != this))
4216 {
4217 retvalue = 0;
4218 goto END;
4219 }
4220 }
4221 else
4222 {
4223 /* No ctrl specified -> start from the beginning */
4224 child = (Win32BaseWindow *)getFirstChild();
4225 if (!child)
4226 {
4227 retvalue = 0;
4228 goto END;
4229 }
4230
4231 if (fPrevious)
4232 {
4233 while (child->getNextChild())
4234 {
4235 child = (Win32BaseWindow *)child->getNextChild();
4236 }
4237 }
4238 }
4239
4240 lastchild = child;
4241 nextchild = (Win32BaseWindow *)child->getNextChild();
4242 while (TRUE)
4243 {
4244 if (!nextchild || (nextchild->getStyle() & WS_GROUP))
4245 {
4246 /* Wrap-around to the beginning of the group */
4247 Win32BaseWindow *pWndTemp;
4248
4249 nextchild = (Win32BaseWindow *)getFirstChild();
4250
4251 for(pWndTemp = nextchild;pWndTemp;pWndTemp = (Win32BaseWindow *)pWndTemp->getNextChild())
4252 {
4253 if (pWndTemp->getStyle() & WS_GROUP)
4254 nextchild = pWndTemp;
4255
4256 if (pWndTemp == child)
4257 break;
4258 }
4259
4260 }
4261 if (nextchild == child)
4262 break;
4263
4264 if ((nextchild->getStyle() & WS_VISIBLE) && !(nextchild->getStyle() & WS_DISABLED))
4265 {
4266 lastchild = nextchild;
4267
4268 if (!fPrevious)
4269 break;
4270 }
4271
4272 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
4273 }
4274 retvalue = lastchild->getWindowHandle();
4275END:
4276 return retvalue;
4277}
4278//******************************************************************************
4279//******************************************************************************
4280#ifdef DEBUG
4281void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle)
4282{
4283 char style[256] = "";
4284 char exstyle[256] = "";
4285
4286 /* Window styles */
4287 if(dwStyle & WS_CHILD)
4288 strcat(style, "WS_CHILD ");
4289 if(dwStyle & WS_POPUP)
4290 strcat(style, "WS_POPUP ");
4291 if(dwStyle & WS_VISIBLE)
4292 strcat(style, "WS_VISIBLE ");
4293 if(dwStyle & WS_DISABLED)
4294 strcat(style, "WS_DISABLED ");
4295 if(dwStyle & WS_CLIPSIBLINGS)
4296 strcat(style, "WS_CLIPSIBLINGS ");
4297 if(dwStyle & WS_CLIPCHILDREN)
4298 strcat(style, "WS_CLIPCHILDREN ");
4299 if(dwStyle & WS_MAXIMIZE)
4300 strcat(style, "WS_MAXIMIZE ");
4301 if(dwStyle & WS_MINIMIZE)
4302 strcat(style, "WS_MINIMIZE ");
4303 if(dwStyle & WS_GROUP)
4304 strcat(style, "WS_GROUP ");
4305 if(dwStyle & WS_TABSTOP)
4306 strcat(style, "WS_TABSTOP ");
4307
4308 if((dwStyle & WS_CAPTION) == WS_CAPTION)
4309 strcat(style, "WS_CAPTION ");
4310 if(dwStyle & WS_DLGFRAME)
4311 strcat(style, "WS_DLGFRAME ");
4312 if(dwStyle & WS_BORDER)
4313 strcat(style, "WS_BORDER ");
4314
4315 if(dwStyle & WS_VSCROLL)
4316 strcat(style, "WS_VSCROLL ");
4317 if(dwStyle & WS_HSCROLL)
4318 strcat(style, "WS_HSCROLL ");
4319 if(dwStyle & WS_SYSMENU)
4320 strcat(style, "WS_SYSMENU ");
4321 if(dwStyle & WS_THICKFRAME)
4322 strcat(style, "WS_THICKFRAME ");
4323 if(dwStyle & WS_MINIMIZEBOX)
4324 strcat(style, "WS_MINIMIZEBOX ");
4325 if(dwStyle & WS_MAXIMIZEBOX)
4326 strcat(style, "WS_MAXIMIZEBOX ");
4327
4328 if(dwExStyle & WS_EX_DLGMODALFRAME)
4329 strcat(exstyle, "WS_EX_DLGMODALFRAME ");
4330 if(dwExStyle & WS_EX_ACCEPTFILES)
4331 strcat(exstyle, "WS_EX_ACCEPTFILES ");
4332 if(dwExStyle & WS_EX_NOPARENTNOTIFY)
4333 strcat(exstyle, "WS_EX_NOPARENTNOTIFY ");
4334 if(dwExStyle & WS_EX_TOPMOST)
4335 strcat(exstyle, "WS_EX_TOPMOST ");
4336 if(dwExStyle & WS_EX_TRANSPARENT)
4337 strcat(exstyle, "WS_EX_TRANSPARENT ");
4338
4339 if(dwExStyle & WS_EX_MDICHILD)
4340 strcat(exstyle, "WS_EX_MDICHILD ");
4341 if(dwExStyle & WS_EX_TOOLWINDOW)
4342 strcat(exstyle, "WS_EX_TOOLWINDOW ");
4343 if(dwExStyle & WS_EX_WINDOWEDGE)
4344 strcat(exstyle, "WS_EX_WINDOWEDGE ");
4345 if(dwExStyle & WS_EX_CLIENTEDGE)
4346 strcat(exstyle, "WS_EX_CLIENTEDGE ");
4347 if(dwExStyle & WS_EX_CONTEXTHELP)
4348 strcat(exstyle, "WS_EX_CONTEXTHELP ");
4349 if(dwExStyle & WS_EX_RIGHT)
4350 strcat(exstyle, "WS_EX_RIGHT ");
4351 if(dwExStyle & WS_EX_LEFT)
4352 strcat(exstyle, "WS_EX_LEFT ");
4353 if(dwExStyle & WS_EX_RTLREADING)
4354 strcat(exstyle, "WS_EX_RTLREADING ");
4355 if(dwExStyle & WS_EX_LTRREADING)
4356 strcat(exstyle, "WS_EX_LTRREADING ");
4357 if(dwExStyle & WS_EX_LEFTSCROLLBAR)
4358 strcat(exstyle, "WS_EX_LEFTSCROLLBAR ");
4359 if(dwExStyle & WS_EX_RIGHTSCROLLBAR)
4360 strcat(exstyle, "WS_EX_RIGHTSCROLLBAR ");
4361 if(dwExStyle & WS_EX_CONTROLPARENT)
4362 strcat(exstyle, "WS_EX_CONTROLPARENT ");
4363 if(dwExStyle & WS_EX_STATICEDGE)
4364 strcat(exstyle, "WS_EX_STATICEDGE ");
4365 if(dwExStyle & WS_EX_APPWINDOW)
4366 strcat(exstyle, "WS_EX_APPWINDOW ");
4367
4368 dprintf(("Window style: %x %s", dwStyle, style));
4369 dprintf(("Window exStyle: %x %s (FS = %x)", dwExStyle, exstyle, GetFS()));
4370}
4371#endif
4372//******************************************************************************
4373//******************************************************************************
4374
4375GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.