source: trunk/src/user32/win32wbase.cpp

Last change on this file was 22135, checked in by dmik, 8 years ago

user32: Make r22134 actually work.

It would not due to using a virtual function from the base destructor
(which always calls the base version instead of the derived).

File size: 151.9 KB
RevLine 
[10607]1/* $Id: win32wbase.cpp,v 1.390 2004-05-24 09:02:00 sandervl Exp $ */
[2469]2/*
3 * Win32 Window Base Class for OS/2
4 *
[7762]5 * Copyright 1998-2002 Sander van Leeuwen (sandervl@xs4all.nl)
[2469]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)
[2852]10 * Corel version: corel20000212
[2469]11 *
12 * Copyright 1993, 1994, 1996 Alexandre Julliard
13 * 1995 Alex Korobka
14 *
15 * TODO: Not thread/process safe
16 *
[5935]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 *
[3662]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)
[2469]27 *
[6169]28 * NOTE: Status of window:
29 * Before a window has processed WM_NCCREATE:
30 * - GetTopWindow can't return that window handle
31 * - GetWindow(parent, GW_CHILD) can't return that window handle
32 * - IsChild works
33 * TODO: Does this affect more functions?? (other GetWindow ops)
34 * (verified in NT4, SP6)
35 *
[2469]36 * Project Odin Software License can be found in LICENSE.TXT
37 *
38 */
39#include <os2win.h>
40#include <win.h>
41#include <stdlib.h>
42#include <string.h>
43#include <stdarg.h>
44#include <assert.h>
45#include <misc.h>
46#include <heapstring.h>
[4848]47#include <winuser32.h>
[8132]48#include <custombuild.h>
[4848]49#include "win32wbase.h"
[10033]50#include "win32wfake.h"
[2469]51#include "wndmsg.h"
52#include "oslibwin.h"
53#include "oslibmsg.h"
54#include "oslibutil.h"
55#include "oslibgdi.h"
56#include "oslibres.h"
57#include "oslibdos.h"
58#include "syscolor.h"
59#include "win32wndhandle.h"
60#include "dc.h"
61#include "win32wdesktop.h"
62#include "pmwindow.h"
63#include "controls.h"
64#include <wprocess.h>
[21916]65#include <win/hook.h>
66#include "menu.h"
[2469]67#define INCL_TIMERWIN32
68#include "timer.h"
[8999]69#include "user32api.h"
[10379]70#include "callwrap.h"
[2469]71
[2834]72#define DBG_LOCALLOG DBG_win32wbase
[2803]73#include "dbglocal.h"
74
[2469]75/* bits in the dwKeyData */
76#define KEYDATA_ALT 0x2000
77#define KEYDATA_PREVSTATE 0x4000
78
79void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle);
80
[21916]81static BOOL fDestroyAll = FALSE;
[2469]82//For quick lookup of current process id
83static ULONG currentProcessId = -1;
[6783]84static int iF10Key = 0;
85static int iMenuSysKey = 0;
[2469]86
87//******************************************************************************
88//******************************************************************************
[10190]89Win32BaseWindow::Win32BaseWindow()
[5935]90 : GenericObject(&windows, &critsect), ChildWindow(&critsect)
[2469]91{
[7765]92 Init();
[2469]93}
94//******************************************************************************
95//******************************************************************************
96Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
[5935]97 : GenericObject(&windows, &critsect), ChildWindow(&critsect)
[2469]98{
[7765]99 Init();
100 this->isUnicode = isUnicode;
[8942]101 // call member function
[7765]102 CreateWindowExA(lpCreateStructA, classAtom);
[2469]103}
104//******************************************************************************
105//******************************************************************************
106void Win32BaseWindow::Init()
107{
108 isUnicode = FALSE;
109 fFirstShow = TRUE;
110 fIsDialog = FALSE;
111 fIsModalDialogOwner = FALSE;
112 OS2HwndModalDialog = 0;
[6166]113 fParentChange = FALSE;
[2469]114 fDestroyWindowCalled = FALSE;
[9101]115 fChildDestructionInProgress = FALSE;
[2469]116 fTaskList = FALSE;
117 fParentDC = FALSE;
[3365]118 fComingToTop = FALSE;
[5258]119 fMinMaxChange = FALSE;
[10316]120 fPMUpdateRegionChanged = FALSE;
[5685]121 fEraseBkgndFlag = TRUE;
[8553]122 fIsDragDropActive= FALSE;
[9933]123 fDirtyUpdateRegion = FALSE;
[9953]124 fWindowLocked = FALSE;
[22135]125 fFakeWindow = FALSE;
[2469]126
[6169]127 state = STATE_INIT;
[2469]128 windowNameA = NULL;
129 windowNameW = NULL;
[10190]130 windowNameLengthA = 0;
131 windowNameLengthW = 0;
132
[5242]133 userWindowBytes = NULL;;
134 nrUserWindowBytes= 0;
[2469]135
136 OS2Hwnd = 0;
[5685]137 OS2HwndFrame = 0;
[2469]138 hSysMenu = 0;
139 Win32Hwnd = 0;
140
[8942]141 // allocate a Win32 HWND, return it in Win32Hwnd and associate object
142 // pointer with it
[2469]143 if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
144 {
145 dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
146 DebugInt3();
147 }
[10379]148 Win32HwndOrg = Win32Hwnd;
[2469]149
150 posx = posy = 0;
151 width = height = 0;
152
153 dwExStyle = 0;
154 dwStyle = 0;
[6008]155 dwOldStyle = 0;
[2469]156 win32wndproc = 0;
157 hInstance = 0;
[2489]158 dwIDMenu = 0; //0xFFFFFFFF; //default -1
[2469]159 userData = 0;
160 contextHelpId = 0;
[2666]161 hotkey = 0;
[2469]162
163 hwndLinkAfter = HWND_BOTTOM;
164 flags = 0;
[7801]165 lastHitTestVal = HTCLIENT;
[2469]166 owner = NULL;
167 windowClass = 0;
168
[6762]169 hIcon = 0;
170 hIconSm = 0;
[2469]171
[6762]172 horzScrollInfo = NULL;
173 vertScrollInfo = NULL;
[2469]174
[6762]175 propertyList = NULL;
[3493]176
[6762]177 cbExtra = 0;
178 pExtra = NULL;
179
[2469]180 ownDC = 0;
181 hWindowRegion = 0;
[2672]182 hClipRegion = 0;
[10316]183 hVisRegion = 0;
[9933]184 hUpdateRegion = 0;
[2469]185
[3610]186 hTaskList = 0;
187
[2469]188 if(currentProcessId == -1)
189 {
190 currentProcessId = GetCurrentProcessId();
191 }
192 dwThreadId = GetCurrentThreadId();
193 dwProcessId = currentProcessId;
[3662]194
195 memset(&windowpos, 0, sizeof(windowpos));
[4497]196 //min and max position are initially -1 (verified in NT4, SP6)
197 windowpos.ptMinPosition.x = -1;
198 windowpos.ptMinPosition.y = -1;
199 windowpos.ptMaxPosition.x = -1;
200 windowpos.ptMaxPosition.y = -1;
[6902]201
202 lpVisRgnNotifyProc = NULL;
203 dwVisRgnNotifyParam = NULL;
[9930]204
205 pfnOldPMWndProc = NULL;
[10060]206
207 memset(hdcWindow, 0, sizeof(hdcWindow));
208 nrOpenDCs = 0;
[2469]209}
210//******************************************************************************
211//todo get rid of resources (menu, icon etc)
212//******************************************************************************
213Win32BaseWindow::~Win32BaseWindow()
214{
[5935]215 if(getRefCount() < 0) {
216 DebugInt3();
217 }
218
[3610]219 if(hTaskList) {
[4515]220 OSLibWinRemoveFromTasklist(hTaskList);
[3610]221 }
222
[22135]223 if (!isFakeWindow()) {
[22134]224 OSLibWinSetVisibleRegionNotify(OS2Hwnd, FALSE);
225 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
226 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
227 }
[2469]228
229 if(fDestroyAll) {
230 dprintf(("Destroying window %x %s", getWindowHandle(), windowNameA));
231 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
232 }
[5964]233 else
234 if(getParent() && getParent()->getFirstChild() == this && getNextChild() == NULL)
235 {
236 //if we're the last child that's being destroyed and our
[10190]237 //parent window was also destroyed, then we
[5964]238 if(getParent()->IsWindowDestroyed())
239 {
[7890]240 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
241 RELEASE_WNDOBJ(wndparent);
[5964]242 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
243 }
244 }
[10190]245 else
[7890]246 {
247 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
248 if(wndparent && !fDestroyAll) {
249 RELEASE_WNDOBJ(wndparent);
250 }
251 }
252 if(owner && !fDestroyAll) {
253 RELEASE_WNDOBJ(owner);
254 }
255
[10396]256 // Decrement class window counter
[10379]257 // NOTE: Must be done before ReleaseDC call for ownDC!
[4825]258 if(windowClass) {
[5935]259 RELEASE_CLASSOBJ(windowClass);
[4825]260 }
261
[10379]262 if(ownDC)
263 ReleaseDC(Win32HwndOrg, ownDC);
[2663]264
[2469]265 if(Win32Hwnd)
266 HwFreeWindowHandle(Win32Hwnd);
267
[5242]268 if(userWindowBytes)
269 free(userWindowBytes);
[2663]270
[2469]271 if(windowNameA) {
272 free(windowNameA);
273 windowNameA = NULL;
274 }
275 if(windowNameW) {
276 free(windowNameW);
277 windowNameW = NULL;
278 }
279 if(vertScrollInfo) {
280 free(vertScrollInfo);
281 vertScrollInfo = NULL;
282 }
283 if(horzScrollInfo) {
284 free(horzScrollInfo);
285 horzScrollInfo = NULL;
286 }
[3493]287 if(propertyList) {
[3584]288 removeWindowProps();
[3493]289 }
[9933]290 if(hUpdateRegion) {
291 DeleteObject(hUpdateRegion);
292 hUpdateRegion = NULL;
293 }
[2469]294}
295//******************************************************************************
296//******************************************************************************
297void Win32BaseWindow::DestroyAll()
298{
299 fDestroyAll = TRUE;
300 GenericObject::DestroyAll(windows);
301}
302//******************************************************************************
303//******************************************************************************
304BOOL Win32BaseWindow::isChild()
305{
306 return ((dwStyle & WS_CHILD) != 0);
307}
308//******************************************************************************
309//******************************************************************************
310BOOL Win32BaseWindow::IsWindowUnicode()
311{
[21916]312 dprintf2(("IsWindowUnicode %x %d", getWindowHandle(),
313 WINPROC_GetProcType((HWINDOWPROC)getWindowProc()) == WIN_PROC_32W));
314 return (WINPROC_GetProcType((HWINDOWPROC)getWindowProc()) == WIN_PROC_32W);
[2469]315}
316//******************************************************************************
317//******************************************************************************
318BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
319{
320 char buffer[256];
[2672]321
322#ifdef DEBUG
323 PrintWindowStyle(cs->style, cs->dwExStyle);
324#endif
325
[3610]326 //If window has no owner/parent window, then it will be added to the tasklist
327 //(depending on visibility state)
328 if (!cs->hwndParent) fTaskList = TRUE;
329
[2672]330 sw = SW_SHOW;
331 SetLastError(0);
332
333 /* Find the parent window */
334 if (cs->hwndParent)
335 {
336 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
337 if(!window) {
338 dprintf(("Bad parent %04x\n", cs->hwndParent ));
339 SetLastError(ERROR_INVALID_PARAMETER);
340 return FALSE;
341 }
342 /* Make sure parent is valid */
[21641]343 if (!window->IsWindow() )
[2672]344 {
[5935]345 RELEASE_WNDOBJ(window);
[2672]346 dprintf(("Bad parent %04x\n", cs->hwndParent ));
347 SetLastError(ERROR_INVALID_PARAMETER);
348 return FALSE;
349 }
[9143]350 if (window->getExStyle() & WS_EX_TOPMOST)
[10190]351 cs->dwExStyle |= WS_EX_TOPMOST;
[9143]352
[5935]353 RELEASE_WNDOBJ(window);
[3153]354 /* Windows does this for overlapped windows
355 * (I don't know about other styles.) */
356 if (cs->hwndParent == GetDesktopWindow() && (!(cs->style & WS_CHILD) || (cs->style & WS_POPUP)))
357 {
[3284]358 cs->hwndParent = 0;
[3153]359 }
[2672]360 }
361 else
362 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
[5429]363 dprintf(("No parent for child window" ));
[2672]364 SetLastError(ERROR_INVALID_PARAMETER);
365 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
366 }
367
[4825]368 /* Find the window class */
369 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
370 if (!windowClass)
371 {
[2672]372 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
[5429]373 dprintf(("Bad class '%s'", buffer ));
[2672]374 SetLastError(ERROR_INVALID_PARAMETER);
375 return 0;
[4825]376 }
377
[2672]378#ifdef DEBUG
[4825]379 if(HIWORD(cs->lpszClass))
380 {
[5429]381 if(isUnicode) dprintf(("Window class %ls", cs->lpszClass));
382 else dprintf(("Window class %s", cs->lpszClass));
[4825]383 }
384 else dprintf(("Window class %x", cs->lpszClass));
[2672]385#endif
386
[4825]387 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
388 * with an atom as the class name, put some programs expect to have a *REAL* string in
389 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
390 */
391 if (!HIWORD(cs->lpszClass) ) {
[2672]392 if (isUnicode) {
393 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
394 }
395 else {
396 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
397 }
398 cs->lpszClass = buffer;
[4825]399 }
400 /* Fix the coordinates */
401 fXDefault = FALSE;
402 fCXDefault = FALSE;
[10091]403 FixCoordinates(cs, &sw);
[2672]404
[7708]405 /* Correct the window style - stage 1
406 *
407 * These are patches that appear to affect both the style loaded into the
408 * WIN structure and passed in the CreateStruct to the WM_CREATE etc.
409 *
410 * WS_EX_WINDOWEDGE appears to be enforced based on the other styles, so
411 * why does the user get to set it?
412 */
413
414 /* This has been tested for WS_CHILD | WS_VISIBLE. It has not been
415 * tested for WS_POPUP
416 */
417 if ((cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
418 ((!(cs->dwExStyle & WS_EX_STATICEDGE)) &&
419 (cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
420 cs->dwExStyle |= WS_EX_WINDOWEDGE;
421 else
422 cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
423
[4825]424 //Allocate window words
[5242]425 nrUserWindowBytes = windowClass->getExtraWndBytes();
426 if(nrUserWindowBytes) {
427 userWindowBytes = (char *)_smalloc(nrUserWindowBytes);
428 memset(userWindowBytes, 0, nrUserWindowBytes);
[4825]429 }
[2672]430
[8945]431 // check if it's the standard child window case
[4825]432 if ((cs->style & WS_CHILD) && cs->hwndParent)
433 {
[2672]434 SetParent(cs->hwndParent);
[8945]435 owner = NULL;
[2680]436 //SvL: Shell positioning shouldn't be done for child windows! (breaks Notes)
437 fXDefault = fCXDefault = FALSE;
[4825]438 }
439 else
440 {
[8945]441 // either no child window or a popup window
442
[2672]443 SetParent(0);
444 if (!cs->hwndParent || (cs->hwndParent == windowDesktop->getWindowHandle())) {
445 owner = NULL;
446 }
447 else
448 {
[8945]449 // we're a popup window
450
451 Win32BaseWindow *wndparent = GetWindowFromHandle(cs->hwndParent);
[5964]452 if(wndparent) {
453 owner = GetWindowFromHandle(wndparent->GetTopParent());
454 RELEASE_WNDOBJ(wndparent);
455 }
[10190]456 else owner = NULL;
[5964]457
[2672]458 if(owner == NULL)
459 {
460 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
461 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
462 return FALSE;
463 }
464 }
[4825]465 }
[2672]466
[21916]467 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc,
468 windowClass->getWindowProc((isUnicode) ? WNDPROC_UNICODE : WNDPROC_ASCII),
469 WINPROC_GetProcType((HWINDOWPROC)windowClass->getWindowProc((isUnicode) ? WNDPROC_UNICODE : WNDPROC_ASCII)),
470 WIN_PROC_WINDOW);
[6008]471 hInstance = cs->hInstance;
472 dwStyle = cs->style & ~WS_VISIBLE;
473 dwOldStyle = dwStyle;
474 dwExStyle = cs->dwExStyle;
[2672]475
[4825]476 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
[2672]477
[7708]478 /* Correct the window style phase 2 */
[4825]479 if (!(cs->style & WS_CHILD))
480 {
[2672]481 dwStyle |= WS_CLIPSIBLINGS;
482 if (!(cs->style & WS_POPUP))
483 {
484 dwStyle |= WS_CAPTION;
485 flags |= WIN_NEED_SIZE;
486 }
487 }
488
[7525]489 //WinZip 8.0 crashes when a dialog created after opening a zipfile receives
490 //the WM_SIZE message (before WM_INITDIALOG)
491 //Opera doesn't like this either.
492 if(IsDialog()) {
493 flags |= WIN_NEED_SIZE;
494 }
495
[4825]496 //copy pointer of CREATESTRUCT for usage in MsgCreate method
497 tmpcs = cs;
[2672]498
[4825]499 //Store our window object pointer in thread local memory, so PMWINDOW.CPP can retrieve it
500 TEB *teb = GetThreadTEB();
501 if(teb == NULL) {
[4658]502 dprintf(("Window creation failed - teb == NULL")); //this is VERY bad
[2672]503 ExitProcess(666);
504 return FALSE;
[4825]505 }
506 teb->o.odin.newWindow = (ULONG)this;
[2672]507
[5951]508 DWORD dwOSWinStyle, dwOSFrameStyle;
509 OSLibWinConvertStyle(dwStyle,dwExStyle,&dwOSWinStyle, &dwOSFrameStyle);
[2677]510
[8945]511 // create PM windows - frame and client window
512 HWND hwndOS2Frame = (getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP;
513 OS2Hwnd = OSLibWinCreateWindow(hwndOS2Frame,
514 dwOSWinStyle,
515 dwOSFrameStyle,
516 (char *)windowNameA,
[10275]517 (owner) ? owner->getOS2WindowHandle() : 0,
[4825]518 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
[8945]519 0,
520 fTaskList,
521 fXDefault | fCXDefault,
522 windowClass->getStyle(),
523 &OS2HwndFrame);
[4825]524 if(OS2Hwnd == 0) {
[3853]525 dprintf(("Window creation failed!! OS LastError %0x", OSLibWinGetLastError()));
[2672]526 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
527 return FALSE;
[4825]528 }
529 OSLibWinSetVisibleRegionNotify(OS2Hwnd, TRUE);
[6169]530 state = STATE_CREATED;
[4825]531 SetLastError(0);
532 return TRUE;
[2672]533}
[2677]534//******************************************************************************
535//******************************************************************************
[3662]536BOOL Win32BaseWindow::MsgCreate(HWND hwndOS2)
[2672]537{
[5173]538 CREATESTRUCTA *cs = tmpcs; //pointer to CREATESTRUCT used in CreateWindowExA method
539 POINT maxSize, maxPos, minTrack, maxTrack;
540 HWND hwnd = getWindowHandle();
[5429]541 LRESULT (* CALLBACK localSend32)(HWND, UINT, WPARAM, LPARAM);
[2469]542
[4825]543 OS2Hwnd = hwndOS2;
[2469]544
[5935]545 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, getWindowHandle()) == FALSE) {
[2677]546 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
547 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
[2469]548 return FALSE;
[4825]549 }
550 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
[2677]551 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
[2469]552 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
553 return FALSE;
[4825]554 }
[5146]555 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32FLAGS, 0) == FALSE) {
556 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
557 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
558 return FALSE;
559 }
[2469]560
[4825]561 if (HOOK_IsHooked( WH_CBT ))
562 {
563 CBT_CREATEWNDA cbtc;
564 LRESULT ret;
565
566 cbtc.lpcs = cs;
567 cbtc.hwndInsertAfter = hwndLinkAfter;
568 ret = (isUnicode) ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc)
569 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc);
570 if(ret)
571 {
[8132]572 dprintf(("CBT-hook returned non-0 !!"));
[4825]573 SetLastError(ERROR_CAN_NOT_COMPLETE); //todo: wrong error
574 return FALSE;
575 }
576 //todo: if hook changes parent, we need to do so too!!!!!!!!!!
577 }
578
579 if (cs->style & WS_HSCROLL)
580 {
581 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
582 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
583 horzScrollInfo->MaxVal = 100;
584 horzScrollInfo->flags = ESB_ENABLE_BOTH;
585 }
586
587 if (cs->style & WS_VSCROLL)
588 {
589 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
590 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
591 vertScrollInfo->MaxVal = 100;
592 vertScrollInfo->flags = ESB_ENABLE_BOTH;
593 }
[10190]594
[7338]595 // initially allocate the window name fields
[4825]596 if(HIWORD(cs->lpszName))
597 {
598 if (!isUnicode)
599 {
[10190]600 windowNameLengthA = strlen(cs->lpszName);
601 windowNameA = (LPSTR)_smalloc(windowNameLengthA+1);
602 strcpy(windowNameA,cs->lpszName);
603
604 windowNameLengthW = lstrlenAtoW( windowNameA, -1 );
605 windowNameW = (LPWSTR)_smalloc(( windowNameLengthW + 1 ) * sizeof( WCHAR ) );
606 lstrcpyAtoW( windowNameW, windowNameA );
[4825]607 }
608 else
609 {
[5496]610 // Wide
[10190]611 windowNameLengthW = lstrlenW((LPWSTR)cs->lpszName);
612 windowNameW = (LPWSTR)_smalloc((windowNameLengthW+1)*sizeof(WCHAR));
613 strcpyW(windowNameW,(LPWSTR)cs->lpszName);
614
[7338]615 // windowNameW[lstrlenW((LPWSTR)cs->lpszName)] = 0; // need ?
[10190]616
[5496]617 // Ascii
[10190]618 windowNameLengthA = lstrlenWtoA( windowNameW, -1 );
619 windowNameA = (LPSTR)_smalloc( windowNameLengthA + 1 );
620 lstrcpyWtoA( windowNameA, windowNameW );
[4825]621 }
[10190]622
623 dprintf(("windowNameA 0x%lx to 0x%lx windowNameW : 0x%lx to 0x%lx",
624 windowNameA, windowNameA + windowNameLengthA,
625 windowNameW, windowNameW + windowNameLengthW ));
626
[5951]627 if(fOS2Look) {
[21544]628 OSLibWinSetTitleBarText(OS2HwndFrame, windowNameA);
[5951]629 }
[4825]630 }
631
[3462]632//SvL: This completely messes up MS Word 97 (no button bar, no menu)
633#if 0
[2666]634 //adjust CW_USEDEFAULT position
[2677]635 if (fXDefault | fCXDefault)
[2666]636 {
637 RECT rect;
638
[3462]639 //SvL: Returns invalid rectangle (not the expected shell default size)
[3662]640 OSLibWinQueryWindowRect(OS2Hwnd,&rect,RELATIVE_TO_SCREEN);
[2677]641 if (getParent()) mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2WindowHandle(),&rect);
642 if (fXDefault)
[2666]643 {
644 cs->x = rect.left;
645 cs->y = rect.top;
[2677]646 if (!fCXDefault)
647 {
648 //CB: todo: adjust pos to screen rect
649 }
[2666]650 }
[2677]651 if (fCXDefault)
[2666]652 {
653 cs->cx = rect.right-rect.left;
654 cs->cy = rect.bottom-rect.top;
655 }
656 }
[3462]657#endif
[2666]658
[4825]659 //Set icon from window or class
660 if (hIcon)
[6168]661 OSLibWinSetIcon(OS2HwndFrame,hIcon);
[4825]662 else
663 if (windowClass->getIcon())
[6168]664 OSLibWinSetIcon(OS2HwndFrame,windowClass->getIcon());
[2852]665
[4825]666 /* Get class or window DC if needed */
667 if(windowClass->getStyle() & CS_OWNDC) {
[2672]668 dprintf(("Class with CS_OWNDC style"));
[3662]669 ownDC = GetDCEx(getWindowHandle(), NULL, DCX_USESTYLE);
[4825]670 }
671 else
672 if (windowClass->getStyle() & CS_PARENTDC) {
[2672]673 fParentDC = TRUE;
674 ownDC = 0;
[4825]675 }
676 else
677 if (windowClass->getStyle() & CS_CLASSDC) {
[2672]678 dprintf(("WARNING: Class with CS_CLASSDC style!"));
[5973]679 //not a good solution, but it's a bit difficult to share a single
680 //DC among different windows... DevOpenDC apparently can't be used
681 //for window DCs and WinOpenWindowDC must be associated with a window
[10406]682 ownDC = GetDCEx(getWindowHandle(), NULL, DCX_USESTYLE);
[4825]683 }
684 /* Set the window menu */
685 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
686 {
[2469]687 if (cs->hMenu) {
688 ::SetMenu(getWindowHandle(), cs->hMenu);
689 }
690 else {
691 if (windowClass->getMenuNameA()) {
[2834]692 cs->hMenu = LoadMenuA(windowClass->getInstance(),windowClass->getMenuNameA());
693#if 0 //CB: hack for treeview test cases bug
694if (!cs->hMenu) cs->hMenu = LoadMenuA(windowClass->getInstance(),"MYAPP");
695#endif
[2469]696 if (cs->hMenu) ::SetMenu(getWindowHandle(), cs->hMenu );
697 }
698 }
[4825]699 }
700 else
701 {
[2469]702 setWindowId((DWORD)cs->hMenu);
[4825]703 }
704 hSysMenu = (dwStyle & WS_SYSMENU) ? MENU_GetSysMenu(Win32Hwnd,0):0;
[2469]705
[4825]706 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
707 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
708 {
[5215]709 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
[3462]710 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
711 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
712 if (cs->cx < minTrack.x) cs->cx = minTrack.x;
713 if (cs->cy < minTrack.y) cs->cy = minTrack.y;
[9572]714 if (cs->cx < 0) cs->cx = 0;
715 if (cs->cy < 0) cs->cy = 0;
[4825]716 }
[3462]717
[4825]718 //set client & window rectangles from CreateWindowEx CREATESTRUCT
719 rectWindow.left = cs->x;
720 rectWindow.right = cs->x+cs->cx;
721 rectWindow.top = cs->y;
722 rectWindow.bottom = cs->y+cs->cy;
723 rectClient = rectWindow;
724 OffsetRect(&rectClient, -rectClient.left, -rectClient.top);
[2469]725
[4825]726 /* Send the WM_CREATE message
727 * Perhaps we shouldn't allow width/height changes as well.
728 * See p327 in "Internals".
729 */
730 maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
[2469]731
[4825]732 if(fTaskList) {
[5685]733 hTaskList = OSLibWinAddToTaskList(OS2HwndFrame, windowNameA, (cs->style & WS_VISIBLE) ? 1 : 0);
[4825]734 }
[3610]735
[5429]736 localSend32 = (isUnicode) ? ::SendMessageW : ::SendMessageA;
737
[6169]738 state = STATE_PRE_WMNCCREATE;
[5429]739 if(localSend32(getWindowHandle(), WM_NCCREATE,0,(LPARAM)cs))
[4825]740 {
[2469]741 RECT tmpRect;
742
[3144]743 //CB: recheck flags
744 if (cs->style & (WS_POPUP | WS_CHILD))
745 {
[4515]746 fXDefault = FALSE;
747 if (fCXDefault)
748 {
749 fCXDefault = FALSE;
750 cs->cx = cs->cy = 0;
[4558]751 rectWindow.right = rectWindow.left;
752 rectWindow.bottom = rectWindow.top;
[4515]753 }
[3144]754 }
[2469]755 tmpRect = rectWindow;
[6169]756 state = STATE_POST_WMNCCREATE;
[2469]757
758 //set the window size and update the client
[9265]759 //@@PF Popup children of inactive windows can thus bring inactive window
760 //on top, this is not correct, popup windows can be on top only if their owner
[10190]761 //is in foreground, otherwise they are linked after owner.
[9265]762 if (((dwStyle & (WS_CHILD|WS_POPUP)) == WS_POPUP) && getOwner() && (getOwner()->getWindowHandle() != GetForegroundWindow()))
763 {
764 hwndLinkAfter = getOwner()->getWindowHandle();
765 }
[2469]766 SetWindowPos(hwndLinkAfter, tmpRect.left, tmpRect.top, tmpRect.right-tmpRect.left, tmpRect.bottom-tmpRect.top,SWP_NOACTIVATE | SWP_NOREDRAW | SWP_FRAMECHANGED);
[6169]767
768 state = STATE_PRE_WMCREATE;
[2469]769 if (cs->style & WS_VISIBLE) dwStyle |= WS_VISIBLE; //program could change position in WM_CREATE
[5429]770 if( (localSend32(getWindowHandle(), WM_CREATE, 0, (LPARAM)cs )) != -1 )
[2469]771 {
[6169]772 state = STATE_POST_WMCREATE;
773
[2552]774 if(!(flags & WIN_NEED_SIZE))
775 {
[7801]776 SendMessageA(getWindowHandle(), WM_SIZE, SIZE_RESTORED,
777 MAKELONG(rectClient.right-rectClient.left,
778 rectClient.bottom-rectClient.top));
[2552]779
[5173]780 if(!::IsWindow(hwnd))
781 {
782 dprintf(("Createwindow: WM_SIZE destroyed window"));
783 goto end;
784 }
[7801]785 SendMessageA(getWindowHandle(), WM_MOVE,0,MAKELONG(rectClient.left,rectClient.top));
[5173]786 if(!::IsWindow(hwnd))
787 {
788 dprintf(("Createwindow: WM_MOVE destroyed window"));
789 goto end;
790 }
[2469]791 }
[9572]792
[5074]793 if (getStyle() & (WS_MINIMIZE | WS_MAXIMIZE))
794 {
[5173]795 RECT newPos;
796 UINT swFlag = (getStyle() & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
[5074]797 setStyle(getStyle() & ~(WS_MAXIMIZE | WS_MINIMIZE));
[5173]798 MinMaximize(swFlag, &newPos);
[5074]799 swFlag = ((getStyle() & WS_CHILD) || GetActiveWindow()) ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
800 : SWP_NOZORDER | SWP_FRAMECHANGED;
801 SetWindowPos(0, newPos.left, newPos.top, newPos.right, newPos.bottom, swFlag);
[5173]802 if(!::IsWindow(hwnd))
803 {
804 dprintf(("Createwindow: min/max destroyed window"));
805 goto end;
806 }
[5074]807 }
808
[2469]809 if( (getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
810 {
811 /* Notify the parent window only */
[4194]812 if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
813 {
[7801]814 SendMessageA(getParent()->getWindowHandle(), WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, getWindowId()), (LPARAM)getWindowHandle());
[4515]815 }
[5173]816 if(!::IsWindow(hwnd))
[2469]817 {
818 dprintf(("Createwindow: WM_PARENTNOTIFY destroyed window"));
819 goto end;
820 }
821 }
822
[3679]823 if(cs->style & WS_VISIBLE) {
[4515]824 dwStyle &= ~WS_VISIBLE;
825 ShowWindow(sw);
[3679]826 }
[2469]827
828 /* Call WH_SHELL hook */
829 if (!(getStyle() & WS_CHILD) && !owner)
[3773]830 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWCREATED, getWindowHandle(), 0);
[2469]831
[8132]832 //Call custom Odin hook for window creation (for all windows)
833 HOOK_CallOdinHookA(HODIN_WINDOWCREATED, hwnd, 0);
834
[2469]835 SetLastError(0);
836 return TRUE;
837 }
[4825]838 }
839 dprintf(("Window creation FAILED (NCCREATE cancelled creation)"));
840 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
[2469]841end:
[4825]842 return FALSE;
[2469]843}
844//******************************************************************************
845//******************************************************************************
846ULONG Win32BaseWindow::MsgQuit()
847{
[7801]848 return SendMessageA(getWindowHandle(), WM_QUIT, 0, 0);
[2469]849}
850//******************************************************************************
851//******************************************************************************
852ULONG Win32BaseWindow::MsgClose()
853{
[7801]854 return SendMessageA(getWindowHandle(), WM_CLOSE,0,0);
[2469]855}
856//******************************************************************************
857//******************************************************************************
858ULONG Win32BaseWindow::MsgDestroy()
859{
860 ULONG rc;
861 Win32BaseWindow *child;
862 HWND hwnd = getWindowHandle();
863
[6169]864 state = STATE_DESTROYED;
[2469]865
866 if(fDestroyWindowCalled == FALSE)
[9101]867 {//this window was destroyed because DestroyWindow was called for its parent
[2469]868 //so: send a WM_PARENTNOTIFY now as that hasn't happened yet
869 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
870 {
[3565]871 if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
[2469]872 {
873 /* Notify the parent window only */
[7801]874 SendMessageA(getParent()->getWindowHandle(), WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
[2469]875 }
[3566]876//// else DebugInt3();
[2469]877 }
878 }
[22043]879
880 // there may be no window proc already (reset to null with SetWindowLong by
881 // the application), avoid the debug assertion
882 if (win32wndproc)
883 SendMessageA(getWindowHandle(),WM_DESTROY, 0, 0);
884
[2469]885 if(::IsWindow(hwnd) == FALSE) {
886 //object already destroyed, so return immediately
887 return 1;
888 }
889
[22043]890 if (win32wndproc)
891 SendMessageA(getWindowHandle(),WM_NCDESTROY, 0, 0);
892
[5935]893 TIMER_KillTimerFromWindow(getWindowHandle());
[2469]894
[6169]895 if(getRefCount() == 0 && getFirstChild() == NULL && state == STATE_CREATED) {
[2469]896 delete this;
897 }
[4515]898 else {
899 //make sure no message can ever arrive for this window again (PM or from other win32 windows)
[7890]900 dprintf(("Mark window %x (%x) as deleted; refcount %d", getWindowHandle(), this, getRefCount()));
[5935]901 markDeleted();
[4515]902 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
903 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
904 if(Win32Hwnd) {
905 HwFreeWindowHandle(Win32Hwnd);
906 Win32Hwnd = 0;
907 }
[10396]908 // Decrement class window counter
[10379]909 // NOTE: Must be done before ReleaseDC call for ownDC!
910 if(windowClass) {
911 RELEASE_CLASSOBJ(windowClass);
912 }
913
914 if(ownDC) {
915 ReleaseDC(Win32Hwnd, ownDC);
916 ownDC = 0;
917 }
[4515]918 }
[2469]919 return 1;
920}
921//******************************************************************************
922//******************************************************************************
923ULONG Win32BaseWindow::MsgEnable(BOOL fEnable)
924{
925 if(fEnable) {
926 dwStyle &= ~WS_DISABLED;
927 }
928 else dwStyle |= WS_DISABLED;
929
[7801]930 return SendMessageA(getWindowHandle(),WM_ENABLE, fEnable, 0);
[2469]931}
932//******************************************************************************
933//TODO: SW_PARENTCLOSING/OPENING flag (lParam)
934//******************************************************************************
935ULONG Win32BaseWindow::MsgShow(BOOL fShow)
936{
[6169]937 if(!CanReceiveSizeMsgs() || fDestroyWindowCalled) {
[2469]938 return 1;
939 }
940
941 if(fShow) {
[5236]942 setStyle(getStyle() | WS_VISIBLE);
943 if(getStyle() & WS_MINIMIZE) {
944 return ShowWindow(SW_RESTORE);
945 }
[2469]946 }
[5236]947 else setStyle(getStyle() & ~WS_VISIBLE);
[2469]948
[5685]949 //already sent from ShowWindow
[7801]950//// return SendMessageA(getWindowHandle(),WM_SHOWWINDOW, fShow, 0);
[5685]951 return 0;
[2469]952}
953//******************************************************************************
954//******************************************************************************
955ULONG Win32BaseWindow::MsgPosChanging(LPARAM lp)
956{
957 //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
958 // a WM_WINDOWPOSCHANGED msg -> crash)
[6169]959 if(!CanReceiveSizeMsgs() || fDestroyWindowCalled)
[2521]960 return 0;
[2469]961
[7801]962 return SendMessageA(getWindowHandle(),WM_WINDOWPOSCHANGING, 0, lp);
[2469]963}
964//******************************************************************************
965//******************************************************************************
966ULONG Win32BaseWindow::MsgPosChanged(LPARAM lp)
967{
968 //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
969 // a WM_WINDOWPOSCHANGED msg -> crash)
[6173]970 if(!CanReceiveSizeMsgs() || fDestroyWindowCalled)
[2469]971 return 1;
972
[7801]973 return SendMessageA(getWindowHandle(),WM_WINDOWPOSCHANGED, 0, lp);
[2469]974}
975//******************************************************************************
976//******************************************************************************
977ULONG Win32BaseWindow::MsgScroll(ULONG msg, ULONG scrollCode, ULONG scrollPos)
978{
979 //According to the SDK docs, the scrollbar handle (lParam) is 0 when the standard
980 //window scrollbars send these messages
[7801]981 return SendMessageA(getWindowHandle(),msg, MAKELONG(scrollCode, scrollPos), 0);
[2469]982}
983//******************************************************************************
984//******************************************************************************
985ULONG Win32BaseWindow::MsgActivate(BOOL fActivate, BOOL fMinimized, HWND hwnd, HWND hwndOS2Win)
986{
987 ULONG rc, procidhwnd = -1, threadidhwnd = 0;
988
[3501]989 //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
990 if(fDestroyWindowCalled) {
[3584]991 return 0;
[3501]992 }
[2469]993
994 //According to SDK docs, if app returns FALSE & window is being deactivated,
995 //default processing is cancelled
996 //TODO: According to Wine we should proceed anyway if window is sysmodal
[7801]997 if(SendMessageA(getWindowHandle(),WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
[2469]998 {
[5060]999 dprintf(("WARNING: WM_NCACTIVATE return code = FALSE -> cancel processing"));
[2469]1000 return 0;
1001 }
[5217]1002 /* child windows get a WM_CHILDACTIVATE message */
[2533]1003 if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
1004 {
[5217]1005 if(fActivate) {//WM_CHILDACTIVE is for activation only
[7801]1006 SendMessageA(getWindowHandle(),WM_CHILDACTIVATE, 0, 0L);
[5217]1007 }
[2533]1008 return 0;
1009 }
1010
[7801]1011 return SendMessageA(getWindowHandle(),WM_ACTIVATE, MAKELONG((fActivate) ? WA_ACTIVE : WA_INACTIVE, fMinimized), hwnd);
[2469]1012}
1013//******************************************************************************
1014//******************************************************************************
[6783]1015ULONG Win32BaseWindow::MsgChildActivate(BOOL fActivate)
1016{
1017 //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
1018 if(fDestroyWindowCalled) {
1019 return 0;
1020 }
1021
1022 //According to SDK docs, if app returns FALSE & window is being deactivated,
1023 //default processing is cancelled
1024 //TODO: According to Wine we should proceed anyway if window is sysmodal
[7801]1025 if(SendMessageA(getWindowHandle(),WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
[6783]1026 {
1027 dprintf(("WARNING: WM_NCACTIVATE return code = FALSE -> cancel processing"));
1028 return 0;
1029 }
1030 /* child windows get a WM_CHILDACTIVATE message */
1031 if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
1032 {
1033 if(fActivate) {//WM_CHILDACTIVE is for activation only
[7801]1034 SendMessageA(getWindowHandle(),WM_CHILDACTIVATE, 0, 0L);
[6783]1035 }
1036 return 0;
1037 }
1038 DebugInt3();
1039 return 0;
1040}
1041//******************************************************************************
1042//******************************************************************************
[2469]1043ULONG Win32BaseWindow::DispatchMsgA(MSG *msg)
1044{
[7801]1045 return SendMessageA(getWindowHandle(),msg->message, msg->wParam, msg->lParam);
[2469]1046}
1047//******************************************************************************
1048//******************************************************************************
1049ULONG Win32BaseWindow::DispatchMsgW(MSG *msg)
1050{
[7801]1051 return SendMessageW(getWindowHandle(), msg->message, msg->wParam, msg->lParam);
[2469]1052}
1053//******************************************************************************
1054//******************************************************************************
1055ULONG Win32BaseWindow::MsgSetFocus(HWND hwnd)
1056{
[9791]1057 //Notify that focus has changed (necessary for SetFocus(0) handling)
1058 SetFocusChanged();
1059
[3501]1060 //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
1061 if(fDestroyWindowCalled) {
[3584]1062 return 0;
[3501]1063 }
1064
[9765]1065 // if in <= 8bpp mode, then we must send a WM_QUERYNEWPALETTE message here
1066 // this gives the app the chance to realize its palette
1067 if(ScreenBitsPerPel <= 8) {
1068 SendMessageA(getWindowHandle(),WM_QUERYNEWPALETTE, 0, 0);
1069 }
[7801]1070 return SendMessageA(getWindowHandle(),WM_SETFOCUS, hwnd, 0);
[2469]1071}
1072//******************************************************************************
1073//******************************************************************************
1074ULONG Win32BaseWindow::MsgKillFocus(HWND hwnd)
1075{
[9791]1076 //Notify that focus has changed (necessary for SetFocus(0) handling)
1077 SetFocusChanged();
1078
[3501]1079 //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
1080 if(fDestroyWindowCalled) {
[3584]1081 return 0;
[3501]1082 }
[7801]1083 return SendMessageA(getWindowHandle(),WM_KILLFOCUS, hwnd, 0);
[2469]1084}
1085//******************************************************************************
1086//******************************************************************************
1087ULONG Win32BaseWindow::MsgButton(MSG *msg)
1088{
[21988]1089 BOOL eatMsg = FALSE;
1090 BOOL fClick = FALSE;
[2469]1091
[21372]1092 dprintf(("MsgButton %d at (%d,%d) %X %X", msg->message, msg->pt.x, msg->pt.y, msg->wParam, msg->lParam));
[21987]1093
[10190]1094 switch(msg->message)
[7801]1095 {
[2469]1096 case WM_LBUTTONDBLCLK:
1097 case WM_RBUTTONDBLCLK:
1098 case WM_MBUTTONDBLCLK:
[21987]1099 if (!(windowClass && windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS))
1100 {
1101 msg->message = msg->message - (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN); //dblclick -> down
1102 return MsgButton(msg);
1103 }
1104 break;
[2795]1105 case WM_NCLBUTTONDBLCLK:
1106 case WM_NCRBUTTONDBLCLK:
1107 case WM_NCMBUTTONDBLCLK:
[21987]1108 //Docs say CS_DBLCLKS style doesn't matter for non-client double clicks
1109 fClick = TRUE;
1110 break;
[2795]1111
[2469]1112 case WM_LBUTTONDOWN:
1113 case WM_RBUTTONDOWN:
1114 case WM_MBUTTONDOWN:
[21987]1115 if (getParent())
1116 {
1117 dprintf(("notifying parent: %X %X", msg->wParam, msg->lParam));
1118 NotifyParent(msg->message, msg->wParam, /*0*/msg->lParam);
1119 }
1120 // fall through to set fClick
[2469]1121 case WM_NCLBUTTONDOWN:
1122 case WM_NCRBUTTONDOWN:
1123 case WM_NCMBUTTONDOWN:
[21987]1124 fClick = TRUE;
1125 break;
[2469]1126 }
1127
1128 if(fClick)
1129 {
[21988]1130 HWND hwndTop;
[2469]1131
1132 /* Activate the window if needed */
[5935]1133 hwndTop = GetTopParent();
[2469]1134
1135 HWND hwndActive = GetActiveWindow();
1136 if (hwndTop && (getWindowHandle() != hwndActive))
1137 {
[21988]1138 LONG ret = SendMessageA(getWindowHandle(),WM_MOUSEACTIVATE, hwndTop,
1139 MAKELONG( lastHitTestVal, msg->message) );
[2469]1140
[21988]1141 //SendMessageA(getWindowHandle(), msg->message, msg->wParam, msg->lParam);
1142 dprintf2(("WM_MOUSEACTIVATE returned %d foreground %x top %x", ret, GetForegroundWindow(), hwndTop));
[3153]1143
[21988]1144 if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
1145 eatMsg = TRUE;
1146
1147 //SvL: 0 is not documented, but experiments in NT4 show that
1148 // the window will get activated when it returns this.
1149 // (FreeCell is an example)
1150 if(((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT) || (ret == 0))
1151 && (hwndTop != GetForegroundWindow()) )
1152 {
1153 Win32BaseWindow *win32top = Win32BaseWindow::GetWindowFromHandle(hwndTop);
1154
1155 //SvL: Calling OSLibSetActiveWindow(hwndTop); causes focus problems
1156 if (win32top) {
1157 //Must use client window handle (not frame!!)
1158 SetFocus(win32top->getWindowHandle());
1159 RELEASE_WNDOBJ(win32top);
[2469]1160 }
[21988]1161 }
[2469]1162 }
1163 }
1164
[7801]1165 SendMessageA(getWindowHandle(),WM_SETCURSOR, getWindowHandle(), MAKELONG(lastHitTestVal, msg->message));
[2469]1166
[21988]1167 return eatMsg ? 0 : SendMessageA(getWindowHandle(),msg->message, msg->wParam, msg->lParam);
[2469]1168}
1169//******************************************************************************
1170//******************************************************************************
[5236]1171ULONG Win32BaseWindow::MsgPaint(ULONG tmp, ULONG select)
[2469]1172{
[2881]1173 if (select && IsWindowIconic())
[7801]1174 return SendMessageA(getWindowHandle(),WM_PAINTICON, 1, 0);
[2469]1175 else
[7801]1176 return SendMessageA(getWindowHandle(),WM_PAINT, 0, 0);
[2469]1177}
1178//******************************************************************************
[10190]1179//
[9933]1180// Win32BaseWindow::saveAndValidateUpdateRegion
1181//
[10190]1182// If an application doesn't validate the update region while processing
[9933]1183// WM_PAINT, then we must remember it for the next time. Also validates
1184// the current update region.
1185//
1186// Parameters:
1187// Returns:
1188//
1189// NOTE:
1190// Windows will only send a WM_PAINT once until another part of the
1191// window is invalidated. Unfortunately PM keeps on sending
1192// WM_PAINT messages until we validate the update region.
1193//
1194// This affects UpdateWindow, RedrawWindow, GetUpdateRgn, GetUpdateRect,
1195// BeginPaint and the next WM_PAINT message.
1196//
1197//******************************************************************************
1198void Win32BaseWindow::saveAndValidateUpdateRegion()
1199{
1200 if(hUpdateRegion == NULL) {
1201 hUpdateRegion = ::CreateRectRgn(0, 0, 1, 1);
1202 }
1203
1204 dprintf(("Win32BaseWindow::saveAndValidateUpdateRegion; marked dirty!"));
1205
1206 //save update region
1207 ::GetUpdateRgn(getWindowHandle(), hUpdateRegion, FALSE);
1208
1209 //and validate it so PM won't bother us again
1210 ::ValidateRgn(getWindowHandle(), hUpdateRegion);
1211
1212 //we just pretend the entire window is invalid. easier this way
1213 fDirtyUpdateRegion = TRUE;
1214}
1215//******************************************************************************
[10190]1216//
[9933]1217// Win32BaseWindow::checkForDirtyUpdateRegion
1218//
[10190]1219// If an application doesn't validate the update region while processing
[9933]1220// WM_PAINT, then we must remember it for the next time. If the window has
1221// a dirty update region, then invalidate that region.
1222//
1223// Parameters:
1224// Returns:
1225//
1226// NOTE:
1227//
1228//******************************************************************************
1229void Win32BaseWindow::checkForDirtyUpdateRegion()
1230{
1231 if(fDirtyUpdateRegion) {
1232 dprintf(("Win32BaseWindow::checkForDirtyUpdateRegion; marked dirty -> invalidate whole window!"));
1233 fDirtyUpdateRegion = FALSE;
1234 ::InvalidateRgn(getWindowHandle(), hUpdateRegion, TRUE);
1235 }
1236}
1237//******************************************************************************
[2469]1238//TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
1239// (or are we simply erasing too much here)
1240//******************************************************************************
1241ULONG Win32BaseWindow::MsgEraseBackGround(HDC hdc)
1242{
1243 ULONG rc;
1244 HDC hdcErase = hdc;
1245
[10316]1246 if (hdcErase == 0) {
1247 DebugInt3();
1248 return 0;
1249 }
[2469]1250
[2881]1251 if(IsWindowIconic())
[7801]1252 rc = SendMessageA(getWindowHandle(),WM_ICONERASEBKGND, hdcErase, 0);
[2469]1253 else
[7801]1254 rc = SendMessageA(getWindowHandle(),WM_ERASEBKGND, hdcErase, 0);
[10316]1255
[2469]1256 return (rc);
1257}
1258//******************************************************************************
1259//******************************************************************************
1260ULONG Win32BaseWindow::MsgMouseMove(MSG *msg)
1261{
1262 //TODO: hiword should be 0 if window enters menu mode (SDK docs)
[7703]1263 //SDK: WM_SETCURSOR is not sent if the mouse is captured
1264 if(GetCapture() == 0) {
[7801]1265 SendMessageA(getWindowHandle(),WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, msg->message));
[7703]1266 }
[2469]1267
1268 //translated message == WM_(NC)MOUSEMOVE
[7801]1269 return SendMessageA(getWindowHandle(),msg->message, msg->wParam, msg->lParam);
[2469]1270}
1271//******************************************************************************
1272//******************************************************************************
1273ULONG Win32BaseWindow::MsgChar(MSG *msg)
1274{
[21529]1275 if (IsWindowUnicode()) {
1276 // Unicode windows expect the character code in UTF-16 while we save it
1277 // in ascii format, so we need to convert before sending to the window
1278 if (msg->message == WINWM_CHAR) {
1279 CHAR charA;
1280 WCHAR charW;
1281
1282 charA = msg->wParam;
1283 MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
1284 msg->wParam= charW;
1285 dprintf(("MsgChar: Convert to Unicode src=%x res=%x", charA, charW));
1286 }
1287 return DispatchMsgW(msg);
1288 }
1289 return DispatchMsgA(msg);
[2469]1290}
1291//******************************************************************************
1292//******************************************************************************
[10316]1293ULONG Win32BaseWindow::MsgNCPaint(PRECT pUpdateRect, HRGN hrgnUpdate)
[2469]1294{
1295 ULONG rc;
1296 RECT client = rectClient;
1297
[5685]1298 if ((pUpdateRect->left >= client.left) && (pUpdateRect->left < client.right) &&
1299 (pUpdateRect->right >= client.left) && (pUpdateRect->right < client.right) &&
1300 (pUpdateRect->top >= client.top) && (pUpdateRect->top < client.bottom) &&
[8105]1301 (pUpdateRect->bottom >= client.top) && (pUpdateRect->bottom < client.bottom)
1302 && (!(getStyle() & WS_MINIMIZE)))
[5685]1303 {
1304 return 0;
1305 }
[2469]1306
[10316]1307 rc = SendMessageA(getWindowHandle(),WM_NCPAINT, hrgnUpdate, 0);
[8105]1308 //Send WM_PAINTICON here if minimized, because client window will
1309 //not receive a (valid) WM_PAINT message
[10190]1310 if (getStyle() & WS_MINIMIZE)
[8105]1311 {
1312 rc = SendMessageA(getWindowHandle(),WM_PAINTICON, 1, 0);
1313 }
[3341]1314
[5685]1315 return rc;
[2469]1316}
1317//******************************************************************************
1318//Called when either the frame's size or position has changed (lpWndPos != NULL)
1319//or when the frame layout has changed (i.e. scrollbars added/removed) (lpWndPos == NULL)
1320//******************************************************************************
1321ULONG Win32BaseWindow::MsgFormatFrame(WINDOWPOS *lpWndPos)
1322{
1323 RECT oldWindowRect = rectWindow, client = rectClient, newWindowRect;
[5646]1324 RECT newClientRect;
[2469]1325 WINDOWPOS wndPos;
1326 ULONG rc;
1327
[5685]1328 if(lpWndPos)
1329 {
[4497]1330 //set new window rectangle
1331 setWindowRect(lpWndPos->x, lpWndPos->y, lpWndPos->x+lpWndPos->cx,
[3662]1332 lpWndPos->y+lpWndPos->cy);
[4497]1333 newWindowRect = rectWindow;
[5685]1334 }
1335 else {
[4497]1336 wndPos.hwnd = getWindowHandle();
1337 wndPos.hwndInsertAfter = 0;
1338 newWindowRect= rectWindow;
1339 wndPos.x = newWindowRect.left;
1340 wndPos.y = newWindowRect.top;
1341 wndPos.cx = newWindowRect.right - newWindowRect.left;
1342 wndPos.cy = newWindowRect.bottom - newWindowRect.top;
1343 wndPos.flags = SWP_FRAMECHANGED;
1344 lpWndPos = &wndPos;
[5685]1345 }
[2469]1346
[5685]1347 newClientRect = rectClient;
1348 rc = SendNCCalcSize(TRUE, &newWindowRect, &oldWindowRect, &client, lpWndPos, &newClientRect);
1349 rectClient = newClientRect; //must update rectClient here
[2469]1350
[5685]1351 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));
1352 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));
[3783]1353
[6169]1354 if(!CanReceiveSizeMsgs() || !EqualRect(&client, &rectClient)) {
[5685]1355 OSLibWinSetClientPos(getOS2WindowHandle(), rectClient.left, rectClient.top, getClientWidth(), getClientHeight(), getWindowHeight());
1356 }
1357
[3783]1358#if 1
[4497]1359//this doesn't always work
[6169]1360// if(CanReceiveSizeMsgs() && (client.left != rectClient.left || client.top != rectClient.top))
1361 if(CanReceiveSizeMsgs() && ((oldWindowRect.right - oldWindowRect.left < rectClient.left
[3789]1362 || oldWindowRect.bottom - oldWindowRect.top < rectClient.top) ||
1363 (EqualRect(&oldWindowRect, &rectWindow) && (client.left != rectClient.left || client.top != rectClient.top))))
[3783]1364 {
1365 Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild();
1366
[4497]1367 //client rectangle has moved -> inform children
1368 dprintf(("MsgFormatFrame -> client rectangle has changed, move children"));
1369 while(child) {
1370 ::SetWindowPos(child->getWindowHandle(),
1371 HWND_TOP, child->getWindowRect()->left,
1372 child->getWindowRect()->top, 0, 0,
[3789]1373 SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
[4497]1374 child = (Win32BaseWindow *)child->getNextChild();
1375 }
[3783]1376 }
1377#endif
[10013]1378 //WS_EX_TOOLWINDOW is incompatible with the OS2Look (titlebar thinner + smaller font)
[10190]1379 if(fOS2Look && ((dwStyle & WS_CAPTION) == WS_CAPTION) && !(dwExStyle & WS_EX_TOOLWINDOW))
[5951]1380 {
1381 RECT rect = {0};
[9345]1382 BOOL fCloseButton;
1383
1384 fCloseButton = !(windowClass && (windowClass->getClassLongA(GCL_STYLE) & CS_NOCLOSE));
1385
[5951]1386 int height = getWindowHeight();
1387 RECTLOS2 rectOS2;
1388
1389 AdjustRectOuter(&rect, FALSE);
1390
1391 rect.left = -rect.left;
1392 rect.top = rect.bottom - rect.top;
1393 rect.right = rectWindow.right - rectWindow.left - rect.right;
[10190]1394
[5951]1395 rectOS2.xLeft = rect.left;
1396 rectOS2.xRight = rect.right;
1397 rectOS2.yBottom = height - rect.top;
1398 rectOS2.yTop = height - rect.bottom;
[9345]1399
[10190]1400 //@@PF Disable close button as well when needed by application
[9345]1401 OSLibChangeCloseButtonState(getOS2FrameWindowHandle(), fCloseButton);
1402 OSLibWinPositionFrameControls(getOS2FrameWindowHandle(), &rectOS2,
1403 dwStyle, dwExStyle, IconForWindow(ICON_SMALL),
[10190]1404 fCloseButton, windowClass->getIcon() != NULL);
[5951]1405 }
[2469]1406 return rc;
1407}
1408//******************************************************************************
1409//******************************************************************************
1410ULONG Win32BaseWindow::MsgSetText(LPSTR lpsz, LONG cch)
1411{
[7801]1412 return SendMessageA(getWindowHandle(),WM_SETTEXT, 0, (LPARAM)lpsz);
[2469]1413}
1414//******************************************************************************
1415//******************************************************************************
1416ULONG Win32BaseWindow::MsgGetTextLength()
1417{
[7801]1418 return SendMessageA(getWindowHandle(),WM_GETTEXTLENGTH, 0, 0);
[2469]1419}
1420//******************************************************************************
1421//******************************************************************************
[2552]1422void Win32BaseWindow::MsgGetText(char *wndtext, ULONG textlength)
[2469]1423{
[7801]1424 SendMessageA(getWindowHandle(),WM_GETTEXT, textlength, (LPARAM)wndtext);
[2469]1425}
1426//******************************************************************************
1427//******************************************************************************
1428BOOL Win32BaseWindow::isMDIClient()
1429{
1430 return FALSE;
1431}
1432//******************************************************************************
1433//******************************************************************************
1434BOOL Win32BaseWindow::isMDIChild()
1435{
1436 return FALSE;
1437}
1438//******************************************************************************
1439//TODO: Not complete
1440//******************************************************************************
1441BOOL Win32BaseWindow::isFrameWindow()
1442{
[3662]1443 if(getParent() == NULL)
[2469]1444 return TRUE;
1445
1446 return FALSE;
1447}
1448//******************************************************************************
1449//******************************************************************************
[3663]1450BOOL Win32BaseWindow::isDesktopWindow()
1451{
1452 return FALSE;
1453}
1454//******************************************************************************
1455//******************************************************************************
[2881]1456BOOL Win32BaseWindow::IsWindowIconic()
1457{
1458 return ((getStyle() & WS_MINIMIZE) && windowClass->getIcon());
1459}
1460//******************************************************************************
1461//******************************************************************************
[2469]1462SCROLLBAR_INFO *Win32BaseWindow::getScrollInfo(int nBar)
1463{
1464 switch(nBar)
1465 {
1466 case SB_HORZ:
1467 if (!horzScrollInfo)
1468 {
1469 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1470 if (!horzScrollInfo) break;
1471 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
1472 horzScrollInfo->MaxVal = 100;
1473 horzScrollInfo->flags = ESB_ENABLE_BOTH;
1474 }
1475 return horzScrollInfo;
1476
1477 case SB_VERT:
1478 if (!vertScrollInfo)
1479 {
1480 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1481 if (!vertScrollInfo) break;
1482 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
1483 vertScrollInfo->MaxVal = 100;
1484 vertScrollInfo->flags = ESB_ENABLE_BOTH;
1485 }
1486 return vertScrollInfo;
1487 }
1488
1489 return NULL;
1490}
1491//******************************************************************************
1492//******************************************************************************
1493LRESULT Win32BaseWindow::DefWndControlColor(UINT ctlType, HDC hdc)
1494{
1495 //SvL: Set background color to default button color (not window (white))
1496 if(ctlType == CTLCOLOR_BTN)
1497 {
1498 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
1499 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1500 return GetSysColorBrush(COLOR_BTNFACE);
1501 }
1502 //SvL: Set background color to default dialog color if window is dialog
1503 if((ctlType == CTLCOLOR_DLG || ctlType == CTLCOLOR_STATIC) && IsDialog()) {
1504 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
1505 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1506 return GetSysColorBrush(COLOR_BTNFACE);
1507 }
1508 if( ctlType == CTLCOLOR_SCROLLBAR)
1509 {
1510 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
1511 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
1512 SetTextColor( hdc, GetSysColor(COLOR_3DFACE));
1513 SetBkColor( hdc, bk);
1514
1515 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
1516 * we better use 0x55aa bitmap brush to make scrollbar's background
1517 * look different from the window background.
1518 */
1519 if (bk == GetSysColor(COLOR_WINDOW)) {
[2873]1520 return GetPattern55AABrush();
[2469]1521 }
[2857]1522
[2469]1523 UnrealizeObject( hb );
1524 return (LRESULT)hb;
1525 }
1526
1527 SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
1528
1529 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
1530 {
1531 SetBkColor( hdc, GetSysColor(COLOR_WINDOW) );
1532 }
1533 else
1534 {
1535 SetBkColor( hdc, GetSysColor(COLOR_3DFACE) );
1536 return (LRESULT)GetSysColorBrush(COLOR_3DFACE);
1537 }
1538 return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
1539}
1540//******************************************************************************
1541//******************************************************************************
1542LRESULT Win32BaseWindow::DefWndPrint(HDC hdc,ULONG uFlags)
1543{
1544 /*
1545 * Visibility flag.
1546 */
1547 if ( (uFlags & PRF_CHECKVISIBLE) &&
[5586]1548 !IsWindowVisible(getWindowHandle()) )
[2469]1549 return 0;
1550
1551 /*
1552 * Unimplemented flags.
1553 */
1554 if ( (uFlags & PRF_CHILDREN) ||
1555 (uFlags & PRF_OWNED) ||
1556 (uFlags & PRF_NONCLIENT) )
1557 {
1558 dprintf(("WM_PRINT message with unsupported flags\n"));
1559 }
1560
1561 /*
1562 * Background
1563 */
1564 if ( uFlags & PRF_ERASEBKGND)
[7801]1565 SendMessageA(getWindowHandle(),WM_ERASEBKGND, (WPARAM)hdc, 0);
[2469]1566
1567 /*
1568 * Client area
1569 */
1570 if ( uFlags & PRF_CLIENT)
[7801]1571 SendMessageA(getWindowHandle(),WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
[2469]1572
1573
1574 return 0;
1575}
1576//******************************************************************************
1577//******************************************************************************
1578LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
1579{
[21303]1580
[21344]1581 dprintf(("DefWndProc: winmsg: %x for %x Msg %s", Msg, Win32Hwnd, GetMsgText(/*HIWORD(lParam)*/Msg)));
[21303]1582
[2469]1583 switch(Msg)
1584 {
1585 case WM_CLOSE:
1586 dprintf(("DefWindowProcA: WM_CLOSE %x", getWindowHandle()));
1587 DestroyWindow();
1588 return 0;
1589
1590 case WM_GETTEXTLENGTH:
[10190]1591 return windowNameLengthA;
[2469]1592
1593 case WM_GETTEXT:
[10190]1594 if (!lParam || !wParam)
[7338]1595 return 0;
[10190]1596 if (!windowNameA)
[7338]1597 ((LPSTR)lParam)[0] = 0;
[10190]1598 else
1599 lstrcpynA(( LPSTR )lParam, windowNameA, wParam );
1600 return strlen(( LPSTR )lParam );
[2469]1601
1602 case WM_SETTEXT:
1603 {
1604 LPCSTR lpsz = (LPCSTR)lParam;
[10190]1605
[7338]1606 // reallocate if new buffer is larger
1607 if (!lParam)
[2469]1608 {
[7338]1609 free(windowNameA);
1610 free(windowNameW);
[10190]1611 windowNameLengthA = 0;
1612 windowNameLengthW = 0;
[7338]1613 windowNameA = NULL;
1614 windowNameW = NULL;
[2469]1615 }
1616 else
1617 {
[7338]1618 if (windowNameA)
1619 {
1620 free(windowNameA);
1621 windowNameA = NULL;
1622 }
[10190]1623
[7338]1624 if (windowNameW)
1625 {
1626 free(windowNameW);
1627 windowNameW = NULL;
1628 }
[10190]1629
[10261]1630 windowNameLengthA = strlen( lpsz );
1631 windowNameA = (LPSTR)_smalloc(windowNameLengthA+1);
[10190]1632 strcpy(windowNameA, lpsz);
[10261]1633 windowNameLengthW = lstrlenAtoW( lpsz, -1 );
1634 windowNameW = (LPWSTR)_smalloc(( windowNameLengthW + 1 )*sizeof(WCHAR));
[10190]1635 lstrcpyAtoW( windowNameW, windowNameA );
[2469]1636 }
[10190]1637
[2469]1638 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, lParam));
[2611]1639 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
[2469]1640 {
[5074]1641 HandleNCPaint((HRGN)1);
1642 if(hTaskList) {
[5685]1643 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), (getStyle() & WS_VISIBLE) ? 1 : 0);
[5074]1644 }
[5994]1645 if(fOS2Look) {
[21544]1646 OSLibWinSetTitleBarText(OS2HwndFrame, getWindowNameA());
[5994]1647 }
[2469]1648 }
1649
1650 return TRUE;
1651 }
1652
1653 case WM_SETREDRAW:
1654 {
[5074]1655 if (wParam)
[2469]1656 {
[5074]1657 setStyle(getStyle() | WS_VISIBLE);
[5440]1658 dprintf(("Enable window update for %x", getWindowHandle()));
[5721]1659 OSLibWinEnableWindowUpdate(OS2HwndFrame, OS2Hwnd, TRUE);
[2469]1660 }
[5074]1661 else
1662 {
1663 if (getStyle() & WS_VISIBLE)
1664 {
1665 setStyle(getStyle() & ~WS_VISIBLE);
[5440]1666 dprintf(("Disable window update for %x", getWindowHandle()));
[5721]1667 OSLibWinEnableWindowUpdate(OS2HwndFrame, OS2Hwnd, FALSE);
[5074]1668 }
1669 }
1670 return 0;
[2469]1671 }
1672
1673 case WM_CTLCOLORMSGBOX:
1674 case WM_CTLCOLOREDIT:
1675 case WM_CTLCOLORLISTBOX:
1676 case WM_CTLCOLORBTN:
1677 case WM_CTLCOLORDLG:
1678 case WM_CTLCOLORSTATIC:
1679 case WM_CTLCOLORSCROLLBAR:
1680 return DefWndControlColor(Msg - WM_CTLCOLORMSGBOX, (HDC)wParam);
1681
1682 case WM_CTLCOLOR:
1683 return DefWndControlColor(HIWORD(lParam), (HDC)wParam);
1684
1685 case WM_VKEYTOITEM:
1686 case WM_CHARTOITEM:
[9550]1687 return -1;
[2469]1688
1689 case WM_PARENTNOTIFY:
1690 return 0;
1691
1692 case WM_MOUSEACTIVATE:
1693 {
[9550]1694 HWND hwnd = getWindowHandle();
1695
[2469]1696 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
[9550]1697 if (::GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
[10190]1698 {
1699 LONG ret = ::SendMessageW( ::GetParent(hwnd), WM_MOUSEACTIVATE, wParam, lParam );
1700 if (ret) return ret;
1701 }
[9550]1702
[10190]1703 /* Caption clicks are handled by the NC_HandleNCLButtonDown() */
[9550]1704 return (LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE;
[2469]1705 }
1706
1707 case WM_ACTIVATE:
[5060]1708 /* The default action in Windows is to set the keyboard focus to
1709 * the window, if it's being activated and not minimized */
[4497]1710 if (LOWORD(wParam) != WA_INACTIVE) {
[5060]1711 if(!(getStyle() & WS_MINIMIZE))
1712 SetFocus(getWindowHandle());
[4497]1713 }
1714 return 0;
[2469]1715
1716 case WM_SETCURSOR:
1717 {
1718 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
[5258]1719 if((getStyle() & WS_CHILD))
[2469]1720 {
1721 if(getParent()) {
[7801]1722 LRESULT rc = SendMessageA(getParent()->getWindowHandle(), WM_SETCURSOR, wParam, lParam);
[2469]1723 if(rc) return rc;
1724 }
1725 }
[5258]1726 if (wParam == getWindowHandle())
[2469]1727 {
1728 HCURSOR hCursor;
1729
1730 switch(LOWORD(lParam))
1731 {
1732 case HTCLIENT:
1733 hCursor = windowClass ? windowClass->getCursor():LoadCursorA(0,IDC_ARROWA);
1734 break;
1735
1736 case HTLEFT:
1737 case HTRIGHT:
1738 hCursor = LoadCursorA(0,IDC_SIZEWEA);
1739 break;
1740
1741 case HTTOP:
1742 case HTBOTTOM:
1743 hCursor = LoadCursorA(0,IDC_SIZENSA);
1744 break;
1745
1746 case HTTOPLEFT:
1747 case HTBOTTOMRIGHT:
1748 hCursor = LoadCursorA(0,IDC_SIZENWSEA);
1749 break;
1750
1751 case HTTOPRIGHT:
1752 case HTBOTTOMLEFT:
1753 hCursor = LoadCursorA(0,IDC_SIZENESWA);
1754 break;
1755
1756 default:
1757 hCursor = LoadCursorA(0,IDC_ARROWA);
1758 break;
1759 }
1760
1761 if (hCursor)
1762 {
1763 SetCursor(hCursor);
1764 return 1;
[2552]1765 }
1766 else return 0;
1767 }
1768 else return 0;
[2469]1769 }
1770
1771 case WM_MOUSEMOVE:
1772 return 0;
1773
[9259]1774 case WM_MOUSEWHEEL:
1775 if (::GetWindowLongA( getWindowHandle(), GWL_STYLE ) & WS_CHILD)
1776 return ::SendMessageA( ::GetParent(getWindowHandle()), WM_MOUSEWHEEL, wParam, lParam );
[10190]1777 break;
[9259]1778
[2469]1779 case WM_WINDOWPOSCHANGED:
1780 {
1781 PWINDOWPOS wpos = (PWINDOWPOS)lParam;
1782 WPARAM wp = SIZE_RESTORED;
1783
[9572]1784 //According to Wine these are always sent, but experiments in Windows NT4, SP6
1785 //show otherwise
[2469]1786 if (!(wpos->flags & SWP_NOMOVE) && !(wpos->flags & SWP_NOCLIENTMOVE))
1787 {
[7801]1788 SendMessageA(getWindowHandle(),WM_MOVE, 0, MAKELONG(rectClient.left,rectClient.top));
[2469]1789 }
[9572]1790 //According to Wine these are always sent, but experiments in Windows NT4, SP6
1791 //show otherwise
[2469]1792 if (!(wpos->flags & SWP_NOSIZE) && !(wpos->flags & SWP_NOCLIENTSIZE))
1793 {
1794 if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
[2552]1795 else
1796 if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
[2469]1797
[7801]1798 SendMessageA(getWindowHandle(),WM_SIZE, wp, MAKELONG(rectClient.right - rectClient.left,
[2469]1799 rectClient.bottom - rectClient.top));
1800 }
1801 return 0;
1802 }
1803 case WM_WINDOWPOSCHANGING:
1804 return HandleWindowPosChanging((WINDOWPOS *)lParam);
1805
1806 case WM_ERASEBKGND:
1807 case WM_ICONERASEBKGND:
1808 {
[10045]1809 HBRUSH hBrush;
1810 RECT rect;
1811 int rc;
[10190]1812
1813 if (!windowClass || (!windowClass->getBackgroundBrush()
[10045]1814 && !(getStyle() & WS_MINIMIZE))) return 0;
[2469]1815
[10045]1816 //PF For PM desktop/MDI icons allocate brush as well to avoid
1817 //garbage in icons
[2469]1818
[10045]1819 if (!windowClass->getBackgroundBrush())
1820 hBrush = GetStockObject(GRAY_BRUSH);
1821 else
[2469]1822 {
[10045]1823 hBrush = windowClass->getBackgroundBrush();
[2663]1824 if (hBrush <= (HBRUSH)(SYSCOLOR_GetLastColor()+1))
1825 hBrush = GetSysColorBrush(hBrush-1);
[10045]1826 }
[2469]1827
[10190]1828
[10045]1829 rc = GetClipBox( (HDC)wParam, &rect );
1830 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
[2672]1831 FillRect( (HDC)wParam, &rect, hBrush);
[10045]1832
[2469]1833 return 1;
1834 }
1835
1836 case WM_PRINT:
1837 return DefWndPrint(wParam,lParam);
1838
[8105]1839 case WM_SYNCPAINT:
1840 RedrawWindow(getWindowHandle(), NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN);
1841 return 0;
1842
[2469]1843 case WM_PAINTICON:
1844 case WM_PAINT:
1845 {
1846 PAINTSTRUCT ps;
1847 HDC hdc = BeginPaint(getWindowHandle(), &ps );
1848 if( hdc )
1849 {
[5236]1850 if( (getStyle() & WS_MINIMIZE) && (getWindowClass()->getIcon() || hIcon))
1851 {
1852 int x = (rectWindow.right - rectWindow.left - GetSystemMetrics(SM_CXICON))/2;
1853 int y = (rectWindow.bottom - rectWindow.top - GetSystemMetrics(SM_CYICON))/2;
1854 dprintf(("Painting class icon: vis rect=(%i,%i - %i,%i)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom ));
1855 DrawIcon(hdc, x, y, hIcon ? hIcon:getWindowClass()->getIcon() );
1856 }
1857 EndPaint(getWindowHandle(), &ps );
[2469]1858 }
1859 return 0;
1860 }
1861
1862 case WM_GETDLGCODE:
1863 return 0;
1864
1865 case WM_NCPAINT:
1866 return HandleNCPaint((HRGN)wParam);
1867
1868 case WM_NCACTIVATE:
1869 return HandleNCActivate(wParam);
1870
1871 case WM_NCCREATE:
1872 return(TRUE);
1873
1874 case WM_NCDESTROY:
1875 return 0;
1876
1877 case WM_NCCALCSIZE:
1878 return HandleNCCalcSize((BOOL)wParam,(RECT*)lParam);
1879
1880 case WM_NCLBUTTONDOWN:
1881 return HandleNCLButtonDown(wParam,lParam);
1882
1883 case WM_LBUTTONDBLCLK:
1884 case WM_NCLBUTTONDBLCLK:
1885 return HandleNCLButtonDblClk(wParam,lParam);
1886
1887 case WM_NCRBUTTONDOWN:
1888 case WM_NCRBUTTONDBLCLK:
1889 case WM_NCMBUTTONDOWN:
1890 case WM_NCMBUTTONDBLCLK:
1891 if (lastHitTestVal == HTERROR) MessageBeep(MB_ICONEXCLAMATION);
1892 return 0;
1893
1894 case WM_NCRBUTTONUP:
1895 return HandleNCRButtonUp(wParam,lParam);
1896
1897 case WM_NCMBUTTONUP:
1898 return 0;
1899
1900 case WM_NCHITTEST:
1901 {
1902 POINT point;
[2852]1903 LRESULT retvalue;
[2469]1904
1905 point.x = (SHORT)LOWORD(lParam);
1906 point.y = (SHORT)HIWORD(lParam);
1907
[2852]1908 retvalue = HandleNCHitTest(point);
1909#if 0 //CB: let the Corel people fix the bugs first
1910 if(retvalue == HTMENU)
1911 MENU_TrackMouseMenuBar_MouseMove(Win32Hwnd,point,TRUE);
1912 else
1913 MENU_TrackMouseMenuBar_MouseMove(Win32Hwnd,point,FALSE);
1914#endif
[21367]1915 dprintf(("Hittest: %X", retvalue));
[2852]1916 return retvalue;
[2469]1917 }
1918
1919 case WM_SYSCOMMAND:
1920 {
1921 POINT point;
1922
1923 point.x = LOWORD(lParam);
1924 point.y = HIWORD(lParam);
1925 return HandleSysCommand(wParam,&point);
1926 }
1927
[9607]1928 case WM_KEYDOWN:
[10190]1929 if(wParam == VK_F10) iF10Key = VK_F10;
1930 break;
[9607]1931
[2469]1932 case WM_SYSKEYDOWN:
[6783]1933 {
[10190]1934 if( HIWORD(lParam) & KEYDATA_ALT )
1935 {
1936 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1937 if( wParam == VK_MENU && !iMenuSysKey )
1938 iMenuSysKey = 1;
1939 else
1940 iMenuSysKey = 0;
[2469]1941
[10190]1942 iF10Key = 0;
1943
1944 if( wParam == VK_F4 ) /* try to close the window */
1945 {
[7620]1946 HWND top = GetTopParent();
[6783]1947 if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
1948 PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
[10190]1949 }
[9466]1950
1951 //Default OS/2 app behaviour for system keys
1952 if(fOS2Look)
1953 {
[10190]1954 if( wParam == VK_F5 ) /* try to restore the window */
1955 {
1956 HWND top = GetTopParent();
[9466]1957 /* No checks needed SC_RESTORE handler does them */
[10190]1958 PostMessageW( top, WM_SYSCOMMAND, SC_RESTORE, 0 );
1959 }
[9466]1960
[10190]1961 if( wParam == VK_F7 ) /* size the window */
1962 {
1963 HWND top = GetTopParent();
1964 PostMessageW( top, WM_SYSCOMMAND, SC_MOVE, 0 );
1965 }
[9466]1966
[10190]1967 if( wParam == VK_F8 ) /* move the window */
1968 {
1969 HWND top = GetTopParent();
1970 if ( GetWindowLongA(top, GWL_STYLE) & WS_SIZEBOX)
1971 PostMessageW( top, WM_SYSCOMMAND, SC_SIZE, 0 );
1972 }
[9466]1973
[10190]1974 if( wParam == VK_F9 ) /* try to minimize the window */
1975 {
1976 HWND top = GetTopParent();
1977 if ( GetWindowLongA(top, GWL_STYLE) & WS_MINIMIZEBOX)
1978 PostMessageW( top, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
1979 }
[9466]1980
[10190]1981 if( wParam == VK_F10 ) /* try to maximize the window */
1982 {
1983 HWND top = GetTopParent();
1984 if ( GetWindowLongA(top, GWL_STYLE) & WS_MAXIMIZEBOX)
1985 PostMessageW( top, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
[9466]1986 }
[10190]1987 }
[9466]1988
[10190]1989 }
1990 else if( wParam == VK_F10 )
1991 iF10Key = 1;
1992 else
1993 if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000))
[7801]1994 SendMessageW(getWindowHandle(), WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE );
[2469]1995 return 0;
[6783]1996 }
[2469]1997
[2834]1998 case WM_KEYUP:
[9818]1999 //Single Alt down + up always generates WM_SYSKEYUP
2000 iMenuSysKey = 0;
2001 // no break;
[2834]2002 case WM_SYSKEYUP:
[10190]2003 /* Press and release F10 or ALT */
2004 if (((wParam == VK_MENU) && iMenuSysKey) ||
[6783]2005 ((wParam == VK_F10) && iF10Key))
[9607]2006 ::SendMessageW( GetTopParent(), WM_SYSCOMMAND, SC_KEYMENU, 0L );
[10190]2007 iMenuSysKey = iF10Key = 0;
[6783]2008 break;
[2834]2009
[2469]2010 case WM_SYSCHAR:
2011 {
[6783]2012 iMenuSysKey = 0;
[3462]2013 if (wParam == VK_RETURN && (getStyle() & WS_MINIMIZE))
[2469]2014 {
2015 PostMessageA(getWindowHandle(), WM_SYSCOMMAND,
2016 (WPARAM)SC_RESTORE, 0L );
2017 break;
2018 }
[3462]2019 if((HIWORD(lParam) & KEYDATA_ALT) && wParam)
[2469]2020 {
[4485]2021 if (wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_F4)
[3584]2022 break;
[3462]2023 if (wParam == VK_SPACE && (getStyle() & WS_CHILD)) {
[6783]2024 ::SendMessageW(GetParent(), Msg, wParam, lParam );
[3584]2025 }
[7801]2026 else ::SendMessageA(getWindowHandle(), WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam );
[2469]2027 }
[3747]2028#if 0
[3462]2029 else /* check for Ctrl-Esc */
[3584]2030 if (wParam != VK_ESCAPE) MessageBeep(0);
2031 break;
[3747]2032#endif
[2469]2033 }
[2834]2034
[2666]2035 case WM_SETHOTKEY:
2036 hotkey = wParam;
2037 return 1; //CB: always successful
2038
2039 case WM_GETHOTKEY:
2040 return hotkey;
2041
[8993]2042 case WM_RBUTTONUP:
2043 {
[10190]2044 POINT pt;
2045 pt.x = SLOWORD(lParam);
2046 pt.y = SHIWORD(lParam);
2047 ClientToScreen(getWindowHandle(), &pt);
[8993]2048 SendMessageA( getWindowHandle(), WM_CONTEXTMENU, getWindowHandle(),MAKELPARAM(pt.x, pt.y) );
2049 }
2050 break;
[2666]2051
[8993]2052 case WM_CONTEXTMENU:
2053 if ((dwStyle & WS_CHILD) && getParent())
2054 SendMessageA(getParent()->getWindowHandle(), WM_CONTEXTMENU,wParam,lParam);
2055 else
2056 {
2057 LONG hitcode;
2058 POINT pt;
2059 if (!GetSysMenu()) return 0;
2060 pt.x = SLOWORD(lParam);
2061 pt.y = SHIWORD(lParam);
2062 hitcode = HandleNCHitTest(pt);
2063
2064 /* Track system popup if click was in the caption area. */
2065 if (hitcode==HTCAPTION || hitcode==HTSYSMENU)
2066 TrackPopupMenu(GetSysMenu(),
2067 TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
2068 pt.x, pt.y, 0, getWindowHandle(), NULL);
2069 }
2070 return 0;
2071
[2469]2072 case WM_SHOWWINDOW:
2073 if (!lParam) return 0; /* sent from ShowWindow */
2074 if (!(dwStyle & WS_POPUP) || !owner) return 0;
2075 if ((dwStyle & WS_VISIBLE) && wParam) return 0;
2076 else if (!(dwStyle & WS_VISIBLE) && !wParam) return 0;
[2852]2077 ShowWindow(wParam ? SW_SHOW:SW_HIDE);
[2469]2078 return 0;
2079
2080 case WM_CANCELMODE:
2081 if (getParent() == windowDesktop) EndMenu();
2082 if (GetCapture() == Win32Hwnd) ReleaseCapture();
2083 return 0;
2084
2085 case WM_DROPOBJECT:
2086 return DRAG_FILE;
2087
2088 case WM_QUERYDROPOBJECT:
[2666]2089 return (dwExStyle & WS_EX_ACCEPTFILES) ? 1:0;
[2469]2090
2091 case WM_QUERYDRAGICON:
2092 {
[2852]2093 HICON hDragIcon = windowClass->getCursor();
[2469]2094 UINT len;
2095
[2852]2096 if(hDragIcon) return (LRESULT)hDragIcon;
[2469]2097 for(len = 1; len < 64; len++)
2098 {
[2852]2099 hDragIcon = LoadIconA(hInstance,MAKEINTRESOURCEA(len));
2100 if(hDragIcon)
2101 return (LRESULT)hDragIcon;
[2469]2102 }
2103 return (LRESULT)LoadIconA(0,IDI_APPLICATIONA);
2104 }
2105
2106 case WM_QUERYOPEN:
2107 case WM_QUERYENDSESSION:
2108 return 1;
2109
2110 case WM_NOTIFYFORMAT:
[2666]2111 return IsWindowUnicode() ? NFR_UNICODE:NFR_ANSI;
[2469]2112
2113 case WM_SETICON:
2114 case WM_GETICON:
[2852]2115 {
2116 LRESULT result = 0;
[3153]2117
[2852]2118 /* Set the appropriate icon members in the window structure. */
2119 if (wParam == ICON_SMALL)
2120 {
2121 result = hIconSm;
[2469]2122 if (Msg == WM_SETICON)
[2852]2123 hIconSm = (HICON)lParam;
2124 }
2125 else
2126 {
2127 result = hIcon;
2128 if (Msg == WM_SETICON)
2129 {
2130 hIcon = (HICON)lParam;
[3153]2131 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
[6168]2132 OSLibWinSetIcon(OS2HwndFrame,hIcon);
[2852]2133 }
2134 }
[3153]2135 if ((Msg == WM_SETICON) && ((dwStyle & WS_CAPTION) == WS_CAPTION))
2136 HandleNCPaint((HRGN)1);
2137
[2852]2138 return result;
2139 }
[2469]2140
[2852]2141 case WM_HELP:
[7801]2142 if (getParent()) SendMessageA(getParent()->getWindowHandle(), Msg,wParam,lParam);
[2857]2143 break;
[2469]2144
2145 case WM_NOTIFY:
2146 return 0; //comctl32 controls expect this
2147
[10216]2148 case WM_IME_CHAR:
[21303]2149 if( wParam & 0xFF00 ) // DBCS ?
[10261]2150 SendMessageA( getWindowHandle(), WM_CHAR, ( WPARAM )( BYTE )( wParam >> 8 ), lParam );
[10216]2151 SendMessageA( getWindowHandle(), WM_CHAR, ( WPARAM )( BYTE )( wParam & 0xFF ), lParam );
2152 break;
2153
[2469]2154 default:
2155 return 0;
2156 }
2157 return 0;
2158}
2159//******************************************************************************
2160//******************************************************************************
2161LRESULT Win32BaseWindow::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
2162{
2163 switch(Msg)
2164 {
2165 case WM_GETTEXTLENGTH:
[10190]2166 return windowNameLengthW;
[2469]2167
2168 case WM_GETTEXT:
[10190]2169 if (!lParam || !wParam)
[7338]2170 return 0;
2171 if (!windowNameW)
2172 ((LPWSTR)lParam)[0] = 0;
[10190]2173 else
2174 lstrcpynW(( LPWSTR )lParam, windowNameW, wParam );
[2469]2175
[10190]2176 return strlenW(( LPWSTR )lParam );
2177
[2469]2178 case WM_SETTEXT:
2179 {
2180 LPWSTR lpsz = (LPWSTR)lParam;
[10190]2181
[7338]2182 // reallocate if new buffer is larger
2183 if (!lParam)
[2469]2184 {
[7338]2185 free(windowNameA);
2186 free(windowNameW);
[10190]2187 windowNameLengthA = 0;
2188 windowNameLengthW = 0;
[7338]2189 windowNameA = NULL;
2190 windowNameW = NULL;
[2469]2191 }
2192 else
2193 {
[7338]2194 if (windowNameA)
2195 {
2196 free(windowNameA);
2197 windowNameA = NULL;
2198 }
[10190]2199
[7338]2200 if (windowNameW)
2201 {
2202 free(windowNameW);
2203 windowNameW = NULL;
2204 }
[10190]2205
[10261]2206 windowNameLengthW = lstrlenW( lpsz );
2207 windowNameW = (LPWSTR)_smalloc((windowNameLengthW+1)*sizeof(WCHAR));
[10190]2208 strcpyW(windowNameW, lpsz);
[10261]2209 windowNameLengthA = lstrlenWtoA( lpsz, -1 );
2210 windowNameA = (LPSTR)_smalloc( windowNameLengthA + 1 );
[10190]2211 lstrcpyWtoA( windowNameA, windowNameW );
[2469]2212 }
[7338]2213
[10190]2214 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, windowNameA));
[2611]2215 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
[2469]2216 {
[5685]2217 HandleNCPaint((HRGN)1);
2218 if(hTaskList) {
2219 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), (getStyle() & WS_VISIBLE) ? 1 : 0);
2220 }
[5994]2221 if(fOS2Look) {
[21544]2222 OSLibWinSetTitleBarText(OS2HwndFrame, getWindowNameA());
[5994]2223 }
[2469]2224 }
2225
2226 return TRUE;
2227 }
2228
[10216]2229 case WM_IME_CHAR:
2230 SendMessageW( getWindowHandle(), WM_CHAR, wParam, lParam );
2231 return 0;
2232
[2469]2233 default:
2234 return DefWindowProcA(Msg, wParam, lParam);
2235 }
2236}
2237//******************************************************************************
2238//******************************************************************************
2239void Win32BaseWindow::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
2240{
2241 Win32BaseWindow *window = this;
2242 Win32BaseWindow *parentwindow;
2243
2244 while(window)
2245 {
2246 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
2247 {
[21988]2248 /* Notify the parent window only */
2249 parentwindow = window->getParent();
2250 if(parentwindow) {
2251 /* PF We should map points for each window accordingly! */
2252 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN || Msg == WM_RBUTTONDOWN ||
2253 Msg == WM_LBUTTONUP || Msg == WM_MBUTTONUP || Msg == WM_RBUTTONUP)
2254 {
2255 POINTS pt = MAKEPOINTS(lParam);
2256 POINT point;
[10061]2257
[21988]2258 point.x = pt.x;
2259 point.y = pt.y;
[10061]2260
[21988]2261 MapWindowPoints(getWindowHandle(),parentwindow->getWindowHandle(), &point, 1);
2262 lParam = MAKELPARAM(point.x, point.y);
2263 wParam = MAKEWPARAM(Msg, 0 /* undefined according to MSDN, 0 under XP */);
[2469]2264 }
[21988]2265 else
2266 {
2267 lParam = getWindowHandle();
2268 wParam = MAKEWPARAM(Msg, getWindowId());
2269 }
2270 SendMessageA(parentwindow->getWindowHandle(), WM_PARENTNOTIFY, wParam, lParam);
2271 }
[10061]2272
[2469]2273 }
2274 else break;
2275
2276 window = parentwindow;
2277 }
2278}
2279//******************************************************************************
[3153]2280// Returns the big or small icon for the window, falling back to the
2281// class as windows does.
[2469]2282//******************************************************************************
[3153]2283HICON Win32BaseWindow::IconForWindow(WPARAM fType)
2284{
2285 HICON hWndIcon;
2286
2287 if (fType == ICON_BIG)
2288 {
[4497]2289 if (hIcon)
2290 hWndIcon = hIcon;
2291 else
2292 if (windowClass && windowClass->getIcon())
2293 hWndIcon = windowClass->getIcon();
2294 else
[10190]2295 if (!(dwStyle & DS_MODALFRAME))
[9637]2296 {//SvL: load it as shared or else we'll leak icons
2297 hWndIcon = LoadImageA(0,MAKEINTRESOURCEA(OIC_ODINICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR|LR_SHARED);
2298 }
[3153]2299 else hWndIcon = 0;
[4497]2300 }
2301 else
[3153]2302 {
[4497]2303 if (hIconSm)
2304 hWndIcon = hIconSm;
2305 else
2306 if (hIcon)
2307 hWndIcon = hIcon;
2308 else
2309 if (windowClass && windowClass->getIconSm())
2310 hWndIcon = windowClass->getIconSm();
2311 else
2312 if (windowClass && windowClass->getIcon())
2313 hWndIcon = windowClass->getIcon();
2314 else
[10190]2315 if (!(dwStyle & DS_MODALFRAME))
[9637]2316 {//SvL: load it as shared or else we'll leak icons
2317 hWndIcon = LoadImageA(0,MAKEINTRESOURCEA(OIC_ODINICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR|LR_SHARED);
2318 }
[3153]2319 else hWndIcon = 0;
2320 }
2321
2322 return hWndIcon;
2323}
2324//******************************************************************************
2325//******************************************************************************
[2469]2326BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
2327{
[3662]2328 ULONG swp = 0;
[3501]2329 HWND hWinAfter;
[3584]2330 BOOL rc,wasVisible,showFlag;
[3662]2331 RECT newPos = {0, 0, 0, 0};
[2469]2332
2333 dprintf(("ShowWindow %x %x", getWindowHandle(), nCmdShow));
[3662]2334 wasVisible = (getStyle() & WS_VISIBLE) != 0;
2335
[6008]2336 dwOldStyle = getStyle();
2337
[10031]2338 /*
2339 * SW_SHOWDEFAULT is an reference to the startup info wShowWindow member.
2340 */
2341 if (nCmdShow == SW_SHOWDEFAULT)
2342 {
2343 nCmdShow = GetProcessDword(0, GPD_STARTF_SHOWWINDOW);
2344 dprintf(("ShowWindow: GetProcessDword(0, GPD_STARTF_SHOWWINDOW) -> %x", nCmdShow));
2345 }
2346
[10190]2347
[2469]2348 switch(nCmdShow)
2349 {
[4497]2350 case SW_HIDE:
2351 if (!wasVisible) goto END;
[5685]2352
2353 swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER;
[4497]2354 break;
[3584]2355
[5237]2356 case SW_SHOWMINNOACTIVE:
[4497]2357 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
2358 /* fall through */
2359 case SW_SHOWMINIMIZED:
2360 swp |= SWP_SHOWWINDOW;
2361 /* fall through */
2362 case SW_MINIMIZE:
[5685]2363 swp |= SWP_FRAMECHANGED;
2364 if( !(getStyle() & WS_MINIMIZE) ) {
2365 swp |= MinMaximize(SW_MINIMIZE, &newPos );
2366 fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
[5236]2367 }
[5685]2368 else swp |= SWP_NOSIZE | SWP_NOMOVE;
[4497]2369 break;
[2469]2370
[4497]2371 case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
[5236]2372 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
[5258]2373 if( !(getStyle() & WS_MAXIMIZE) ) {
[5236]2374 swp |= MinMaximize(SW_MAXIMIZE, &newPos );
[5258]2375 fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
2376 }
[5236]2377 else swp |= SWP_NOSIZE | SWP_NOMOVE;
2378 break;
[2469]2379
[4497]2380 case SW_SHOWNA:
[5236]2381 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
2382 /* fall through */
[4497]2383 case SW_SHOW:
2384 swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
[3662]2385
[4497]2386 /*
2387 * ShowWindow has a little peculiar behavior that if the
2388 * window is already the topmost window, it will not
2389 * activate it.
2390 */
2391 if (::GetTopWindow((HWND)0)==getWindowHandle() && (wasVisible || GetActiveWindow() == getWindowHandle()))
2392 swp |= SWP_NOACTIVATE;
[3662]2393
[4497]2394 break;
[3662]2395
[4497]2396 case SW_SHOWNOACTIVATE:
[10379]2397 swp |= SWP_NOZORDER | SWP_NOACTIVATE;
[4497]2398 /* fall through */
2399 case SW_SHOWNORMAL: /* same as SW_NORMAL: */
2400 case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
2401 case SW_RESTORE:
[8032]2402 dprintf(("ShowWindow:restoring window"));
2403
[4497]2404 swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
[5246]2405 if( getStyle() & (WS_MINIMIZE | WS_MAXIMIZE) ) {
[4497]2406 swp |= MinMaximize(SW_RESTORE, &newPos );
[5258]2407 fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
[5246]2408 }
[4497]2409 else swp |= SWP_NOSIZE | SWP_NOMOVE;
2410 break;
[2469]2411 }
[3662]2412
2413 showFlag = (nCmdShow != SW_HIDE);
2414 if (showFlag != wasVisible)
2415 {
[7801]2416 SendMessageA(getWindowHandle(),WM_SHOWWINDOW, showFlag, 0 );
[3662]2417 if (!::IsWindow( getWindowHandle() )) goto END;
[3610]2418 }
[3584]2419
[3662]2420 /* We can't activate a child window */
2421 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_MDICHILD))
2422 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
[2469]2423
[8105]2424 if (!(getStyle() & WS_MINIMIZE)) {
[9418]2425 SetWindowPos(HWND_TOP, newPos.left, newPos.top, newPos.right, newPos.bottom, LOWORD(swp), TRUE);
[8105]2426 }
2427 else OSLibWinMinimizeWindow(getOS2FrameWindowHandle());
[3587]2428
[8301]2429 if(!(swp & SWP_NOACTIVATE) && (!(getStyle() & WS_MINIMIZE))) {
[5685]2430 OSLibWinSetActiveWindow(OS2HwndFrame);
[3773]2431 }
2432
[3501]2433 if (flags & WIN_NEED_SIZE)
2434 {
2435 /* should happen only in CreateWindowEx() */
2436 int wParam = SIZE_RESTORED;
2437
2438 flags &= ~WIN_NEED_SIZE;
2439 if (dwStyle & WS_MAXIMIZE)
2440 wParam = SIZE_MAXIMIZED;
2441 else
2442 if (dwStyle & WS_MINIMIZE)
2443 wParam = SIZE_MINIMIZED;
2444
[7801]2445 SendMessageA(getWindowHandle(),WM_SIZE, wParam,
[3501]2446 MAKELONG(rectClient.right-rectClient.left,
2447 rectClient.bottom-rectClient.top));
[7801]2448 SendMessageA(getWindowHandle(),WM_MOVE,0,MAKELONG(rectClient.left,rectClient.top));
[3501]2449 }
[5440]2450//testestest
2451 //temporary workaround for file dialogs with template dialog child
[5496]2452 //they don't redraw when switching directories
[5440]2453 //For some reason the new child's (syslistview32) update rectangle stays
2454 //empty after its parent is made visible with ShowWindow
2455 //TODO: find real cause
2456 if(!wasVisible) {
2457 InvalidateRect(getWindowHandle(), NULL, TRUE);
2458 }
2459//testestest
[9418]2460
[3662]2461END:
[5258]2462 fMinMaxChange = FALSE;
[3662]2463 return wasVisible;
[2469]2464}
2465//******************************************************************************
2466//******************************************************************************
[10190]2467BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx,
[9418]2468 int cy, UINT fuFlags, BOOL fShowWindow)
[2469]2469{
2470 BOOL rc = FALSE;
2471 Win32BaseWindow *window;
2472 HWND hParent = 0;
[3662]2473 RECT oldClientRect = rectClient;
[2469]2474
2475 if (fuFlags &
2476 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
2477 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
2478 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
[4843]2479 SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_DEFERERASE |
[9550]2480 SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_ASYNCWINDOWPOS))
[2469]2481 {
[4843]2482 dprintf(("ERROR: SetWindowPos; UNKNOWN flag"));
[2469]2483 return FALSE;
2484 }
2485
[9550]2486 if( fuFlags & (SWP_DEFERERASE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_ASYNCWINDOWPOS)) {
[4843]2487 dprintf(("WARNING: SetWindowPos; unsupported flag"));
2488 }
2489
[2469]2490 if(IsWindowDestroyed()) {
2491 //changing the position of a window that's being destroyed can cause crashes in PMMERGE
2492 dprintf(("SetWindowPos; window already destroyed"));
2493 return TRUE;
2494 }
[7294]2495
[10089]2496 if(state >= STATE_CREATED) {
2497 /* Fix redundant flags */
2498 if(getStyle() & WS_VISIBLE) {
2499 fuFlags &= ~SWP_SHOWWINDOW;
2500 }
2501 else
2502 {
2503 if (!(fuFlags & SWP_SHOWWINDOW))
2504 fuFlags |= SWP_NOREDRAW;
2505 fuFlags &= ~SWP_HIDEWINDOW;
2506 }
[10585]2507 //SvL: These checks are causing problems in Lotus Notes 6
2508 // It's not entirely clear why, but child windows are not placed
[10587]2509 // correctly when enabling them.
[10585]2510#if 0
[10089]2511 if((rectWindow.right - rectWindow.left == cx) && (rectWindow.bottom - rectWindow.top == cy)) {
2512 fuFlags |= SWP_NOSIZE; /* Already the right size */
2513 }
[3482]2514
[10089]2515 if((rectWindow.left == x) && (rectWindow.top == y)) {
2516 fuFlags |= SWP_NOMOVE; /* Already the right position */
2517 }
[10585]2518#endif
[3482]2519
[10089]2520 if(getWindowHandle() == GetActiveWindow()) {
2521 fuFlags |= SWP_NOACTIVATE; /* Already active */
2522 }
2523 else
2524 if((getStyle() & (WS_POPUP | WS_CHILD)) != WS_CHILD )
[3482]2525 {
[10089]2526 if(!(fuFlags & SWP_NOACTIVATE)) /* Bring to the top when activating */
2527 {
2528 fuFlags &= ~SWP_NOZORDER;
2529 hwndInsertAfter = HWND_TOP;
2530 }
[3482]2531 }
2532 }
[10585]2533
[7294]2534 /* TODO: Check hwndInsertAfter */
[3482]2535
[6169]2536 //Note: Solitaire crashes when receiving WM_SIZE messages before WM_CREATE
2537 if(state < STATE_POST_WMNCCREATE)
[4558]2538 {//don't change size; modify internal structures only
2539 //TODO: not 100% correct yet (activate)
[6928]2540 dprintf2(("state < STATE_POST_WMNCCREATE"));
[4558]2541 if(!(fuFlags & SWP_NOZORDER)) {
2542 hwndLinkAfter = hwndInsertAfter;
2543 }
2544 if(!(fuFlags & SWP_NOMOVE)) {
2545 rectWindow.bottom = (rectWindow.bottom - rectWindow.top) + y;
2546 rectWindow.top = y;
2547 rectWindow.right = (rectWindow.right - rectWindow.left) + x;
2548 rectWindow.left = x;
2549 }
2550 if(!(fuFlags & SWP_NOSIZE)) {
2551 rectWindow.bottom = rectWindow.top + cy;
2552 rectWindow.right = rectWindow.left + cx;
2553 }
2554 return TRUE;
2555 }
2556
[2469]2557 WINDOWPOS wpos;
2558 SWP swp, swpOld;
2559 wpos.flags = fuFlags;
2560 wpos.cy = cy;
2561 wpos.cx = cx;
2562 wpos.x = x;
2563 wpos.y = y;
2564 wpos.hwndInsertAfter = hwndInsertAfter;
2565 wpos.hwnd = getWindowHandle();
2566
2567 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE))
2568 {
[3662]2569 if (isChild())
2570 {
2571 if(!getParent()) {
[4497]2572 dprintf(("WARNING: Win32BaseWindow::SetWindowPos window %x is child but has no parent!!", getWindowHandle()));
[3662]2573 }
[2469]2574 }
[5685]2575 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
[2469]2576 }
[10190]2577 if((dwOldStyle & WS_MINIMIZE) && (getStyle() & WS_MINIMIZE))
[9418]2578 {//don't allow size changes if the window is minimized
2579 //we will update the restore position at the end of this method
2580 if(!(wpos.flags & SWP_NOSIZE)) {
[9463]2581 //TODO: updating the window rectangle doesn't look right
[9418]2582 wpos.flags |= SWP_NOSIZE;
2583 rectWindow.right = rectWindow.left + wpos.cx;
2584 rectWindow.bottom = rectWindow.top + wpos.cy;
[9463]2585 dprintf(("WARNING: Don't allow size change for minimized window; only save new restore position"));
2586 dprintf(("new window rectangle (%d,%d)(%d,%d)", rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
[9418]2587 }
2588 }
[2469]2589
[10396]2590 // Hack alert: This makes sure the tooltips windows in OpenOffice don't
[10379]2591 // activate the owner windows too.
2592 // First condition takes care of SetWindowPos during window
2593 // creation. The 2nd one for calls made by OpenOffice
[10396]2594 if(((getStyle() & WS_POPUP) && (getExStyle() & WS_EX_TOPMOST)) || (fuFlags & SWP_NOOWNERZORDER))
2595 {
[10379]2596 //SWP_NOOWNERZORDER means only the z-order of this window changes; it
2597 //should not affect the owner
2598 //PM doesn't support this feature, so this hack might work
2599 wpos.flags |= SWP_NOZORDER;
2600 }
2601
[3662]2602 if(getParent()) {
[5685]2603 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, getParent()->getClientHeight(),
[6008]2604 OS2HwndFrame);
[4497]2605 }
[5685]2606 else OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, OSLibQueryScreenHeight(), OS2HwndFrame);
2607
[2469]2608 if (swp.fl == 0) {
[6928]2609 dprintf2(("swp.fl == 0"));
[3662]2610 if(fuFlags & SWP_FRAMECHANGED)
[4497]2611 {
[4628]2612 NotifyFrameChanged(&wpos, &oldClientRect);
[2469]2613 }
[10033]2614 if(!fShowWindow && !(getStyle() & (WS_MINIMIZE|WS_MAXIMIZE)) && !(fuFlags & (SWP_NOSIZE | SWP_NOMOVE)))
[9418]2615 {
2616 //Restore position always changes when the window position is changed
[9778]2617 dprintf(("Save new restore position %x (%d,%d)(%d,%d)", getWindowHandle(), rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
[9418]2618 windowpos.rcNormalPosition = rectWindow;
2619 }
[2469]2620 return TRUE;
2621 }
2622
2623// if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
2624 if ((swp.hwndInsertBehind > HWNDOS_BOTTOM))
2625 {
2626 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
2627 if(wndBehind) {
[5685]2628 swp.hwndInsertBehind = wndBehind->getOS2FrameWindowHandle();
[5950]2629 RELEASE_WNDOBJ(wndBehind);
[2469]2630 }
2631 else {
2632 dprintf(("ERROR: SetWindowPos: hwndInsertBehind %x invalid!",swp.hwndInsertBehind));
2633 swp.hwndInsertBehind = 0;
2634 }
2635 }
[5685]2636 swp.hwnd = OS2HwndFrame;
[2469]2637
[9590]2638 //SvL: Must also deactivate the window when hiding it or else focus won't
2639 // change. (NOTE: make sure this doesn't cause regressions (01-02-2003)
[10190]2640 if((swp.fl & (SWPOS_HIDE|SWPOS_DEACTIVATE)) == (SWPOS_HIDE|SWPOS_DEACTIVATE))
[9590]2641 {
2642 //we must make sure the owner is not disabled or else the focus will
2643 //be switched to the wrong window
2644 Win32BaseWindow *topOwner;
2645
2646 if(getOwner() == NULL) {
2647 windowDesktop->addRef();
2648 topOwner = windowDesktop;
2649 }
2650 else topOwner = GetWindowFromHandle(getOwner()->GetTopParent());
2651
2652 if(topOwner != NULL) {
2653 DWORD dwStyle = topOwner->GetWindowLong(GWL_STYLE, FALSE);
2654 if(dwStyle & WS_DISABLED) {
2655 swp.fl &= ~SWPOS_DEACTIVATE;
2656 }
2657 }
2658 else DebugInt3();
2659 }
2660
[5586]2661 if(fuFlags & SWP_SHOWWINDOW && !IsWindowVisible(getWindowHandle())) {
[3584]2662 setStyle(getStyle() | WS_VISIBLE);
[4497]2663 if(hTaskList) {
2664 dprintf(("Adding window %x to tasklist", getWindowHandle()));
[5685]2665 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), 1);
[4497]2666 }
[2569]2667 }
[3488]2668 else
[5586]2669 if((fuFlags & SWP_HIDEWINDOW) && IsWindowVisible(getWindowHandle())) {
[3584]2670 setStyle(getStyle() & ~WS_VISIBLE);
[5236]2671 if(hTaskList && !(getStyle() & WS_MINIMIZE)) {
[4497]2672 dprintf(("Removing window %x from tasklist", getWindowHandle()));
[5685]2673 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), 0);
[4497]2674 }
[3488]2675 }
[3800]2676 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
[9418]2677
[3800]2678 rc = OSLibWinSetMultWindowPos(&swp, 1);
[3603]2679 if(rc == FALSE)
[2469]2680 {
2681 dprintf(("OSLibWinSetMultWindowPos failed! Error %x",OSLibWinGetLastError()));
[4497]2682 return 0;
[2469]2683 }
[3603]2684
[3144]2685 if((fuFlags & SWP_FRAMECHANGED) && (fuFlags & (SWP_NOMOVE | SWP_NOSIZE) == (SWP_NOMOVE | SWP_NOSIZE)))
[2469]2686 {
[5685]2687 NotifyFrameChanged(&wpos, &oldClientRect);
[2469]2688 }
[10033]2689 if(!fShowWindow && !(getStyle() & (WS_MINIMIZE|WS_MAXIMIZE)))
[9418]2690 {
[7734]2691 //Restore position always changes when the window position is changed
[9778]2692 dprintf(("Save new restore position %x (%d,%d)(%d,%d)", getWindowHandle(), rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
[7734]2693 windowpos.rcNormalPosition = rectWindow;
2694 }
[9635]2695 //MSDN says the entire client area will be invalidated when SWP_NOCOPYBITS
2696 //is specified (fixes repaint issues when window is made smaller)
2697 if((fuFlags & (SWP_NOCOPYBITS|SWP_NOREDRAW)) == SWP_NOCOPYBITS) {
2698 InvalidateRect(getWindowHandle(), NULL, TRUE);
2699 }
[10485]2700
[10587]2701 if(!(fuFlags & SWP_NOSIZE))
[10485]2702 {
2703 // We must call this function or open DC will get out of sync
2704 // (PM will not always send us a WM_VRNENABLED message)
2705 RecalcVisibleRegion(this);
2706 }
[2469]2707 return (rc);
2708}
2709//******************************************************************************
[5215]2710//Called by ScrollWindowEx (dc.cpp) to notify child window that it has moved
[4628]2711//******************************************************************************
[5215]2712BOOL Win32BaseWindow::ScrollWindow(int dx, int dy)
2713{
2714 rectWindow.left += dx;
2715 rectWindow.right += dx;
2716 rectWindow.top += dy;
2717 rectWindow.bottom += dy;
[7801]2718 SendMessageA(getWindowHandle(),WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
[5215]2719 return TRUE;
2720}
2721//******************************************************************************
2722//******************************************************************************
[4628]2723void Win32BaseWindow::NotifyFrameChanged(WINDOWPOS *wpos, RECT *oldClientRect)
2724{
[4839]2725 HRGN hrgn, hrgnClient;
2726 RECT rect;
2727
[4628]2728 MsgFormatFrame(NULL);
[4945]2729
[4825]2730 if(RECT_WIDTH(rectClient) != RECT_WIDTH(*oldClientRect) ||
2731 RECT_HEIGHT(rectClient) != RECT_HEIGHT(*oldClientRect))
[4628]2732 {
[4945]2733 wpos->flags &= ~(SWP_NOSIZE|SWP_NOCLIENTSIZE);
2734 wpos->cx = RECT_WIDTH(rectWindow);
2735 wpos->cy = RECT_HEIGHT(rectWindow);
[4628]2736 }
2737
[5056]2738 if(rectClient.left != oldClientRect->left ||
[4945]2739 rectClient.top != oldClientRect->top)
2740 {
2741 wpos->flags &= ~(SWP_NOMOVE|SWP_NOCLIENTMOVE);
2742 wpos->x = rectWindow.left;
2743 wpos->y = rectWindow.top;
2744 }
[10190]2745
[4628]2746 WINDOWPOS wpOld = *wpos;
[7294]2747 if(!(wpos->flags & SWP_NOSENDCHANGING))
[7801]2748 SendMessageA(getWindowHandle(),WM_WINDOWPOSCHANGING, 0, (LPARAM)wpos);
[4628]2749
2750 if ((wpos->hwndInsertAfter != wpOld.hwndInsertAfter) ||
2751 (wpos->x != wpOld.x) || (wpos->y != wpOld.y) || (wpos->cx != wpOld.cx) || (wpos->cy != wpOld.cy) || (wpos->flags != wpOld.flags))
2752 {
2753 dprintf(("WARNING, NotifyFrameChanged: TODO -> adjust flags!!!!"));
2754 SetWindowPos(wpos->hwndInsertAfter, wpos->x, wpos->y, wpos->cx, wpos->cy, wpos->flags | SWP_NOSENDCHANGING);
2755 }
[7801]2756 else SendMessageA(getWindowHandle(),WM_WINDOWPOSCHANGED, 0, (LPARAM)wpos);
[4839]2757
[5246]2758 //Calculate invalid areas
[4839]2759 rect = rectWindow;
2760 OffsetRect(&rect, -rectWindow.left, -rectWindow.top);
2761 hrgn = CreateRectRgnIndirect(&rect);
2762 if (!hrgn) {
2763 dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
2764 return;
2765 }
2766 rect = rectClient;
2767 hrgnClient = CreateRectRgnIndirect(&rect);
2768 if (!hrgn) {
2769 dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
2770 return;
2771 }
2772 CombineRgn(hrgn, hrgn, hrgnClient, RGN_DIFF);
2773 DeleteObject(hrgnClient);
2774
2775 if(!EqualRect(oldClientRect, &rectClient)) {
2776 UnionRect(oldClientRect, oldClientRect, &rectClient);
2777 hrgnClient = CreateRectRgnIndirect(oldClientRect);
2778 if (!hrgn) {
2779 dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
2780 return;
2781 }
2782 CombineRgn(hrgn, hrgn, hrgnClient, RGN_OR);
2783 DeleteObject(hrgnClient);
2784 }
[5246]2785 RedrawWindow(getWindowHandle(), NULL, hrgn, RDW_ALLCHILDREN |
2786 RDW_INVALIDATE | RDW_ERASE | RDW_FRAME);
[4839]2787 DeleteObject(hrgn);
[4628]2788}
2789//******************************************************************************
[3873]2790//TODO: Check how this api really works in NT
[2469]2791//******************************************************************************
[3662]2792BOOL Win32BaseWindow::SetWindowPlacement(WINDOWPLACEMENT *wndpl)
[2469]2793{
[5373]2794 dprintf(("SetWindowPlacement %x min (%d,%d)", getWindowHandle(), wndpl->ptMinPosition.x, wndpl->ptMinPosition.y));
2795 dprintf(("SetWindowPlacement %x max (%d,%d)", getWindowHandle(), wndpl->ptMaxPosition.x, wndpl->ptMaxPosition.y));
2796 dprintf(("SetWindowPlacement %x norm (%d,%d)(%d,%d)", getWindowHandle(), wndpl->rcNormalPosition.left, wndpl->rcNormalPosition.top, wndpl->rcNormalPosition.right, wndpl->rcNormalPosition.bottom));
[3662]2797 windowpos.ptMinPosition = wndpl->ptMinPosition;
2798 windowpos.ptMaxPosition = wndpl->ptMaxPosition;
2799 windowpos.rcNormalPosition = wndpl->rcNormalPosition;
2800
2801 if(getStyle() & WS_MINIMIZE )
[2469]2802 {
[5236]2803 //TODO: Why can't this be (0,0)?
2804 if(wndpl->flags & WPF_SETMINPOSITION && !(!windowpos.ptMinPosition.x && !windowpos.ptMinPosition.y)) {
2805 SetWindowPos(0, windowpos.ptMinPosition.x, windowpos.ptMinPosition.y,
2806 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
2807 }
[3662]2808 }
2809 else
2810 if(getStyle() & WS_MAXIMIZE )
2811 {
[4497]2812 //TODO: Why can't this be (0,0)?
2813 if(windowpos.ptMaxPosition.x != 0 || windowpos.ptMaxPosition.y != 0 )
2814 SetWindowPos(0, windowpos.ptMaxPosition.x, windowpos.ptMaxPosition.y,
2815 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
[3662]2816 }
2817 else {
[3873]2818 SetWindowPos(0, windowpos.rcNormalPosition.left, windowpos.rcNormalPosition.top,
[4497]2819 windowpos.rcNormalPosition.right - windowpos.rcNormalPosition.left,
2820 windowpos.rcNormalPosition.bottom - windowpos.rcNormalPosition.top,
2821 SWP_NOZORDER | SWP_NOACTIVATE );
[3662]2822 }
2823 ShowWindow(wndpl->showCmd);
2824 if( ::IsWindow(getWindowHandle()) && getStyle() & WS_MINIMIZE )
2825 {
[4497]2826 /* SDK: ...valid only the next time... */
2827 if(wndpl->flags & WPF_RESTORETOMAXIMIZED)
[7734]2828 setFlags(getFlags() | WIN_RESTORE_MAX);
[3662]2829 }
2830 return TRUE;
2831}
2832//******************************************************************************
2833//******************************************************************************
2834BOOL Win32BaseWindow::GetWindowPlacement(LPWINDOWPLACEMENT wndpl)
2835{
[4497]2836 wndpl->length = sizeof(*wndpl);
[3662]2837 if(getStyle() & WS_MINIMIZE )
[4497]2838 wndpl->showCmd = SW_SHOWMINIMIZED;
[3662]2839 else wndpl->showCmd = (getStyle() & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
[2469]2840
[4497]2841 //TODO: Verify if this is correct -> SDK docs claim this flag must always be set to 0
[3662]2842 if(getFlags() & WIN_RESTORE_MAX )
2843 wndpl->flags = WPF_RESTORETOMAXIMIZED;
2844 else wndpl->flags = 0;
[2469]2845
[3662]2846 wndpl->ptMinPosition = windowpos.ptMinPosition;
2847 wndpl->ptMaxPosition = windowpos.ptMaxPosition;
[4497]2848 //Must be in parent coordinates (or screen if no parent); verified in NT4, SP6
[8101]2849 wndpl->rcNormalPosition = windowpos.rcNormalPosition;
[2469]2850
[3662]2851 return TRUE;
[2469]2852}
2853//******************************************************************************
2854//Also destroys all the child windows (destroy children first, parent last)
[9101]2855//TODO: Don't rely on PM to do the right thing. Send WM_(NC)DESTROY &
2856// destroy children ourselves (see Wine)
[2469]2857//******************************************************************************
2858BOOL Win32BaseWindow::DestroyWindow()
2859{
[8999]2860 HWND hwnd = getWindowHandle();
[3501]2861
2862 dprintf(("DestroyWindow %x", hwnd));
2863
[8999]2864#if 0
2865 /* Look whether the focus is within the tree of windows we will
2866 * be destroying.
2867 */
2868 HWND hwndFocus = GetFocus();
2869 if (hwndFocus == hwnd || ::IsChild( hwnd, hwndFocus ))
2870 {
2871 HWND parent = GetAncestor( hwnd, GA_PARENT );
2872 if (parent == GetDesktopWindow()) parent = 0;
2873 SetFocus( parent );
2874 }
2875#endif
[2469]2876 /* Call hooks */
2877 if(HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, getWindowHandle(), 0L))
2878 {
2879 return FALSE;
2880 }
[10190]2881
[2469]2882 if(!(getStyle() & WS_CHILD) && getOwner() == NULL)
2883 {
2884 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWDESTROYED, getWindowHandle(), 0L);
2885 /* FIXME: clean up palette - see "Internals" p.352 */
2886 }
2887
2888 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
2889 {
[3853]2890 if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
[2469]2891 {
2892 /* Notify the parent window only */
[7801]2893 SendMessageA(getParent()->getWindowHandle(), WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
[3501]2894 if(!::IsWindow(hwnd) )
[2469]2895 {
2896 return TRUE;
2897 }
2898 }
[3853]2899//// else DebugInt3();
[2469]2900 }
[10332]2901 //Must remove the switch entry here to avoid problems with XWorkPlace
2902 if(hTaskList) {
2903 OSLibWinRemoveFromTasklist(hTaskList);
2904 hTaskList = 0;
2905 }
2906
[3501]2907 /* Hide the window */
[5586]2908 if(IsWindowVisible(getWindowHandle()))
[3501]2909 {
2910 SetWindowPos(0, 0, 0, 0, 0, SWP_HIDEWINDOW |
[3584]2911 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
[3501]2912 if(!::IsWindow(hwnd))
2913 {
[3584]2914 return TRUE;
[3501]2915 }
2916 }
2917 dprintf(("DestroyWindow %x -> HIDDEN", hwnd));
[10190]2918
[6972]2919 // check the handle for the last active popup window
2920 Win32BaseWindow* owner = getOwner();
2921 if (NULL != owner)
2922 {
[7801]2923 if (owner->getLastActive() == hwnd)
2924 owner->setLastActive( owner->getWindowHandle() );
[8999]2925
2926 //SvL: Not sure this is correct, but it solves the problem of reassigning
2927 // activation. A disabled window will never be activated ->
2928 // possible that the wrong window is chosen by PM.
2929 // PM chooses another window to be activated before WM_DESTROY is
2930 // sent. VPC enables the owner when it receives that message,
2931 // but by then it's too late.
[9001]2932 // (MFC created modeless dialog)
2933 //TODO: This might be the wrong place to do it. EndDialog is called,
[10190]2934 // so perhaps it should be done there. (although Wine only
[9001]2935 // enables the owner if the dialog is modal)
[8999]2936 ::EnableWindow(owner->getWindowHandle(), 1);
[6972]2937 }
[10190]2938
[2469]2939 fDestroyWindowCalled = TRUE;
[9101]2940
2941//hack alert; PM crashes if child calls DestroyWindow for parent/owner in WM_DESTROY
2942// handler; must postpone it
2943 if(fChildDestructionInProgress) {
2944 dprintf(("Postponing parent destruction because of dying child"));
2945 OSLibPostMessageDirect(OS2HwndFrame, WIN32APP_POSTPONEDESTROY, 0, 0);
2946 return TRUE;
2947 }
2948
2949 BOOL fOldChildDestructionInProgress = FALSE;
2950 if(GetParent()) {
2951 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(GetParent());
2952 if(window) {
2953 fOldChildDestructionInProgress = window->IsChildDestructionInProgress();
2954 window->SetChildDestructionInProgress(TRUE);
2955 RELEASE_WNDOBJ(window);
2956 }
2957 }
2958//hack end
2959
2960 BOOL ret = OSLibWinDestroyWindow(OS2HwndFrame);
2961
2962//hack alert; PM crashes if child calls DestroyWindow for parent/owner in WM_DESTROY
2963// handler; must postpone it
2964 if(GetParent()) {
2965 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(GetParent());
2966 if(window) {
2967 window->SetChildDestructionInProgress(fOldChildDestructionInProgress);
2968 RELEASE_WNDOBJ(window);
2969 }
2970 }
2971//hack end
2972 return ret;
[2469]2973}
2974//******************************************************************************
2975//******************************************************************************
2976Win32BaseWindow *Win32BaseWindow::getParent()
2977{
[8377]2978 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
2979 //experiment
2980#if 0
2981 return ((ULONG)wndparent == (ULONG)windowDesktop) ? NULL : wndparent;
2982#else
2983 return wndparent;
2984#endif
[2469]2985}
2986//******************************************************************************
[10316]2987// Win32BaseWindow::GetParent
2988//
2989// If the window is a child window, then return the parent window handle.
2990// If it's a popup window, then return the owner
2991//
2992// Returns window handle of parent or owner window
2993//
2994// Note: does not set last error if no parent (verified in NT4, SP6)
[2469]2995//******************************************************************************
2996HWND Win32BaseWindow::GetParent()
2997{
[3663]2998 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
2999
[10190]3000 if(getStyle() & WS_CHILD)
[8377]3001 {
3002 if(wndparent) {
3003 return wndparent->getWindowHandle();
3004 }
3005 dprintf(("WARNING: GetParent: WS_CHILD but no parent!!"));
3006 DebugInt3();
3007 return 0;
3008 }
[10190]3009 else
[8377]3010 if(getStyle() & WS_POPUP)
3011 return (getOwner()) ? getOwner()->getWindowHandle() : 0;
3012 else return 0;
[2469]3013}
3014//******************************************************************************
3015//******************************************************************************
3016HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
3017{
[8377]3018 HWND oldhwnd;
3019 Win32BaseWindow *newparent;
3020 Win32BaseWindow *oldparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
3021 BOOL fShow = FALSE;
[2469]3022
[8377]3023 if(oldparent) {
[3251]3024 oldhwnd = oldparent->getWindowHandle();
[3663]3025 oldparent->removeChild(this);
[8377]3026 }
3027 else oldhwnd = 0;
[2469]3028
[8377]3029 /* Windows hides the window first, then shows it again
3030 * including the WM_SHOWWINDOW messages and all */
3031 if(IsWindowCreated() && (getStyle() & WS_VISIBLE)) {
[4497]3032 ShowWindow(SW_HIDE);
[4839]3033 fShow = TRUE;
[8377]3034 }
3035 if(oldparent) {
[6166]3036 //release parent here (increased refcount during creation)
[5950]3037 RELEASE_WNDOBJ(oldparent);
[8377]3038 }
3039 newparent = GetWindowFromHandle(hwndNewParent);
3040 if(newparent && !newparent->isDesktopWindow())
3041 {
[2469]3042 setParent(newparent);
[3663]3043 getParent()->addChild(this);
[6166]3044 fParentChange = TRUE;
[8943]3045 // in case we haven't finished creating the window whose parent we're
3046 // setting here, the OS/2 HWND might not exist yet and we call the PM
3047 // API with a NULLHANDLE - no problem
3048 // when we create the OS/2 window lateron, we will create it with the
3049 // right parent anyway.
[5685]3050 OSLibWinSetParent(getOS2FrameWindowHandle(), getParent()->getOS2WindowHandle());
[3663]3051 if(!(getStyle() & WS_CHILD))
3052 {
[4497]3053 if(getWindowId())
[5685]3054 {
3055 DestroyMenu( (HMENU) getWindowId() );
3056 setWindowId(0);
3057 }
[3663]3058 }
[6166]3059 //SvL: Even though the win32 coordinates might not change, the PM
3060 // coordinates can. We must make sure the control stays at the
3061 // same position (y) relative to the (new) parent.
[8944]3062 // TODO: shouldn't we check the state of the window and not do it in INIT state?
[6166]3063 SetWindowPos(HWND_TOPMOST, rectWindow.left, rectWindow.top, 0, 0,
3064 SWP_NOACTIVATE|SWP_NOSIZE);
3065 fParentChange = FALSE;
[8377]3066 }
3067 else {
[5951]3068 if(newparent) RELEASE_WNDOBJ(newparent);
3069
[2469]3070 setParent(windowDesktop);
[5951]3071 windowDesktop->addRef();
[3663]3072 windowDesktop->addChild(this);
[5685]3073 OSLibWinSetParent(getOS2FrameWindowHandle(), OSLIB_HWND_DESKTOP);
[4497]3074
[9342]3075 //Do not change the window id!
3076//// setWindowId(0);
[8377]3077 }
3078 /* SetParent additionally needs to make hwndChild the topmost window
3079 in the x-order and send the expected WM_WINDOWPOSCHANGING and
3080 WM_WINDOWPOSCHANGED notification messages.
3081 */
3082 if(state >= STATE_PRE_WMNCCREATE) {
[4839]3083 SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0,
3084 SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|(fShow? SWP_SHOWWINDOW : 0));
[3662]3085
[8377]3086 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
3087 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
3088 }
3089 return oldhwnd;
[2469]3090}
3091//******************************************************************************
3092//******************************************************************************
3093BOOL Win32BaseWindow::IsChild(HWND hwndParent)
3094{
[8377]3095 // PH: Optimizer won't unroll calls to getParent() even
3096 // in release build.
3097 Win32BaseWindow *_parent = getParent();
[10190]3098
3099 if(_parent)
[8377]3100 {
3101 if(_parent->getWindowHandle() == hwndParent)
3102 return TRUE;
[10190]3103
[8377]3104 return _parent->IsChild(hwndParent);
3105 }
[10190]3106 else
[8377]3107 return 0;
[2469]3108}
3109//******************************************************************************
3110//******************************************************************************
3111HWND Win32BaseWindow::GetTopWindow()
3112{
[8377]3113 HWND hwndTop;
3114 Win32BaseWindow *topwindow;
[3679]3115
3116 hwndTop = OSLibWinQueryWindow(getOS2WindowHandle(), QWOS_TOP);
[5685]3117 if(!isDesktopWindow())
3118 {
3119 topwindow = GetWindowFromOS2FrameHandle(hwndTop);
[6169]3120 //Note: GetTopWindow can't return a window that hasn't processed
3121 // WM_NCCREATE yet (verified in NT4, SP6)
[6173]3122 if(topwindow) {
3123 if(topwindow->state >= STATE_POST_WMNCCREATE) {
3124 hwndTop = topwindow->getWindowHandle();
3125 }
3126 else hwndTop = topwindow->GetWindow(GW_HWNDNEXT);
[5935]3127 RELEASE_WNDOBJ(topwindow);
3128 return hwndTop;
[5685]3129 }
[6169]3130 if(topwindow) RELEASE_WNDOBJ(topwindow);
[5685]3131 return 0;
[3679]3132 }
3133 while(hwndTop) {
[5685]3134 topwindow = GetWindowFromOS2FrameHandle(hwndTop);
[6169]3135 //Note: GetTopWindow can't return a window that hasn't processed
3136 // WM_NCCREATE yet (verified in NT4, SP6)
[6173]3137 if(topwindow) {
3138 if(topwindow->state >= STATE_POST_WMNCCREATE) {
3139 hwndTop = topwindow->getWindowHandle();
3140 }
3141 else hwndTop = topwindow->GetWindow(GW_HWNDNEXT);
[5935]3142 RELEASE_WNDOBJ(topwindow);
3143 return hwndTop;
[5685]3144 }
[6169]3145 if(topwindow) RELEASE_WNDOBJ(topwindow);
[4497]3146 hwndTop = OSLibWinQueryWindow(hwndTop, QWOS_NEXT);
3147 }
[3679]3148
3149 return 0;
[2469]3150}
3151//******************************************************************************
3152// Get the top-level parent for a child window.
3153//******************************************************************************
[5935]3154HWND Win32BaseWindow::GetTopParent()
[2469]3155{
[8377]3156 Win32BaseWindow *window = this;
3157 HWND hwndTopParent = 0;
[2469]3158
[5935]3159 lock();
[2469]3160 while(window && (window->getStyle() & WS_CHILD))
3161 {
3162 window = window->getParent();
3163 }
[5935]3164 if(window) {
3165 hwndTopParent = window->getWindowHandle();
3166 }
3167 unlock();
3168 return hwndTopParent;
[2469]3169}
3170//******************************************************************************
3171//TODO: Should not enumerate children that are created during the enumeration!
[7801]3172//TODO: Do this more efficiently
[2469]3173//******************************************************************************
3174BOOL Win32BaseWindow::EnumChildWindows(WNDENUMPROC lpfn, LPARAM lParam)
3175{
[8377]3176 BOOL rc = TRUE;
3177 HWND hwnd;
3178 Win32BaseWindow *prevchild = 0, *child = 0;
[2469]3179
3180 dprintf(("EnumChildWindows of %x parameter %x %x (%x)", getWindowHandle(), lpfn, lParam, getFirstChild()));
[5968]3181 lock();
[7464]3182 for (child = (Win32BaseWindow *)getFirstChild(); child != NULL; child = (Win32BaseWindow *)child->getNextChild())
[2469]3183 {
[3747]3184 dprintf(("EnumChildWindows: enumerating child %x (owner %x; parent %x)", child->getWindowHandle(), (child->getOwner()) ? child->getOwner()->getWindowHandle() : 0, getWindowHandle()));
[2469]3185 hwnd = child->getWindowHandle();
[5968]3186 if(child->IsWindowDestroyed() || child->getOwner()) {
[2469]3187 continue; //shouldn't have an owner (Wine)
3188 }
[5968]3189 child->addRef();
3190 unlock();
[10379]3191 if(WrapCallback2((WNDPROC)lpfn, hwnd, lParam) == FALSE)
[2469]3192 {
[5968]3193 child->release();
3194 return FALSE;
[2469]3195 }
[5968]3196 child->release();
3197 lock();
[2469]3198 //check if the window still exists
3199 if(!::IsWindow(hwnd))
3200 {
3201 child = prevchild;
[7464]3202 if(child == NULL) break;
[2469]3203 continue;
3204 }
3205 if(child->getFirstChild() != NULL)
3206 {
3207 dprintf(("EnumChildWindows: Enumerate children of %x", child->getWindowHandle()));
[5968]3208 child->addRef();
3209 unlock();
[2469]3210 if(child->EnumChildWindows(lpfn, lParam) == FALSE)
3211 {
[5968]3212 child->release();
3213 return FALSE;
[2469]3214 }
[5968]3215 child->release();
3216 lock();
[2469]3217 }
3218 prevchild = child;
3219 }
[5968]3220 unlock();
[2469]3221 return rc;
3222}
3223//******************************************************************************
3224//Enumerate first-level children only and check thread id
[9783]3225//NOTE: NT4 returns first-level children in Z-order!
[2469]3226//******************************************************************************
3227BOOL Win32BaseWindow::EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
3228{
[9783]3229 Win32BaseWindow *wnd = NULL;
3230 HWND henum, hwnd, hwndWin32;
[8377]3231 ULONG tid, pid;
3232 BOOL rc;
[2469]3233
[9783]3234 //Enumerate all top-level windows and check the process and thread ids
3235 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
3236 hwnd = OSLibWinGetNextWindow(henum);
[2469]3237
[9783]3238 while(hwnd)
[2469]3239 {
[9783]3240 wnd = GetWindowFromOS2FrameHandle(hwnd);
3241 if(wnd) {
3242 hwndWin32 = wnd->getWindowHandle();
3243 }
3244 else hwndWin32 = 0;
[2469]3245
[9783]3246 if(wnd) RELEASE_WNDOBJ(wnd);
3247
3248 if(hwndWin32) {
3249 OSLibWinQueryWindowProcess(hwnd, &pid, &tid);
3250
3251 if(dwThreadId == tid) {
3252 dprintf(("EnumThreadWindows: Found Window %x", hwndWin32));
[10379]3253 if((rc = WrapCallback2((WNDPROC)lpfn, hwndWin32, lParam)) == FALSE) {
[9783]3254 break;
3255 }
[2469]3256 }
3257 }
[9783]3258 hwnd = OSLibWinGetNextWindow(henum);
[2469]3259 }
[9783]3260 OSLibWinEndEnumWindows(henum);
[2469]3261 return TRUE;
3262}
3263//******************************************************************************
3264//Enumerate first-level children only
3265//******************************************************************************
3266BOOL Win32BaseWindow::EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
3267{
[8377]3268 Win32BaseWindow *window;
3269 BOOL rc;
3270 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
3271 DWORD dwStyle;
[2469]3272
3273 dprintf(("EnumWindows %x %x", lpfn, lParam));
3274
[10190]3275 for(int i=0;i<MAX_WINDOW_HANDLES;i++)
[2469]3276 {
[8210]3277 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
3278 if(window) {
3279 if(window->getWindowHandle() != hwnd) {
3280 dprintf(("CORRUPT WINDOW %x %x", window, hwnd));
3281 }
3282 RELEASE_WNDOBJ(window);
3283 dwStyle = ::GetWindowLongA(hwnd, GWL_STYLE);
3284 if ((dwStyle & WS_POPUP) || ((dwStyle & WS_CAPTION) == WS_CAPTION))
[7801]3285 {
[8210]3286 dprintf2(("EnumWindows: Found Window %x", hwnd));
[10379]3287 if((rc = WrapCallback2((WNDPROC)lpfn, hwnd, lParam)) == FALSE) {
[7801]3288 break;
3289 }
3290 }
[2469]3291 }
[8210]3292 hwnd++;
[2469]3293 }
3294 return TRUE;
3295}
3296//******************************************************************************
3297//******************************************************************************
[5935]3298HWND Win32BaseWindow::FindWindowById(int id)
[2469]3299{
[6012]3300 HWND hwnd;
3301
[5935]3302 lock();
[2469]3303 for (Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
3304 {
3305 if (child->getWindowId() == id)
3306 {
[6012]3307 hwnd = child->getWindowHandle();
[5935]3308 unlock();
[6012]3309 return hwnd;
[2469]3310 }
3311 }
[5935]3312 unlock();
[2469]3313 return 0;
3314}
3315//******************************************************************************
3316//TODO:
3317//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
3318//the current process owns them.
3319//******************************************************************************
[2956]3320HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, ATOM atom, LPSTR lpszWindow)
[2469]3321{
[8377]3322 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
3323 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
3324 Win32BaseWindow *firstchild = child;
[2469]3325
[2956]3326 dprintf(("FindWindowEx %x %x %x %s", hwndParent, hwndChildAfter, atom, lpszWindow));
3327 if((hwndParent != 0 && !parent) ||
[2469]3328 (hwndChildAfter != 0 && !child) ||
[2956]3329 (hwndParent == 0 && hwndChildAfter != 0))
[2469]3330 {
[5950]3331 if(parent) RELEASE_WNDOBJ(parent);
3332 if(firstchild) RELEASE_WNDOBJ(firstchild);
[2469]3333 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
3334 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
3335 return 0;
3336 }
[2956]3337 SetLastError(0);
3338 if(hwndParent != 0)
[2469]3339 {//if the current process owns the window, just do a quick search
[5950]3340 lock(&critsect);
[2469]3341 child = (Win32BaseWindow *)parent->getFirstChild();
3342 if(hwndChildAfter != 0)
3343 {
3344 while(child)
3345 {
3346 if(child->getWindowHandle() == hwndChildAfter)
3347 {
3348 child = (Win32BaseWindow *)child->getNextChild();
3349 break;
3350 }
3351 child = (Win32BaseWindow *)child->getNextChild();
3352 }
3353 }
3354 while(child)
3355 {
[2956]3356 //According to Wine, the class doesn't need to be specified
3357 if((!atom || child->getWindowClass()->getAtom() == atom) &&
3358 (!lpszWindow || child->hasWindowName(lpszWindow)))
[2469]3359 {
3360 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
[5950]3361 HWND hwndChild = child->getWindowHandle();
3362 unlock(&critsect);
3363 if(parent) RELEASE_WNDOBJ(parent);
3364 if(firstchild) RELEASE_WNDOBJ(firstchild);
3365 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
3366 return hwndChild;
[2469]3367 }
3368 child = (Win32BaseWindow *)child->getNextChild();
3369 }
[5950]3370 unlock(&critsect);
3371 if(parent) RELEASE_WNDOBJ(parent);
3372 if(firstchild) RELEASE_WNDOBJ(firstchild);
[2469]3373 }
3374 else {
3375 Win32BaseWindow *wnd;
3376 HWND henum, hwnd;
3377
3378 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
3379 hwnd = OSLibWinGetNextWindow(henum);
3380
3381 while(hwnd)
3382 {
[5685]3383 wnd = GetWindowFromOS2FrameHandle(hwnd);
[2469]3384 if(wnd) {
[2956]3385 //According to Wine, the class doesn't need to be specified
3386 if((!atom || wnd->getWindowClass()->getAtom() == atom) &&
3387 (!lpszWindow || wnd->hasWindowName(lpszWindow)))
[2469]3388 {
3389 OSLibWinEndEnumWindows(henum);
3390 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
[5935]3391 HWND hwndret = wnd->getWindowHandle();
3392 RELEASE_WNDOBJ(wnd);
3393 return hwndret;
[2469]3394 }
[5935]3395 RELEASE_WNDOBJ(wnd);
[2469]3396 }
3397 hwnd = OSLibWinGetNextWindow(henum);
3398 }
3399 OSLibWinEndEnumWindows(henum);
[5950]3400 if(parent) RELEASE_WNDOBJ(parent);
3401 if(firstchild) RELEASE_WNDOBJ(firstchild);
[2469]3402 }
3403 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
3404 return 0;
3405}
3406//******************************************************************************
3407//******************************************************************************
3408HWND Win32BaseWindow::GetWindow(UINT uCmd)
3409{
3410 HWND hwndRelated = 0;
3411 Win32BaseWindow *window;
3412
3413 switch(uCmd)
3414 {
3415 case GW_HWNDFIRST:
[7090]3416 window = (Win32BaseWindow *)getParent();
3417 if(window)
[4825]3418 {
3419 hwndRelated = OSLibWinQueryWindow(window->getOS2WindowHandle(), QWOS_TOP);
[5685]3420 window = GetWindowFromOS2FrameHandle(hwndRelated);
[4825]3421 if(window) {
[5685]3422 hwndRelated = window->getWindowHandle();
[5935]3423 RELEASE_WNDOBJ(window);
[4825]3424 }
3425 else hwndRelated = 0;
[4203]3426 }
[5685]3427 else {
3428 dprintf(("WARNING: GW_HWNDFIRST not correctly implemented for toplevel/most windows!"));
3429 hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
3430 }
[4203]3431 break;
3432
3433 case GW_HWNDLAST:
[7090]3434 window = (Win32BaseWindow *)getParent();
3435 if(window) {
[5685]3436 hwndRelated = OSLibWinQueryWindow(window->getOS2WindowHandle(), QWOS_BOTTOM);
3437 dprintf(("os2 handle %x", hwndRelated));
3438 window = GetWindowFromOS2FrameHandle(hwndRelated);
3439 if(window) {
3440 hwndRelated = window->getWindowHandle();
[5935]3441 RELEASE_WNDOBJ(window);
[5685]3442 }
3443 else hwndRelated = 0;
[4203]3444 }
[5685]3445 else {
3446 dprintf(("WARNING: GW_HWNDLAST not correctly implemented for toplevel/most windows!"));
3447 hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
3448 }
[4203]3449 break;
3450
3451 case GW_HWNDNEXT:
[5685]3452 if(getParent()) {
3453 hwndRelated = OSLibWinQueryWindow(getOS2FrameWindowHandle(), QWOS_NEXT);
3454 window = GetWindowFromOS2FrameHandle(hwndRelated);
3455 if(window) {
3456 hwndRelated = window->getWindowHandle();
[5935]3457 RELEASE_WNDOBJ(window);
[5685]3458 }
3459 else hwndRelated = 0;
[4203]3460 }
[5685]3461 else {
3462 dprintf(("WARNING: GW_HWNDNEXT not correctly implemented for toplevel/most windows!"));
3463 hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
3464 }
[4203]3465 break;
3466
3467 case GW_HWNDPREV:
[5685]3468 if(getParent()) {
3469 hwndRelated = OSLibWinQueryWindow(getOS2FrameWindowHandle(), QWOS_PREV);
3470 window = GetWindowFromOS2FrameHandle(hwndRelated);
3471 if(window) {
3472 hwndRelated = window->getWindowHandle();
[5935]3473 RELEASE_WNDOBJ(window);
[5685]3474 }
3475 else hwndRelated = 0;
[4203]3476 }
[5685]3477 else {
3478 dprintf(("WARNING: GW_HWNDPREV not correctly implemented for toplevel/most windows!"));
3479 hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
3480 }
[4203]3481 break;
3482
3483 case GW_OWNER:
[7090]3484 {
3485 Win32BaseWindow *owner = getOwner();
3486 if(owner) {
3487 hwndRelated = owner->getWindowHandle();
[4203]3488 }
3489 break;
[7090]3490 }
[4203]3491
3492 case GW_CHILD:
[4497]3493 hwndRelated = OSLibWinQueryWindow(getOS2WindowHandle(), QWOS_TOP);
[5685]3494 window = GetWindowFromOS2FrameHandle(hwndRelated);
[6169]3495
3496 //Before a window has processed WM_NCCREATE:
3497 //- GetWindow(parent, GW_CHILD) can't return that window handle
3498 //(verified in NT4, SP6)
[4825]3499 if(window) {
[6169]3500 if(window->state >= STATE_POST_WMNCCREATE) {
3501 hwndRelated = window->getWindowHandle();
[10190]3502 RELEASE_WNDOBJ(window);
[6169]3503 }
3504 else {
3505 hwndRelated = window->GetWindow(GW_HWNDNEXT);
[10190]3506 RELEASE_WNDOBJ(window);
[6169]3507 }
[4203]3508 }
[4825]3509 else hwndRelated = 0;
[6169]3510
[4203]3511 break;
[6927]3512
[7095]3513 //for internal use only
[6927]3514 case GW_HWNDNEXTCHILD:
3515 lock();
3516 window = (Win32BaseWindow *)getNextChild();
3517 if(window) {
3518 hwndRelated = window->getWindowHandle();
3519 }
3520 else hwndRelated = 0;
3521 unlock();
3522 break;
3523
[7095]3524 case GW_HWNDPREVCHILD:
3525 DebugInt3();
3526 break;
3527
[6927]3528 case GW_HWNDFIRSTCHILD:
3529 lock();
3530 window = (Win32BaseWindow *)getFirstChild();
3531 if(window) {
3532 hwndRelated = window->getWindowHandle();
3533 }
3534 else hwndRelated = 0;
3535 unlock();
3536 break;
3537
3538 case GW_HWNDLASTCHILD:
3539 lock();
3540 window = (Win32BaseWindow *)getFirstChild();
3541 if(window) {
3542 while (window->getNextChild())
3543 {
3544 window = (Win32BaseWindow *)window->getNextChild();
3545 }
3546 hwndRelated = window->getWindowHandle();
3547 }
3548 else hwndRelated = 0;
3549 unlock();
3550 break;
[4203]3551 }
[2469]3552end:
3553 dprintf(("GetWindow %x %d returned %x", getWindowHandle(), uCmd, hwndRelated));
3554 return hwndRelated;
3555}
3556//******************************************************************************
3557//******************************************************************************
[9930]3558PRECT Win32BaseWindow::getWindowRect()
[10190]3559{
3560 return &rectWindow;
[9930]3561}
3562//******************************************************************************
3563//******************************************************************************
[2469]3564HWND Win32BaseWindow::SetActiveWindow()
3565{
3566 HWND hwndActive;
3567
3568 dprintf(("SetActiveWindow %x", getWindowHandle()));
[6902]3569 if(getStyle() & WS_CHILD) {
3570// if(getStyle() & (WS_DISABLED | WS_CHILD)) {
[6718]3571 dprintf(("WARNING: Window is a child or disabled"));
3572 return 0;
3573 }
3574
[5725]3575 if(GetActiveWindow() == getWindowHandle()) {
3576 dprintf(("Window already active"));
3577 return getWindowHandle();
3578 }
[3773]3579 if (HOOK_IsHooked( WH_CBT ))
3580 {
3581 CBTACTIVATESTRUCT cbta;
3582 LRESULT ret;
3583
3584 cbta.fMouse = FALSE;
3585 cbta.hWndActive = GetActiveWindow();
3586 ret = HOOK_CallHooksA(WH_CBT, HCBT_ACTIVATE, getWindowHandle(), (LPARAM)&cbta);
3587 if(ret)
3588 {
3589 dprintf(("SetActiveWindow %x, CBT hook cancelled operation", getWindowHandle()));
3590 return cbta.hWndActive;
3591 }
3592 }
[4839]3593 SetWindowPos(HWND_TOP, 0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
[3773]3594
[4839]3595// if(OSLibWinSetActiveWindow(OS2Hwnd) == FALSE) {
3596// dprintf(("OSLibWinSetActiveWindow %x returned FALSE!", OS2Hwnd));
3597// }
[2948]3598 hwndActive = GetActiveWindow();
3599 return (hwndActive) ? hwndActive : windowDesktop->getWindowHandle(); //pretend the desktop was active
[2469]3600}
3601//******************************************************************************
[5217]3602//Used to change active status of an mdi window
3603//******************************************************************************
3604BOOL Win32BaseWindow::DeactivateChildWindow()
3605{
3606 /* child windows get a WM_CHILDACTIVATE message */
3607 if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
3608 {
3609 ULONG flags = OSLibWinGetWindowULong(getOS2WindowHandle(), OFFSET_WIN32FLAGS);
3610 OSLibWinSetWindowULong(getOS2WindowHandle(), OFFSET_WIN32FLAGS, (flags & ~WINDOWFLAG_ACTIVE));
3611 return TRUE;
3612 }
3613 DebugInt3(); //should not be called for non-child window
3614 return FALSE;
3615}
3616//******************************************************************************
[10033]3617//WM_ENABLE is sent to hwnd, but not to its children (as it should be)
[2469]3618//******************************************************************************
3619BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
3620{
[3388]3621 BOOL rc;
3622
[5713]3623 dprintf(("Win32BaseWindow::EnableWindow %x %d", getWindowHandle(), fEnable));
3624 //return true if previous state was disabled, else false (sdk docs)
3625 rc = (getStyle() & WS_DISABLED) != 0;
3626 if(rc && !fEnable) {
[7801]3627 SendMessageA(getWindowHandle(), WM_CANCELMODE, 0, 0);
[5713]3628 }
3629 OSLibWinEnableWindow(OS2HwndFrame, fEnable);
3630 if(fEnable == FALSE) {
[3584]3631 //SvL: No need to clear focus as PM already does this
3632 if(getWindowHandle() == GetCapture()) {
3633 ReleaseCapture(); /* A disabled window can't capture the mouse */
3634 dprintf(("Released capture for window %x that is being disabled", getWindowHandle()));
3635 }
[5713]3636 }
3637 return rc;
[2469]3638}
3639//******************************************************************************
3640//******************************************************************************
3641BOOL Win32BaseWindow::CloseWindow()
3642{
[8101]3643 if (::GetWindowLongW( getWindowHandle() , GWL_STYLE ) & WS_CHILD) return FALSE;
3644 ShowWindow( SW_MINIMIZE );
3645 return TRUE;
[2469]3646}
3647//******************************************************************************
[3513]3648//TODO: Not be 100% correct; should return active window of current thread
3649// or NULL when there is none -> WinQueryActiveWindow just returns
3650// the current active window
[2469]3651//******************************************************************************
3652HWND Win32BaseWindow::GetActiveWindow()
3653{
3654 HWND hwndActive;
3655
3656 hwndActive = OSLibWinQueryActiveWindow();
3657 return OS2ToWin32Handle(hwndActive);
3658}
3659//******************************************************************************
3660//******************************************************************************
3661BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
3662{
[5496]3663 INT len = GetWindowTextLength(fUnicode);
[2469]3664 BOOL res;
3665
3666 if (wndname == NULL)
[5496]3667 return (len == 0);
[2469]3668
3669 len++;
3670 if (fUnicode)
3671 {
[5496]3672 WCHAR *text = (WCHAR*)malloc(len*sizeof(WCHAR));
[2469]3673
[5496]3674 GetWindowTextW(text,len);
3675 res = (lstrcmpW(text,(LPWSTR)wndname) == 0);
3676 free(text);
3677 }
3678 else
[2469]3679 {
[5496]3680 CHAR *text = (CHAR*)malloc(len*sizeof(CHAR));
[2469]3681
[5496]3682 GetWindowTextA(text,len);
3683 res = (strcmp(text,wndname) == 0);
3684 free(text);
[2469]3685 }
3686
3687 return res;
3688}
3689//******************************************************************************
3690//******************************************************************************
3691CHAR *Win32BaseWindow::getWindowNamePtrA()
3692{
[5496]3693 INT len = GetWindowTextLength(FALSE);
[2469]3694 CHAR *text;
3695
3696 if (len == 0) return NULL;
3697 len++;
3698 text = (CHAR*)malloc(len*sizeof(CHAR));
3699 GetWindowTextA(text,len);
3700
3701 return text;
3702}
3703//******************************************************************************
3704//******************************************************************************
3705WCHAR *Win32BaseWindow::getWindowNamePtrW()
3706{
[5496]3707 INT len = GetWindowTextLength(TRUE);
[2469]3708 WCHAR *text;
3709
3710 if (len == 0) return NULL;
3711 len++;
3712 text = (WCHAR*)malloc(len*sizeof(WCHAR));
3713 GetWindowTextW(text,len);
3714
3715 return text;
3716}
3717//******************************************************************************
3718//******************************************************************************
3719VOID Win32BaseWindow::freeWindowNamePtr(PVOID namePtr)
3720{
3721 if (namePtr) free(namePtr);
3722}
3723//******************************************************************************
[4524]3724//When using this API for a window that was created by a different process, NT
3725//does NOT send WM_GETTEXTLENGTH.
[2469]3726//******************************************************************************
[5496]3727int Win32BaseWindow::GetWindowTextLength(BOOL fUnicode)
[2469]3728{
[4524]3729 //if the destination window is created by this process, send message
[10190]3730 if(dwProcessId == currentProcessId)
[7801]3731 {
[5496]3732 if(fUnicode) {
[7801]3733 return SendMessageW(getWindowHandle(), WM_GETTEXTLENGTH,0,0);
[5496]3734 }
[7801]3735 else return SendMessageA(getWindowHandle(), WM_GETTEXTLENGTH,0,0);
[4524]3736 }
3737 //else get data directory from window structure
[5496]3738 //TODO: must lock window structure.... (TODO)
[10190]3739 return fUnicode ? windowNameLengthW : windowNameLengthA;
[2469]3740}
3741//******************************************************************************
[4524]3742//When using this API for a window that was created by a different process, NT
3743//does NOT send WM_GETTEXT.
[2469]3744//******************************************************************************
3745int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
3746{
[4524]3747 //if the destination window is created by this process, send message
3748 if(dwProcessId == currentProcessId) {
[7801]3749 return SendMessageA(getWindowHandle(),WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
[4524]3750 }
[10190]3751
[4524]3752 //else get data directory from window structure
3753 if (!lpsz || !cch) return 0;
3754 if (!windowNameA) lpsz[0] = 0;
[10190]3755 else lstrcpynA( lpsz, windowNameA, cch );
3756 return strlen( lpsz );
[2469]3757}
3758//******************************************************************************
[4524]3759//When using this API for a window that was created by a different process, NT
3760//does NOT send WM_GETTEXT.
[2469]3761//******************************************************************************
3762int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
3763{
[4524]3764 //if the destination window is created by this process, send message
3765 if(dwProcessId == currentProcessId) {
[7801]3766 return ::SendMessageW(getWindowHandle(), WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
[4524]3767 }
3768 //else get data directory from window structure
[10190]3769 if (!lpsz || !cch)
[7801]3770 return 0;
[10190]3771 if (!windowNameW)
[7801]3772 lpsz[0] = 0;
[10190]3773 else
3774 lstrcpynW( lpsz, windowNameW, cch );
3775
3776 return strlenW( lpsz );
[2469]3777}
3778//******************************************************************************
[4524]3779//TODO: How does this work when the target window belongs to a different process???
[2469]3780//******************************************************************************
3781BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
3782{
[7801]3783 return SendMessageA(getWindowHandle(),WM_SETTEXT,0,(LPARAM)lpsz);
[2469]3784}
3785//******************************************************************************
3786//******************************************************************************
3787BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
3788{
[7801]3789 return SendMessageW(getWindowHandle(), WM_SETTEXT,0,(LPARAM)lpsz);
[2469]3790}
3791//******************************************************************************
3792//******************************************************************************
[7241]3793LONG Win32BaseWindow::SetWindowLong(int index, ULONG value, BOOL fUnicode)
[2469]3794{
3795 LONG oldval;
3796
3797 switch(index) {
3798 case GWL_EXSTYLE:
3799 {
3800 STYLESTRUCT ss;
3801
[4194]3802 if(dwExStyle == value) {
[5056]3803 oldval = value;
[4497]3804 break;
[5056]3805 }
[2469]3806 ss.styleOld = dwExStyle;
3807 ss.styleNew = value;
3808 dprintf(("SetWindowLong GWL_EXSTYLE %x old %x new style %x", getWindowHandle(), dwExStyle, value));
[7801]3809 SendMessageA(getWindowHandle(),WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
[2469]3810 setExStyle(ss.styleNew);
[7801]3811 SendMessageA(getWindowHandle(),WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
[9866]3812
[10190]3813 OSLibSetWindowStyle(getOS2FrameWindowHandle(), getOS2WindowHandle(),
[9866]3814 getStyle(), getExStyle(),ss.styleOld);
3815
[4194]3816 oldval = ss.styleOld;
[5056]3817 break;
[2469]3818 }
3819 case GWL_STYLE:
3820 {
[8624]3821 STYLESTRUCT ss;
[10190]3822
[2881]3823 //SvL: TODO: Can you change minimize or maximize status here too?
3824
[4194]3825 if(dwStyle == value) {
[5056]3826 oldval = value;
[4497]3827 break;
[4194]3828 }
[6040]3829 dprintf(("SetWindowLong GWL_STYLE %x old %x new style %x (%x)", getWindowHandle(), dwStyle, value));
[10190]3830
[8624]3831 //Changing WS_CHILD style is allowed
[2469]3832 ss.styleOld = getStyle();
[8624]3833 ss.styleNew = value;
[7801]3834 SendMessageA(getWindowHandle(),WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
[2469]3835 setStyle(ss.styleNew);
[7801]3836 SendMessageA(getWindowHandle(),WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
[6040]3837
[10190]3838 OSLibSetWindowStyle(getOS2FrameWindowHandle(), getOS2WindowHandle(),
[9866]3839 getStyle(), getExStyle(),ss.styleOld);
3840
[6040]3841 //TODO: Might not be correct to use ShowWindow here
3842 if((ss.styleOld & WS_VISIBLE) != (ss.styleNew & WS_VISIBLE)) {
3843 if(ss.styleNew & WS_VISIBLE)
3844 ShowWindow(SW_SHOWNOACTIVATE);
3845 else ShowWindow(SW_HIDE);
3846 }
[9765]3847
[2469]3848#ifdef DEBUG
3849 PrintWindowStyle(ss.styleNew, 0);
3850#endif
[4194]3851 oldval = ss.styleOld;
3852 break;
[2469]3853 }
3854 case GWL_WNDPROC:
[4188]3855 {
[5056]3856 //Note: Type of SetWindowLong determines new window proc type
[4188]3857 // UNLESS the new window proc has already been registered
3858 // (use the old type in that case)
3859 // (VERIFIED in NT 4, SP6)
3860 WINDOWPROCTYPE type = WINPROC_GetProcType((HWINDOWPROC)value);
[5056]3861 if(type == WIN_PROC_INVALID) {
3862 type = (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A;
3863 }
[21916]3864 oldval = (LONG)WINPROC_GetProc((HWINDOWPROC)win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
[7703]3865 dprintf(("SetWindowLong%c GWL_WNDPROC %x old %x new wndproc %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), oldval, value));
[4188]3866 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, type, WIN_PROC_WINDOW);
[4194]3867 break;
[4188]3868 }
[2469]3869 case GWL_HINSTANCE:
3870 oldval = hInstance;
3871 hInstance = value;
[4194]3872 break;
[2657]3873
[2469]3874 case GWL_HWNDPARENT:
[9783]3875 dprintf(("GWL_ID GWL_HWNDPARENT %x, new %x", GetParent(), value));
[4194]3876 oldval = SetParent((HWND)value);
3877 break;
[2657]3878
[2469]3879 case GWL_ID:
[7409]3880 dprintf(("GWL_ID old %x, new %x", getWindowId(), value));
[2469]3881 oldval = getWindowId();
3882 setWindowId(value);
[4194]3883 break;
[2657]3884
[2469]3885 case GWL_USERDATA:
3886 oldval = userData;
3887 userData = value;
[4194]3888 break;
[2657]3889
[2469]3890 default:
[5242]3891 if(index >= 0 && index + sizeof(ULONG) <= nrUserWindowBytes)
[2469]3892 {
[5242]3893 oldval = *(ULONG *)(userWindowBytes + index);
3894 *(ULONG *)(userWindowBytes + index) = value;
[4497]3895 break;
[2469]3896 }
[5056]3897 dprintf(("WARNING: SetWindowLong%c %x %d %x returned %x INVALID index!", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
[5074]3898 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
[2469]3899 return 0;
3900 }
[5060]3901 //Note: NT4, SP6 does not set the last error to 0
[4194]3902 SetLastError(ERROR_SUCCESS);
3903 dprintf2(("SetWindowLong%c %x %d %x returned %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value, oldval));
3904 return oldval;
[2469]3905}
3906//******************************************************************************
3907//******************************************************************************
[7241]3908ULONG Win32BaseWindow::GetWindowLong(int index, BOOL fUnicode)
[2469]3909{
3910 ULONG value;
3911
3912 switch(index) {
3913 case GWL_EXSTYLE:
3914 value = dwExStyle;
3915 break;
3916 case GWL_STYLE:
3917 value = dwStyle;
3918 break;
3919 case GWL_WNDPROC:
[21916]3920 value = (LONG)WINPROC_GetProc((HWINDOWPROC)win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
[2469]3921 break;
3922 case GWL_HINSTANCE:
3923 value = hInstance;
3924 break;
3925 case GWL_HWNDPARENT:
[5056]3926 value = GetParent();
[2469]3927 break;
3928 case GWL_ID:
3929 value = getWindowId();
3930 break;
3931 case GWL_USERDATA:
3932 value = userData;
3933 break;
3934 default:
[5242]3935 if(index >= 0 && index + sizeof(ULONG) <= nrUserWindowBytes)
[2469]3936 {
[5242]3937 value = *(ULONG *)(userWindowBytes + index);
[2469]3938 break;
3939 }
[5242]3940 dprintf(("WARNING: GetWindowLong%c %x %d %x returned %x INVALID index!", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
[5074]3941 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
[2469]3942 return 0;
3943 }
[5397]3944 dprintf2(("GetWindowLong%c %x %d %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
[5060]3945 //Note: NT4, SP6 does not set the last error to 0
3946 SetLastError(ERROR_SUCCESS);
[2469]3947 return value;
3948}
3949//******************************************************************************
3950//******************************************************************************
3951WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
3952{
3953 WORD oldval;
3954
[5242]3955 if(index >= 0 && index + sizeof(WORD) <= nrUserWindowBytes)
[5056]3956 {
[5242]3957 oldval = *(WORD *)(userWindowBytes + index);
3958 *(WORD *)(userWindowBytes + index) = value;
[5060]3959 //Note: NT4, SP6 does not set the last error to 0
[5242]3960 dprintf2(("SetWindowWord %x %d %x returned %x", getWindowHandle(), index, value, oldval));
[5060]3961 SetLastError(ERROR_SUCCESS);
[2469]3962 return oldval;
[5056]3963 }
[6394]3964 switch(index)
3965 {
3966 case GWW_HINSTANCE:
3967 oldval = hInstance;
3968 hInstance = value;
3969 break;
3970
3971 case GWW_HWNDPARENT:
3972 oldval = SetParent((HWND)(WNDHANDLE_MAGIC_HIGHWORD | value));
3973 break;
3974
3975 case GWW_ID:
3976 oldval = getWindowId();
3977 setWindowId(value);
3978 break;
3979
3980 default:
3981 dprintf(("WARNING: SetWindowWord %x %d %x returned %x INVALID index!", getWindowHandle(), index, value));
3982 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
3983 return 0;
3984 }
3985 //Note: NT4, SP6 does not set the last error to 0
3986 SetLastError(ERROR_SUCCESS);
3987 dprintf2(("SetWindowWord %x %d %x returned %x", getWindowHandle(), index, value, oldval));
3988 return oldval;
[2469]3989}
3990//******************************************************************************
3991//******************************************************************************
3992WORD Win32BaseWindow::GetWindowWord(int index)
3993{
[5242]3994 if(index >= 0 && index + sizeof(WORD) <= nrUserWindowBytes)
[2469]3995 {
[5060]3996 //Note: NT4, SP6 does not set the last error to 0
3997 SetLastError(ERROR_SUCCESS);
[5242]3998 dprintf2(("GetWindowWord %x %d %x", getWindowHandle(), index, *(WORD *)(userWindowBytes + index)));
3999 return *(WORD *)(userWindowBytes + index);
[2469]4000 }
[6394]4001 switch(index)
4002 {
[10190]4003 case GWW_ID:
4004 if(HIWORD(getWindowId()))
[6394]4005 dprintf(("WARNING: GWW_ID: discards high bits of 0x%08x!\n", getWindowId()));
4006 return (WORD)getWindowId();
4007
[10190]4008 case GWW_HWNDPARENT:
[6394]4009 dprintf(("WARNING: GWW_HWNDPARENT: discards high bits of 0x%08x!\n", GetParent()));
[10190]4010 return (WORD) GetParent();
[6394]4011
[10190]4012 case GWW_HINSTANCE:
4013 if (HIWORD(hInstance))
[6394]4014 dprintf(("WARNING: GWW_HINSTANCE: discards high bits of 0x%08x!\n", hInstance));
4015 return (WORD)hInstance;
4016 }
4017
[5242]4018 dprintf(("WARNING: GetWindowWord %x %d returned %x INVALID index!", getWindowHandle(), index));
[5074]4019 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
[2469]4020 return 0;
4021}
4022//******************************************************************************
[9953]4023// Win32BaseWindow::setVisibleRgnNotifyProc
4024//
4025// Sets the visible region change notification handler. Called when
4026// the window receives a WM_VRNDISABLED or WM_VRNENABLED message (PM).
4027//
4028// Parameters:
4029// VISRGN_NOTIFY_PROC lpNotifyProc - notification handler
4030// DWORD dwUserData - caller supplied parameter for handler invocations
[10190]4031//
[9953]4032// Returns:
4033// TRUE - Success
4034// FALSE - Failure
4035//
4036//******************************************************************************
4037BOOL Win32BaseWindow::setVisibleRgnNotifyProc(VISRGN_NOTIFY_PROC lpNotifyProc, DWORD dwUserData)
4038{
4039 lpVisRgnNotifyProc = lpNotifyProc;
4040 dwVisRgnNotifyParam = dwUserData;
4041 return TRUE;
4042}
4043//******************************************************************************
4044// Win32BaseWindow::callVisibleRgnNotifyProc
4045//
4046// Call the visible region change notification handler. Called when
4047// the window receives a WM_VRNDISABLED or WM_VRNENABLED message (PM).
4048//
4049// Parameters:
4050// BOOL fDrawingAllowed - drawing is allowed or not
[10190]4051//
[9953]4052// Returns:
4053// TRUE - Success
4054// FALSE - Failure
4055//
4056//******************************************************************************
[10190]4057void Win32BaseWindow::callVisibleRgnNotifyProc(BOOL fDrawingAllowed)
[9953]4058{
4059 if(fDrawingAllowed) {
4060 fWindowLocked = TRUE;
4061 }
4062 else {
4063 fWindowLocked = FALSE;
4064 }
4065 if(lpVisRgnNotifyProc) {
4066 lpVisRgnNotifyProc(getWindowHandle(), fDrawingAllowed, dwVisRgnNotifyParam);
4067 }
4068}
4069//******************************************************************************
[10060]4070// Win32BaseWindow::queryOpenDCs
4071//
4072// Return the DCs that are currently open for this window
4073//
4074// Parameters:
4075// HDC *phdcWindow - pointer to HDC array (IN)
4076// int chdcWindow - size of HDC array (IN)
4077// int *pnrdcs - number of HDCs returned (OUT)
[10190]4078//
[10060]4079// Returns:
4080// TRUE - Success
4081// FALSE - Failure
4082//
4083//******************************************************************************
4084BOOL Win32BaseWindow::queryOpenDCs(HDC *phdcWindow, int chdcWindow, int *pnrdcs)
4085{
4086 if(nrOpenDCs == 0) return FALSE;
4087
4088 if(chdcWindow < nrOpenDCs) {
4089 DebugInt3();
4090 return FALSE;
4091 }
4092
[10076]4093 lock(&critsect);
[10060]4094 int j = 0;
4095 for(int i=0;i<MAX_OPENDCS && j<nrOpenDCs;i++) {
4096 if(hdcWindow[i] != 0) {
4097 phdcWindow[j] = hdcWindow[i];
4098 j++;
4099 }
4100 }
[10076]4101 unlock(&critsect);
[10060]4102 *pnrdcs = nrOpenDCs;
4103 return TRUE;
4104}
4105//******************************************************************************
4106// Win32BaseWindow::addOpenDC
4107//
4108// Add DC to list of open DCS
4109//
4110// Parameters:
4111// HDC hdc - HDC to be added to our list of open DCs
[10190]4112//
[10060]4113// Returns:
4114//
4115//******************************************************************************
4116void Win32BaseWindow::addOpenDC(HDC hdc)
4117{
[10076]4118 lock(&critsect);
[21916]4119 int i;
4120 for(i=0;i<MAX_OPENDCS;i++) {
[10060]4121 if(hdcWindow[i] == 0) {
4122 hdcWindow[i] = hdc;
4123 break;
4124 }
4125 }
[10076]4126 unlock(&critsect);
[10060]4127 if(i == MAX_OPENDCS) {
[10134]4128 dprintf(("Open DCs:"));
4129 for(int i=0;i<MAX_OPENDCS;i++) {
4130 dprintf(("Window %x DC %x", WindowFromDC(hdcWindow[i]), hdcWindow[i]));
4131 }
[10060]4132 DebugInt3(); //no room!
4133 return;
4134 }
4135
[10076]4136 dprintf2(("Win32BaseWindow::addOpenDC %x %x %d", getWindowHandle(), hdc, nrOpenDCs+1));
[10060]4137 nrOpenDCs++;
4138}
4139//******************************************************************************
4140// Win32BaseWindow::removeOpenDC
4141//
4142// Remove DC from list of open DCS
4143//
4144// Parameters:
4145// HDC hdc - HDC to be removed from our list of open DCs
[10190]4146//
[10060]4147// Returns:
4148//
4149//******************************************************************************
4150void Win32BaseWindow::removeOpenDC(HDC hdc)
4151{
4152 if(nrOpenDCs == 0) {
[10076]4153 dprintf(("Win32BaseWindow::removeOpenDC %x hdc %x not found!! (1)", getWindowHandle(), hdc));
[10529]4154 //Some applications call ReleaseDC before EndPaint
4155// DebugInt3();
[10060]4156 return;
4157 }
[10076]4158 lock(&critsect);
[21916]4159 int i;
4160 for(i=0;i<MAX_OPENDCS;i++) {
[10060]4161 if(hdcWindow[i] == hdc) {
4162 hdcWindow[i] = 0;
4163 break;
4164 }
4165 }
[10076]4166 unlock(&critsect);
[10060]4167 if(i == MAX_OPENDCS) {
[10076]4168 dprintf(("Win32BaseWindow::removeOpenDC hdc %x not found!!", hdc));
[10060]4169 DebugInt3(); //not found
4170 return;
4171 }
[10076]4172 dprintf2(("Win32BaseWindow::removeOpenDC %x %x", getWindowHandle(), hdc, nrOpenDCs-1));
[10060]4173 nrOpenDCs--;
4174}
4175//******************************************************************************
[5935]4176//Locates window in linked list and increases reference count (if found)
4177//Window object must be unreferenced after usage
[2469]4178//******************************************************************************
[5935]4179Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
4180{
4181 Win32BaseWindow *window;
4182
[6040]4183////TODO: temporary workaround for crashes in Opera (pmwinx; releasesemaphore)
4184//// while browsing
4185//// Not thread safe now!
[6012]4186//// lock(&critsect);
[5935]4187 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
4188 if(window) {
[5951]4189//// dprintf(("addRef %x; refcount %d", hwnd, window->getRefCount()+1));
[5935]4190 window->addRef();
4191 }
[6012]4192//// unlock(&critsect);
[5935]4193 return window;
4194 }
[6012]4195//// unlock(&critsect);
[5935]4196// dprintf2(("Win32BaseWindow::GetWindowFromHandle: not a win32 window %x", hwnd));
4197 return NULL;
4198}
4199//******************************************************************************
4200//Locates window in linked list and increases reference count (if found)
4201//Window object must be unreferenced after usage
4202//******************************************************************************
4203Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwndOS2)
4204{
4205 DWORD magic;
[10190]4206 HWND hwnd;
[5935]4207
4208 if(hwndOS2 == OSLIB_HWND_DESKTOP)
4209 {
4210 windowDesktop->addRef();
4211 return windowDesktop;
4212 }
4213
4214 hwnd = (HWND)OSLibWinGetWindowULong(hwndOS2, OFFSET_WIN32WNDPTR);
4215 magic = OSLibWinGetWindowULong(hwndOS2, OFFSET_WIN32PM_MAGIC);
4216
4217 if(hwnd && CheckMagicDword(magic)) {
4218 return GetWindowFromHandle(hwnd);
4219 }
4220// dprintf2(("Win32BaseWindow::GetWindowFromOS2Handle: not an Odin os2 window %x", hwndOS2));
[10033]4221
[10190]4222 //Now check if it's a fake window
[10033]4223 Win32FakeWindow *window = Win32FakeWindow::GetWindowFromOS2Handle(hwndOS2);
4224 if(window) {
4225 return window;
4226 }
[5935]4227 return 0;
4228}
4229//******************************************************************************
4230//Locates window in linked list and increases reference count (if found)
4231//Window object must be unreferenced after usage
4232//******************************************************************************
4233Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
4234{
4235 return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
4236}
4237//******************************************************************************
4238//******************************************************************************
4239HWND WIN32API Win32ToOS2Handle(HWND hwnd)
4240{
4241 HWND hwndOS2;
4242
4243 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
4244
4245 if(window) {
4246 hwndOS2 = window->getOS2WindowHandle();
4247 RELEASE_WNDOBJ(window);
4248 return hwndOS2;
4249 }
4250// dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
4251 return hwnd;
4252}
4253//******************************************************************************
4254//******************************************************************************
[6902]4255HWND WIN32API Win32ToOS2FrameHandle(HWND hwnd)
4256{
4257 HWND hwndOS2;
4258
4259 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
4260
4261 if(window) {
4262 hwndOS2 = window->getOS2FrameWindowHandle();
4263 RELEASE_WNDOBJ(window);
4264 return hwndOS2;
4265 }
4266// dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
4267 return hwnd;
4268}
4269//******************************************************************************
4270//******************************************************************************
[5935]4271HWND WIN32API OS2ToWin32Handle(HWND hwnd)
4272{
4273 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
4274 HWND hwndWin32;
4275
4276 if(window) {
4277 hwndWin32 = window->getWindowHandle();
4278 RELEASE_WNDOBJ(window);
4279 return hwndWin32;
4280 }
4281 window = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwnd);
4282 if(window) {
4283 hwndWin32 = window->getWindowHandle();
4284 RELEASE_WNDOBJ(window);
4285 return hwndWin32;
4286 }
4287
4288// dprintf2(("Win32BaseWindow::OS2ToWin32Handle: not a win32 window %x", hwnd));
4289 return 0;
4290// else return hwnd; //OS/2 window handle
4291}
[6375]4292#ifdef DEBUG
4293LONG Win32BaseWindow::addRef()
4294{
[7703]4295// dprintf2(("addRef %x %d", getWindowHandle(), getRefCount()+1));
[6375]4296 return GenericObject::addRef();
4297}
[5935]4298//******************************************************************************
4299//******************************************************************************
[21916]4300LONG Win32BaseWindow::release(const char *function, int line)
[6375]4301{
[7703]4302// dprintf2(("release %s %d %x %d", function, line, getWindowHandle(), getRefCount()-1));
[6375]4303 return GenericObject::release();
4304}
4305#endif
4306//******************************************************************************
4307//******************************************************************************
[5935]4308GenericObject *Win32BaseWindow::windows = NULL;
[10587]4309VMutex Win32BaseWindow::critsect;
[5935]4310
4311//******************************************************************************
4312//******************************************************************************
[2469]4313#ifdef DEBUG
4314void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle)
4315{
4316 char style[256] = "";
4317 char exstyle[256] = "";
4318
4319 /* Window styles */
4320 if(dwStyle & WS_CHILD)
4321 strcat(style, "WS_CHILD ");
4322 if(dwStyle & WS_POPUP)
4323 strcat(style, "WS_POPUP ");
4324 if(dwStyle & WS_VISIBLE)
4325 strcat(style, "WS_VISIBLE ");
4326 if(dwStyle & WS_DISABLED)
4327 strcat(style, "WS_DISABLED ");
4328 if(dwStyle & WS_CLIPSIBLINGS)
4329 strcat(style, "WS_CLIPSIBLINGS ");
4330 if(dwStyle & WS_CLIPCHILDREN)
4331 strcat(style, "WS_CLIPCHILDREN ");
4332 if(dwStyle & WS_MAXIMIZE)
4333 strcat(style, "WS_MAXIMIZE ");
4334 if(dwStyle & WS_MINIMIZE)
4335 strcat(style, "WS_MINIMIZE ");
4336 if(dwStyle & WS_GROUP)
4337 strcat(style, "WS_GROUP ");
4338 if(dwStyle & WS_TABSTOP)
4339 strcat(style, "WS_TABSTOP ");
4340
4341 if((dwStyle & WS_CAPTION) == WS_CAPTION)
4342 strcat(style, "WS_CAPTION ");
4343 if(dwStyle & WS_DLGFRAME)
4344 strcat(style, "WS_DLGFRAME ");
4345 if(dwStyle & WS_BORDER)
4346 strcat(style, "WS_BORDER ");
4347
4348 if(dwStyle & WS_VSCROLL)
4349 strcat(style, "WS_VSCROLL ");
4350 if(dwStyle & WS_HSCROLL)
4351 strcat(style, "WS_HSCROLL ");
4352 if(dwStyle & WS_SYSMENU)
4353 strcat(style, "WS_SYSMENU ");
4354 if(dwStyle & WS_THICKFRAME)
4355 strcat(style, "WS_THICKFRAME ");
4356 if(dwStyle & WS_MINIMIZEBOX)
4357 strcat(style, "WS_MINIMIZEBOX ");
4358 if(dwStyle & WS_MAXIMIZEBOX)
4359 strcat(style, "WS_MAXIMIZEBOX ");
4360
4361 if(dwExStyle & WS_EX_DLGMODALFRAME)
4362 strcat(exstyle, "WS_EX_DLGMODALFRAME ");
4363 if(dwExStyle & WS_EX_ACCEPTFILES)
4364 strcat(exstyle, "WS_EX_ACCEPTFILES ");
4365 if(dwExStyle & WS_EX_NOPARENTNOTIFY)
4366 strcat(exstyle, "WS_EX_NOPARENTNOTIFY ");
4367 if(dwExStyle & WS_EX_TOPMOST)
4368 strcat(exstyle, "WS_EX_TOPMOST ");
4369 if(dwExStyle & WS_EX_TRANSPARENT)
4370 strcat(exstyle, "WS_EX_TRANSPARENT ");
4371
4372 if(dwExStyle & WS_EX_MDICHILD)
4373 strcat(exstyle, "WS_EX_MDICHILD ");
4374 if(dwExStyle & WS_EX_TOOLWINDOW)
4375 strcat(exstyle, "WS_EX_TOOLWINDOW ");
4376 if(dwExStyle & WS_EX_WINDOWEDGE)
4377 strcat(exstyle, "WS_EX_WINDOWEDGE ");
4378 if(dwExStyle & WS_EX_CLIENTEDGE)
4379 strcat(exstyle, "WS_EX_CLIENTEDGE ");
4380 if(dwExStyle & WS_EX_CONTEXTHELP)
4381 strcat(exstyle, "WS_EX_CONTEXTHELP ");
4382 if(dwExStyle & WS_EX_RIGHT)
4383 strcat(exstyle, "WS_EX_RIGHT ");
4384 if(dwExStyle & WS_EX_LEFT)
4385 strcat(exstyle, "WS_EX_LEFT ");
4386 if(dwExStyle & WS_EX_RTLREADING)
4387 strcat(exstyle, "WS_EX_RTLREADING ");
4388 if(dwExStyle & WS_EX_LTRREADING)
4389 strcat(exstyle, "WS_EX_LTRREADING ");
4390 if(dwExStyle & WS_EX_LEFTSCROLLBAR)
4391 strcat(exstyle, "WS_EX_LEFTSCROLLBAR ");
4392 if(dwExStyle & WS_EX_RIGHTSCROLLBAR)
4393 strcat(exstyle, "WS_EX_RIGHTSCROLLBAR ");
4394 if(dwExStyle & WS_EX_CONTROLPARENT)
4395 strcat(exstyle, "WS_EX_CONTROLPARENT ");
4396 if(dwExStyle & WS_EX_STATICEDGE)
4397 strcat(exstyle, "WS_EX_STATICEDGE ");
4398 if(dwExStyle & WS_EX_APPWINDOW)
4399 strcat(exstyle, "WS_EX_APPWINDOW ");
4400
4401 dprintf(("Window style: %x %s", dwStyle, style));
[4203]4402 dprintf(("Window exStyle: %x %s", dwExStyle, exstyle));
[2469]4403}
4404#endif
4405//******************************************************************************
4406//******************************************************************************
Note: See TracBrowser for help on using the repository browser.