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

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

get/peekmessage fixes, timer fix, (user/new) replaced wm_hittest code; added wm_ncactivate, changed system menu

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