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

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

bugfixes + os/2 look support added

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