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

Last change on this file since 5725 was 5725, checked in by sandervl, 24 years ago

destroy menu window after it has been used (instead of just hiding it)

File size: 128.5 KB
Line 
1/* $Id: win32wbase.cpp,v 1.258 2001-05-17 09:50:30 sandervl Exp $ */
2/*
3 * Win32 Window Base Class for OS/2
4 *
5 * Copyright 1998-2001 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 * Copyright 1999-2000 Christoph Bratschi (cbratschi@datacomm.ch)
8 *
9 * Parts based on Wine Windows code (windows\win.c)
10 * Corel version: corel20000212
11 *
12 * Copyright 1993, 1994, 1996 Alexandre Julliard
13 * 1995 Alex Korobka
14 *
15 * TODO: Not thread/process safe
16 *
17 * NOTE: Client rectangle always relative to frame window
18 * Window rectangle in parent coordinates (relative to parent's client window)
19 * (screen coord. if no parent)
20 *
21 * Project Odin Software License can be found in LICENSE.TXT
22 *
23 */
24#include <os2win.h>
25#include <win.h>
26#include <stdlib.h>
27#include <string.h>
28#include <stdarg.h>
29#include <assert.h>
30#include <misc.h>
31#include <heapstring.h>
32#include <winuser32.h>
33#include "win32wbase.h"
34#include "wndmsg.h"
35#include "oslibwin.h"
36#include "oslibmsg.h"
37#include "oslibutil.h"
38#include "oslibgdi.h"
39#include "oslibres.h"
40#include "oslibdos.h"
41#include "syscolor.h"
42#include "win32wndhandle.h"
43#include "dc.h"
44#include "win32wdesktop.h"
45#include "pmwindow.h"
46#include "controls.h"
47#include <wprocess.h>
48#include <win\hook.h>
49#include <menu.h>
50#define INCL_TIMERWIN32
51#include "timer.h"
52
53#define DBG_LOCALLOG DBG_win32wbase
54#include "dbglocal.h"
55
56/* bits in the dwKeyData */
57#define KEYDATA_ALT 0x2000
58#define KEYDATA_PREVSTATE 0x4000
59
60void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle);
61
62static fDestroyAll = FALSE;
63//For quick lookup of current process id
64static ULONG currentProcessId = -1;
65
66//******************************************************************************
67//******************************************************************************
68Win32BaseWindow::Win32BaseWindow(DWORD objType) : GenericObject(&windows, objType)
69{
70 Init();
71}
72//******************************************************************************
73//******************************************************************************
74Win32BaseWindow::Win32BaseWindow(HWND hwndOS2, ULONG reserved) : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
75{
76 Init();
77 OS2Hwnd = hwndOS2;
78}
79//******************************************************************************
80//******************************************************************************
81Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
82 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
83{
84 Init();
85 this->isUnicode = isUnicode;
86 CreateWindowExA(lpCreateStructA, classAtom);
87}
88//******************************************************************************
89//******************************************************************************
90void Win32BaseWindow::Init()
91{
92 isUnicode = FALSE;
93 fFirstShow = TRUE;
94 fIsDialog = FALSE;
95 fIsModalDialogOwner = FALSE;
96 OS2HwndModalDialog = 0;
97 fInternalMsg = FALSE;
98 fNoSizeMsg = FALSE;
99 fIsDestroyed = FALSE;
100 fDestroyWindowCalled = FALSE;
101 fCreated = FALSE;
102 fTaskList = FALSE;
103 fParentDC = FALSE;
104 fComingToTop = FALSE;
105 fCreateSetWindowPos = FALSE;
106 fCreationFinished= FALSE;
107 fMinMaxChange = FALSE;
108 fVisibleRegionChanged = FALSE;
109 fEraseBkgndFlag = TRUE;
110
111 windowNameA = NULL;
112 windowNameW = NULL;
113
114 userWindowBytes = NULL;;
115 nrUserWindowBytes= 0;
116
117 magic = WIN32PM_MAGIC;
118 OS2Hwnd = 0;
119 OS2HwndFrame = 0;
120 hSysMenu = 0;
121 Win32Hwnd = 0;
122
123 if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
124 {
125 dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
126 DebugInt3();
127 }
128
129 posx = posy = 0;
130 width = height = 0;
131
132 dwExStyle = 0;
133 dwStyle = 0;
134 win32wndproc = 0;
135 hInstance = 0;
136 dwIDMenu = 0; //0xFFFFFFFF; //default -1
137 userData = 0;
138 contextHelpId = 0;
139 hotkey = 0;
140
141
142 hwndLinkAfter = HWND_BOTTOM;
143 flags = 0;
144 lastHitTestVal = HTOS_NORMAL;
145 owner = NULL;
146 windowClass = 0;
147
148 hIcon = 0;
149 hIconSm = 0;
150
151 horzScrollInfo = NULL;
152 vertScrollInfo = NULL;
153
154 propertyList = NULL;
155
156 ownDC = 0;
157 hWindowRegion = 0;
158 hClipRegion = 0;
159
160 hTaskList = 0;
161
162 if(currentProcessId == -1)
163 {
164 currentProcessId = GetCurrentProcessId();
165 }
166 dwThreadId = GetCurrentThreadId();
167 dwProcessId = currentProcessId;
168
169 memset(&windowpos, 0, sizeof(windowpos));
170 //min and max position are initially -1 (verified in NT4, SP6)
171 windowpos.ptMinPosition.x = -1;
172 windowpos.ptMinPosition.y = -1;
173 windowpos.ptMaxPosition.x = -1;
174 windowpos.ptMaxPosition.y = -1;
175}
176//******************************************************************************
177//todo get rid of resources (menu, icon etc)
178//******************************************************************************
179Win32BaseWindow::~Win32BaseWindow()
180{
181 if(hTaskList) {
182 OSLibWinRemoveFromTasklist(hTaskList);
183 }
184
185 OSLibWinSetVisibleRegionNotify(OS2Hwnd, FALSE);
186 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
187 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
188
189 if(!fDestroyAll && getParent() && getParent()->getFirstChild() == this && getNextChild() == NULL)
190 {
191 //if we're the last child that's being destroyed and our
192 //parent window was also destroyed, then we delete the parent object
193 if(getParent()->IsWindowDestroyed())
194 {
195 dprintf(("Last Child (%x) destroyed, get rid of our parent window (%x)", getWindowHandle(), getParent()->getWindowHandle()));
196 delete getParent();
197 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
198 }
199 }
200 else
201 if(fDestroyAll) {
202 dprintf(("Destroying window %x %s", getWindowHandle(), windowNameA));
203 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
204 }
205
206 /* Decrement class window counter */
207 if(windowClass) {
208 windowClass->DecreaseWindowCount();
209 }
210
211 if(isOwnDC())
212 releaseOwnDC(ownDC);
213
214 if(Win32Hwnd)
215 HwFreeWindowHandle(Win32Hwnd);
216
217 if(userWindowBytes)
218 free(userWindowBytes);
219
220 if(windowNameA) {
221 free(windowNameA);
222 windowNameA = NULL;
223 }
224 if(windowNameW) {
225 free(windowNameW);
226 windowNameW = NULL;
227 }
228 if(vertScrollInfo) {
229 free(vertScrollInfo);
230 vertScrollInfo = NULL;
231 }
232 if(horzScrollInfo) {
233 free(horzScrollInfo);
234 horzScrollInfo = NULL;
235 }
236 if(propertyList) {
237 removeWindowProps();
238 }
239}
240//******************************************************************************
241//******************************************************************************
242void Win32BaseWindow::DestroyAll()
243{
244 fDestroyAll = TRUE;
245 GenericObject::DestroyAll(windows);
246}
247//******************************************************************************
248//******************************************************************************
249BOOL Win32BaseWindow::isChild()
250{
251 return ((dwStyle & WS_CHILD) != 0);
252}
253//******************************************************************************
254//******************************************************************************
255BOOL Win32BaseWindow::IsWindowUnicode()
256{
257 dprintf2(("IsWindowUnicode %x %d", getWindowHandle(), WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W));
258 return (WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W);
259}
260//******************************************************************************
261//******************************************************************************
262BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
263{
264 char buffer[256];
265
266#ifdef DEBUG
267 PrintWindowStyle(cs->style, cs->dwExStyle);
268#endif
269
270 //If window has no owner/parent window, then it will be added to the tasklist
271 //(depending on visibility state)
272 if (!cs->hwndParent) fTaskList = TRUE;
273
274 sw = SW_SHOW;
275 SetLastError(0);
276
277 /* Find the parent window */
278 if (cs->hwndParent)
279 {
280 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
281 if(!window) {
282 dprintf(("Bad parent %04x\n", cs->hwndParent ));
283 SetLastError(ERROR_INVALID_PARAMETER);
284 return FALSE;
285 }
286 /* Make sure parent is valid */
287 if (!window->IsWindow() )
288 {
289 dprintf(("Bad parent %04x\n", cs->hwndParent ));
290 SetLastError(ERROR_INVALID_PARAMETER);
291 return FALSE;
292 }
293 /* Windows does this for overlapped windows
294 * (I don't know about other styles.) */
295 if (cs->hwndParent == GetDesktopWindow() && (!(cs->style & WS_CHILD) || (cs->style & WS_POPUP)))
296 {
297 cs->hwndParent = 0;
298 }
299 }
300 else
301 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
302 dprintf(("No parent for child window" ));
303 SetLastError(ERROR_INVALID_PARAMETER);
304 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
305 }
306
307 /* Find the window class */
308 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
309 if (!windowClass)
310 {
311 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
312 dprintf(("Bad class '%s'", buffer ));
313 SetLastError(ERROR_INVALID_PARAMETER);
314 return 0;
315 }
316 /* Increment class window counter */
317 windowClass->IncreaseWindowCount();
318
319#ifdef DEBUG
320 if(HIWORD(cs->lpszClass))
321 {
322 if(isUnicode) dprintf(("Window class %ls", cs->lpszClass));
323 else dprintf(("Window class %s", cs->lpszClass));
324 }
325 else dprintf(("Window class %x", cs->lpszClass));
326#endif
327
328 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
329 * with an atom as the class name, put some programs expect to have a *REAL* string in
330 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
331 */
332 if (!HIWORD(cs->lpszClass) ) {
333 if (isUnicode) {
334 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
335 }
336 else {
337 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
338 }
339 cs->lpszClass = buffer;
340 }
341
342 /* Fix the coordinates */
343 fXDefault = FALSE;
344 fCXDefault = FALSE;
345 if ((cs->x == CW_USEDEFAULT) || (cs->x == CW_USEDEFAULT16))
346 {
347 /* Never believe Microsoft's documentation... CreateWindowEx doc says
348 * that if an overlapped window is created with WS_VISIBLE style bit
349 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
350 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
351 * reveals that
352 *
353 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
354 * 2) it does not ignore the y parameter as the docs claim; instead, it
355 * uses it as second parameter to ShowWindow() unless y is either
356 * CW_USEDEFAULT or CW_USEDEFAULT16.
357 *
358 * The fact that we didn't do 2) caused bogus windows pop up when wine
359 * was running apps that were using this obscure feature. Example -
360 * calc.exe that comes with Win98 (only Win98, it's different from
361 * the one that comes with Win95 and NT)
362 */
363 if ((cs->y != CW_USEDEFAULT) && (cs->y != CW_USEDEFAULT16)) sw = cs->y;
364
365 /* We have saved cs->y, now we can trash it */
366 cs->x = 0;
367 cs->y = 0;
368 fXDefault = TRUE;
369 }
370 if ((cs->cx == CW_USEDEFAULT) || (cs->cx == CW_USEDEFAULT16))
371 {
372 cs->cx = 600; /* FIXME */
373 cs->cy = 400;
374 fCXDefault = TRUE;
375 }
376 if (cs->style & (WS_POPUP | WS_CHILD))
377 {
378 fXDefault = FALSE;
379 if (fCXDefault)
380 {
381 fCXDefault = FALSE;
382 cs->cx = cs->cy = 0;
383 }
384 }
385 if (fXDefault && !fCXDefault) fXDefault = FALSE; //CB: only x positioning doesn't work (calc.exe,cdrlabel.exe)
386
387 if (cs->x < 0) cs->x = 0;
388 if (cs->y < 0) cs->y = 0;
389
390 //Allocate window words
391 nrUserWindowBytes = windowClass->getExtraWndBytes();
392 if(nrUserWindowBytes) {
393 userWindowBytes = (char *)_smalloc(nrUserWindowBytes);
394 memset(userWindowBytes, 0, nrUserWindowBytes);
395 }
396
397 if ((cs->style & WS_CHILD) && cs->hwndParent)
398 {
399 SetParent(cs->hwndParent);
400// owner = GetWindowFromHandle(cs->hwndParent);
401 owner = 0;
402/* if(owner == NULL)
403 {
404 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
405 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
406 return FALSE;
407 }*/
408 //SvL: Shell positioning shouldn't be done for child windows! (breaks Notes)
409 fXDefault = fCXDefault = FALSE;
410 }
411 else
412 {
413 SetParent(0);
414 if (!cs->hwndParent || (cs->hwndParent == windowDesktop->getWindowHandle())) {
415 owner = NULL;
416 }
417 else
418 {
419 owner = GetWindowFromHandle(cs->hwndParent)->GetTopParent();
420 if(owner == NULL)
421 {
422 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
423 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
424 return FALSE;
425 }
426 }
427 }
428
429 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc(), WINPROC_GetProcType(windowClass->getWindowProc()), WIN_PROC_WINDOW);
430 hInstance = cs->hInstance;
431 dwStyle = cs->style & ~WS_VISIBLE;
432 dwExStyle = cs->dwExStyle;
433
434 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
435
436 /* Correct the window style */
437 if (!(cs->style & WS_CHILD))
438 {
439 dwStyle |= WS_CLIPSIBLINGS;
440 if (!(cs->style & WS_POPUP))
441 {
442 dwStyle |= WS_CAPTION;
443 flags |= WIN_NEED_SIZE;
444 }
445 }
446 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
447
448 //copy pointer of CREATESTRUCT for usage in MsgCreate method
449 tmpcs = cs;
450
451 //Store our window object pointer in thread local memory, so PMWINDOW.CPP can retrieve it
452 TEB *teb = GetThreadTEB();
453 if(teb == NULL) {
454 dprintf(("Window creation failed - teb == NULL")); //this is VERY bad
455 ExitProcess(666);
456 return FALSE;
457 }
458
459 teb->o.odin.newWindow = (ULONG)this;
460
461 DWORD dwOSWinStyle;
462
463 OSLibWinConvertStyle(dwStyle,dwExStyle,&dwOSWinStyle);
464
465 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
466 dwOSWinStyle,(char *)windowNameA,
467 (owner) ? owner->getOS2WindowHandle() : ((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP),
468 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
469 0, fTaskList,fXDefault | fCXDefault,windowClass->getStyle(), &OS2HwndFrame);
470 if(OS2Hwnd == 0) {
471 dprintf(("Window creation failed!! OS LastError %0x", OSLibWinGetLastError()));
472 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
473 return FALSE;
474 }
475 OSLibWinSetVisibleRegionNotify(OS2Hwnd, TRUE);
476 fCreationFinished = TRUE; //creation done with success
477 SetLastError(0);
478 return TRUE;
479}
480//******************************************************************************
481//******************************************************************************
482BOOL Win32BaseWindow::MsgCreate(HWND hwndOS2)
483{
484 CREATESTRUCTA *cs = tmpcs; //pointer to CREATESTRUCT used in CreateWindowExA method
485 POINT maxSize, maxPos, minTrack, maxTrack;
486 HWND hwnd = getWindowHandle();
487 LRESULT (* CALLBACK localSend32)(HWND, UINT, WPARAM, LPARAM);
488
489 OS2Hwnd = hwndOS2;
490
491 fNoSizeMsg = TRUE;
492
493 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
494 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
495 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
496 return FALSE;
497 }
498 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
499 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
500 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
501 return FALSE;
502 }
503 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32FLAGS, 0) == FALSE) {
504 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
505 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
506 return FALSE;
507 }
508
509 if (HOOK_IsHooked( WH_CBT ))
510 {
511 CBT_CREATEWNDA cbtc;
512 LRESULT ret;
513
514 cbtc.lpcs = cs;
515 cbtc.hwndInsertAfter = hwndLinkAfter;
516 ret = (isUnicode) ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc)
517 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc);
518 if(ret)
519 {
520 dprintf(("CBT-hook returned 0!!"));
521 SetLastError(ERROR_CAN_NOT_COMPLETE); //todo: wrong error
522 return FALSE;
523 }
524 //todo: if hook changes parent, we need to do so too!!!!!!!!!!
525 }
526
527 if (cs->style & WS_HSCROLL)
528 {
529 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
530 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
531 horzScrollInfo->MaxVal = 100;
532 horzScrollInfo->flags = ESB_ENABLE_BOTH;
533 }
534
535 if (cs->style & WS_VSCROLL)
536 {
537 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
538 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
539 vertScrollInfo->MaxVal = 100;
540 vertScrollInfo->flags = ESB_ENABLE_BOTH;
541 }
542
543 if(HIWORD(cs->lpszName))
544 {
545 if (!isUnicode)
546 {
547 int wndNameLength = strlen(cs->lpszName);
548 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
549 strcpy(windowNameA,cs->lpszName);
550 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
551 lstrcpyAtoW(windowNameW,windowNameA);
552 windowNameA[wndNameLength] = 0;
553 windowNameW[wndNameLength] = 0;
554 }
555 else
556 {
557 // Wide
558 int wndNameLength = lstrlenW((LPWSTR)cs->lpszName);
559 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
560 lstrcpyW(windowNameW,(LPWSTR)cs->lpszName);
561 windowNameW[lstrlenW((LPWSTR)cs->lpszName)] = 0; // need ?
562 // Ascii
563 LPSTR tmp = HEAP_strdupWtoA(GetProcessHeap(), 0, (LPWSTR)cs->lpszName);
564 if(tmp) {
565 long tmpLength = strlen( tmp );
566 windowNameA = (LPSTR)_smalloc(tmpLength+1);
567 strcpy(windowNameA,tmp);
568 windowNameA[tmpLength] = 0; // need ?
569 HEAP_free(tmp);
570 } else {
571 windowNameA = (LPSTR)_smalloc(1);
572 windowNameA[0] = 0;
573 }
574 }
575 }
576
577//SvL: This completely messes up MS Word 97 (no button bar, no menu)
578#if 0
579 //adjust CW_USEDEFAULT position
580 if (fXDefault | fCXDefault)
581 {
582 RECT rect;
583
584 //SvL: Returns invalid rectangle (not the expected shell default size)
585 OSLibWinQueryWindowRect(OS2Hwnd,&rect,RELATIVE_TO_SCREEN);
586 if (getParent()) mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2WindowHandle(),&rect);
587 if (fXDefault)
588 {
589 cs->x = rect.left;
590 cs->y = rect.top;
591 if (!fCXDefault)
592 {
593 //CB: todo: adjust pos to screen rect
594 }
595 }
596 if (fCXDefault)
597 {
598 cs->cx = rect.right-rect.left;
599 cs->cy = rect.bottom-rect.top;
600 }
601 }
602#endif
603
604 fakeWinBase.hwndThis = OS2Hwnd;
605 fakeWinBase.pWindowClass = windowClass;
606
607 //Set icon from window or class
608 if (hIcon)
609 OSLibWinSetIcon(OS2Hwnd,hIcon);
610 else
611 if (windowClass->getIcon())
612 OSLibWinSetIcon(OS2Hwnd,windowClass->getIcon());
613
614 /* Get class or window DC if needed */
615 if(windowClass->getStyle() & CS_OWNDC) {
616 dprintf(("Class with CS_OWNDC style"));
617 ownDC = GetDCEx(getWindowHandle(), NULL, DCX_USESTYLE);
618 }
619 else
620 if (windowClass->getStyle() & CS_PARENTDC) {
621 fParentDC = TRUE;
622 ownDC = 0;
623 }
624 else
625 if (windowClass->getStyle() & CS_CLASSDC) {
626 dprintf(("WARNING: Class with CS_CLASSDC style!"));
627 ownDC = 0;
628 }
629 /* Set the window menu */
630 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
631 {
632 if (cs->hMenu) {
633 ::SetMenu(getWindowHandle(), cs->hMenu);
634 }
635 else {
636 if (windowClass->getMenuNameA()) {
637 cs->hMenu = LoadMenuA(windowClass->getInstance(),windowClass->getMenuNameA());
638#if 0 //CB: hack for treeview test cases bug
639if (!cs->hMenu) cs->hMenu = LoadMenuA(windowClass->getInstance(),"MYAPP");
640#endif
641 if (cs->hMenu) ::SetMenu(getWindowHandle(), cs->hMenu );
642 }
643 }
644 }
645 else
646 {
647 setWindowId((DWORD)cs->hMenu);
648 }
649 hSysMenu = (dwStyle & WS_SYSMENU) ? MENU_GetSysMenu(Win32Hwnd,0):0;
650
651 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
652 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
653 {
654 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
655 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
656 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
657 if (cs->cx < minTrack.x) cs->cx = minTrack.x;
658 if (cs->cy < minTrack.y) cs->cy = minTrack.y;
659 }
660
661 if(cs->style & WS_CHILD)
662 {
663 if(cs->cx < 0) cs->cx = 0;
664 if(cs->cy < 0) cs->cy = 0;
665 }
666 else
667 {
668 if (cs->cx <= 0) cs->cx = 1;
669 if (cs->cy <= 0) cs->cy = 1;
670 }
671
672 //set client & window rectangles from CreateWindowEx CREATESTRUCT
673 rectWindow.left = cs->x;
674 rectWindow.right = cs->x+cs->cx;
675 rectWindow.top = cs->y;
676 rectWindow.bottom = cs->y+cs->cy;
677 rectClient = rectWindow;
678 OffsetRect(&rectClient, -rectClient.left, -rectClient.top);
679
680 /* Send the WM_CREATE message
681 * Perhaps we shouldn't allow width/height changes as well.
682 * See p327 in "Internals".
683 */
684 maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
685
686 //Note: Solitaire crashes when receiving WM_SIZE messages before WM_CREATE
687 fCreated = TRUE;
688
689 if(fTaskList) {
690 hTaskList = OSLibWinAddToTaskList(OS2HwndFrame, windowNameA, (cs->style & WS_VISIBLE) ? 1 : 0);
691 }
692
693 localSend32 = (isUnicode) ? ::SendMessageW : ::SendMessageA;
694
695 if(localSend32(getWindowHandle(), WM_NCCREATE,0,(LPARAM)cs))
696 {
697 RECT tmpRect;
698
699 //CB: recheck flags
700 if (cs->style & (WS_POPUP | WS_CHILD))
701 {
702 fXDefault = FALSE;
703 if (fCXDefault)
704 {
705 fCXDefault = FALSE;
706 cs->cx = cs->cy = 0;
707 rectWindow.right = rectWindow.left;
708 rectWindow.bottom = rectWindow.top;
709 }
710 }
711 tmpRect = rectWindow;
712
713 fCreateSetWindowPos = TRUE;
714
715 //set the window size and update the client
716 SetWindowPos(hwndLinkAfter, tmpRect.left, tmpRect.top, tmpRect.right-tmpRect.left, tmpRect.bottom-tmpRect.top,SWP_NOACTIVATE | SWP_NOREDRAW | SWP_FRAMECHANGED);
717 fNoSizeMsg = FALSE;
718 if (cs->style & WS_VISIBLE) dwStyle |= WS_VISIBLE; //program could change position in WM_CREATE
719 if( (localSend32(getWindowHandle(), WM_CREATE, 0, (LPARAM)cs )) != -1 )
720 {
721 if(!(flags & WIN_NEED_SIZE))
722 {
723 SendInternalMessageA(WM_SIZE, SIZE_RESTORED,
724 MAKELONG(rectClient.right-rectClient.left,
725 rectClient.bottom-rectClient.top));
726
727 if(!::IsWindow(hwnd))
728 {
729 dprintf(("Createwindow: WM_SIZE destroyed window"));
730 goto end;
731 }
732 SendInternalMessageA(WM_MOVE,0,MAKELONG(rectClient.left,rectClient.top));
733 if(!::IsWindow(hwnd))
734 {
735 dprintf(("Createwindow: WM_MOVE destroyed window"));
736 goto end;
737 }
738 }
739 if (getStyle() & (WS_MINIMIZE | WS_MAXIMIZE))
740 {
741 RECT newPos;
742 UINT swFlag = (getStyle() & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
743 setStyle(getStyle() & ~(WS_MAXIMIZE | WS_MINIMIZE));
744 MinMaximize(swFlag, &newPos);
745 swFlag = ((getStyle() & WS_CHILD) || GetActiveWindow()) ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
746 : SWP_NOZORDER | SWP_FRAMECHANGED;
747 SetWindowPos(0, newPos.left, newPos.top, newPos.right, newPos.bottom, swFlag);
748 if(!::IsWindow(hwnd))
749 {
750 dprintf(("Createwindow: min/max destroyed window"));
751 goto end;
752 }
753 }
754
755 if( (getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
756 {
757 /* Notify the parent window only */
758 if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
759 {
760 getParent()->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, getWindowId()), (LPARAM)getWindowHandle());
761 }
762 if(!::IsWindow(hwnd))
763 {
764 dprintf(("Createwindow: WM_PARENTNOTIFY destroyed window"));
765 goto end;
766 }
767 }
768
769 if(cs->style & WS_VISIBLE) {
770 dwStyle &= ~WS_VISIBLE;
771 ShowWindow(sw);
772 }
773
774 /* Call WH_SHELL hook */
775 if (!(getStyle() & WS_CHILD) && !owner)
776 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWCREATED, getWindowHandle(), 0);
777
778 SetLastError(0);
779 return TRUE;
780 }
781 }
782 dprintf(("Window creation FAILED (NCCREATE cancelled creation)"));
783 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
784end:
785 return FALSE;
786}
787//******************************************************************************
788//******************************************************************************
789ULONG Win32BaseWindow::MsgQuit()
790{
791 return SendInternalMessageA(WM_QUIT, 0, 0);
792}
793//******************************************************************************
794//******************************************************************************
795ULONG Win32BaseWindow::MsgClose()
796{
797 return SendInternalMessageA(WM_CLOSE,0,0);
798}
799//******************************************************************************
800//******************************************************************************
801ULONG Win32BaseWindow::MsgDestroy()
802{
803 ULONG rc;
804 Win32BaseWindow *child;
805 HWND hwnd = getWindowHandle();
806
807 fIsDestroyed = TRUE;
808
809 if(fDestroyWindowCalled == FALSE)
810 {//this window was destroyed because DestroyWindow was called for it's parent
811 //so: send a WM_PARENTNOTIFY now as that hasn't happened yet
812 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
813 {
814 if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
815 {
816 /* Notify the parent window only */
817 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
818 }
819//// else DebugInt3();
820 }
821 }
822 SendInternalMessageA(WM_DESTROY, 0, 0);
823 if(::IsWindow(hwnd) == FALSE) {
824 //object already destroyed, so return immediately
825 return 1;
826 }
827 SendInternalMessageA(WM_NCDESTROY, 0, 0);
828
829 TIMER_KillTimerFromWindow(OS2Hwnd);
830
831 if(getFirstChild() == NULL && fCreationFinished) {
832 delete this;
833 }
834 else {
835 //make sure no message can ever arrive for this window again (PM or from other win32 windows)
836 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
837 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
838 if(Win32Hwnd) {
839 HwFreeWindowHandle(Win32Hwnd);
840 Win32Hwnd = 0;
841 }
842 }
843 return 1;
844}
845//******************************************************************************
846//******************************************************************************
847ULONG Win32BaseWindow::MsgEnable(BOOL fEnable)
848{
849 if(fEnable) {
850 dwStyle &= ~WS_DISABLED;
851 }
852 else dwStyle |= WS_DISABLED;
853
854 return SendInternalMessageA(WM_ENABLE, fEnable, 0);
855}
856//******************************************************************************
857//TODO: SW_PARENTCLOSING/OPENING flag (lParam)
858//******************************************************************************
859ULONG Win32BaseWindow::MsgShow(BOOL fShow)
860{
861 if(fNoSizeMsg || fDestroyWindowCalled) {
862 return 1;
863 }
864
865 if(fShow) {
866 setStyle(getStyle() | WS_VISIBLE);
867 if(getStyle() & WS_MINIMIZE) {
868 return ShowWindow(SW_RESTORE);
869 }
870 }
871 else setStyle(getStyle() & ~WS_VISIBLE);
872
873 //already sent from ShowWindow
874//// return SendInternalMessageA(WM_SHOWWINDOW, fShow, 0);
875 return 0;
876}
877//******************************************************************************
878//******************************************************************************
879ULONG Win32BaseWindow::MsgPosChanging(LPARAM lp)
880{
881 //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
882 // a WM_WINDOWPOSCHANGED msg -> crash)
883 if(fNoSizeMsg || fDestroyWindowCalled)
884 return 0;
885
886 return SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, lp);
887}
888//******************************************************************************
889//******************************************************************************
890ULONG Win32BaseWindow::MsgPosChanged(LPARAM lp)
891{
892 //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
893 // a WM_WINDOWPOSCHANGED msg -> crash)
894 if(fNoSizeMsg || fDestroyWindowCalled)
895 return 1;
896
897 return SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, lp);
898}
899//******************************************************************************
900//******************************************************************************
901ULONG Win32BaseWindow::MsgScroll(ULONG msg, ULONG scrollCode, ULONG scrollPos)
902{
903 //According to the SDK docs, the scrollbar handle (lParam) is 0 when the standard
904 //window scrollbars send these messages
905 return SendInternalMessageA(msg, MAKELONG(scrollCode, scrollPos), 0);
906}
907//******************************************************************************
908//******************************************************************************
909ULONG Win32BaseWindow::MsgActivate(BOOL fActivate, BOOL fMinimized, HWND hwnd, HWND hwndOS2Win)
910{
911 ULONG rc, procidhwnd = -1, threadidhwnd = 0;
912
913 //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
914 if(fDestroyWindowCalled) {
915 return 0;
916 }
917
918 //According to SDK docs, if app returns FALSE & window is being deactivated,
919 //default processing is cancelled
920 //TODO: According to Wine we should proceed anyway if window is sysmodal
921 if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
922 {
923 dprintf(("WARNING: WM_NCACTIVATE return code = FALSE -> cancel processing"));
924 return 0;
925 }
926 /* child windows get a WM_CHILDACTIVATE message */
927 if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
928 {
929 if(fActivate) {//WM_CHILDACTIVE is for activation only
930 SendInternalMessageA(WM_CHILDACTIVATE, 0, 0L);
931 }
932 return 0;
933 }
934
935 rc = SendInternalMessageA(WM_ACTIVATE, MAKELONG((fActivate) ? WA_ACTIVE : WA_INACTIVE, fMinimized), hwnd);
936
937 if(hwndOS2Win) {
938 threadidhwnd = O32_GetWindowThreadProcessId(hwndOS2Win, &procidhwnd);
939 }
940 //Warning: temporary hack to force focus to newly created window
941 //RealPlayer 8 does not pass WM_ACTIVATE to defwindowproc and doesn't call
942 //setfocus -> keyboard focus not set
943 //TODO: Find real cause!!
944 if(GetFocus() == 0 && fActivate) {
945 if(!(getStyle() & WS_MINIMIZE))
946 SetFocus(getWindowHandle());
947 }
948 //Warning: temporary hack to force focus to newly created window
949
950 if(fActivate) {
951 SendInternalMessageA(WM_ACTIVATEAPP, 1, dwThreadId); //activate; specify window thread id
952 }
953 else SendInternalMessageA(WM_ACTIVATEAPP, 0, threadidhwnd); //deactivate; specify thread id of other process
954 return rc;
955}
956//******************************************************************************
957//******************************************************************************
958ULONG Win32BaseWindow::DispatchMsgA(MSG *msg)
959{
960 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
961}
962//******************************************************************************
963//******************************************************************************
964ULONG Win32BaseWindow::DispatchMsgW(MSG *msg)
965{
966 return SendInternalMessageW(msg->message, msg->wParam, msg->lParam);
967}
968//******************************************************************************
969//******************************************************************************
970ULONG Win32BaseWindow::MsgSetFocus(HWND hwnd)
971{
972 //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
973 if(fDestroyWindowCalled) {
974 return 0;
975 }
976
977 return SendInternalMessageA(WM_SETFOCUS, hwnd, 0);
978}
979//******************************************************************************
980//******************************************************************************
981ULONG Win32BaseWindow::MsgKillFocus(HWND hwnd)
982{
983 //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
984 if(fDestroyWindowCalled) {
985 return 0;
986 }
987 return SendInternalMessageA(WM_KILLFOCUS, hwnd, 0);
988}
989//******************************************************************************
990//******************************************************************************
991ULONG Win32BaseWindow::MsgButton(MSG *msg)
992{
993 BOOL fClick = FALSE;
994
995// dprintf(("MsgButton at (%d,%d)", msg->pt.x, msg->pt.y));
996 switch(msg->message) {
997 case WM_LBUTTONDBLCLK:
998 case WM_RBUTTONDBLCLK:
999 case WM_MBUTTONDBLCLK:
1000 if (!(windowClass && windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS))
1001 {
1002 msg->message = msg->message - (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN); //dblclick -> down
1003 MsgButton(msg);
1004 msg->message++; //button-up
1005 return MsgButton(msg);
1006 }
1007 break;
1008 case WM_NCLBUTTONDBLCLK:
1009 case WM_NCRBUTTONDBLCLK:
1010 case WM_NCMBUTTONDBLCLK:
1011 //Docs say CS_DBLCLKS style doesn't matter for non-client double clicks
1012 fClick = TRUE;
1013 break;
1014
1015 case WM_LBUTTONDOWN:
1016 case WM_RBUTTONDOWN:
1017 case WM_MBUTTONDOWN:
1018 case WM_NCLBUTTONDOWN:
1019 case WM_NCRBUTTONDOWN:
1020 case WM_NCMBUTTONDOWN:
1021 fClick = TRUE;
1022 break;
1023 }
1024
1025 if(fClick)
1026 {
1027 HWND hwndTop;
1028
1029 /* Activate the window if needed */
1030 hwndTop = (GetTopParent()) ? GetTopParent()->getWindowHandle() : 0;
1031
1032 HWND hwndActive = GetActiveWindow();
1033 if (hwndTop && (getWindowHandle() != hwndActive))
1034 {
1035 LONG ret = SendInternalMessageA(WM_MOUSEACTIVATE, hwndTop,
1036 MAKELONG( lastHitTestVal, msg->message) );
1037
1038#if 0
1039 if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
1040 eatMsg = TRUE;
1041#endif
1042 if(((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT))
1043 && (hwndTop != GetForegroundWindow()) )
1044 {
1045 Win32BaseWindow *win32top = Win32BaseWindow::GetWindowFromHandle(hwndTop);
1046
1047 //SvL: Calling OSLibSetActiveWindow(hwndTop); causes focus problems
1048 if (win32top) OSLibWinSetFocus(win32top->getOS2FrameWindowHandle());
1049 }
1050 }
1051 }
1052
1053 SendInternalMessageA(WM_SETCURSOR, getWindowHandle(), MAKELONG(lastHitTestVal, msg->message));
1054
1055 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1056}
1057//******************************************************************************
1058//******************************************************************************
1059ULONG Win32BaseWindow::MsgPaint(ULONG tmp, ULONG select)
1060{
1061 if (select && IsWindowIconic())
1062 return SendInternalMessageA(WM_PAINTICON, 1, 0);
1063 else
1064 return SendInternalMessageA(WM_PAINT, 0, 0);
1065}
1066//******************************************************************************
1067//TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
1068// (or are we simply erasing too much here)
1069//******************************************************************************
1070ULONG Win32BaseWindow::MsgEraseBackGround(HDC hdc)
1071{
1072 ULONG rc;
1073 HDC hdcErase = hdc;
1074
1075 if (hdcErase == 0)
1076 hdcErase = GetDC(getWindowHandle());
1077
1078 if(IsWindowIconic())
1079 rc = SendInternalMessageA(WM_ICONERASEBKGND, hdcErase, 0);
1080 else
1081 rc = SendInternalMessageA(WM_ERASEBKGND, hdcErase, 0);
1082 if (hdc == 0)
1083 ReleaseDC(getWindowHandle(), hdcErase);
1084 return (rc);
1085}
1086//******************************************************************************
1087//******************************************************************************
1088ULONG Win32BaseWindow::MsgMouseMove(MSG *msg)
1089{
1090 //TODO: hiword should be 0 if window enters menu mode (SDK docs)
1091 SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, msg->message));
1092
1093 //translated message == WM_(NC)MOUSEMOVE
1094 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1095}
1096//******************************************************************************
1097//******************************************************************************
1098ULONG Win32BaseWindow::MsgChar(MSG *msg)
1099{
1100 return DispatchMsgA(msg);
1101}
1102//******************************************************************************
1103//TODO: Should use update region, not rectangle
1104//******************************************************************************
1105ULONG Win32BaseWindow::MsgNCPaint(PRECT pUpdateRect)
1106{
1107 HRGN hrgn;
1108 ULONG rc;
1109 RECT client = rectClient;
1110
1111 if ((pUpdateRect->left >= client.left) && (pUpdateRect->left < client.right) &&
1112 (pUpdateRect->right >= client.left) && (pUpdateRect->right < client.right) &&
1113 (pUpdateRect->top >= client.top) && (pUpdateRect->top < client.bottom) &&
1114 (pUpdateRect->bottom >= client.top) && (pUpdateRect->bottom < client.bottom))
1115 {
1116 return 0;
1117 }
1118
1119 dprintf(("MsgNCPaint (%d,%d)(%d,%d)", pUpdateRect->left, pUpdateRect->top, pUpdateRect->right, pUpdateRect->bottom));
1120 hrgn = CreateRectRgnIndirect(pUpdateRect);
1121
1122 rc = SendInternalMessageA(WM_NCPAINT, hrgn, 0);
1123
1124 DeleteObject(hrgn);
1125
1126 return rc;
1127}
1128//******************************************************************************
1129//Called when either the frame's size or position has changed (lpWndPos != NULL)
1130//or when the frame layout has changed (i.e. scrollbars added/removed) (lpWndPos == NULL)
1131//******************************************************************************
1132ULONG Win32BaseWindow::MsgFormatFrame(WINDOWPOS *lpWndPos)
1133{
1134 RECT oldWindowRect = rectWindow, client = rectClient, newWindowRect;
1135 RECT newClientRect;
1136 WINDOWPOS wndPos;
1137 ULONG rc;
1138
1139 if(lpWndPos)
1140 {
1141 //set new window rectangle
1142 setWindowRect(lpWndPos->x, lpWndPos->y, lpWndPos->x+lpWndPos->cx,
1143 lpWndPos->y+lpWndPos->cy);
1144 newWindowRect = rectWindow;
1145 }
1146 else {
1147 wndPos.hwnd = getWindowHandle();
1148 wndPos.hwndInsertAfter = 0;
1149 newWindowRect= rectWindow;
1150 wndPos.x = newWindowRect.left;
1151 wndPos.y = newWindowRect.top;
1152 wndPos.cx = newWindowRect.right - newWindowRect.left;
1153 wndPos.cy = newWindowRect.bottom - newWindowRect.top;
1154 wndPos.flags = SWP_FRAMECHANGED;
1155 lpWndPos = &wndPos;
1156 }
1157
1158 newClientRect = rectClient;
1159 rc = SendNCCalcSize(TRUE, &newWindowRect, &oldWindowRect, &client, lpWndPos, &newClientRect);
1160 rectClient = newClientRect; //must update rectClient here
1161
1162 dprintf(("MsgFormatFrame: old client rect (%d,%d)(%d,%d), new client (%d,%d)(%d,%d)", client.left, client.top, client.right, client.bottom, rectClient.left, rectClient.top, rectClient.right, rectClient.bottom));
1163 dprintf(("MsgFormatFrame: old window rect (%d,%d)(%d,%d), new window (%d,%d)(%d,%d)", oldWindowRect.left, oldWindowRect.top, oldWindowRect.right, oldWindowRect.bottom, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
1164
1165 if(fNoSizeMsg || !EqualRect(&client, &rectClient)) {
1166 OSLibWinSetClientPos(getOS2WindowHandle(), rectClient.left, rectClient.top, getClientWidth(), getClientHeight(), getWindowHeight());
1167 }
1168
1169#if 1
1170//this doesn't always work
1171// if(!fNoSizeMsg && (client.left != rectClient.left || client.top != rectClient.top))
1172 if(!fNoSizeMsg && ((oldWindowRect.right - oldWindowRect.left < rectClient.left
1173 || oldWindowRect.bottom - oldWindowRect.top < rectClient.top) ||
1174 (EqualRect(&oldWindowRect, &rectWindow) && (client.left != rectClient.left || client.top != rectClient.top))))
1175 {
1176 Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild();
1177
1178 //client rectangle has moved -> inform children
1179 dprintf(("MsgFormatFrame -> client rectangle has changed, move children"));
1180 while(child) {
1181 ::SetWindowPos(child->getWindowHandle(),
1182 HWND_TOP, child->getWindowRect()->left,
1183 child->getWindowRect()->top, 0, 0,
1184 SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
1185 child = (Win32BaseWindow *)child->getNextChild();
1186 }
1187 }
1188#endif
1189 return rc;
1190}
1191//******************************************************************************
1192//******************************************************************************
1193ULONG Win32BaseWindow::MsgSetText(LPSTR lpsz, LONG cch)
1194{
1195 return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
1196}
1197//******************************************************************************
1198//******************************************************************************
1199ULONG Win32BaseWindow::MsgGetTextLength()
1200{
1201 return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
1202}
1203//******************************************************************************
1204//******************************************************************************
1205void Win32BaseWindow::MsgGetText(char *wndtext, ULONG textlength)
1206{
1207 SendInternalMessageA(WM_GETTEXT, textlength, (LPARAM)wndtext);
1208}
1209//******************************************************************************
1210//******************************************************************************
1211BOOL Win32BaseWindow::isMDIClient()
1212{
1213 return FALSE;
1214}
1215//******************************************************************************
1216//******************************************************************************
1217BOOL Win32BaseWindow::isMDIChild()
1218{
1219 return FALSE;
1220}
1221//******************************************************************************
1222//TODO: Not complete
1223//******************************************************************************
1224BOOL Win32BaseWindow::isFrameWindow()
1225{
1226 if(getParent() == NULL)
1227 return TRUE;
1228
1229 return FALSE;
1230}
1231//******************************************************************************
1232//******************************************************************************
1233BOOL Win32BaseWindow::isDesktopWindow()
1234{
1235 return FALSE;
1236}
1237//******************************************************************************
1238//******************************************************************************
1239BOOL Win32BaseWindow::IsWindowIconic()
1240{
1241 return ((getStyle() & WS_MINIMIZE) && windowClass->getIcon());
1242}
1243//******************************************************************************
1244//******************************************************************************
1245SCROLLBAR_INFO *Win32BaseWindow::getScrollInfo(int nBar)
1246{
1247 switch(nBar)
1248 {
1249 case SB_HORZ:
1250 if (!horzScrollInfo)
1251 {
1252 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1253 if (!horzScrollInfo) break;
1254 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
1255 horzScrollInfo->MaxVal = 100;
1256 horzScrollInfo->flags = ESB_ENABLE_BOTH;
1257 }
1258 return horzScrollInfo;
1259
1260 case SB_VERT:
1261 if (!vertScrollInfo)
1262 {
1263 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1264 if (!vertScrollInfo) break;
1265 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
1266 vertScrollInfo->MaxVal = 100;
1267 vertScrollInfo->flags = ESB_ENABLE_BOTH;
1268 }
1269 return vertScrollInfo;
1270 }
1271
1272 return NULL;
1273}
1274//******************************************************************************
1275//******************************************************************************
1276LRESULT Win32BaseWindow::DefWndControlColor(UINT ctlType, HDC hdc)
1277{
1278 //SvL: Set background color to default button color (not window (white))
1279 if(ctlType == CTLCOLOR_BTN)
1280 {
1281 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
1282 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1283 return GetSysColorBrush(COLOR_BTNFACE);
1284 }
1285 //SvL: Set background color to default dialog color if window is dialog
1286 if((ctlType == CTLCOLOR_DLG || ctlType == CTLCOLOR_STATIC) && IsDialog()) {
1287 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
1288 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1289 return GetSysColorBrush(COLOR_BTNFACE);
1290 }
1291
1292 if( ctlType == CTLCOLOR_SCROLLBAR)
1293 {
1294 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
1295 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
1296 SetTextColor( hdc, GetSysColor(COLOR_3DFACE));
1297 SetBkColor( hdc, bk);
1298
1299 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
1300 * we better use 0x55aa bitmap brush to make scrollbar's background
1301 * look different from the window background.
1302 */
1303 if (bk == GetSysColor(COLOR_WINDOW)) {
1304 return GetPattern55AABrush();
1305 }
1306
1307 UnrealizeObject( hb );
1308 return (LRESULT)hb;
1309 }
1310
1311 SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
1312
1313 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
1314 {
1315 SetBkColor( hdc, GetSysColor(COLOR_WINDOW) );
1316 }
1317 else
1318 {
1319 SetBkColor( hdc, GetSysColor(COLOR_3DFACE) );
1320 return (LRESULT)GetSysColorBrush(COLOR_3DFACE);
1321 }
1322 return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
1323}
1324//******************************************************************************
1325//******************************************************************************
1326LRESULT Win32BaseWindow::DefWndPrint(HDC hdc,ULONG uFlags)
1327{
1328 /*
1329 * Visibility flag.
1330 */
1331 if ( (uFlags & PRF_CHECKVISIBLE) &&
1332 !IsWindowVisible(getWindowHandle()) )
1333 return 0;
1334
1335 /*
1336 * Unimplemented flags.
1337 */
1338 if ( (uFlags & PRF_CHILDREN) ||
1339 (uFlags & PRF_OWNED) ||
1340 (uFlags & PRF_NONCLIENT) )
1341 {
1342 dprintf(("WM_PRINT message with unsupported flags\n"));
1343 }
1344
1345 /*
1346 * Background
1347 */
1348 if ( uFlags & PRF_ERASEBKGND)
1349 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
1350
1351 /*
1352 * Client area
1353 */
1354 if ( uFlags & PRF_CLIENT)
1355 SendInternalMessageA(WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
1356
1357
1358 return 0;
1359}
1360//******************************************************************************
1361//******************************************************************************
1362LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
1363{
1364 switch(Msg)
1365 {
1366 case WM_CLOSE:
1367 dprintf(("DefWindowProcA: WM_CLOSE %x", getWindowHandle()));
1368 DestroyWindow();
1369 return 0;
1370
1371 case WM_GETTEXTLENGTH:
1372 if(windowNameA) {
1373 return strlen(windowNameA);
1374 }
1375 else {
1376 return 0;
1377 }
1378
1379 case WM_GETTEXT:
1380 if (!lParam || !wParam) return 0;
1381 if (!windowNameA) ((LPSTR)lParam)[0] = 0;
1382 else lstrcpynA((LPSTR)lParam, windowNameA, wParam);
1383 return min((windowNameA ? strlen(windowNameA) : 0), wParam);
1384
1385 case WM_SETTEXT:
1386 {
1387 LPCSTR lpsz = (LPCSTR)lParam;
1388
1389 if(windowNameA) free(windowNameA);
1390 if(windowNameW) free(windowNameW);
1391 if (lParam)
1392 {
1393 int wndNameLength = strlen(lpsz);
1394 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
1395 strcpy(windowNameA, lpsz);
1396 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
1397 lstrcpyAtoW(windowNameW, windowNameA);
1398 }
1399 else
1400 {
1401 windowNameA = NULL;
1402 windowNameW = NULL;
1403 }
1404 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, lParam));
1405 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1406 {
1407 HandleNCPaint((HRGN)1);
1408 if(hTaskList) {
1409 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), (getStyle() & WS_VISIBLE) ? 1 : 0);
1410 }
1411 }
1412
1413 return TRUE;
1414 }
1415
1416 case WM_SETREDRAW:
1417 {
1418 if (wParam)
1419 {
1420 setStyle(getStyle() | WS_VISIBLE);
1421 dprintf(("Enable window update for %x", getWindowHandle()));
1422 OSLibWinEnableWindowUpdate(OS2HwndFrame, OS2Hwnd, TRUE);
1423 }
1424 else
1425 {
1426 if (getStyle() & WS_VISIBLE)
1427 {
1428 setStyle(getStyle() & ~WS_VISIBLE);
1429 dprintf(("Disable window update for %x", getWindowHandle()));
1430 OSLibWinEnableWindowUpdate(OS2HwndFrame, OS2Hwnd, FALSE);
1431 }
1432 }
1433 return 0;
1434 }
1435
1436 case WM_CTLCOLORMSGBOX:
1437 case WM_CTLCOLOREDIT:
1438 case WM_CTLCOLORLISTBOX:
1439 case WM_CTLCOLORBTN:
1440 case WM_CTLCOLORDLG:
1441 case WM_CTLCOLORSTATIC:
1442 case WM_CTLCOLORSCROLLBAR:
1443 return DefWndControlColor(Msg - WM_CTLCOLORMSGBOX, (HDC)wParam);
1444
1445 case WM_CTLCOLOR:
1446 return DefWndControlColor(HIWORD(lParam), (HDC)wParam);
1447
1448 case WM_VKEYTOITEM:
1449 case WM_CHARTOITEM:
1450 return -1;
1451
1452 case WM_PARENTNOTIFY:
1453 return 0;
1454
1455 case WM_MOUSEACTIVATE:
1456 {
1457 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1458 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
1459 {
1460 if(getParent()) {
1461 LRESULT rc = getParent()->SendInternalMessageA(WM_MOUSEACTIVATE, wParam, lParam );
1462 if(rc) return rc;
1463 }
1464 }
1465 return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
1466 }
1467
1468 case WM_ACTIVATE:
1469 /* The default action in Windows is to set the keyboard focus to
1470 * the window, if it's being activated and not minimized */
1471 if (LOWORD(wParam) != WA_INACTIVE) {
1472 if(!(getStyle() & WS_MINIMIZE))
1473 SetFocus(getWindowHandle());
1474 }
1475 return 0;
1476
1477 case WM_SETCURSOR:
1478 {
1479 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1480 if((getStyle() & WS_CHILD))
1481 {
1482 if(getParent()) {
1483 LRESULT rc = getParent()->SendInternalMessageA(WM_SETCURSOR, wParam, lParam);
1484 if(rc) return rc;
1485 }
1486 }
1487 if (wParam == getWindowHandle())
1488 {
1489 HCURSOR hCursor;
1490
1491 switch(LOWORD(lParam))
1492 {
1493 case HTCLIENT:
1494 hCursor = windowClass ? windowClass->getCursor():LoadCursorA(0,IDC_ARROWA);
1495 break;
1496
1497 case HTLEFT:
1498 case HTRIGHT:
1499 hCursor = LoadCursorA(0,IDC_SIZEWEA);
1500 break;
1501
1502 case HTTOP:
1503 case HTBOTTOM:
1504 hCursor = LoadCursorA(0,IDC_SIZENSA);
1505 break;
1506
1507 case HTTOPLEFT:
1508 case HTBOTTOMRIGHT:
1509 hCursor = LoadCursorA(0,IDC_SIZENWSEA);
1510 break;
1511
1512 case HTTOPRIGHT:
1513 case HTBOTTOMLEFT:
1514 hCursor = LoadCursorA(0,IDC_SIZENESWA);
1515 break;
1516
1517 default:
1518 hCursor = LoadCursorA(0,IDC_ARROWA);
1519 break;
1520 }
1521
1522 if (hCursor)
1523 {
1524 SetCursor(hCursor);
1525 return 1;
1526 }
1527 else return 0;
1528 }
1529 else return 0;
1530 }
1531
1532 case WM_MOUSEMOVE:
1533 return 0;
1534
1535 case WM_WINDOWPOSCHANGED:
1536 {
1537 PWINDOWPOS wpos = (PWINDOWPOS)lParam;
1538 WPARAM wp = SIZE_RESTORED;
1539
1540 if (!(wpos->flags & SWP_NOMOVE) && !(wpos->flags & SWP_NOCLIENTMOVE))
1541 {
1542 SendInternalMessageA(WM_MOVE, 0, MAKELONG(rectClient.left,rectClient.top));
1543 }
1544 if (!(wpos->flags & SWP_NOSIZE) && !(wpos->flags & SWP_NOCLIENTSIZE))
1545 {
1546 if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
1547 else
1548 if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
1549
1550 SendInternalMessageA(WM_SIZE, wp, MAKELONG(rectClient.right - rectClient.left,
1551 rectClient.bottom - rectClient.top));
1552 }
1553 return 0;
1554 }
1555 case WM_WINDOWPOSCHANGING:
1556 return HandleWindowPosChanging((WINDOWPOS *)lParam);
1557
1558 case WM_ERASEBKGND:
1559 case WM_ICONERASEBKGND:
1560 {
1561 RECT rect;
1562 int rc;
1563
1564 if(getWindowHandle() == 0x68000044) {
1565 rc = GetClipBox( (HDC)wParam, &rect );
1566 FillRect( (HDC)wParam, &rect, GetSysColorBrush(COLOR_WINDOWTEXT));
1567 return 1;
1568 }
1569
1570 if (!windowClass || !windowClass->getBackgroundBrush()) return 0;
1571
1572 rc = GetClipBox( (HDC)wParam, &rect );
1573 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
1574 {
1575 HBRUSH hBrush = windowClass->getBackgroundBrush();
1576
1577 if (hBrush <= (HBRUSH)(SYSCOLOR_GetLastColor()+1))
1578 hBrush = GetSysColorBrush(hBrush-1);
1579
1580 FillRect( (HDC)wParam, &rect, hBrush);
1581 }
1582 return 1;
1583 }
1584
1585 case WM_PRINT:
1586 return DefWndPrint(wParam,lParam);
1587
1588 case WM_PAINTICON:
1589 case WM_PAINT:
1590 {
1591 PAINTSTRUCT ps;
1592 HDC hdc = BeginPaint(getWindowHandle(), &ps );
1593 if( hdc )
1594 {
1595 if( (getStyle() & WS_MINIMIZE) && (getWindowClass()->getIcon() || hIcon))
1596 {
1597 int x = (rectWindow.right - rectWindow.left - GetSystemMetrics(SM_CXICON))/2;
1598 int y = (rectWindow.bottom - rectWindow.top - GetSystemMetrics(SM_CYICON))/2;
1599 dprintf(("Painting class icon: vis rect=(%i,%i - %i,%i)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom ));
1600 DrawIcon(hdc, x, y, hIcon ? hIcon:getWindowClass()->getIcon() );
1601 }
1602 EndPaint(getWindowHandle(), &ps );
1603 }
1604 return 0;
1605 }
1606
1607 case WM_GETDLGCODE:
1608 return 0;
1609
1610 case WM_NCPAINT:
1611 return HandleNCPaint((HRGN)wParam);
1612
1613 case WM_NCACTIVATE:
1614 return HandleNCActivate(wParam);
1615
1616 case WM_NCCREATE:
1617 return(TRUE);
1618
1619 case WM_NCDESTROY:
1620 return 0;
1621
1622 case WM_NCCALCSIZE:
1623 return HandleNCCalcSize((BOOL)wParam,(RECT*)lParam);
1624
1625 case WM_NCLBUTTONDOWN:
1626 return HandleNCLButtonDown(wParam,lParam);
1627
1628 case WM_LBUTTONDBLCLK:
1629 case WM_NCLBUTTONDBLCLK:
1630 return HandleNCLButtonDblClk(wParam,lParam);
1631
1632 case WM_NCRBUTTONDOWN:
1633 case WM_NCRBUTTONDBLCLK:
1634 case WM_NCMBUTTONDOWN:
1635 case WM_NCMBUTTONDBLCLK:
1636 if (lastHitTestVal == HTERROR) MessageBeep(MB_ICONEXCLAMATION);
1637 return 0;
1638
1639 case WM_NCRBUTTONUP:
1640 return HandleNCRButtonUp(wParam,lParam);
1641
1642 case WM_NCMBUTTONUP:
1643 return 0;
1644
1645 case WM_NCHITTEST:
1646 {
1647 POINT point;
1648 LRESULT retvalue;
1649
1650 point.x = (SHORT)LOWORD(lParam);
1651 point.y = (SHORT)HIWORD(lParam);
1652
1653 retvalue = HandleNCHitTest(point);
1654#if 0 //CB: let the Corel people fix the bugs first
1655 if(retvalue == HTMENU)
1656 MENU_TrackMouseMenuBar_MouseMove(Win32Hwnd,point,TRUE);
1657 else
1658 MENU_TrackMouseMenuBar_MouseMove(Win32Hwnd,point,FALSE);
1659#endif
1660 return retvalue;
1661 }
1662
1663 case WM_SYSCOMMAND:
1664 {
1665 POINT point;
1666
1667 point.x = LOWORD(lParam);
1668 point.y = HIWORD(lParam);
1669 return HandleSysCommand(wParam,&point);
1670 }
1671
1672 case WM_SYSKEYDOWN:
1673 if(wParam == VK_F4) /* try to close the window */
1674 {
1675 Win32BaseWindow *window = GetTopParent();
1676 if(window && !(window->getClass()->getStyle() & CS_NOCLOSE))
1677 PostMessageA(window->getWindowHandle(), WM_SYSCOMMAND, SC_CLOSE, 0);
1678 return 0;
1679 }
1680
1681 Win32BaseWindow *siblingWindow;
1682 HWND sibling;
1683 char nameBuffer [40], mnemonic;
1684 int nameLength;
1685
1686 GetWindowTextA (nameBuffer, 40);
1687
1688 // search all sibling to see it this key is their mnemonic
1689 sibling = GetWindow (GW_HWNDFIRST);
1690 while (sibling != 0) {
1691 siblingWindow = GetWindowFromHandle (sibling);
1692 nameLength = siblingWindow->GetWindowTextA (nameBuffer, 40);
1693
1694 // find the siblings mnemonic
1695 mnemonic = '\0';
1696 for (int i=0 ; i<nameLength ; i++) {
1697 if (IsDBCSLeadByte(nameBuffer[i])) {
1698 // Skip DBCS
1699 continue;
1700 }
1701 if (nameBuffer [i] == '&') {
1702 mnemonic = nameBuffer [i+1];
1703 if ((mnemonic >= 'a') && (mnemonic <= 'z'))
1704 mnemonic -= 32; // make it uppercase
1705 break; // stop searching
1706 }
1707 }
1708
1709 // key matches siblings mnemonic, send mouseclick
1710 if (mnemonic == (char) wParam) {
1711 siblingWindow->SendInternalMessageA (BM_CLICK, 0, 0);
1712 }
1713
1714 sibling = siblingWindow->GetNextWindow (GW_HWNDNEXT);
1715 }
1716
1717 return 0;
1718
1719#if 0 //CB: todo: MSDN docu: Windown handles these messages and not WM_SYSCHAR (the code below doesn't work)
1720 case WM_KEYDOWN:
1721 case WM_KEYUP:
1722 case WM_SYSKEYDOWN:
1723 case WM_SYSKEYUP:
1724#endif
1725
1726 case WM_SYSCHAR:
1727 {
1728 int iMenuSysKey = 0;
1729 if (wParam == VK_RETURN && (getStyle() & WS_MINIMIZE))
1730 {
1731 PostMessageA(getWindowHandle(), WM_SYSCOMMAND,
1732 (WPARAM)SC_RESTORE, 0L );
1733 break;
1734 }
1735 if((HIWORD(lParam) & KEYDATA_ALT) && wParam)
1736 {
1737 if (wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_F4)
1738 break;
1739 if (wParam == VK_SPACE && (getStyle() & WS_CHILD)) {
1740 getParent()->SendMessageA(Msg, wParam, lParam );
1741 }
1742 else SendMessageA(WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam );
1743 }
1744#if 0
1745 else /* check for Ctrl-Esc */
1746 if (wParam != VK_ESCAPE) MessageBeep(0);
1747 break;
1748#endif
1749 }
1750
1751 case WM_SETHOTKEY:
1752 hotkey = wParam;
1753 return 1; //CB: always successful
1754
1755 case WM_GETHOTKEY:
1756 return hotkey;
1757
1758 case WM_CONTEXTMENU:
1759 if ((dwStyle & WS_CHILD) && getParent())
1760 getParent()->SendInternalMessageA(WM_CONTEXTMENU,wParam,lParam);
1761 return 0;
1762
1763 case WM_SHOWWINDOW:
1764 if (!lParam) return 0; /* sent from ShowWindow */
1765 if (!(dwStyle & WS_POPUP) || !owner) return 0;
1766 if ((dwStyle & WS_VISIBLE) && wParam) return 0;
1767 else if (!(dwStyle & WS_VISIBLE) && !wParam) return 0;
1768 ShowWindow(wParam ? SW_SHOW:SW_HIDE);
1769 return 0;
1770
1771 case WM_CANCELMODE:
1772 if (getParent() == windowDesktop) EndMenu();
1773 if (GetCapture() == Win32Hwnd) ReleaseCapture();
1774 return 0;
1775
1776 case WM_DROPOBJECT:
1777 return DRAG_FILE;
1778
1779 case WM_QUERYDROPOBJECT:
1780 return (dwExStyle & WS_EX_ACCEPTFILES) ? 1:0;
1781
1782 case WM_QUERYDRAGICON:
1783 {
1784 HICON hDragIcon = windowClass->getCursor();
1785 UINT len;
1786
1787 if(hDragIcon) return (LRESULT)hDragIcon;
1788 for(len = 1; len < 64; len++)
1789 {
1790 hDragIcon = LoadIconA(hInstance,MAKEINTRESOURCEA(len));
1791 if(hDragIcon)
1792 return (LRESULT)hDragIcon;
1793 }
1794 return (LRESULT)LoadIconA(0,IDI_APPLICATIONA);
1795 }
1796
1797 case WM_QUERYOPEN:
1798 case WM_QUERYENDSESSION:
1799 return 1;
1800
1801 case WM_NOTIFYFORMAT:
1802 return IsWindowUnicode() ? NFR_UNICODE:NFR_ANSI;
1803
1804 case WM_SETICON:
1805 case WM_GETICON:
1806 {
1807 LRESULT result = 0;
1808
1809 /* Set the appropriate icon members in the window structure. */
1810 if (wParam == ICON_SMALL)
1811 {
1812 result = hIconSm;
1813 if (Msg == WM_SETICON)
1814 hIconSm = (HICON)lParam;
1815 }
1816 else
1817 {
1818 result = hIcon;
1819 if (Msg == WM_SETICON)
1820 {
1821 hIcon = (HICON)lParam;
1822 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1823 OSLibWinSetIcon(OS2Hwnd,hIcon);
1824 }
1825 }
1826 if ((Msg == WM_SETICON) && ((dwStyle & WS_CAPTION) == WS_CAPTION))
1827 HandleNCPaint((HRGN)1);
1828
1829 return result;
1830 }
1831
1832 case WM_HELP:
1833 if (getParent()) getParent()->SendInternalMessageA(Msg,wParam,lParam);
1834 break;
1835
1836 case WM_NOTIFY:
1837 return 0; //comctl32 controls expect this
1838
1839 default:
1840 return 0;
1841 }
1842 return 0;
1843}
1844//******************************************************************************
1845//******************************************************************************
1846LRESULT Win32BaseWindow::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
1847{
1848 switch(Msg)
1849 {
1850 case WM_GETTEXTLENGTH:
1851 if(windowNameW) {
1852 return lstrlenW(windowNameW);
1853 }
1854 else return 0;
1855
1856 case WM_GETTEXT:
1857 if (!lParam || !wParam) return 0;
1858 if (!windowNameW) ((LPWSTR)lParam)[0] = 0;
1859 else lstrcpynW((LPWSTR)lParam,windowNameW,wParam);
1860 return min((windowNameW ? lstrlenW(windowNameW) : 0),wParam);
1861
1862 case WM_SETTEXT:
1863 {
1864 LPWSTR lpsz = (LPWSTR)lParam;
1865
1866 if(windowNameA) free(windowNameA);
1867 if(windowNameW) free(windowNameW);
1868 if (lParam)
1869 {
1870 // Wide
1871 int wndNameLength = lstrlenW(lpsz);
1872 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
1873 lstrcpyW(windowNameW,lpsz);
1874 // Ascii
1875 LPSTR tmp = HEAP_strdupWtoA(GetProcessHeap(), 0, lpsz);
1876 if(tmp) {
1877 long tmpLength = strlen( tmp );
1878 windowNameA = (LPSTR)_smalloc(tmpLength+1);
1879 strcpy(windowNameA,tmp);
1880 windowNameA[tmpLength] = 0; // need ?
1881 HEAP_free(tmp);
1882 }
1883 else {
1884 windowNameA = (LPSTR)_smalloc(1);
1885 windowNameA[0] = 0;
1886 }
1887 }
1888 else
1889 {
1890 windowNameA = NULL;
1891 windowNameW = NULL;
1892 }
1893 dprintf(("WM_SETTEXT of %x\n",Win32Hwnd));
1894 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1895 {
1896 HandleNCPaint((HRGN)1);
1897 if(hTaskList) {
1898 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), (getStyle() & WS_VISIBLE) ? 1 : 0);
1899 }
1900 }
1901
1902 return TRUE;
1903 }
1904
1905 default:
1906 return DefWindowProcA(Msg, wParam, lParam);
1907 }
1908}
1909//******************************************************************************
1910//******************************************************************************
1911LRESULT Win32BaseWindow::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1912{
1913 //if the destination window is created by this process & thread, call window proc directly
1914 if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
1915 return SendInternalMessageA(Msg, wParam, lParam);
1916 }
1917 //otherwise use WinSendMsg to send it to the right process/thread
1918 dprintf(("SendMessages (inter-process) %x %x %x %x", getWindowHandle(), Msg, wParam, lParam));
1919 return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, FALSE);
1920}
1921//******************************************************************************
1922//******************************************************************************
1923LRESULT Win32BaseWindow::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
1924{
1925 //if the destination window is created by this process & thread, call window proc directly
1926 if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
1927 return SendInternalMessageW(Msg, wParam, lParam);
1928 }
1929 //otherwise use WinSendMsg to send it to the right process/thread
1930 return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, TRUE);
1931}
1932//******************************************************************************
1933//Called as a result of an OS/2 message or called from a class method
1934//******************************************************************************
1935LRESULT Win32BaseWindow::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1936{
1937 LRESULT rc;
1938 HWND hwnd = getWindowHandle();
1939 BOOL fInternalMsgBackup = fInternalMsg;
1940
1941 //if the destination window was created by this process & thread, call window proc directly
1942 if(dwProcessId != currentProcessId || dwThreadId != GetCurrentThreadId()) {
1943 dprintf(("SendMessages (inter-process) %x %x %x %x", getWindowHandle(), Msg, wParam, lParam));
1944 return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, FALSE);
1945 }
1946
1947 DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, FALSE, TRUE);
1948
1949 CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, FALSE);
1950
1951 fInternalMsg = TRUE;
1952 switch(Msg)
1953 {
1954 case WM_CREATE:
1955 {
1956 if(CallWindowProcA(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
1957 dprintf(("WM_CREATE returned -1\n"));
1958 rc = -1; //don't create window
1959 break;
1960 }
1961 rc = 0;
1962 break;
1963 }
1964 case WM_LBUTTONDOWN:
1965 case WM_MBUTTONDOWN:
1966 case WM_RBUTTONDOWN:
1967 {
1968 if (getParent())
1969 {
1970 POINTS pt = MAKEPOINTS(lParam);
1971 POINT point;
1972
1973 point.x = pt.x;
1974 point.y = pt.y;
1975 MapWindowPoints(getWindowHandle(), getParent()->getWindowHandle(), &point, 1);
1976 NotifyParent(Msg,wParam,MAKELPARAM(point.x,point.y));
1977 }
1978 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1979 break;
1980 }
1981 case WM_NCHITTEST:
1982 rc = lastHitTestVal = win32wndproc(getWindowHandle(), WM_NCHITTEST, wParam, lParam);
1983 break;
1984
1985 case WM_DESTROY:
1986 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1987 break;
1988
1989 default:
1990 rc = CallWindowProcA(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
1991 break;
1992 }
1993 if(!::IsWindow(hwnd)) {
1994 //window might have been destroyed by now. (this pointer invalid)
1995 //we must return immediately
1996 //(MS Visual C++ install heap corruption)
1997 //TODO: could happen in several places here!!!!
1998 return rc;
1999 }
2000 fInternalMsg = fInternalMsgBackup;
2001 return rc;
2002}
2003//******************************************************************************
2004//Called as a result of an OS/2 message or called from a class method
2005//******************************************************************************
2006LRESULT Win32BaseWindow::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
2007{
2008 LRESULT rc;
2009 HWND hwnd = getWindowHandle();
2010 BOOL fInternalMsgBackup = fInternalMsg;
2011
2012 //if the destination window was created by this process & thread, call window proc directly
2013 if(dwProcessId != currentProcessId || dwThreadId != GetCurrentThreadId()) {
2014 dprintf(("SendMessages (inter-process) %x %x %x %x", getWindowHandle(), Msg, wParam, lParam));
2015 return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, FALSE);
2016 }
2017
2018 DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, TRUE, TRUE);
2019
2020 CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, TRUE);
2021
2022 fInternalMsg = TRUE;
2023 switch(Msg)
2024 {
2025 case WM_CREATE:
2026 {
2027 if(CallWindowProcW(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
2028 dprintf(("WM_CREATE returned -1\n"));
2029 rc = -1; //don't create window
2030 break;
2031 }
2032 rc = 0;
2033 break;
2034 }
2035 case WM_LBUTTONDOWN:
2036 case WM_MBUTTONDOWN:
2037 case WM_RBUTTONDOWN:
2038 NotifyParent(Msg, wParam, lParam);
2039 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
2040 break;
2041
2042 case WM_NCHITTEST:
2043 rc = lastHitTestVal = win32wndproc(getWindowHandle(), WM_NCHITTEST, wParam, lParam);
2044 break;
2045
2046 case WM_DESTROY:
2047 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
2048 break;
2049 default:
2050 rc = CallWindowProcW(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
2051 break;
2052 }
2053 if(!::IsWindow(hwnd)) {
2054 //window might have been destroyed by now. (this pointer invalid)
2055 //we must return immediately
2056 //(MS Visual C++ install heap corruption)
2057 //TODO: could happen in several places here!!!!
2058 return rc;
2059 }
2060 fInternalMsg = fInternalMsgBackup;
2061 return rc;
2062}
2063//******************************************************************************
2064//******************************************************************************
2065void Win32BaseWindow::CallWindowHookProc(ULONG hooktype, ULONG Msg, WPARAM wParam, LPARAM lParam, BOOL fUnicode)
2066{
2067 CWPSTRUCT cwp;
2068
2069 cwp.lParam = lParam;
2070 cwp.wParam = wParam;
2071 cwp.message = Msg;
2072 cwp.hwnd = getWindowHandle();
2073
2074 switch(hooktype) {
2075 case WH_CALLWNDPROC:
2076 if(fUnicode) {
2077 HOOK_CallHooksW(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
2078 }
2079 else HOOK_CallHooksA(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
2080 break;
2081 }
2082}
2083//******************************************************************************
2084//TODO: Do this more efficiently
2085//******************************************************************************
2086LRESULT Win32BaseWindow::BroadcastMessageA(int type, UINT msg, WPARAM wParam, LPARAM lParam)
2087{
2088 Win32BaseWindow *window;
2089 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
2090
2091 dprintf(("BroadCastMessageA %x %x %x", msg, wParam, lParam, GetFS()));
2092
2093 for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
2094 window = GetWindowFromHandle(hwnd++);
2095 if(window) {
2096 if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
2097 {
2098 if(type == BROADCAST_SEND) {
2099 ::SendMessageA(window->getWindowHandle(), msg, wParam, lParam);
2100 }
2101 else PostMessageA(window->getWindowHandle(), msg, wParam, lParam);
2102 }
2103 }
2104 }
2105 return 0;
2106}
2107//******************************************************************************
2108//TODO: Do this more efficiently
2109//******************************************************************************
2110LRESULT Win32BaseWindow::BroadcastMessageW(int type, UINT msg, WPARAM wParam, LPARAM lParam)
2111{
2112 Win32BaseWindow *window;
2113 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
2114
2115 dprintf(("BroadCastMessageW %x %x %x", msg, wParam, lParam));
2116
2117 for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
2118 window = GetWindowFromHandle(hwnd++);
2119 if(window) {
2120 if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
2121 {
2122 if(type == BROADCAST_SEND) {
2123 ::SendMessageW(window->getWindowHandle(), msg, wParam, lParam);
2124 }
2125 else PostMessageW(window->getWindowHandle(), msg, wParam, lParam);
2126 }
2127 }
2128 }
2129 return 0;
2130}
2131//******************************************************************************
2132//******************************************************************************
2133void Win32BaseWindow::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
2134{
2135 Win32BaseWindow *window = this;
2136 Win32BaseWindow *parentwindow;
2137
2138 while(window)
2139 {
2140 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
2141 {
2142 /* Notify the parent window only */
2143 parentwindow = window->getParent();
2144 if(parentwindow) {
2145 parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, getWindowId()), lParam );
2146 }
2147 }
2148 else break;
2149
2150 window = parentwindow;
2151 }
2152}
2153//******************************************************************************
2154// Returns the big or small icon for the window, falling back to the
2155// class as windows does.
2156//******************************************************************************
2157HICON Win32BaseWindow::IconForWindow(WPARAM fType)
2158{
2159 HICON hWndIcon;
2160
2161 if (fType == ICON_BIG)
2162 {
2163 if (hIcon)
2164 hWndIcon = hIcon;
2165 else
2166 if (windowClass && windowClass->getIcon())
2167 hWndIcon = windowClass->getIcon();
2168 else
2169 if (!(dwStyle & DS_MODALFRAME))
2170 hWndIcon = LoadImageA(0,MAKEINTRESOURCEA(OIC_ODINICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR);
2171 else hWndIcon = 0;
2172 }
2173 else
2174 {
2175 if (hIconSm)
2176 hWndIcon = hIconSm;
2177 else
2178 if (hIcon)
2179 hWndIcon = hIcon;
2180 else
2181 if (windowClass && windowClass->getIconSm())
2182 hWndIcon = windowClass->getIconSm();
2183 else
2184 if (windowClass && windowClass->getIcon())
2185 hWndIcon = windowClass->getIcon();
2186 else
2187 if (!(dwStyle & DS_MODALFRAME))
2188 hWndIcon = LoadImageA(0,MAKEINTRESOURCEA(OIC_ODINICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR);
2189 else hWndIcon = 0;
2190 }
2191
2192 return hWndIcon;
2193}
2194//******************************************************************************
2195//******************************************************************************
2196BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
2197{
2198 ULONG swp = 0;
2199 HWND hWinAfter;
2200 BOOL rc,wasVisible,showFlag;
2201 RECT newPos = {0, 0, 0, 0};
2202
2203 dprintf(("ShowWindow %x %x", getWindowHandle(), nCmdShow));
2204 wasVisible = (getStyle() & WS_VISIBLE) != 0;
2205
2206 switch(nCmdShow)
2207 {
2208 case SW_HIDE:
2209 if (!wasVisible) goto END;
2210
2211 swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER;
2212 break;
2213
2214 case SW_SHOWMINNOACTIVE:
2215 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
2216 /* fall through */
2217 case SW_SHOWMINIMIZED:
2218 swp |= SWP_SHOWWINDOW;
2219 /* fall through */
2220 case SW_MINIMIZE:
2221 swp |= SWP_FRAMECHANGED;
2222 if( !(getStyle() & WS_MINIMIZE) ) {
2223 swp |= MinMaximize(SW_MINIMIZE, &newPos );
2224 fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
2225 }
2226 else swp |= SWP_NOSIZE | SWP_NOMOVE;
2227 break;
2228
2229 case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
2230 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
2231 if( !(getStyle() & WS_MAXIMIZE) ) {
2232 swp |= MinMaximize(SW_MAXIMIZE, &newPos );
2233 fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
2234 }
2235 else swp |= SWP_NOSIZE | SWP_NOMOVE;
2236 break;
2237
2238 case SW_SHOWNA:
2239 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
2240 /* fall through */
2241 case SW_SHOW:
2242 swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
2243
2244 /*
2245 * ShowWindow has a little peculiar behavior that if the
2246 * window is already the topmost window, it will not
2247 * activate it.
2248 */
2249 if (::GetTopWindow((HWND)0)==getWindowHandle() && (wasVisible || GetActiveWindow() == getWindowHandle()))
2250 swp |= SWP_NOACTIVATE;
2251
2252 break;
2253
2254 case SW_SHOWNOACTIVATE:
2255 swp |= SWP_NOZORDER;
2256 if (GetActiveWindow())
2257 swp |= SWP_NOACTIVATE;
2258 /* fall through */
2259 case SW_SHOWNORMAL: /* same as SW_NORMAL: */
2260 case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
2261 case SW_RESTORE:
2262 //TODO: WIN_RESTORE_MAX flag!!!!!!!!!!!!!!
2263 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
2264
2265 if( getStyle() & (WS_MINIMIZE | WS_MAXIMIZE) ) {
2266 swp |= MinMaximize(SW_RESTORE, &newPos );
2267 fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
2268 }
2269 else swp |= SWP_NOSIZE | SWP_NOMOVE;
2270 break;
2271 }
2272
2273 showFlag = (nCmdShow != SW_HIDE);
2274 if (showFlag != wasVisible)
2275 {
2276 SendInternalMessageA(WM_SHOWWINDOW, showFlag, 0 );
2277 if (!::IsWindow( getWindowHandle() )) goto END;
2278 }
2279
2280 /* We can't activate a child window */
2281 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_MDICHILD))
2282 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
2283
2284 SetWindowPos(HWND_TOP, newPos.left, newPos.top, newPos.right, newPos.bottom, LOWORD(swp));
2285
2286 if(!(swp & SWP_NOACTIVATE)) {
2287 OSLibWinSetActiveWindow(OS2HwndFrame);
2288 }
2289
2290 if (flags & WIN_NEED_SIZE)
2291 {
2292 /* should happen only in CreateWindowEx() */
2293 int wParam = SIZE_RESTORED;
2294
2295 flags &= ~WIN_NEED_SIZE;
2296 if (dwStyle & WS_MAXIMIZE)
2297 wParam = SIZE_MAXIMIZED;
2298 else
2299 if (dwStyle & WS_MINIMIZE)
2300 wParam = SIZE_MINIMIZED;
2301
2302 SendInternalMessageA(WM_SIZE, wParam,
2303 MAKELONG(rectClient.right-rectClient.left,
2304 rectClient.bottom-rectClient.top));
2305 SendInternalMessageA(WM_MOVE,0,MAKELONG(rectClient.left,rectClient.top));
2306 }
2307//testestest
2308 //temporary workaround for file dialogs with template dialog child
2309 //they don't redraw when switching directories
2310 //For some reason the new child's (syslistview32) update rectangle stays
2311 //empty after its parent is made visible with ShowWindow
2312 //TODO: find real cause
2313 if(!wasVisible) {
2314 InvalidateRect(getWindowHandle(), NULL, TRUE);
2315 }
2316//testestest
2317END:
2318 fMinMaxChange = FALSE;
2319 return wasVisible;
2320}
2321//******************************************************************************
2322//******************************************************************************
2323BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
2324{
2325 BOOL rc = FALSE;
2326 Win32BaseWindow *window;
2327 HWND hParent = 0;
2328 RECT oldClientRect = rectClient;
2329
2330 if (fuFlags &
2331 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
2332 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
2333 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
2334 SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_DEFERERASE |
2335 SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE))
2336 {
2337 dprintf(("ERROR: SetWindowPos; UNKNOWN flag"));
2338 return FALSE;
2339 }
2340
2341 if( fuFlags & (SWP_DEFERERASE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)) {
2342 dprintf(("WARNING: SetWindowPos; unsupported flag"));
2343 }
2344
2345 if(IsWindowDestroyed()) {
2346 //changing the position of a window that's being destroyed can cause crashes in PMMERGE
2347 dprintf(("SetWindowPos; window already destroyed"));
2348 return TRUE;
2349 }
2350#if 0
2351 /* Fix redundant flags */
2352 if(getStyle() & WS_VISIBLE) {
2353 fuFlags &= ~SWP_SHOWWINDOW;
2354 }
2355 else
2356 {
2357 if (!(fuFlags & SWP_SHOWWINDOW))
2358 fuFlags |= SWP_NOREDRAW;
2359 fuFlags &= ~SWP_HIDEWINDOW;
2360 }
2361
2362 if(cx < 0) cx = 0;
2363 if(cy < 0) cy = 0;
2364
2365 if((rectWindow.right - rectWindow.left == cx) && (rectWindow.bottom - rectWindow.top == cy)) {
2366 fuFlags |= SWP_NOSIZE; /* Already the right size */
2367 }
2368
2369 if((rectWindow.left == x) && (rectWindow.top == y)) {
2370 fuFlags |= SWP_NOMOVE; /* Already the right position */
2371 }
2372
2373 if(getWindowHandle() == GetActiveWindow()) {
2374 fuFlags |= SWP_NOACTIVATE; /* Already active */
2375 }
2376 else
2377 if((getStyle() & (WS_POPUP | WS_CHILD)) != WS_CHILD )
2378 {
2379 if(!(fuFlags & SWP_NOACTIVATE)) /* Bring to the top when activating */
2380 {
2381 fuFlags &= ~SWP_NOZORDER;
2382 hwndInsertAfter = HWND_TOP;
2383 }
2384 }
2385#endif
2386
2387 if(!fCreateSetWindowPos)
2388 {//don't change size; modify internal structures only
2389 //TODO: not 100% correct yet (activate)
2390 if(!(fuFlags & SWP_NOZORDER)) {
2391 hwndLinkAfter = hwndInsertAfter;
2392 }
2393 if(!(fuFlags & SWP_NOMOVE)) {
2394 rectWindow.bottom = (rectWindow.bottom - rectWindow.top) + y;
2395 rectWindow.top = y;
2396 rectWindow.right = (rectWindow.right - rectWindow.left) + x;
2397 rectWindow.left = x;
2398 }
2399 if(!(fuFlags & SWP_NOSIZE)) {
2400 rectWindow.bottom = rectWindow.top + cy;
2401 rectWindow.right = rectWindow.left + cx;
2402 }
2403 return TRUE;
2404 }
2405
2406 WINDOWPOS wpos;
2407 SWP swp, swpOld;
2408 wpos.flags = fuFlags;
2409 wpos.cy = cy;
2410 wpos.cx = cx;
2411 wpos.x = x;
2412 wpos.y = y;
2413 wpos.hwndInsertAfter = hwndInsertAfter;
2414 wpos.hwnd = getWindowHandle();
2415
2416 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE))
2417 {
2418 if (isChild())
2419 {
2420 if(!getParent()) {
2421 dprintf(("WARNING: Win32BaseWindow::SetWindowPos window %x is child but has no parent!!", getWindowHandle()));
2422 }
2423 }
2424 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
2425 }
2426
2427 if(getParent()) {
2428 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, getParent()->getClientHeight(),
2429 OS2HwndFrame);
2430 }
2431 else OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, OSLibQueryScreenHeight(), OS2HwndFrame);
2432
2433 if (swp.fl == 0) {
2434 if(fuFlags & SWP_FRAMECHANGED)
2435 {
2436 NotifyFrameChanged(&wpos, &oldClientRect);
2437 }
2438 return TRUE;
2439 }
2440
2441// if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
2442 if ((swp.hwndInsertBehind > HWNDOS_BOTTOM))
2443 {
2444 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
2445 if(wndBehind) {
2446 swp.hwndInsertBehind = wndBehind->getOS2FrameWindowHandle();
2447 }
2448 else {
2449 dprintf(("ERROR: SetWindowPos: hwndInsertBehind %x invalid!",swp.hwndInsertBehind));
2450 swp.hwndInsertBehind = 0;
2451 }
2452 }
2453 swp.hwnd = OS2HwndFrame;
2454
2455 if(fuFlags & SWP_SHOWWINDOW && !IsWindowVisible(getWindowHandle())) {
2456 setStyle(getStyle() | WS_VISIBLE);
2457 if(hTaskList) {
2458 dprintf(("Adding window %x to tasklist", getWindowHandle()));
2459 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), 1);
2460 }
2461 }
2462 else
2463 if((fuFlags & SWP_HIDEWINDOW) && IsWindowVisible(getWindowHandle())) {
2464 setStyle(getStyle() & ~WS_VISIBLE);
2465 if(hTaskList && !(getStyle() & WS_MINIMIZE)) {
2466 dprintf(("Removing window %x from tasklist", getWindowHandle()));
2467 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), 0);
2468 }
2469 }
2470 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
2471 rc = OSLibWinSetMultWindowPos(&swp, 1);
2472
2473 if(rc == FALSE)
2474 {
2475 dprintf(("OSLibWinSetMultWindowPos failed! Error %x",OSLibWinGetLastError()));
2476 return 0;
2477 }
2478
2479 if((fuFlags & SWP_FRAMECHANGED) && (fuFlags & (SWP_NOMOVE | SWP_NOSIZE) == (SWP_NOMOVE | SWP_NOSIZE)))
2480 {
2481 NotifyFrameChanged(&wpos, &oldClientRect);
2482 }
2483 return (rc);
2484}
2485//******************************************************************************
2486//Called by ScrollWindowEx (dc.cpp) to notify child window that it has moved
2487//******************************************************************************
2488BOOL Win32BaseWindow::ScrollWindow(int dx, int dy)
2489{
2490 rectWindow.left += dx;
2491 rectWindow.right += dx;
2492 rectWindow.top += dy;
2493 rectWindow.bottom += dy;
2494 SendInternalMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
2495 return TRUE;
2496}
2497//******************************************************************************
2498//******************************************************************************
2499void Win32BaseWindow::NotifyFrameChanged(WINDOWPOS *wpos, RECT *oldClientRect)
2500{
2501 HRGN hrgn, hrgnClient;
2502 RECT rect;
2503
2504 MsgFormatFrame(NULL);
2505
2506 if(RECT_WIDTH(rectClient) != RECT_WIDTH(*oldClientRect) ||
2507 RECT_HEIGHT(rectClient) != RECT_HEIGHT(*oldClientRect))
2508 {
2509 wpos->flags &= ~(SWP_NOSIZE|SWP_NOCLIENTSIZE);
2510 wpos->cx = RECT_WIDTH(rectWindow);
2511 wpos->cy = RECT_HEIGHT(rectWindow);
2512 }
2513
2514 if(rectClient.left != oldClientRect->left ||
2515 rectClient.top != oldClientRect->top)
2516 {
2517 wpos->flags &= ~(SWP_NOMOVE|SWP_NOCLIENTMOVE);
2518 wpos->x = rectWindow.left;
2519 wpos->y = rectWindow.top;
2520 }
2521
2522 WINDOWPOS wpOld = *wpos;
2523 SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, (LPARAM)wpos);
2524
2525 if ((wpos->hwndInsertAfter != wpOld.hwndInsertAfter) ||
2526 (wpos->x != wpOld.x) || (wpos->y != wpOld.y) || (wpos->cx != wpOld.cx) || (wpos->cy != wpOld.cy) || (wpos->flags != wpOld.flags))
2527 {
2528 dprintf(("WARNING, NotifyFrameChanged: TODO -> adjust flags!!!!"));
2529 SetWindowPos(wpos->hwndInsertAfter, wpos->x, wpos->y, wpos->cx, wpos->cy, wpos->flags | SWP_NOSENDCHANGING);
2530 }
2531 else SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, (LPARAM)wpos);
2532
2533 //Calculate invalid areas
2534 rect = rectWindow;
2535 OffsetRect(&rect, -rectWindow.left, -rectWindow.top);
2536 hrgn = CreateRectRgnIndirect(&rect);
2537 if (!hrgn) {
2538 dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
2539 return;
2540 }
2541 rect = rectClient;
2542 hrgnClient = CreateRectRgnIndirect(&rect);
2543 if (!hrgn) {
2544 dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
2545 return;
2546 }
2547 CombineRgn(hrgn, hrgn, hrgnClient, RGN_DIFF);
2548 DeleteObject(hrgnClient);
2549
2550 if(!EqualRect(oldClientRect, &rectClient)) {
2551 UnionRect(oldClientRect, oldClientRect, &rectClient);
2552 hrgnClient = CreateRectRgnIndirect(oldClientRect);
2553 if (!hrgn) {
2554 dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
2555 return;
2556 }
2557 CombineRgn(hrgn, hrgn, hrgnClient, RGN_OR);
2558 DeleteObject(hrgnClient);
2559 }
2560 RedrawWindow(getWindowHandle(), NULL, hrgn, RDW_ALLCHILDREN |
2561 RDW_INVALIDATE | RDW_ERASE | RDW_FRAME);
2562 DeleteObject(hrgn);
2563}
2564//******************************************************************************
2565//TODO: Check how this api really works in NT
2566//******************************************************************************
2567BOOL Win32BaseWindow::SetWindowPlacement(WINDOWPLACEMENT *wndpl)
2568{
2569 dprintf(("SetWindowPlacement %x min (%d,%d)", getWindowHandle(), wndpl->ptMinPosition.x, wndpl->ptMinPosition.y));
2570 dprintf(("SetWindowPlacement %x max (%d,%d)", getWindowHandle(), wndpl->ptMaxPosition.x, wndpl->ptMaxPosition.y));
2571 dprintf(("SetWindowPlacement %x norm (%d,%d)(%d,%d)", getWindowHandle(), wndpl->rcNormalPosition.left, wndpl->rcNormalPosition.top, wndpl->rcNormalPosition.right, wndpl->rcNormalPosition.bottom));
2572 windowpos.ptMinPosition = wndpl->ptMinPosition;
2573 windowpos.ptMaxPosition = wndpl->ptMaxPosition;
2574 windowpos.rcNormalPosition = wndpl->rcNormalPosition;
2575
2576 if(getStyle() & WS_MINIMIZE )
2577 {
2578 //TODO: Why can't this be (0,0)?
2579 if(wndpl->flags & WPF_SETMINPOSITION && !(!windowpos.ptMinPosition.x && !windowpos.ptMinPosition.y)) {
2580 SetWindowPos(0, windowpos.ptMinPosition.x, windowpos.ptMinPosition.y,
2581 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
2582 }
2583 }
2584 else
2585 if(getStyle() & WS_MAXIMIZE )
2586 {
2587 //TODO: Why can't this be (0,0)?
2588 if(windowpos.ptMaxPosition.x != 0 || windowpos.ptMaxPosition.y != 0 )
2589 SetWindowPos(0, windowpos.ptMaxPosition.x, windowpos.ptMaxPosition.y,
2590 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
2591 }
2592 else {
2593 SetWindowPos(0, windowpos.rcNormalPosition.left, windowpos.rcNormalPosition.top,
2594 windowpos.rcNormalPosition.right - windowpos.rcNormalPosition.left,
2595 windowpos.rcNormalPosition.bottom - windowpos.rcNormalPosition.top,
2596 SWP_NOZORDER | SWP_NOACTIVATE );
2597 }
2598 ShowWindow(wndpl->showCmd);
2599 if( ::IsWindow(getWindowHandle()) && getStyle() & WS_MINIMIZE )
2600 {
2601 /* SDK: ...valid only the next time... */
2602 if(wndpl->flags & WPF_RESTORETOMAXIMIZED)
2603 setFlags(getFlags() | WIN_RESTORE_MAX);
2604 }
2605 return TRUE;
2606}
2607//******************************************************************************
2608//******************************************************************************
2609BOOL Win32BaseWindow::GetWindowPlacement(LPWINDOWPLACEMENT wndpl)
2610{
2611 wndpl->length = sizeof(*wndpl);
2612 if(getStyle() & WS_MINIMIZE )
2613 wndpl->showCmd = SW_SHOWMINIMIZED;
2614 else wndpl->showCmd = (getStyle() & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
2615
2616 //TODO: Verify if this is correct -> SDK docs claim this flag must always be set to 0
2617 if(getFlags() & WIN_RESTORE_MAX )
2618 wndpl->flags = WPF_RESTORETOMAXIMIZED;
2619 else wndpl->flags = 0;
2620
2621 wndpl->ptMinPosition = windowpos.ptMinPosition;
2622 wndpl->ptMaxPosition = windowpos.ptMaxPosition;
2623 //Must be in parent coordinates (or screen if no parent); verified in NT4, SP6
2624 wndpl->rcNormalPosition = rectWindow;
2625
2626 return TRUE;
2627}
2628//******************************************************************************
2629//Also destroys all the child windows (destroy children first, parent last)
2630//******************************************************************************
2631BOOL Win32BaseWindow::DestroyWindow()
2632{
2633 HWND hwnd = getWindowHandle();
2634
2635 dprintf(("DestroyWindow %x", hwnd));
2636
2637 /* Call hooks */
2638 if(HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, getWindowHandle(), 0L))
2639 {
2640 return FALSE;
2641 }
2642
2643 if(!(getStyle() & WS_CHILD) && getOwner() == NULL)
2644 {
2645 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWDESTROYED, getWindowHandle(), 0L);
2646 /* FIXME: clean up palette - see "Internals" p.352 */
2647 }
2648
2649 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
2650 {
2651 if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
2652 {
2653 /* Notify the parent window only */
2654 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
2655 if(!::IsWindow(hwnd) )
2656 {
2657 return TRUE;
2658 }
2659 }
2660//// else DebugInt3();
2661 }
2662 /* Hide the window */
2663 if(IsWindowVisible(getWindowHandle()))
2664 {
2665 SetWindowPos(0, 0, 0, 0, 0, SWP_HIDEWINDOW |
2666 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
2667 if(!::IsWindow(hwnd))
2668 {
2669 return TRUE;
2670 }
2671 }
2672 dprintf(("DestroyWindow %x -> HIDDEN", hwnd));
2673
2674 fDestroyWindowCalled = TRUE;
2675 return OSLibWinDestroyWindow(OS2HwndFrame);
2676}
2677//******************************************************************************
2678//******************************************************************************
2679Win32BaseWindow *Win32BaseWindow::getParent()
2680{
2681 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
2682 return ((ULONG)wndparent == (ULONG)windowDesktop) ? NULL : wndparent;
2683}
2684//******************************************************************************
2685//Note: does not set last error if no parent (verified in NT4, SP6)
2686//******************************************************************************
2687HWND Win32BaseWindow::GetParent()
2688{
2689 if((!(getStyle() & (WS_POPUP|WS_CHILD)))) {
2690 return 0;
2691 }
2692
2693 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
2694
2695 if(getStyle() & WS_CHILD) {
2696 if(wndparent) {
2697 return wndparent->getWindowHandle();
2698 }
2699 dprintf(("WARNING: GetParent: WS_CHILD but no parent!!"));
2700 DebugInt3();
2701 return 0;
2702 }
2703 else return (getOwner()) ? getOwner()->getWindowHandle() : 0;
2704}
2705//******************************************************************************
2706//******************************************************************************
2707HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
2708{
2709 HWND oldhwnd;
2710 Win32BaseWindow *newparent;
2711 Win32BaseWindow *oldparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
2712 BOOL fShow = FALSE;
2713
2714 if(oldparent) {
2715 oldhwnd = oldparent->getWindowHandle();
2716 oldparent->removeChild(this);
2717 }
2718 else oldhwnd = 0;
2719
2720 /* Windows hides the window first, then shows it again
2721 * including the WM_SHOWWINDOW messages and all */
2722 if(fCreated && (getStyle() & WS_VISIBLE)) {
2723 ShowWindow(SW_HIDE);
2724 fShow = TRUE;
2725 }
2726
2727 newparent = GetWindowFromHandle(hwndNewParent);
2728 if(newparent && !newparent->isDesktopWindow())
2729 {
2730 setParent(newparent);
2731 getParent()->addChild(this);
2732 OSLibWinSetParent(getOS2FrameWindowHandle(), getParent()->getOS2WindowHandle());
2733 if(!(getStyle() & WS_CHILD))
2734 {
2735 //TODO: Send WM_STYLECHANGED msg?
2736 setStyle(getStyle() | WS_CHILD);
2737 if(getWindowId())
2738 {
2739 DestroyMenu( (HMENU) getWindowId() );
2740 setWindowId(0);
2741 }
2742 }
2743 }
2744 else {
2745 setParent(windowDesktop);
2746 windowDesktop->addChild(this);
2747 OSLibWinSetParent(getOS2FrameWindowHandle(), OSLIB_HWND_DESKTOP);
2748
2749 //TODO: Send WM_STYLECHANGED msg?
2750 setStyle(getStyle() & ~WS_CHILD);
2751 setWindowId(0);
2752 }
2753 /* SetParent additionally needs to make hwndChild the topmost window
2754 in the x-order and send the expected WM_WINDOWPOSCHANGING and
2755 WM_WINDOWPOSCHANGED notification messages.
2756 */
2757 if(fCreated) {
2758 SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0,
2759 SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|(fShow? SWP_SHOWWINDOW : 0));
2760
2761 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
2762 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
2763 }
2764 return oldhwnd;
2765}
2766//******************************************************************************
2767//******************************************************************************
2768BOOL Win32BaseWindow::IsChild(HWND hwndParent)
2769{
2770 if(getParent()) {
2771 if(getParent()->getWindowHandle() == hwndParent)
2772 return TRUE;
2773
2774 return getParent()->IsChild(hwndParent);
2775 }
2776 else return 0;
2777}
2778//******************************************************************************
2779//******************************************************************************
2780HWND Win32BaseWindow::GetTopWindow()
2781{
2782 HWND hwndTop;
2783 Win32BaseWindow *topwindow;
2784
2785 hwndTop = OSLibWinQueryWindow(getOS2WindowHandle(), QWOS_TOP);
2786 if(!isDesktopWindow())
2787 {
2788 topwindow = GetWindowFromOS2FrameHandle(hwndTop);
2789 if(topwindow) {
2790 return topwindow->getWindowHandle();
2791 }
2792 return 0;
2793 }
2794 while(hwndTop) {
2795 topwindow = GetWindowFromOS2FrameHandle(hwndTop);
2796 if(topwindow) {
2797 return topwindow->getWindowHandle();
2798 }
2799 hwndTop = OSLibWinQueryWindow(hwndTop, QWOS_NEXT);
2800 }
2801
2802 return 0;
2803}
2804//******************************************************************************
2805// Get the top-level parent for a child window.
2806//******************************************************************************
2807Win32BaseWindow *Win32BaseWindow::GetTopParent()
2808{
2809 Win32BaseWindow *window = this;
2810
2811 while(window && (window->getStyle() & WS_CHILD))
2812 {
2813 window = window->getParent();
2814 }
2815 return window;
2816}
2817//******************************************************************************
2818//TODO: Should not enumerate children that are created during the enumeration!
2819//******************************************************************************
2820BOOL Win32BaseWindow::EnumChildWindows(WNDENUMPROC lpfn, LPARAM lParam)
2821{
2822 BOOL rc = TRUE;
2823 HWND hwnd;
2824 Win32BaseWindow *prevchild = 0, *child = 0;
2825
2826 dprintf(("EnumChildWindows of %x parameter %x %x (%x)", getWindowHandle(), lpfn, lParam, getFirstChild()));
2827 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2828 {
2829 dprintf(("EnumChildWindows: enumerating child %x (owner %x; parent %x)", child->getWindowHandle(), (child->getOwner()) ? child->getOwner()->getWindowHandle() : 0, getWindowHandle()));
2830 hwnd = child->getWindowHandle();
2831 if(child->getOwner()) {
2832 continue; //shouldn't have an owner (Wine)
2833 }
2834 if(lpfn(hwnd, lParam) == FALSE)
2835 {
2836 rc = FALSE;
2837 break;
2838 }
2839 //check if the window still exists
2840 if(!::IsWindow(hwnd))
2841 {
2842 child = prevchild;
2843 continue;
2844 }
2845 if(child->getFirstChild() != NULL)
2846 {
2847 dprintf(("EnumChildWindows: Enumerate children of %x", child->getWindowHandle()));
2848 if(child->EnumChildWindows(lpfn, lParam) == FALSE)
2849 {
2850 rc = FALSE;
2851 break;
2852 }
2853 }
2854 prevchild = child;
2855 }
2856 return rc;
2857}
2858//******************************************************************************
2859//Enumerate first-level children only and check thread id
2860//******************************************************************************
2861BOOL Win32BaseWindow::EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
2862{
2863 Win32BaseWindow *child = 0;
2864 ULONG tid, pid;
2865 BOOL rc;
2866 HWND hwnd;
2867
2868 dprintf(("EnumThreadWindows %x %x %x", dwThreadId, lpfn, lParam));
2869
2870 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2871 {
2872 OSLibWinQueryWindowProcess(child->getOS2WindowHandle(), &pid, &tid);
2873
2874 if(dwThreadId == tid) {
2875 dprintf2(("EnumThreadWindows: Found Window %x", child->getWindowHandle()));
2876 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
2877 break;
2878 }
2879 }
2880 }
2881 return TRUE;
2882}
2883//******************************************************************************
2884//Enumerate first-level children only
2885//******************************************************************************
2886BOOL Win32BaseWindow::EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
2887{
2888 Win32BaseWindow *child = 0;
2889 BOOL rc;
2890 HWND hwnd;
2891
2892 dprintf(("EnumWindows %x %x", lpfn, lParam));
2893
2894 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2895 {
2896 hwnd = child->getWindowHandle();
2897
2898 dprintf2(("EnumWindows: Found Window %x", child->getWindowHandle()));
2899 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
2900 break;
2901 }
2902 }
2903 return TRUE;
2904}
2905//******************************************************************************
2906//******************************************************************************
2907Win32BaseWindow *Win32BaseWindow::FindWindowById(int id)
2908{
2909 for (Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2910 {
2911 if (child->getWindowId() == id)
2912 {
2913 return child;
2914 }
2915 }
2916 return 0;
2917}
2918//******************************************************************************
2919//TODO:
2920//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
2921//the current process owns them.
2922//******************************************************************************
2923HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, ATOM atom, LPSTR lpszWindow)
2924{
2925 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
2926 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
2927
2928 dprintf(("FindWindowEx %x %x %x %s", hwndParent, hwndChildAfter, atom, lpszWindow));
2929 if((hwndParent != 0 && !parent) ||
2930 (hwndChildAfter != 0 && !child) ||
2931 (hwndParent == 0 && hwndChildAfter != 0))
2932 {
2933 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
2934 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2935 return 0;
2936 }
2937 SetLastError(0);
2938 if(hwndParent != 0)
2939 {//if the current process owns the window, just do a quick search
2940 child = (Win32BaseWindow *)parent->getFirstChild();
2941 if(hwndChildAfter != 0)
2942 {
2943 while(child)
2944 {
2945 if(child->getWindowHandle() == hwndChildAfter)
2946 {
2947 child = (Win32BaseWindow *)child->getNextChild();
2948 break;
2949 }
2950 child = (Win32BaseWindow *)child->getNextChild();
2951 }
2952 }
2953 while(child)
2954 {
2955 //According to Wine, the class doesn't need to be specified
2956 if((!atom || child->getWindowClass()->getAtom() == atom) &&
2957 (!lpszWindow || child->hasWindowName(lpszWindow)))
2958 {
2959 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
2960 return child->getWindowHandle();
2961 }
2962 child = (Win32BaseWindow *)child->getNextChild();
2963 }
2964 }
2965 else {
2966 Win32BaseWindow *wnd;
2967 HWND henum, hwnd;
2968
2969 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
2970 hwnd = OSLibWinGetNextWindow(henum);
2971
2972 while(hwnd)
2973 {
2974 wnd = GetWindowFromOS2FrameHandle(hwnd);
2975 if(wnd == NULL) {
2976 hwnd = OSLibWinQueryClientWindow(hwnd);
2977 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
2978 }
2979
2980 if(wnd) {
2981 //According to Wine, the class doesn't need to be specified
2982 if((!atom || wnd->getWindowClass()->getAtom() == atom) &&
2983 (!lpszWindow || wnd->hasWindowName(lpszWindow)))
2984 {
2985 OSLibWinEndEnumWindows(henum);
2986 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
2987 return wnd->getWindowHandle();
2988 }
2989 }
2990 hwnd = OSLibWinGetNextWindow(henum);
2991 }
2992 OSLibWinEndEnumWindows(henum);
2993 }
2994 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
2995 return 0;
2996}
2997//******************************************************************************
2998//******************************************************************************
2999HWND Win32BaseWindow::GetWindow(UINT uCmd)
3000{
3001 HWND hwndRelated = 0;
3002 Win32BaseWindow *window;
3003
3004 switch(uCmd)
3005 {
3006 case GW_HWNDFIRST:
3007 if(getParent())
3008 {
3009 window = (Win32BaseWindow *)getParent();
3010 hwndRelated = OSLibWinQueryWindow(window->getOS2WindowHandle(), QWOS_TOP);
3011 window = GetWindowFromOS2FrameHandle(hwndRelated);
3012 if(window) {
3013 hwndRelated = window->getWindowHandle();
3014 }
3015 else hwndRelated = 0;
3016 }
3017 else {
3018 dprintf(("WARNING: GW_HWNDFIRST not correctly implemented for toplevel/most windows!"));
3019 hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
3020 }
3021 break;
3022
3023 case GW_HWNDLAST:
3024 if(getParent()) {
3025 window = (Win32BaseWindow *)getParent();
3026 hwndRelated = OSLibWinQueryWindow(window->getOS2WindowHandle(), QWOS_BOTTOM);
3027 dprintf(("os2 handle %x", hwndRelated));
3028 window = GetWindowFromOS2FrameHandle(hwndRelated);
3029 if(window) {
3030 hwndRelated = window->getWindowHandle();
3031 }
3032 else hwndRelated = 0;
3033 }
3034 else {
3035 dprintf(("WARNING: GW_HWNDLAST not correctly implemented for toplevel/most windows!"));
3036 hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
3037 }
3038 break;
3039
3040 case GW_HWNDNEXT:
3041 if(getParent()) {
3042 hwndRelated = OSLibWinQueryWindow(getOS2FrameWindowHandle(), QWOS_NEXT);
3043 window = GetWindowFromOS2FrameHandle(hwndRelated);
3044 if(window) {
3045 hwndRelated = window->getWindowHandle();
3046 }
3047 else hwndRelated = 0;
3048 }
3049 else {
3050 dprintf(("WARNING: GW_HWNDNEXT not correctly implemented for toplevel/most windows!"));
3051 hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
3052 }
3053 break;
3054
3055 case GW_HWNDPREV:
3056 if(getParent()) {
3057 hwndRelated = OSLibWinQueryWindow(getOS2FrameWindowHandle(), QWOS_PREV);
3058 window = GetWindowFromOS2FrameHandle(hwndRelated);
3059 if(window) {
3060 hwndRelated = window->getWindowHandle();
3061 }
3062 else hwndRelated = 0;
3063 }
3064 else {
3065 dprintf(("WARNING: GW_HWNDPREV not correctly implemented for toplevel/most windows!"));
3066 hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
3067 }
3068 break;
3069
3070 case GW_OWNER:
3071 if(getOwner()) {
3072 hwndRelated = getOwner()->getWindowHandle();
3073 }
3074 break;
3075
3076 case GW_CHILD:
3077 hwndRelated = OSLibWinQueryWindow(getOS2WindowHandle(), QWOS_TOP);
3078 window = GetWindowFromOS2FrameHandle(hwndRelated);
3079 if(window) {
3080 hwndRelated = window->getWindowHandle();
3081 }
3082 else hwndRelated = 0;
3083 break;
3084 }
3085end:
3086 dprintf(("GetWindow %x %d returned %x", getWindowHandle(), uCmd, hwndRelated));
3087 return hwndRelated;
3088}
3089//******************************************************************************
3090//******************************************************************************
3091HWND Win32BaseWindow::SetActiveWindow()
3092{
3093 HWND hwndActive;
3094
3095 dprintf(("SetActiveWindow %x", getWindowHandle()));
3096 if(GetActiveWindow() == getWindowHandle()) {
3097 dprintf(("Window already active"));
3098 return getWindowHandle();
3099 }
3100 if (HOOK_IsHooked( WH_CBT ))
3101 {
3102 CBTACTIVATESTRUCT cbta;
3103 LRESULT ret;
3104
3105 cbta.fMouse = FALSE;
3106 cbta.hWndActive = GetActiveWindow();
3107 ret = HOOK_CallHooksA(WH_CBT, HCBT_ACTIVATE, getWindowHandle(), (LPARAM)&cbta);
3108 if(ret)
3109 {
3110 dprintf(("SetActiveWindow %x, CBT hook cancelled operation", getWindowHandle()));
3111 return cbta.hWndActive;
3112 }
3113 }
3114 SetWindowPos(HWND_TOP, 0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
3115
3116// if(OSLibWinSetActiveWindow(OS2Hwnd) == FALSE) {
3117// dprintf(("OSLibWinSetActiveWindow %x returned FALSE!", OS2Hwnd));
3118// }
3119 hwndActive = GetActiveWindow();
3120 return (hwndActive) ? hwndActive : windowDesktop->getWindowHandle(); //pretend the desktop was active
3121}
3122//******************************************************************************
3123//Used to change active status of an mdi window
3124//******************************************************************************
3125BOOL Win32BaseWindow::DeactivateChildWindow()
3126{
3127 /* child windows get a WM_CHILDACTIVATE message */
3128 if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
3129 {
3130 ULONG flags = OSLibWinGetWindowULong(getOS2WindowHandle(), OFFSET_WIN32FLAGS);
3131 OSLibWinSetWindowULong(getOS2WindowHandle(), OFFSET_WIN32FLAGS, (flags & ~WINDOWFLAG_ACTIVE));
3132 return TRUE;
3133 }
3134 DebugInt3(); //should not be called for non-child window
3135 return FALSE;
3136}
3137//******************************************************************************
3138//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
3139//******************************************************************************
3140BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
3141{
3142 BOOL rc;
3143
3144 dprintf(("Win32BaseWindow::EnableWindow %x %d", getWindowHandle(), fEnable));
3145 //return true if previous state was disabled, else false (sdk docs)
3146 rc = (getStyle() & WS_DISABLED) != 0;
3147 if(rc && !fEnable) {
3148 SendMessageA(WM_CANCELMODE, 0, 0);
3149 }
3150 OSLibWinEnableWindow(OS2HwndFrame, fEnable);
3151 if(fEnable == FALSE) {
3152 //SvL: No need to clear focus as PM already does this
3153 if(getWindowHandle() == GetCapture()) {
3154 ReleaseCapture(); /* A disabled window can't capture the mouse */
3155 dprintf(("Released capture for window %x that is being disabled", getWindowHandle()));
3156 }
3157 }
3158 return rc;
3159}
3160//******************************************************************************
3161//******************************************************************************
3162BOOL Win32BaseWindow::CloseWindow()
3163{
3164 return OSLibWinMinimizeWindow(OS2Hwnd);
3165}
3166//******************************************************************************
3167//TODO: Not be 100% correct; should return active window of current thread
3168// or NULL when there is none -> WinQueryActiveWindow just returns
3169// the current active window
3170//******************************************************************************
3171HWND Win32BaseWindow::GetActiveWindow()
3172{
3173 HWND hwndActive;
3174 Win32BaseWindow *win32wnd;
3175 ULONG magic;
3176
3177 hwndActive = OSLibWinQueryActiveWindow();
3178
3179 return OS2ToWin32Handle(hwndActive);
3180}
3181//******************************************************************************
3182//******************************************************************************
3183BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
3184{
3185 INT len = GetWindowTextLength(fUnicode);
3186 BOOL res;
3187
3188 if (wndname == NULL)
3189 return (len == 0);
3190
3191 len++;
3192 if (fUnicode)
3193 {
3194 WCHAR *text = (WCHAR*)malloc(len*sizeof(WCHAR));
3195
3196 GetWindowTextW(text,len);
3197 res = (lstrcmpW(text,(LPWSTR)wndname) == 0);
3198 free(text);
3199 }
3200 else
3201 {
3202 CHAR *text = (CHAR*)malloc(len*sizeof(CHAR));
3203
3204 GetWindowTextA(text,len);
3205 res = (strcmp(text,wndname) == 0);
3206 free(text);
3207 }
3208
3209 return res;
3210}
3211//******************************************************************************
3212//******************************************************************************
3213CHAR *Win32BaseWindow::getWindowNamePtrA()
3214{
3215 INT len = GetWindowTextLength(FALSE);
3216 CHAR *text;
3217
3218 if (len == 0) return NULL;
3219 len++;
3220 text = (CHAR*)malloc(len*sizeof(CHAR));
3221 GetWindowTextA(text,len);
3222
3223 return text;
3224}
3225//******************************************************************************
3226//******************************************************************************
3227WCHAR *Win32BaseWindow::getWindowNamePtrW()
3228{
3229 INT len = GetWindowTextLength(TRUE);
3230 WCHAR *text;
3231
3232 if (len == 0) return NULL;
3233 len++;
3234 text = (WCHAR*)malloc(len*sizeof(WCHAR));
3235 GetWindowTextW(text,len);
3236
3237 return text;
3238}
3239//******************************************************************************
3240//******************************************************************************
3241VOID Win32BaseWindow::freeWindowNamePtr(PVOID namePtr)
3242{
3243 if (namePtr) free(namePtr);
3244}
3245//******************************************************************************
3246//When using this API for a window that was created by a different process, NT
3247//does NOT send WM_GETTEXTLENGTH.
3248//******************************************************************************
3249int Win32BaseWindow::GetWindowTextLength(BOOL fUnicode)
3250{
3251 //if the destination window is created by this process, send message
3252 if(dwProcessId == currentProcessId) {
3253 if(fUnicode) {
3254 return SendInternalMessageW(WM_GETTEXTLENGTH,0,0);
3255 }
3256 else return SendInternalMessageA(WM_GETTEXTLENGTH,0,0);
3257 }
3258 //else get data directory from window structure
3259 //TODO: must lock window structure.... (TODO)
3260 if(fUnicode) {
3261 if(windowNameW) {
3262 return strlenW(windowNameW);
3263 }
3264 else return 0;
3265 }
3266 else {
3267 if(windowNameA) {
3268 return strlen(windowNameA);
3269 }
3270 else return 0;
3271 }
3272}
3273//******************************************************************************
3274//When using this API for a window that was created by a different process, NT
3275//does NOT send WM_GETTEXT.
3276//******************************************************************************
3277int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
3278{
3279 //if the destination window is created by this process, send message
3280 if(dwProcessId == currentProcessId) {
3281 return SendInternalMessageA(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
3282 }
3283 //else get data directory from window structure
3284 if (!lpsz || !cch) return 0;
3285 if (!windowNameA) lpsz[0] = 0;
3286 else lstrcpynA(lpsz, windowNameA, cch);
3287 return min((windowNameA ? strlen(windowNameA) : 0), cch);
3288}
3289//******************************************************************************
3290//When using this API for a window that was created by a different process, NT
3291//does NOT send WM_GETTEXT.
3292//******************************************************************************
3293int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
3294{
3295 //if the destination window is created by this process, send message
3296 if(dwProcessId == currentProcessId) {
3297 return SendInternalMessageW(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
3298 }
3299 //else get data directory from window structure
3300 if (!lpsz || !cch) return 0;
3301 if (!windowNameW) lpsz[0] = 0;
3302 else lstrcpynW(lpsz, windowNameW, cch);
3303 return min((windowNameW ? strlenW(windowNameW) : 0), cch);
3304}
3305//******************************************************************************
3306//TODO: How does this work when the target window belongs to a different process???
3307//******************************************************************************
3308BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
3309{
3310 return SendInternalMessageA(WM_SETTEXT,0,(LPARAM)lpsz);
3311}
3312//******************************************************************************
3313//******************************************************************************
3314BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
3315{
3316 return SendInternalMessageW(WM_SETTEXT,0,(LPARAM)lpsz);
3317}
3318//******************************************************************************
3319//******************************************************************************
3320LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value, BOOL fUnicode)
3321{
3322 LONG oldval;
3323
3324 switch(index) {
3325 case GWL_EXSTYLE:
3326 {
3327 STYLESTRUCT ss;
3328
3329 if(dwExStyle == value) {
3330 oldval = value;
3331 break;
3332 }
3333 ss.styleOld = dwExStyle;
3334 ss.styleNew = value;
3335 dprintf(("SetWindowLong GWL_EXSTYLE %x old %x new style %x", getWindowHandle(), dwExStyle, value));
3336 SendInternalMessageA(WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
3337 setExStyle(ss.styleNew);
3338 SendInternalMessageA(WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
3339 oldval = ss.styleOld;
3340 break;
3341 }
3342 case GWL_STYLE:
3343 {
3344 STYLESTRUCT ss;
3345
3346 //SvL: TODO: Can you change minimize or maximize status here too?
3347
3348 if(dwStyle == value) {
3349 oldval = value;
3350 break;
3351 }
3352 value &= ~(WS_CHILD|WS_VISIBLE); /* Some bits can't be changed this way (WINE) */
3353 ss.styleOld = getStyle();
3354 ss.styleNew = value | (ss.styleOld & (WS_CHILD|WS_VISIBLE));
3355 dprintf(("SetWindowLong GWL_STYLE %x old %x new style %x", getWindowHandle(), ss.styleOld, ss.styleNew));
3356 SendInternalMessageA(WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
3357 setStyle(ss.styleNew);
3358 SendInternalMessageA(WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
3359 OSLibSetWindowStyle(getOS2FrameWindowHandle(), getOS2WindowHandle(), getStyle(), getExStyle());
3360#ifdef DEBUG
3361 PrintWindowStyle(ss.styleNew, 0);
3362#endif
3363 oldval = ss.styleOld;
3364 break;
3365 }
3366 case GWL_WNDPROC:
3367 {
3368 //Note: Type of SetWindowLong determines new window proc type
3369 // UNLESS the new window proc has already been registered
3370 // (use the old type in that case)
3371 // (VERIFIED in NT 4, SP6)
3372 WINDOWPROCTYPE type = WINPROC_GetProcType((HWINDOWPROC)value);
3373 if(type == WIN_PROC_INVALID) {
3374 type = (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A;
3375 }
3376 oldval = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3377 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, type, WIN_PROC_WINDOW);
3378 break;
3379 }
3380 case GWL_HINSTANCE:
3381 oldval = hInstance;
3382 hInstance = value;
3383 break;
3384
3385 case GWL_HWNDPARENT:
3386 oldval = SetParent((HWND)value);
3387 break;
3388
3389 case GWL_ID:
3390 oldval = getWindowId();
3391 setWindowId(value);
3392 break;
3393
3394 case GWL_USERDATA:
3395 oldval = userData;
3396 userData = value;
3397 break;
3398
3399 default:
3400 if(index >= 0 && index + sizeof(ULONG) <= nrUserWindowBytes)
3401 {
3402 oldval = *(ULONG *)(userWindowBytes + index);
3403 *(ULONG *)(userWindowBytes + index) = value;
3404 break;
3405 }
3406 dprintf(("WARNING: SetWindowLong%c %x %d %x returned %x INVALID index!", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
3407 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
3408 return 0;
3409 }
3410 //Note: NT4, SP6 does not set the last error to 0
3411 SetLastError(ERROR_SUCCESS);
3412 dprintf2(("SetWindowLong%c %x %d %x returned %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value, oldval));
3413 return oldval;
3414}
3415//******************************************************************************
3416//******************************************************************************
3417ULONG Win32BaseWindow::GetWindowLongA(int index, BOOL fUnicode)
3418{
3419 ULONG value;
3420
3421 switch(index) {
3422 case GWL_EXSTYLE:
3423 value = dwExStyle;
3424 break;
3425 case GWL_STYLE:
3426 value = dwStyle;
3427 break;
3428 case GWL_WNDPROC:
3429 value = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3430 break;
3431 case GWL_HINSTANCE:
3432 value = hInstance;
3433 break;
3434 case GWL_HWNDPARENT:
3435 value = GetParent();
3436 break;
3437 case GWL_ID:
3438 value = getWindowId();
3439 break;
3440 case GWL_USERDATA:
3441 value = userData;
3442 break;
3443 default:
3444 if(index >= 0 && index + sizeof(ULONG) <= nrUserWindowBytes)
3445 {
3446 value = *(ULONG *)(userWindowBytes + index);
3447 break;
3448 }
3449 dprintf(("WARNING: GetWindowLong%c %x %d %x returned %x INVALID index!", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
3450 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
3451 return 0;
3452 }
3453 dprintf2(("GetWindowLong%c %x %d %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
3454 //Note: NT4, SP6 does not set the last error to 0
3455 SetLastError(ERROR_SUCCESS);
3456 return value;
3457}
3458//******************************************************************************
3459//******************************************************************************
3460WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
3461{
3462 WORD oldval;
3463
3464 if(index >= 0 && index + sizeof(WORD) <= nrUserWindowBytes)
3465 {
3466 oldval = *(WORD *)(userWindowBytes + index);
3467 *(WORD *)(userWindowBytes + index) = value;
3468 //Note: NT4, SP6 does not set the last error to 0
3469 dprintf2(("SetWindowWord %x %d %x returned %x", getWindowHandle(), index, value, oldval));
3470 SetLastError(ERROR_SUCCESS);
3471 return oldval;
3472 }
3473 dprintf(("WARNING: SetWindowWord %x %d %x returned %x INVALID index!", getWindowHandle(), index, value));
3474 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
3475 return 0;
3476}
3477//******************************************************************************
3478//******************************************************************************
3479WORD Win32BaseWindow::GetWindowWord(int index)
3480{
3481 if(index >= 0 && index + sizeof(WORD) <= nrUserWindowBytes)
3482 {
3483 //Note: NT4, SP6 does not set the last error to 0
3484 SetLastError(ERROR_SUCCESS);
3485 dprintf2(("GetWindowWord %x %d %x", getWindowHandle(), index, *(WORD *)(userWindowBytes + index)));
3486 return *(WORD *)(userWindowBytes + index);
3487 }
3488 dprintf(("WARNING: GetWindowWord %x %d returned %x INVALID index!", getWindowHandle(), index));
3489 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
3490 return 0;
3491}
3492//******************************************************************************
3493//******************************************************************************
3494void Win32BaseWindow::setWindowId(DWORD id)
3495{
3496 dwIDMenu = id;
3497}
3498//******************************************************************************
3499//******************************************************************************
3500Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
3501{
3502 Win32BaseWindow *window;
3503
3504 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
3505 return window;
3506 }
3507// dprintf2(("Win32BaseWindow::GetWindowFromHandle: not a win32 window %x", hwnd));
3508 return NULL;
3509}
3510//******************************************************************************
3511//******************************************************************************
3512Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
3513{
3514 Win32BaseWindow *win32wnd;
3515 DWORD magic;
3516
3517 if(hwnd == OSLIB_HWND_DESKTOP)
3518 {
3519 return windowDesktop;
3520 }
3521
3522 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
3523 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
3524
3525 if(win32wnd && CheckMagicDword(magic)) {
3526 return win32wnd;
3527 }
3528// dprintf2(("Win32BaseWindow::GetWindowFromOS2Handle: not an Odin os2 window %x", hwnd));
3529 return 0;
3530}
3531//******************************************************************************
3532//******************************************************************************
3533Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
3534{
3535 return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
3536}
3537//******************************************************************************
3538//******************************************************************************
3539HWND Win32BaseWindow::getNextDlgGroupItem(HWND hwndCtrl, BOOL fPrevious)
3540{
3541 Win32BaseWindow *child, *nextchild, *lastchild;
3542 HWND retvalue;
3543
3544 if (hwndCtrl)
3545 {
3546 child = GetWindowFromHandle(hwndCtrl);
3547 if (!child)
3548 {
3549 retvalue = 0;
3550 goto END;
3551 }
3552 /* Make sure hwndCtrl is a top-level child */
3553 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
3554 {
3555 child = child->getParent();
3556 if(child == NULL) break;
3557 }
3558
3559 if (!child || (child->getParent() != this))
3560 {
3561 retvalue = 0;
3562 goto END;
3563 }
3564 }
3565 else
3566 {
3567 /* No ctrl specified -> start from the beginning */
3568 child = (Win32BaseWindow *)getFirstChild();
3569 if (!child)
3570 {
3571 retvalue = 0;
3572 goto END;
3573 }
3574
3575 if (fPrevious)
3576 {
3577 while (child->getNextChild())
3578 {
3579 child = (Win32BaseWindow *)child->getNextChild();
3580 }
3581 }
3582 }
3583
3584 lastchild = child;
3585 nextchild = (Win32BaseWindow *)child->getNextChild();
3586 while (TRUE)
3587 {
3588 if (!nextchild || (nextchild->getStyle() & WS_GROUP))
3589 {
3590 /* Wrap-around to the beginning of the group */
3591 Win32BaseWindow *pWndTemp;
3592
3593 nextchild = (Win32BaseWindow *)getFirstChild();
3594
3595 for(pWndTemp = nextchild;pWndTemp;pWndTemp = (Win32BaseWindow *)pWndTemp->getNextChild())
3596 {
3597 if (pWndTemp->getStyle() & WS_GROUP)
3598 nextchild = pWndTemp;
3599
3600 if (pWndTemp == child)
3601 break;
3602 }
3603
3604 }
3605 if (nextchild == child)
3606 break;
3607
3608 if ((nextchild->getStyle() & WS_VISIBLE) && !(nextchild->getStyle() & WS_DISABLED))
3609 {
3610 lastchild = nextchild;
3611
3612 if (!fPrevious)
3613 break;
3614 }
3615
3616 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
3617 }
3618 retvalue = lastchild->getWindowHandle();
3619END:
3620 return retvalue;
3621}
3622//******************************************************************************
3623//******************************************************************************
3624#ifdef DEBUG
3625void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle)
3626{
3627 char style[256] = "";
3628 char exstyle[256] = "";
3629
3630 /* Window styles */
3631 if(dwStyle & WS_CHILD)
3632 strcat(style, "WS_CHILD ");
3633 if(dwStyle & WS_POPUP)
3634 strcat(style, "WS_POPUP ");
3635 if(dwStyle & WS_VISIBLE)
3636 strcat(style, "WS_VISIBLE ");
3637 if(dwStyle & WS_DISABLED)
3638 strcat(style, "WS_DISABLED ");
3639 if(dwStyle & WS_CLIPSIBLINGS)
3640 strcat(style, "WS_CLIPSIBLINGS ");
3641 if(dwStyle & WS_CLIPCHILDREN)
3642 strcat(style, "WS_CLIPCHILDREN ");
3643 if(dwStyle & WS_MAXIMIZE)
3644 strcat(style, "WS_MAXIMIZE ");
3645 if(dwStyle & WS_MINIMIZE)
3646 strcat(style, "WS_MINIMIZE ");
3647 if(dwStyle & WS_GROUP)
3648 strcat(style, "WS_GROUP ");
3649 if(dwStyle & WS_TABSTOP)
3650 strcat(style, "WS_TABSTOP ");
3651
3652 if((dwStyle & WS_CAPTION) == WS_CAPTION)
3653 strcat(style, "WS_CAPTION ");
3654 if(dwStyle & WS_DLGFRAME)
3655 strcat(style, "WS_DLGFRAME ");
3656 if(dwStyle & WS_BORDER)
3657 strcat(style, "WS_BORDER ");
3658
3659 if(dwStyle & WS_VSCROLL)
3660 strcat(style, "WS_VSCROLL ");
3661 if(dwStyle & WS_HSCROLL)
3662 strcat(style, "WS_HSCROLL ");
3663 if(dwStyle & WS_SYSMENU)
3664 strcat(style, "WS_SYSMENU ");
3665 if(dwStyle & WS_THICKFRAME)
3666 strcat(style, "WS_THICKFRAME ");
3667 if(dwStyle & WS_MINIMIZEBOX)
3668 strcat(style, "WS_MINIMIZEBOX ");
3669 if(dwStyle & WS_MAXIMIZEBOX)
3670 strcat(style, "WS_MAXIMIZEBOX ");
3671
3672 if(dwExStyle & WS_EX_DLGMODALFRAME)
3673 strcat(exstyle, "WS_EX_DLGMODALFRAME ");
3674 if(dwExStyle & WS_EX_ACCEPTFILES)
3675 strcat(exstyle, "WS_EX_ACCEPTFILES ");
3676 if(dwExStyle & WS_EX_NOPARENTNOTIFY)
3677 strcat(exstyle, "WS_EX_NOPARENTNOTIFY ");
3678 if(dwExStyle & WS_EX_TOPMOST)
3679 strcat(exstyle, "WS_EX_TOPMOST ");
3680 if(dwExStyle & WS_EX_TRANSPARENT)
3681 strcat(exstyle, "WS_EX_TRANSPARENT ");
3682
3683 if(dwExStyle & WS_EX_MDICHILD)
3684 strcat(exstyle, "WS_EX_MDICHILD ");
3685 if(dwExStyle & WS_EX_TOOLWINDOW)
3686 strcat(exstyle, "WS_EX_TOOLWINDOW ");
3687 if(dwExStyle & WS_EX_WINDOWEDGE)
3688 strcat(exstyle, "WS_EX_WINDOWEDGE ");
3689 if(dwExStyle & WS_EX_CLIENTEDGE)
3690 strcat(exstyle, "WS_EX_CLIENTEDGE ");
3691 if(dwExStyle & WS_EX_CONTEXTHELP)
3692 strcat(exstyle, "WS_EX_CONTEXTHELP ");
3693 if(dwExStyle & WS_EX_RIGHT)
3694 strcat(exstyle, "WS_EX_RIGHT ");
3695 if(dwExStyle & WS_EX_LEFT)
3696 strcat(exstyle, "WS_EX_LEFT ");
3697 if(dwExStyle & WS_EX_RTLREADING)
3698 strcat(exstyle, "WS_EX_RTLREADING ");
3699 if(dwExStyle & WS_EX_LTRREADING)
3700 strcat(exstyle, "WS_EX_LTRREADING ");
3701 if(dwExStyle & WS_EX_LEFTSCROLLBAR)
3702 strcat(exstyle, "WS_EX_LEFTSCROLLBAR ");
3703 if(dwExStyle & WS_EX_RIGHTSCROLLBAR)
3704 strcat(exstyle, "WS_EX_RIGHTSCROLLBAR ");
3705 if(dwExStyle & WS_EX_CONTROLPARENT)
3706 strcat(exstyle, "WS_EX_CONTROLPARENT ");
3707 if(dwExStyle & WS_EX_STATICEDGE)
3708 strcat(exstyle, "WS_EX_STATICEDGE ");
3709 if(dwExStyle & WS_EX_APPWINDOW)
3710 strcat(exstyle, "WS_EX_APPWINDOW ");
3711
3712 dprintf(("Window style: %x %s", dwStyle, style));
3713 dprintf(("Window exStyle: %x %s", dwExStyle, exstyle));
3714}
3715#endif
3716//******************************************************************************
3717//******************************************************************************
3718HWND WIN32API Win32ToOS2Handle(HWND hwnd)
3719{
3720 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
3721
3722 if(window) {
3723 return window->getOS2WindowHandle();
3724 }
3725// dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
3726 return hwnd;
3727}
3728//******************************************************************************
3729//******************************************************************************
3730HWND WIN32API OS2ToWin32Handle(HWND hwnd)
3731{
3732 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
3733
3734 if(window) {
3735 return window->getWindowHandle();
3736 }
3737 window = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwnd);
3738 if(window) {
3739 return window->getWindowHandle();
3740 }
3741
3742// dprintf2(("Win32BaseWindow::OS2ToWin32Handle: not a win32 window %x", hwnd));
3743 return 0;
3744// else return hwnd; //OS/2 window handle
3745}
3746//******************************************************************************
3747//******************************************************************************
3748
3749GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.