Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

win32wbase.cpp

Go to the documentation of this file.
00001 /* $Id: win32wbase.cpp,v 1.312 2002/01/20 15:26:21 sandervl Exp $ */
00002 /*
00003  * Win32 Window Base Class for OS/2
00004  *
00005  * Copyright 1998-2002 Sander van Leeuwen (sandervl@xs4all.nl)
00006  * Copyright 1999      Daniela Engert (dani@ngrt.de)
00007  * Copyright 1999-2000 Christoph Bratschi (cbratschi@datacomm.ch)
00008  *
00009  * Parts based on Wine Windows code (windows\win.c)
00010  *   Corel version: corel20000212
00011  *
00012  * Copyright 1993, 1994, 1996 Alexandre Julliard
00013  *           1995 Alex Korobka
00014  *
00015  * TODO: Not thread/process safe
00016  *
00017  * NOTE: To access a window object, you must call GetWindowFromOS2Handle or
00018  *       GetWindowFromHandle. Both these methods increase the reference count
00019  *       of the object. When you're done with the object, you MUST call
00020  *       the release method!
00021  *       This mechanism prevents premature destruction of objects when there
00022  *       are still clients using it.
00023  *
00024  * NOTE: Client rectangle always relative to frame window
00025  *       Window rectangle in parent coordinates (relative to parent's client window)
00026  *       (screen coord. if no parent)
00027  *
00028  * NOTE: Status of window:
00029  *       Before a window has processed WM_NCCREATE:
00030  *       - GetTopWindow can't return that window handle
00031  *       - GetWindow(parent, GW_CHILD) can't return that window handle
00032  *       - IsChild works
00033  *       TODO: Does this affect more functions?? (other GetWindow ops)
00034  *       (verified in NT4, SP6)
00035  *
00036  * Project Odin Software License can be found in LICENSE.TXT
00037  *
00038  */
00039 #include <os2win.h>
00040 #include <win.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <stdarg.h>
00044 #include <assert.h>
00045 #include <misc.h>
00046 #include <heapstring.h>
00047 #include <winuser32.h>
00048 #include "win32wbase.h"
00049 #include "wndmsg.h"
00050 #include "oslibwin.h"
00051 #include "oslibmsg.h"
00052 #include "oslibutil.h"
00053 #include "oslibgdi.h"
00054 #include "oslibres.h"
00055 #include "oslibdos.h"
00056 #include "syscolor.h"
00057 #include "win32wndhandle.h"
00058 #include "dc.h"
00059 #include "win32wdesktop.h"
00060 #include "pmwindow.h"
00061 #include "controls.h"
00062 #include <wprocess.h>
00063 #include <win\hook.h>
00064 #include <menu.h>
00065 #define INCL_TIMERWIN32
00066 #include "timer.h"
00067 
00068 #define DBG_LOCALLOG    DBG_win32wbase
00069 #include "dbglocal.h"
00070 
00071 /* bits in the dwKeyData */
00072 #define KEYDATA_ALT         0x2000
00073 #define KEYDATA_PREVSTATE   0x4000
00074 
00075 void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle);
00076 
00077 static fDestroyAll = FALSE;
00078 //For quick lookup of current process id
00079 static ULONG currentProcessId = -1;
00080 static int iF10Key = 0;
00081 static int iMenuSysKey = 0;
00082 
00083 
00084 
00085 /***
00086  * Performance Optimization:
00087  * we're directly inlining this micro function from win32wndhandle.cpp.
00088  * Changes there must be reflected here.
00089  ***/
00090 extern ULONG WindowHandleTable[MAX_WINDOW_HANDLES];
00091 
00092 BOOL INLINE i_HwGetWindowHandleData(HWND hwnd, DWORD *pdwUserData)
00093 {
00094   if((hwnd & 0xFFFF0000) != WNDHANDLE_MAGIC_HIGHWORD) {
00095         return FALSE; //unknown window (PM?)
00096   }
00097   hwnd &= WNDHANDLE_MAGIC_MASK;
00098   if(hwnd < MAX_WINDOW_HANDLES) {
00099         *pdwUserData = WindowHandleTable[hwnd];
00100         return TRUE;
00101   }
00102   *pdwUserData = 0;
00103   return FALSE;
00104 }
00105 #define HwGetWindowHandleData(a,b) i_HwGetWindowHandleData(a,b)
00106 
00107 
00108 //******************************************************************************
00109 //******************************************************************************
00110 Win32BaseWindow::Win32BaseWindow() 
00111                      : GenericObject(&windows, &critsect), ChildWindow(&critsect)
00112 {
00113     Init();
00114 }
00115 //******************************************************************************
00116 //******************************************************************************
00117 Win32BaseWindow::Win32BaseWindow(HWND hwndOS2, ATOM classAtom)
00118                      : GenericObject(&windows, &critsect), ChildWindow(&critsect)
00119 {
00120     Init();
00121     OS2Hwnd = OS2HwndFrame = hwndOS2;
00122 
00123     /* Find the window class */
00124     windowClass = Win32WndClass::FindClass(NULL, (LPSTR)classAtom);
00125     if (!windowClass)
00126     {
00127         char buffer[32];
00128         GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
00129         dprintf(("Bad class '%s'", buffer ));
00130         DebugInt3();
00131     }
00132 
00133     //Allocate window words
00134     nrUserWindowBytes = windowClass->getExtraWndBytes();
00135     if(nrUserWindowBytes) {
00136         userWindowBytes = (char *)_smalloc(nrUserWindowBytes);
00137         memset(userWindowBytes, 0, nrUserWindowBytes);
00138     }
00139 
00140     WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc(), WINPROC_GetProcType(windowClass->getWindowProc()), WIN_PROC_WINDOW);
00141     hInstance  = NULL;
00142     dwStyle    = WS_VISIBLE;
00143     dwOldStyle = dwStyle;
00144     dwExStyle  = 0;
00145 
00146     //We pretend this window has no parent and won't change size
00147     //(dangerous assumption!!)
00148     OSLibWinQueryWindowClientRect(OS2Hwnd, &rectClient);
00149     OSLibQueryWindowRectAbsolute (OS2Hwnd, &rectWindow);
00150 
00151     fFakeWindow = TRUE;
00152 }
00153 //******************************************************************************
00154 //******************************************************************************
00155 Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
00156                      : GenericObject(&windows, &critsect), ChildWindow(&critsect)
00157 {
00158     Init();
00159     this->isUnicode = isUnicode;
00160     CreateWindowExA(lpCreateStructA, classAtom);
00161 }
00162 //******************************************************************************
00163 //******************************************************************************
00164 void Win32BaseWindow::Init()
00165 {
00166   isUnicode        = FALSE;
00167   fFirstShow       = TRUE;
00168   fIsDialog        = FALSE;
00169   fIsModalDialogOwner = FALSE;
00170   OS2HwndModalDialog  = 0;
00171   fInternalMsg     = FALSE;
00172   fParentChange    = FALSE;
00173   fDestroyWindowCalled = FALSE;
00174   fTaskList        = FALSE;
00175   fParentDC        = FALSE;
00176   fComingToTop     = FALSE;
00177   fMinMaxChange    = FALSE;
00178   fVisibleRegionChanged = FALSE;
00179   fEraseBkgndFlag  = TRUE;
00180   fFakeWindow      = FALSE;
00181 
00182   state            = STATE_INIT;
00183   windowNameA      = NULL;
00184   windowNameW      = NULL;
00185   windowNameLength = 0;
00186   
00187   userWindowBytes  = NULL;;
00188   nrUserWindowBytes= 0;
00189 
00190   OS2Hwnd          = 0;
00191   OS2HwndFrame     = 0;
00192   hSysMenu         = 0;
00193   Win32Hwnd        = 0;
00194 
00195   if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
00196   {
00197         dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
00198         DebugInt3();
00199   }
00200 
00201   posx = posy      = 0;
00202   width = height   = 0;
00203 
00204   dwExStyle        = 0;
00205   dwStyle          = 0;
00206   dwOldStyle       = 0;
00207   win32wndproc     = 0;
00208   hInstance        = 0;
00209   dwIDMenu         = 0; //0xFFFFFFFF; //default -1
00210   userData         = 0;
00211   contextHelpId    = 0;
00212   hotkey           = 0;
00213 
00214 
00215   hwndLinkAfter    = HWND_BOTTOM;
00216   flags            = 0;
00217   lastHitTestVal   = HTOS_NORMAL;
00218   owner            = NULL;
00219   windowClass      = 0;
00220 
00221   hIcon            = 0;
00222   hIconSm          = 0;
00223 
00224   horzScrollInfo   = NULL;
00225   vertScrollInfo   = NULL;
00226 
00227   propertyList     = NULL;
00228 
00229   cbExtra          = 0;
00230   pExtra           = NULL;
00231 
00232   ownDC              = 0;
00233   hWindowRegion      = 0;
00234   hClipRegion        = 0;
00235 
00236   hTaskList          = 0;
00237 
00238   if(currentProcessId == -1)
00239   {
00240         currentProcessId = GetCurrentProcessId();
00241   }
00242   dwThreadId         = GetCurrentThreadId();
00243   dwProcessId        = currentProcessId;
00244 
00245   memset(&windowpos, 0, sizeof(windowpos));
00246   //min and max position are initially -1 (verified in NT4, SP6)
00247   windowpos.ptMinPosition.x = -1;
00248   windowpos.ptMinPosition.y = -1;
00249   windowpos.ptMaxPosition.x = -1;
00250   windowpos.ptMaxPosition.y = -1;
00251 
00252   lpVisRgnNotifyProc  = NULL;
00253   dwVisRgnNotifyParam = NULL;
00254 }
00255 //******************************************************************************
00256 //todo get rid of resources (menu, icon etc)
00257 //******************************************************************************
00258 Win32BaseWindow::~Win32BaseWindow()
00259 {
00260     if(getRefCount() < 0) {
00261         DebugInt3();
00262     }
00263 
00264     if(hTaskList) {
00265         OSLibWinRemoveFromTasklist(hTaskList);
00266     }
00267 
00268     OSLibWinSetVisibleRegionNotify(OS2Hwnd, FALSE);
00269     OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
00270     OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
00271 
00272     if(fDestroyAll) {
00273         dprintf(("Destroying window %x %s", getWindowHandle(), windowNameA));
00274         setParent(NULL);  //or else we'll crash in the dtor of the ChildWindow class
00275     }
00276     else
00277     if(getParent() && getParent()->getFirstChild() == this && getNextChild() == NULL)
00278     {
00279         //if we're the last child that's being destroyed and our
00280         //parent window was also destroyed, then we 
00281         if(getParent()->IsWindowDestroyed())
00282         {
00283             setParent(NULL);  //or else we'll crash in the dtor of the ChildWindow class
00284         }
00285     }
00286     /* Decrement class window counter */
00287     if(windowClass) {
00288         RELEASE_CLASSOBJ(windowClass);
00289     }
00290 
00291     if(isOwnDC())
00292         releaseOwnDC(ownDC);
00293 
00294     if(Win32Hwnd)
00295         HwFreeWindowHandle(Win32Hwnd);
00296 
00297     if(userWindowBytes)
00298         free(userWindowBytes);
00299 
00300     if(windowNameA) {
00301         free(windowNameA);
00302         windowNameA = NULL;
00303     }
00304     if(windowNameW) {
00305         free(windowNameW);
00306         windowNameW = NULL;
00307     }
00308     if(vertScrollInfo) {
00309         free(vertScrollInfo);
00310         vertScrollInfo = NULL;
00311     }
00312     if(horzScrollInfo) {
00313         free(horzScrollInfo);
00314         horzScrollInfo = NULL;
00315     }
00316     if(propertyList) {
00317         removeWindowProps();
00318     }
00319     Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
00320     if(wndparent && !fDestroyAll) {
00321         RELEASE_WNDOBJ(wndparent);
00322     }
00323     if(owner && !fDestroyAll) {
00324         RELEASE_WNDOBJ(owner);
00325     }
00326 }
00327 //******************************************************************************
00328 //******************************************************************************
00329 void Win32BaseWindow::DestroyAll()
00330 {
00331     fDestroyAll = TRUE;
00332     GenericObject::DestroyAll(windows);
00333 }
00334 //******************************************************************************
00335 //******************************************************************************
00336 BOOL Win32BaseWindow::isChild()
00337 {
00338     return ((dwStyle & WS_CHILD) != 0);
00339 }
00340 //******************************************************************************
00341 //******************************************************************************
00342 BOOL Win32BaseWindow::IsWindowUnicode()
00343 {
00344     dprintf2(("IsWindowUnicode %x %d", getWindowHandle(), WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W));
00345     return (WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W);
00346 }
00347 //******************************************************************************
00348 //******************************************************************************
00349 BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
00350 {
00351  char  buffer[256];
00352 
00353 #ifdef DEBUG
00354     PrintWindowStyle(cs->style, cs->dwExStyle);
00355 #endif
00356 
00357     //If window has no owner/parent window, then it will be added to the tasklist
00358     //(depending on visibility state)
00359     if (!cs->hwndParent) fTaskList = TRUE;
00360 
00361     sw = SW_SHOW;
00362     SetLastError(0);
00363 
00364     /* Find the parent window */
00365     if (cs->hwndParent)
00366     {
00367             Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
00368             if(!window) {
00369                     dprintf(("Bad parent %04x\n", cs->hwndParent ));
00370                     SetLastError(ERROR_INVALID_PARAMETER);
00371                     return FALSE;
00372             }
00373             /* Make sure parent is valid */
00374             if (!window->IsWindow() )
00375             {
00376                     RELEASE_WNDOBJ(window);
00377                     dprintf(("Bad parent %04x\n", cs->hwndParent ));
00378                     SetLastError(ERROR_INVALID_PARAMETER);
00379                     return FALSE;
00380             }
00381             RELEASE_WNDOBJ(window);
00382             /* Windows does this for overlapped windows
00383              * (I don't know about other styles.) */
00384             if (cs->hwndParent == GetDesktopWindow() && (!(cs->style & WS_CHILD) || (cs->style & WS_POPUP)))
00385             {
00386                     cs->hwndParent = 0;
00387             }
00388     }
00389     else
00390     if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
00391             dprintf(("No parent for child window" ));
00392             SetLastError(ERROR_INVALID_PARAMETER);
00393             return FALSE;  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
00394     }
00395 
00396     /* Find the window class */
00397     windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
00398     if (!windowClass)
00399     {
00400         GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
00401         dprintf(("Bad class '%s'", buffer ));
00402         SetLastError(ERROR_INVALID_PARAMETER);
00403         return 0;
00404     }
00405 
00406 #ifdef DEBUG
00407     if(HIWORD(cs->lpszClass))
00408     {
00409          if(isUnicode) dprintf(("Window class %ls", cs->lpszClass));
00410          else          dprintf(("Window class %s", cs->lpszClass));
00411     }
00412     else dprintf(("Window class %x", cs->lpszClass));
00413 #endif
00414 
00415     /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
00416      * with an atom as the class name, put some programs expect to have a *REAL* string in
00417      * lpszClass when the CREATESTRUCT is sent with WM_CREATE
00418      */
00419     if (!HIWORD(cs->lpszClass) ) {
00420         if (isUnicode) {
00421                 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
00422         }
00423         else {
00424                 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
00425         }
00426         cs->lpszClass = buffer;
00427     }
00428 
00429     /* Fix the coordinates */
00430     fXDefault = FALSE;
00431     fCXDefault = FALSE;
00432     if ((cs->x == CW_USEDEFAULT) || (cs->x == CW_USEDEFAULT16))
00433     {
00434        /* Never believe Microsoft's documentation... CreateWindowEx doc says
00435         * that if an overlapped window is created with WS_VISIBLE style bit
00436         * set and the x parameter is set to CW_USEDEFAULT, the system ignores
00437         * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
00438         * reveals that
00439         *
00440         * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
00441         * 2) it does not ignore the y parameter as the docs claim; instead, it
00442         *    uses it as second parameter to ShowWindow() unless y is either
00443         *    CW_USEDEFAULT or CW_USEDEFAULT16.
00444         *
00445         * The fact that we didn't do 2) caused bogus windows pop up when wine
00446         * was running apps that were using this obscure feature. Example -
00447         * calc.exe that comes with Win98 (only Win98, it's different from
00448         * the one that comes with Win95 and NT)
00449         */
00450         if ((cs->y != CW_USEDEFAULT) && (cs->y != CW_USEDEFAULT16)) sw = cs->y;
00451 
00452         /* We have saved cs->y, now we can trash it */
00453         cs->x = 0;
00454         cs->y = 0;
00455         fXDefault = TRUE;
00456     }
00457     if ((cs->cx == CW_USEDEFAULT) || (cs->cx == CW_USEDEFAULT16))
00458     {
00459         cs->cx = 600; /* FIXME */
00460         cs->cy = 400;
00461         fCXDefault = TRUE;
00462     }
00463     if (cs->style & (WS_POPUP | WS_CHILD))
00464     {
00465         fXDefault = FALSE;
00466         if (fCXDefault)
00467         {
00468             fCXDefault = FALSE;
00469             cs->cx = cs->cy = 0;
00470         }
00471     }
00472     if (fXDefault && !fCXDefault) fXDefault = FALSE; //CB: only x positioning doesn't work (calc.exe,cdrlabel.exe)
00473 
00474 
00475     /* Correct the window style - stage 1
00476      *
00477      * These are patches that appear to affect both the style loaded into the
00478      * WIN structure and passed in the CreateStruct to the WM_CREATE etc.
00479      *
00480      * WS_EX_WINDOWEDGE appears to be enforced based on the other styles, so
00481      * why does the user get to set it?
00482      */
00483 
00484     /* This has been tested for WS_CHILD | WS_VISIBLE.  It has not been
00485      * tested for WS_POPUP
00486      */
00487     if ((cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
00488         ((!(cs->dwExStyle & WS_EX_STATICEDGE)) &&
00489           (cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
00490         cs->dwExStyle |= WS_EX_WINDOWEDGE;
00491     else
00492         cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
00493 
00494     //Allocate window words
00495     nrUserWindowBytes = windowClass->getExtraWndBytes();
00496     if(nrUserWindowBytes) {
00497         userWindowBytes = (char *)_smalloc(nrUserWindowBytes);
00498         memset(userWindowBytes, 0, nrUserWindowBytes);
00499     }
00500 
00501     if ((cs->style & WS_CHILD) && cs->hwndParent)
00502     {
00503         SetParent(cs->hwndParent);
00504 //        owner = GetWindowFromHandle(cs->hwndParent);
00505         owner = 0;
00506 /*        if(owner == NULL)
00507         {
00508             dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
00509             SetLastError(ERROR_INVALID_WINDOW_HANDLE);
00510             return FALSE;
00511         }*/
00512         //SvL: Shell positioning shouldn't be done for child windows! (breaks Notes)
00513         fXDefault = fCXDefault = FALSE;
00514     }
00515     else
00516     {
00517         SetParent(0);
00518         if (!cs->hwndParent || (cs->hwndParent == windowDesktop->getWindowHandle())) {
00519             owner = NULL;
00520         }
00521         else
00522         {
00523             Win32BaseWindow *wndparent = GetWindowFromHandle(cs->hwndParent); 
00524             if(wndparent) {
00525                  owner = GetWindowFromHandle(wndparent->GetTopParent());
00526                  RELEASE_WNDOBJ(wndparent);
00527             }
00528             else owner = NULL;        
00529 
00530             if(owner == NULL)
00531             {
00532                 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
00533                 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
00534                 return FALSE;
00535             }
00536         }
00537     }
00538 
00539     WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc(), WINPROC_GetProcType(windowClass->getWindowProc()), WIN_PROC_WINDOW);
00540     hInstance  = cs->hInstance;
00541     dwStyle    = cs->style & ~WS_VISIBLE;
00542     dwOldStyle = dwStyle;
00543     dwExStyle  = cs->dwExStyle;
00544 
00545     hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
00546 
00547     /* Correct the window style phase 2 */
00548     if (!(cs->style & WS_CHILD))
00549     {
00550         dwStyle |= WS_CLIPSIBLINGS;
00551         if (!(cs->style & WS_POPUP))
00552         {
00553             dwStyle |= WS_CAPTION;
00554             flags |= WIN_NEED_SIZE;
00555         }
00556     }
00557     if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
00558 
00559     //WinZip 8.0 crashes when a dialog created after opening a zipfile receives
00560     //the WM_SIZE message (before WM_INITDIALOG)
00561     //Opera doesn't like this either.
00562     if(IsDialog()) {
00563         flags |= WIN_NEED_SIZE;
00564     }
00565 
00566     //copy pointer of CREATESTRUCT for usage in MsgCreate method
00567     tmpcs = cs;
00568 
00569     //Store our window object pointer in thread local memory, so PMWINDOW.CPP can retrieve it
00570     TEB *teb = GetThreadTEB();
00571     if(teb == NULL) {
00572         dprintf(("Window creation failed - teb == NULL")); //this is VERY bad
00573         ExitProcess(666);
00574         return FALSE;
00575     }
00576 
00577     teb->o.odin.newWindow = (ULONG)this;
00578 
00579     DWORD dwOSWinStyle, dwOSFrameStyle;
00580 
00581     OSLibWinConvertStyle(dwStyle,dwExStyle,&dwOSWinStyle, &dwOSFrameStyle);
00582 
00583     OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
00584                                    dwOSWinStyle, dwOSFrameStyle, (char *)windowNameA,
00585                                    (owner) ? owner->getOS2WindowHandle() : ((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP),
00586                                    (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
00587                                    0, fTaskList,fXDefault | fCXDefault,windowClass->getStyle(), &OS2HwndFrame);
00588     if(OS2Hwnd == 0) {
00589         dprintf(("Window creation failed!! OS LastError %0x", OSLibWinGetLastError()));
00590         SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
00591         return FALSE;
00592     }
00593     OSLibWinSetVisibleRegionNotify(OS2Hwnd, TRUE);
00594     state = STATE_CREATED;
00595     SetLastError(0);
00596     return TRUE;
00597 }
00598 //******************************************************************************
00599 //******************************************************************************
00600 BOOL Win32BaseWindow::MsgCreate(HWND hwndOS2)
00601 {
00602  CREATESTRUCTA *cs = tmpcs;  //pointer to CREATESTRUCT used in CreateWindowExA method
00603  POINT          maxSize, maxPos, minTrack, maxTrack;
00604  HWND           hwnd = getWindowHandle();
00605  LRESULT (* CALLBACK localSend32)(HWND, UINT, WPARAM, LPARAM);
00606 
00607     OS2Hwnd      = hwndOS2;
00608 
00609     if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, getWindowHandle()) == FALSE) {
00610         dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
00611         SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
00612         return FALSE;
00613     }
00614     if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
00615         dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
00616         SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
00617         return FALSE;
00618     }
00619     if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32FLAGS, 0) == FALSE) {
00620         dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
00621         SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
00622         return FALSE;
00623     }
00624 
00625     if (HOOK_IsHooked( WH_CBT ))
00626     {
00627         CBT_CREATEWNDA cbtc;
00628         LRESULT ret;
00629 
00630         cbtc.lpcs = cs;
00631         cbtc.hwndInsertAfter = hwndLinkAfter;
00632         ret = (isUnicode) ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc)
00633                           : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc);
00634         if(ret)
00635         {
00636             dprintf(("CBT-hook returned 0!!"));
00637             SetLastError(ERROR_CAN_NOT_COMPLETE); //todo: wrong error
00638             return FALSE;
00639         }
00640         //todo: if hook changes parent, we need to do so too!!!!!!!!!!
00641     }
00642 
00643     if (cs->style & WS_HSCROLL)
00644     {
00645         horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
00646         horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
00647         horzScrollInfo->MaxVal = 100;
00648         horzScrollInfo->flags  = ESB_ENABLE_BOTH;
00649     }
00650 
00651     if (cs->style & WS_VSCROLL)
00652     {
00653         vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
00654         vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
00655         vertScrollInfo->MaxVal = 100;
00656         vertScrollInfo->flags  = ESB_ENABLE_BOTH;
00657     }
00658   
00659     // initially allocate the window name fields
00660     if(HIWORD(cs->lpszName))
00661     {
00662         if (!isUnicode)
00663         {
00664             windowNameLength = strlen(cs->lpszName);
00665             windowNameA = (LPSTR)_smalloc(windowNameLength+1);
00666             memcpy(windowNameA,cs->lpszName,windowNameLength+1);
00667             windowNameW = (LPWSTR)_smalloc((windowNameLength+1)*sizeof(WCHAR));
00668             lstrcpynAtoW(windowNameW,windowNameA,windowNameLength+1);
00669             windowNameA[windowNameLength] = 0;
00670             windowNameW[windowNameLength] = 0;
00671         }
00672         else
00673         {
00674             // Wide
00675             windowNameLength = lstrlenW((LPWSTR)cs->lpszName);
00676             windowNameW = (LPWSTR)_smalloc( (windowNameLength+1)*sizeof(WCHAR) );
00677             memcpy(windowNameW,(LPWSTR)cs->lpszName, (windowNameLength+1)*sizeof(WCHAR) );
00678           
00679             // windowNameW[lstrlenW((LPWSTR)cs->lpszName)] = 0; // need ?
00680           
00681             // Ascii
00682             windowNameA = (LPSTR)_smalloc(windowNameLength+1);
00683             WideCharToMultiByte(CP_ACP,
00684                                 0,
00685                                 windowNameW,
00686                                 windowNameLength,
00687                                 windowNameA,
00688                                 windowNameLength + 1,
00689                                 0,
00690                                 NULL);
00691             windowNameA[windowNameLength] = 0;
00692         }
00693       
00694         if(fOS2Look) {
00695             OSLibWinSetTitleBarText(OS2HwndFrame, windowNameA);
00696         }
00697     }
00698 
00699 //SvL: This completely messes up MS Word 97 (no button bar, no menu)
00700 #if 0
00701   //adjust CW_USEDEFAULT position
00702   if (fXDefault | fCXDefault)
00703   {
00704     RECT rect;
00705 
00706     //SvL: Returns invalid rectangle (not the expected shell default size)
00707     OSLibWinQueryWindowRect(OS2Hwnd,&rect,RELATIVE_TO_SCREEN);
00708     if (getParent()) mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2WindowHandle(),&rect);
00709     if (fXDefault)
00710     {
00711       cs->x = rect.left;
00712       cs->y = rect.top;
00713       if (!fCXDefault)
00714       {
00715         //CB: todo: adjust pos to screen rect
00716       }
00717     }
00718     if (fCXDefault)
00719     {
00720       cs->cx = rect.right-rect.left;
00721       cs->cy = rect.bottom-rect.top;
00722     }
00723   }
00724 #endif
00725 
00726     fakeWinBase.hwndThis     = OS2Hwnd;
00727     fakeWinBase.pWindowClass = windowClass;
00728 
00729     //Set icon from window or class
00730     if (hIcon)
00731         OSLibWinSetIcon(OS2HwndFrame,hIcon);
00732     else
00733     if (windowClass->getIcon())
00734         OSLibWinSetIcon(OS2HwndFrame,windowClass->getIcon());
00735 
00736     /* Get class or window DC if needed */
00737     if(windowClass->getStyle() & CS_OWNDC) {
00738         dprintf(("Class with CS_OWNDC style"));
00739         ownDC = GetDCEx(getWindowHandle(), NULL, DCX_USESTYLE);
00740     }
00741     else
00742     if (windowClass->getStyle() & CS_PARENTDC)  {
00743         fParentDC = TRUE;
00744         ownDC = 0;
00745     }
00746     else
00747     if (windowClass->getStyle() & CS_CLASSDC)  {
00748         dprintf(("WARNING: Class with CS_CLASSDC style!"));
00749         //not a good solution, but it's a bit difficult to share a single
00750         //DC among different windows... DevOpenDC apparently can't be used
00751         //for window DCs and WinOpenWindowDC must be associated with a window
00752         ownDC = GetDCEx(getWindowHandle(), NULL, DCX_USESTYLE);
00753     }
00754     /* Set the window menu */
00755     if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
00756     {
00757         if (cs->hMenu) {
00758             ::SetMenu(getWindowHandle(), cs->hMenu);
00759         }
00760         else {
00761                 if (windowClass->getMenuNameA()) {
00762                         cs->hMenu = LoadMenuA(windowClass->getInstance(),windowClass->getMenuNameA());
00763 #if 0 //CB: hack for treeview test cases bug
00764 if (!cs->hMenu) cs->hMenu = LoadMenuA(windowClass->getInstance(),"MYAPP");
00765 #endif
00766                         if (cs->hMenu) ::SetMenu(getWindowHandle(), cs->hMenu );
00767                 }
00768         }
00769     }
00770     else
00771     {
00772         setWindowId((DWORD)cs->hMenu);
00773     }
00774     hSysMenu = (dwStyle & WS_SYSMENU) ? MENU_GetSysMenu(Win32Hwnd,0):0;
00775 
00776     /* Send the WM_GETMINMAXINFO message and fix the size if needed */
00777     if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
00778     {
00779         GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
00780         if (maxSize.x < cs->cx) cs->cx = maxSize.x;
00781         if (maxSize.y < cs->cy) cs->cy = maxSize.y;
00782         if (cs->cx < minTrack.x) cs->cx = minTrack.x;
00783         if (cs->cy < minTrack.y) cs->cy = minTrack.y;
00784     }
00785 
00786     if(cs->style & WS_CHILD)
00787     {
00788         if(cs->cx < 0) cs->cx = 0;
00789         if(cs->cy < 0) cs->cy = 0;
00790     }
00791     else
00792     {
00793         if (cs->cx <= 0) cs->cx = 1;
00794         if (cs->cy <= 0) cs->cy = 1;
00795     }
00796 
00797     //set client & window rectangles from CreateWindowEx CREATESTRUCT
00798     rectWindow.left = cs->x;
00799     rectWindow.right = cs->x+cs->cx;
00800     rectWindow.top = cs->y;
00801     rectWindow.bottom = cs->y+cs->cy;
00802     rectClient = rectWindow;
00803     OffsetRect(&rectClient, -rectClient.left, -rectClient.top);
00804 
00805     /* Send the WM_CREATE message
00806      * Perhaps we shouldn't allow width/height changes as well.
00807      * See p327 in "Internals".
00808      */
00809     maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
00810 
00811     if(fTaskList) {
00812         hTaskList = OSLibWinAddToTaskList(OS2HwndFrame, windowNameA, (cs->style & WS_VISIBLE) ? 1 : 0);
00813     }
00814 
00815     localSend32 = (isUnicode) ? ::SendMessageW : ::SendMessageA;
00816 
00817     state = STATE_PRE_WMNCCREATE;
00818     if(localSend32(getWindowHandle(), WM_NCCREATE,0,(LPARAM)cs))
00819     {
00820         RECT tmpRect;
00821 
00822         //CB: recheck flags
00823         if (cs->style & (WS_POPUP | WS_CHILD))
00824         {
00825             fXDefault = FALSE;
00826             if (fCXDefault)
00827             {
00828                 fCXDefault = FALSE;
00829                 cs->cx = cs->cy = 0;
00830                 rectWindow.right  = rectWindow.left;
00831                 rectWindow.bottom = rectWindow.top;
00832             }
00833         }
00834         tmpRect = rectWindow;
00835         state   = STATE_POST_WMNCCREATE;
00836 
00837         //set the window size and update the client
00838         SetWindowPos(hwndLinkAfter, tmpRect.left, tmpRect.top, tmpRect.right-tmpRect.left, tmpRect.bottom-tmpRect.top,SWP_NOACTIVATE | SWP_NOREDRAW | SWP_FRAMECHANGED);
00839 
00840         state = STATE_PRE_WMCREATE;
00841         if (cs->style & WS_VISIBLE) dwStyle |= WS_VISIBLE; //program could change position in WM_CREATE
00842         if( (localSend32(getWindowHandle(), WM_CREATE, 0, (LPARAM)cs )) != -1 )
00843         {
00844             state = STATE_POST_WMCREATE;
00845 
00846             if(!(flags & WIN_NEED_SIZE))
00847             {
00848                 SendInternalMessageA(WM_SIZE, SIZE_RESTORED,
00849                                 MAKELONG(rectClient.right-rectClient.left,
00850                                          rectClient.bottom-rectClient.top));
00851 
00852                 if(!::IsWindow(hwnd))
00853                 {
00854                     dprintf(("Createwindow: WM_SIZE destroyed window"));
00855                     goto end;
00856                 }
00857                 SendInternalMessageA(WM_MOVE,0,MAKELONG(rectClient.left,rectClient.top));
00858                 if(!::IsWindow(hwnd))
00859                 {
00860                     dprintf(("Createwindow: WM_MOVE destroyed window"));
00861                     goto end;
00862                 }
00863             }
00864             if (getStyle() & (WS_MINIMIZE | WS_MAXIMIZE))
00865             {
00866                 RECT newPos;
00867                 UINT swFlag = (getStyle() & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
00868                 setStyle(getStyle() & ~(WS_MAXIMIZE | WS_MINIMIZE));
00869                 MinMaximize(swFlag, &newPos);
00870                 swFlag = ((getStyle() & WS_CHILD) || GetActiveWindow()) ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
00871                                                                         : SWP_NOZORDER | SWP_FRAMECHANGED;
00872                 SetWindowPos(0, newPos.left, newPos.top,  newPos.right, newPos.bottom, swFlag);
00873                 if(!::IsWindow(hwnd))
00874                 {
00875                     dprintf(("Createwindow: min/max destroyed window"));
00876                     goto end;
00877                 }
00878             }
00879 
00880             if( (getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
00881             {
00882                 /* Notify the parent window only */
00883                 if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
00884                 {
00885                     getParent()->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, getWindowId()), (LPARAM)getWindowHandle());
00886                 }
00887                 if(!::IsWindow(hwnd))
00888                 {
00889                     dprintf(("Createwindow: WM_PARENTNOTIFY destroyed window"));
00890                     goto end;
00891                 }
00892             }
00893 
00894             if(cs->style & WS_VISIBLE) {
00895                 dwStyle &= ~WS_VISIBLE;
00896                 ShowWindow(sw);
00897             }
00898 
00899             /* Call WH_SHELL hook */
00900             if (!(getStyle() & WS_CHILD) && !owner)
00901                 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWCREATED, getWindowHandle(), 0);
00902 
00903             SetLastError(0);
00904             return TRUE;
00905         }
00906     }
00907     dprintf(("Window creation FAILED (NCCREATE cancelled creation)"));
00908     SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
00909 end:
00910     return FALSE;
00911 }
00912 //******************************************************************************
00913 //******************************************************************************
00914 ULONG Win32BaseWindow::MsgQuit()
00915 {
00916   return SendInternalMessageA(WM_QUIT, 0, 0);
00917 }
00918 //******************************************************************************
00919 //******************************************************************************
00920 ULONG Win32BaseWindow::MsgClose()
00921 {
00922   return SendInternalMessageA(WM_CLOSE,0,0);
00923 }
00924 //******************************************************************************
00925 //******************************************************************************
00926 ULONG Win32BaseWindow::MsgDestroy()
00927 {
00928  ULONG rc;
00929  Win32BaseWindow *child;
00930  HWND hwnd = getWindowHandle();
00931 
00932     state = STATE_DESTROYED;
00933 
00934     if(fDestroyWindowCalled == FALSE)
00935     {//this window was destroyed because DestroyWindow was called for it's parent
00936      //so: send a WM_PARENTNOTIFY now as that hasn't happened yet
00937         if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
00938         {
00939             if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
00940             {
00941                     /* Notify the parent window only */
00942                     getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
00943             }
00944 ////            else    DebugInt3();
00945         }
00946     }
00947     SendInternalMessageA(WM_DESTROY, 0, 0);
00948     if(::IsWindow(hwnd) == FALSE) {
00949         //object already destroyed, so return immediately
00950         return 1;
00951     }
00952     SendInternalMessageA(WM_NCDESTROY, 0, 0);
00953 
00954     TIMER_KillTimerFromWindow(getWindowHandle());
00955 
00956     if(getRefCount() == 0 && getFirstChild() == NULL && state == STATE_CREATED) {
00957         delete this;
00958     }
00959     else {
00960         //make sure no message can ever arrive for this window again (PM or from other win32 windows)
00961         dprintf(("Mark window %x (%x) as deleted", getWindowHandle(), this));
00962         markDeleted();
00963         OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
00964         OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
00965         if(Win32Hwnd) {
00966             HwFreeWindowHandle(Win32Hwnd);
00967             Win32Hwnd = 0;
00968         }
00969     }
00970     return 1;
00971 }
00972 //******************************************************************************
00973 //******************************************************************************
00974 ULONG Win32BaseWindow::MsgEnable(BOOL fEnable)
00975 {
00976     if(fEnable) {
00977          dwStyle &= ~WS_DISABLED;
00978     }
00979     else dwStyle |= WS_DISABLED;
00980 
00981     return SendInternalMessageA(WM_ENABLE, fEnable, 0);
00982 }
00983 //******************************************************************************
00984 //TODO: SW_PARENTCLOSING/OPENING flag (lParam)
00985 //******************************************************************************
00986 ULONG Win32BaseWindow::MsgShow(BOOL fShow)
00987 {
00988     if(!CanReceiveSizeMsgs() || fDestroyWindowCalled) {
00989         return 1;
00990     }
00991 
00992     if(fShow) {
00993          setStyle(getStyle() | WS_VISIBLE);
00994          if(getStyle() & WS_MINIMIZE) {
00995             return ShowWindow(SW_RESTORE);
00996          }
00997     }
00998     else setStyle(getStyle() & ~WS_VISIBLE);
00999 
01000     //already sent from ShowWindow
01001 ////    return SendInternalMessageA(WM_SHOWWINDOW, fShow, 0);
01002     return 0;
01003 }
01004 //******************************************************************************
01005 //******************************************************************************
01006 ULONG Win32BaseWindow::MsgPosChanging(LPARAM lp)
01007 {
01008     //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
01009     //     a WM_WINDOWPOSCHANGED msg -> crash)
01010     if(!CanReceiveSizeMsgs() || fDestroyWindowCalled)
01011         return 0;
01012 
01013     return SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, lp);
01014 }
01015 //******************************************************************************
01016 //******************************************************************************
01017 ULONG Win32BaseWindow::MsgPosChanged(LPARAM lp)
01018 {
01019     //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
01020     //     a WM_WINDOWPOSCHANGED msg -> crash)
01021     if(!CanReceiveSizeMsgs() || fDestroyWindowCalled)
01022         return 1;
01023 
01024     return SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, lp);
01025 }
01026 //******************************************************************************
01027 //******************************************************************************
01028 ULONG Win32BaseWindow::MsgScroll(ULONG msg, ULONG scrollCode, ULONG scrollPos)
01029 {
01030   //According to the SDK docs, the scrollbar handle (lParam) is 0 when the standard
01031   //window scrollbars send these messages
01032   return SendInternalMessageA(msg, MAKELONG(scrollCode, scrollPos), 0);
01033 }
01034 //******************************************************************************
01035 //******************************************************************************
01036 ULONG Win32BaseWindow::MsgActivate(BOOL fActivate, BOOL fMinimized, HWND hwnd, HWND hwndOS2Win)
01037 {
01038  ULONG rc, procidhwnd = -1, threadidhwnd = 0;
01039 
01040     //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
01041     if(fDestroyWindowCalled) {
01042         return 0;
01043     }
01044 
01045     //According to SDK docs, if app returns FALSE & window is being deactivated,
01046     //default processing is cancelled
01047     //TODO: According to Wine we should proceed anyway if window is sysmodal
01048     if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
01049     {
01050         dprintf(("WARNING: WM_NCACTIVATE return code = FALSE -> cancel processing"));
01051         return 0;
01052     }
01053     /* child windows get a WM_CHILDACTIVATE message */
01054     if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
01055     {
01056         if(fActivate) {//WM_CHILDACTIVE is for activation only
01057             SendInternalMessageA(WM_CHILDACTIVATE, 0, 0L);
01058         }
01059         return 0;
01060     }
01061 
01062     return SendInternalMessageA(WM_ACTIVATE, MAKELONG((fActivate) ? WA_ACTIVE : WA_INACTIVE, fMinimized), hwnd);
01063 }
01064 //******************************************************************************
01065 //******************************************************************************
01066 ULONG Win32BaseWindow::MsgChildActivate(BOOL fActivate)
01067 {
01068     //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
01069     if(fDestroyWindowCalled) {
01070         return 0;
01071     }
01072 
01073     //According to SDK docs, if app returns FALSE & window is being deactivated,
01074     //default processing is cancelled
01075     //TODO: According to Wine we should proceed anyway if window is sysmodal
01076     if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
01077     {
01078         dprintf(("WARNING: WM_NCACTIVATE return code = FALSE -> cancel processing"));
01079         return 0;
01080     }
01081     /* child windows get a WM_CHILDACTIVATE message */
01082     if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
01083     {
01084         if(fActivate) {//WM_CHILDACTIVE is for activation only
01085             SendInternalMessageA(WM_CHILDACTIVATE, 0, 0L);
01086         }
01087         return 0;
01088     }
01089     DebugInt3();
01090     return 0;
01091 }
01092 //******************************************************************************
01093 //******************************************************************************
01094 ULONG Win32BaseWindow::DispatchMsgA(MSG *msg)
01095 {
01096     return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
01097 }
01098 //******************************************************************************
01099 //******************************************************************************
01100 ULONG Win32BaseWindow::DispatchMsgW(MSG *msg)
01101 {
01102     return SendInternalMessageW(msg->message, msg->wParam, msg->lParam);
01103 }
01104 //******************************************************************************
01105 //******************************************************************************
01106 ULONG Win32BaseWindow::MsgSetFocus(HWND hwnd)
01107 {
01108     //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
01109     if(fDestroyWindowCalled) {
01110         return 0;
01111     }
01112 
01113     return  SendInternalMessageA(WM_SETFOCUS, hwnd, 0);
01114 }
01115 //******************************************************************************
01116 //******************************************************************************
01117 ULONG Win32BaseWindow::MsgKillFocus(HWND hwnd)
01118 {
01119     //SvL: Don't send WM_(NC)ACTIVATE messages when the window is being destroyed
01120     if(fDestroyWindowCalled) {
01121         return 0;
01122     }
01123     return  SendInternalMessageA(WM_KILLFOCUS, hwnd, 0);
01124 }
01125 //******************************************************************************
01126 //******************************************************************************
01127 ULONG Win32BaseWindow::MsgButton(MSG *msg)
01128 {
01129  BOOL  fClick = FALSE;
01130 
01131     dprintf(("MsgButton %d at (%d,%d)", msg->message, msg->pt.x, msg->pt.y));
01132     switch(msg->message) {
01133         case WM_LBUTTONDBLCLK:
01134         case WM_RBUTTONDBLCLK:
01135         case WM_MBUTTONDBLCLK:
01136                 if (!(windowClass && windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS))
01137                 {
01138                     msg->message = msg->message - (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN); //dblclick -> down
01139                     return MsgButton(msg);
01140                 }
01141                 break;
01142         case WM_NCLBUTTONDBLCLK:
01143         case WM_NCRBUTTONDBLCLK:
01144         case WM_NCMBUTTONDBLCLK:
01145                 //Docs say CS_DBLCLKS style doesn't matter for non-client double clicks
01146                 fClick = TRUE;
01147                 break;
01148 
01149         case WM_LBUTTONDOWN:
01150         case WM_RBUTTONDOWN:
01151         case WM_MBUTTONDOWN:
01152         case WM_NCLBUTTONDOWN:
01153         case WM_NCRBUTTONDOWN:
01154         case WM_NCMBUTTONDOWN:
01155                 fClick = TRUE;
01156                 break;
01157     }
01158 
01159     if(fClick)
01160     {
01161       HWND hwndTop;
01162 
01163         /* Activate the window if needed */
01164         hwndTop = GetTopParent();
01165 
01166         HWND hwndActive = GetActiveWindow();
01167         if (hwndTop && (getWindowHandle() != hwndActive))
01168         {
01169                 LONG ret = SendInternalMessageA(WM_MOUSEACTIVATE, hwndTop,
01170                                                 MAKELONG( lastHitTestVal, msg->message) );
01171 
01172                 dprintf2(("WM_MOUSEACTIVATE returned %d", ret));
01173 #if 0
01174                 if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
01175                          eatMsg = TRUE;
01176 #endif
01177                 //SvL: 0 is not documented, but experiments in NT4 show that
01178                 //     the window will get activated when it returns this.
01179                 //     (FreeCell is an example)
01180                 if(((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT) || (ret == 0))
01181                    && (hwndTop != GetForegroundWindow()) )
01182                 {
01183                     Win32BaseWindow *win32top = Win32BaseWindow::GetWindowFromHandle(hwndTop);
01184 
01185                     //SvL: Calling OSLibSetActiveWindow(hwndTop); causes focus problems
01186                     if (win32top) {
01187                         OSLibWinSetFocus(win32top->getOS2FrameWindowHandle());
01188                         RELEASE_WNDOBJ(win32top);
01189                     }
01190                 }
01191         }
01192     }
01193 
01194     SendInternalMessageA(WM_SETCURSOR, getWindowHandle(), MAKELONG(lastHitTestVal, msg->message));
01195 
01196     return  SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
01197 }
01198 //******************************************************************************
01199 //******************************************************************************
01200 ULONG Win32BaseWindow::MsgPaint(ULONG tmp, ULONG select)
01201 {
01202     if (select && IsWindowIconic())
01203         return SendInternalMessageA(WM_PAINTICON, 1, 0);
01204     else
01205         return SendInternalMessageA(WM_PAINT, 0, 0);
01206 }
01207 //******************************************************************************
01208 //TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
01209 //      (or are we simply erasing too much here)
01210 //******************************************************************************
01211 ULONG Win32BaseWindow::MsgEraseBackGround(HDC hdc)
01212 {
01213     ULONG rc;
01214     HDC   hdcErase = hdc;
01215 
01216     if (hdcErase == 0)
01217         hdcErase = GetDC(getWindowHandle());
01218 
01219     if(IsWindowIconic())
01220         rc = SendInternalMessageA(WM_ICONERASEBKGND, hdcErase, 0);
01221     else
01222         rc = SendInternalMessageA(WM_ERASEBKGND, hdcErase, 0);
01223     if (hdc == 0)
01224         ReleaseDC(getWindowHandle(), hdcErase);
01225     return (rc);
01226 }
01227 //******************************************************************************
01228 //******************************************************************************
01229 ULONG Win32BaseWindow::MsgMouseMove(MSG *msg)
01230 {
01231     //TODO: hiword should be 0 if window enters menu mode (SDK docs)
01232     //SDK: WM_SETCURSOR is not sent if the mouse is captured
01233     if(GetCapture() == 0) {
01234         SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, msg->message));
01235     }
01236 
01237     //translated message == WM_(NC)MOUSEMOVE
01238     return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
01239 }
01240 //******************************************************************************
01241 //******************************************************************************
01242 ULONG Win32BaseWindow::MsgChar(MSG *msg)
01243 {
01244     return DispatchMsgA(msg);
01245 }
01246 //******************************************************************************
01247 //TODO: Should use update region, not rectangle
01248 //******************************************************************************
01249 ULONG Win32BaseWindow::MsgNCPaint(PRECT pUpdateRect)
01250 {
01251     HRGN hrgn;
01252     ULONG rc;
01253     RECT client = rectClient;
01254 
01255     if ((pUpdateRect->left >= client.left) && (pUpdateRect->left < client.right) &&
01256        (pUpdateRect->right >= client.left) && (pUpdateRect->right < client.right) &&
01257        (pUpdateRect->top  >= client.top) && (pUpdateRect->top < client.bottom) &&
01258        (pUpdateRect->bottom >= client.top) && (pUpdateRect->bottom < client.bottom))
01259     {
01260         return 0;
01261     }
01262 
01263     dprintf(("MsgNCPaint (%d,%d)(%d,%d)", pUpdateRect->left, pUpdateRect->top, pUpdateRect->right, pUpdateRect->bottom));
01264     hrgn = CreateRectRgnIndirect(pUpdateRect);
01265 
01266     rc = SendInternalMessageA(WM_NCPAINT, hrgn, 0);
01267 
01268     DeleteObject(hrgn);
01269 
01270     return rc;
01271 }
01272 //******************************************************************************
01273 //Called when either the frame's size or position has changed (lpWndPos != NULL)
01274 //or when the frame layout has changed (i.e. scrollbars added/removed) (lpWndPos == NULL)
01275 //******************************************************************************
01276 ULONG Win32BaseWindow::MsgFormatFrame(WINDOWPOS *lpWndPos)
01277 {
01278   RECT oldWindowRect = rectWindow, client = rectClient, newWindowRect;
01279   RECT newClientRect;
01280   WINDOWPOS wndPos;
01281   ULONG rc;
01282 
01283     if(lpWndPos)
01284     {
01285         //set new window rectangle
01286         setWindowRect(lpWndPos->x, lpWndPos->y, lpWndPos->x+lpWndPos->cx,
01287                       lpWndPos->y+lpWndPos->cy);
01288         newWindowRect = rectWindow;
01289     }
01290     else {
01291         wndPos.hwnd  = getWindowHandle();
01292         wndPos.hwndInsertAfter = 0;
01293         newWindowRect= rectWindow;
01294         wndPos.x     = newWindowRect.left;
01295         wndPos.y     = newWindowRect.top;
01296         wndPos.cx    = newWindowRect.right - newWindowRect.left;
01297         wndPos.cy    = newWindowRect.bottom - newWindowRect.top;
01298         wndPos.flags = SWP_FRAMECHANGED;
01299         lpWndPos     = &wndPos;
01300     }
01301 
01302     newClientRect = rectClient;
01303     rc = SendNCCalcSize(TRUE, &newWindowRect,  &oldWindowRect, &client, lpWndPos, &newClientRect);
01304     rectClient = newClientRect; //must update rectClient here
01305 
01306     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));
01307     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));
01308 
01309     if(!CanReceiveSizeMsgs() || !EqualRect(&client, &rectClient)) {
01310         OSLibWinSetClientPos(getOS2WindowHandle(), rectClient.left, rectClient.top, getClientWidth(), getClientHeight(), getWindowHeight());
01311     }
01312 
01313 #if 1
01314 //this doesn't always work
01315 //  if(CanReceiveSizeMsgs() && (client.left != rectClient.left || client.top != rectClient.top))
01316   if(CanReceiveSizeMsgs() && ((oldWindowRect.right - oldWindowRect.left < rectClient.left
01317                   || oldWindowRect.bottom - oldWindowRect.top < rectClient.top) ||
01318      (EqualRect(&oldWindowRect, &rectWindow) && (client.left != rectClient.left || client.top != rectClient.top))))
01319   {
01320    Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild();
01321 
01322     //client rectangle has moved -> inform children
01323     dprintf(("MsgFormatFrame -> client rectangle has changed, move children"));
01324     while(child) {
01325         ::SetWindowPos(child->getWindowHandle(),
01326                                HWND_TOP, child->getWindowRect()->left,
01327                                child->getWindowRect()->top, 0, 0,
01328                                SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
01329         child = (Win32BaseWindow *)child->getNextChild();
01330     }
01331   }
01332 #endif
01333   if(fOS2Look && ((dwStyle & WS_CAPTION) == WS_CAPTION))
01334   {
01335       RECT rect = {0};
01336       int  height  = getWindowHeight();
01337       RECTLOS2 rectOS2;
01338 
01339       AdjustRectOuter(&rect, FALSE);
01340 
01341       rect.left   = -rect.left;
01342       rect.top    = rect.bottom - rect.top;
01343       rect.right  = rectWindow.right - rectWindow.left - rect.right;
01344  
01345       rectOS2.xLeft   = rect.left;
01346       rectOS2.xRight  = rect.right;
01347       rectOS2.yBottom = height - rect.top;
01348       rectOS2.yTop    = height - rect.bottom;
01349       OSLibWinPositionFrameControls(getOS2FrameWindowHandle(), &rectOS2, dwStyle, dwExStyle, IconForWindow(ICON_SMALL));
01350   }
01351   return rc;
01352 }
01353 //******************************************************************************
01354 //******************************************************************************
01355 ULONG Win32BaseWindow::MsgSetText(LPSTR lpsz, LONG cch)
01356 {
01357     return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
01358 }
01359 //******************************************************************************
01360 //******************************************************************************
01361 ULONG Win32BaseWindow::MsgGetTextLength()
01362 {
01363     return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
01364 }
01365 //******************************************************************************
01366 //******************************************************************************
01367 void Win32BaseWindow::MsgGetText(char *wndtext, ULONG textlength)
01368 {
01369     SendInternalMessageA(WM_GETTEXT, textlength, (LPARAM)wndtext);
01370 }
01371 //******************************************************************************
01372 //******************************************************************************
01373 BOOL Win32BaseWindow::isMDIClient()
01374 {
01375     return FALSE;
01376 }
01377 //******************************************************************************
01378 //******************************************************************************
01379 BOOL Win32BaseWindow::isMDIChild()
01380 {
01381     return FALSE;
01382 }
01383 //******************************************************************************
01384 //TODO: Not complete
01385 //******************************************************************************
01386 BOOL Win32BaseWindow::isFrameWindow()
01387 {
01388     if(getParent() == NULL)
01389         return TRUE;
01390 
01391     return FALSE;
01392 }
01393 //******************************************************************************
01394 //******************************************************************************
01395 BOOL Win32BaseWindow::isDesktopWindow()
01396 {
01397   return FALSE;
01398 }
01399 //******************************************************************************
01400 //******************************************************************************
01401 BOOL Win32BaseWindow::IsWindowIconic()
01402 {
01403     return ((getStyle() & WS_MINIMIZE) && windowClass->getIcon());
01404 }
01405 //******************************************************************************
01406 //******************************************************************************
01407 SCROLLBAR_INFO *Win32BaseWindow::getScrollInfo(int nBar)
01408 {
01409   switch(nBar)
01410   {
01411     case SB_HORZ:
01412       if (!horzScrollInfo)
01413       {
01414         horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
01415         if (!horzScrollInfo) break;
01416         horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
01417         horzScrollInfo->MaxVal = 100;
01418         horzScrollInfo->flags  = ESB_ENABLE_BOTH;
01419       }
01420       return horzScrollInfo;
01421 
01422     case SB_VERT:
01423       if (!vertScrollInfo)
01424       {
01425         vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
01426         if (!vertScrollInfo) break;
01427         vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
01428         vertScrollInfo->MaxVal = 100;
01429         vertScrollInfo->flags  = ESB_ENABLE_BOTH;
01430       }
01431       return vertScrollInfo;
01432   }
01433 
01434   return NULL;
01435 }
01436 //******************************************************************************
01437 //******************************************************************************
01438 LRESULT Win32BaseWindow::DefWndControlColor(UINT ctlType, HDC hdc)
01439 {
01440     //SvL: Set background color to default button color (not window (white))
01441     if(ctlType == CTLCOLOR_BTN)
01442     {
01443         SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
01444         SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
01445         return GetSysColorBrush(COLOR_BTNFACE);
01446     }
01447     //SvL: Set background color to default dialog color if window is dialog
01448     if((ctlType == CTLCOLOR_DLG || ctlType == CTLCOLOR_STATIC) && IsDialog()) {
01449         SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
01450         SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
01451         return GetSysColorBrush(COLOR_BTNFACE);
01452     }
01453     if( ctlType == CTLCOLOR_SCROLLBAR)
01454     {
01455         HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
01456         COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
01457         SetTextColor( hdc, GetSysColor(COLOR_3DFACE));
01458         SetBkColor( hdc, bk);
01459 
01460          /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
01461           * we better use 0x55aa bitmap brush to make scrollbar's background
01462           * look different from the window background.
01463           */
01464         if (bk == GetSysColor(COLOR_WINDOW)) {
01465              return GetPattern55AABrush();
01466         }
01467 
01468         UnrealizeObject( hb );
01469         return (LRESULT)hb;
01470     }
01471 
01472     SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
01473 
01474     if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
01475     {
01476         SetBkColor( hdc, GetSysColor(COLOR_WINDOW) );
01477     }
01478     else
01479     {
01480         SetBkColor( hdc, GetSysColor(COLOR_3DFACE) );
01481         return (LRESULT)GetSysColorBrush(COLOR_3DFACE);
01482     }
01483     return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
01484 }
01485 //******************************************************************************
01486 //******************************************************************************
01487 LRESULT Win32BaseWindow::DefWndPrint(HDC hdc,ULONG uFlags)
01488 {
01489   /*
01490    * Visibility flag.
01491    */
01492   if ( (uFlags & PRF_CHECKVISIBLE) &&
01493        !IsWindowVisible(getWindowHandle()) )
01494       return 0;
01495 
01496   /*
01497    * Unimplemented flags.
01498    */
01499   if ( (uFlags & PRF_CHILDREN) ||
01500        (uFlags & PRF_OWNED)    ||
01501        (uFlags & PRF_NONCLIENT) )
01502   {
01503     dprintf(("WM_PRINT message with unsupported flags\n"));
01504   }
01505 
01506   /*
01507    * Background
01508    */
01509   if ( uFlags & PRF_ERASEBKGND)
01510     SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
01511 
01512   /*
01513    * Client area
01514    */
01515   if ( uFlags & PRF_CLIENT)
01516     SendInternalMessageA(WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
01517 
01518 
01519   return 0;
01520 }
01521 //******************************************************************************
01522 //******************************************************************************
01523 LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
01524 {
01525     switch(Msg)
01526     {
01527     case WM_CLOSE:
01528         dprintf(("DefWindowProcA: WM_CLOSE %x", getWindowHandle()));
01529         DestroyWindow();
01530         return 0;
01531 
01532     case WM_GETTEXTLENGTH:
01533         return windowNameLength;
01534 
01535     case WM_GETTEXT:
01536         if (!lParam || !wParam) 
01537           return 0;
01538         if (!windowNameA) 
01539           ((LPSTR)lParam)[0] = 0;
01540         else 
01541           memcpy((LPSTR)lParam, windowNameA, min(windowNameLength+1, wParam) );
01542         return min(windowNameLength, wParam);
01543 
01544     case WM_SETTEXT:
01545     {
01546         LPCSTR lpsz = (LPCSTR)lParam;
01547       
01548         // reallocate if new buffer is larger
01549         if (!lParam)
01550         {
01551           free(windowNameA);
01552           free(windowNameW);
01553           windowNameLength = 0;
01554           windowNameA      = NULL;
01555           windowNameW      = NULL;
01556         }
01557         else
01558         {
01559           // determine length of new text
01560           int iTextLength = strlen(lpsz);
01561           
01562           if (windowNameLength < iTextLength)
01563           {
01564             if (windowNameA)
01565             {
01566               free(windowNameA);
01567               windowNameA = NULL;
01568             }
01569           
01570             if (windowNameW)
01571             {
01572               free(windowNameW);
01573               windowNameW = NULL;
01574             }
01575           }
01576       
01577           windowNameLength = iTextLength;
01578           if(!windowNameA)
01579             windowNameA = (LPSTR)_smalloc(windowNameLength+1);
01580           memcpy(windowNameA, lpsz, windowNameLength+1);
01581           if(!windowNameW)
01582             windowNameW = (LPWSTR)_smalloc((windowNameLength+1)*sizeof(WCHAR));
01583           lstrcpynAtoW(windowNameW, windowNameA, windowNameLength+1);
01584         }
01585       
01586         dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, lParam));
01587         if ((dwStyle & WS_CAPTION) == WS_CAPTION)
01588         {
01589             HandleNCPaint((HRGN)1);
01590             if(hTaskList) {
01591                 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), (getStyle() & WS_VISIBLE) ? 1 : 0);
01592             }
01593             if(fOS2Look) {
01594                 OSLibWinSetTitleBarText(OS2HwndFrame, getWindowNameA());
01595             }
01596         }
01597 
01598         return TRUE;
01599     }
01600 
01601     case WM_SETREDRAW:
01602     {
01603         if (wParam)
01604         {
01605             setStyle(getStyle() | WS_VISIBLE);
01606             dprintf(("Enable window update for %x", getWindowHandle()));
01607             OSLibWinEnableWindowUpdate(OS2HwndFrame, OS2Hwnd, TRUE);
01608         }
01609         else
01610         {
01611             if (getStyle() & WS_VISIBLE)
01612             {
01613                 setStyle(getStyle() & ~WS_VISIBLE);
01614                 dprintf(("Disable window update for %x", getWindowHandle()));
01615                 OSLibWinEnableWindowUpdate(OS2HwndFrame, OS2Hwnd, FALSE);
01616             }
01617         }
01618         return 0;
01619     }
01620 
01621     case WM_CTLCOLORMSGBOX:
01622     case WM_CTLCOLOREDIT:
01623     case WM_CTLCOLORLISTBOX:
01624     case WM_CTLCOLORBTN:
01625     case WM_CTLCOLORDLG:
01626     case WM_CTLCOLORSTATIC:
01627     case WM_CTLCOLORSCROLLBAR:
01628         return DefWndControlColor(Msg - WM_CTLCOLORMSGBOX, (HDC)wParam);
01629 
01630     case WM_CTLCOLOR:
01631         return DefWndControlColor(HIWORD(lParam), (HDC)wParam);
01632 
01633     case WM_VKEYTOITEM:
01634     case WM_CHARTOITEM:
01635              return -1;
01636 
01637     case WM_PARENTNOTIFY:
01638         return 0;
01639 
01640     case WM_MOUSEACTIVATE:
01641     {
01642         dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
01643         if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
01644         {
01645             if(getParent()) {
01646                 LRESULT rc = getParent()->SendInternalMessageA(WM_MOUSEACTIVATE, wParam, lParam );
01647                 if(rc)  return rc;
01648             }
01649         }
01650         return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
01651     }
01652 
01653     case WM_ACTIVATE:
01654         /* The default action in Windows is to set the keyboard focus to
01655          * the window, if it's being activated and not minimized */
01656         if (LOWORD(wParam) != WA_INACTIVE) {
01657             if(!(getStyle() & WS_MINIMIZE))
01658                 SetFocus(getWindowHandle());
01659         }
01660         return 0;
01661 
01662     case WM_SETCURSOR:
01663     {
01664         dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
01665         if((getStyle() & WS_CHILD))
01666         {
01667             if(getParent()) {
01668                 LRESULT rc = getParent()->SendInternalMessageA(WM_SETCURSOR, wParam, lParam);
01669                 if(rc)  return rc;
01670             }
01671         }
01672         if (wParam == getWindowHandle())
01673         {
01674           HCURSOR hCursor;
01675 
01676           switch(LOWORD(lParam))
01677           {
01678             case HTCLIENT:
01679               hCursor = windowClass ? windowClass->getCursor():LoadCursorA(0,IDC_ARROWA);
01680               break;
01681 
01682             case HTLEFT:
01683             case HTRIGHT:
01684               hCursor = LoadCursorA(0,IDC_SIZEWEA);
01685               break;
01686 
01687             case HTTOP:
01688             case HTBOTTOM:
01689               hCursor = LoadCursorA(0,IDC_SIZENSA);
01690               break;
01691 
01692             case HTTOPLEFT:
01693             case HTBOTTOMRIGHT:
01694               hCursor = LoadCursorA(0,IDC_SIZENWSEA);
01695               break;
01696 
01697             case HTTOPRIGHT:
01698             case HTBOTTOMLEFT:
01699               hCursor = LoadCursorA(0,IDC_SIZENESWA);
01700               break;
01701 
01702             default:
01703               hCursor = LoadCursorA(0,IDC_ARROWA);
01704               break;
01705           }
01706 
01707           if (hCursor)
01708           {
01709             SetCursor(hCursor);
01710             return 1;
01711           }
01712           else return 0;
01713         }
01714         else return 0;
01715     }
01716 
01717     case WM_MOUSEMOVE:
01718         return 0;
01719 
01720     case WM_WINDOWPOSCHANGED:
01721     {
01722         PWINDOWPOS wpos = (PWINDOWPOS)lParam;
01723         WPARAM     wp   = SIZE_RESTORED;
01724 
01725         if (!(wpos->flags & SWP_NOMOVE) && !(wpos->flags & SWP_NOCLIENTMOVE))
01726         {
01727             SendInternalMessageA(WM_MOVE, 0, MAKELONG(rectClient.left,rectClient.top));
01728         }
01729         if (!(wpos->flags & SWP_NOSIZE) && !(wpos->flags & SWP_NOCLIENTSIZE))
01730         {
01731             if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
01732             else
01733             if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
01734 
01735             SendInternalMessageA(WM_SIZE, wp, MAKELONG(rectClient.right  - rectClient.left,
01736                                                        rectClient.bottom - rectClient.top));
01737         }
01738         return 0;
01739     }
01740     case WM_WINDOWPOSCHANGING:
01741         return HandleWindowPosChanging((WINDOWPOS *)lParam);
01742 
01743     case WM_ERASEBKGND:
01744     case WM_ICONERASEBKGND:
01745     {
01746       RECT rect;
01747       int rc;
01748 
01749         if (!windowClass || !windowClass->getBackgroundBrush()) return 0;
01750 
01751         rc = GetClipBox( (HDC)wParam, &rect );
01752         if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
01753         {
01754             HBRUSH hBrush = windowClass->getBackgroundBrush();
01755 
01756             if (hBrush <= (HBRUSH)(SYSCOLOR_GetLastColor()+1))
01757                 hBrush = GetSysColorBrush(hBrush-1);
01758 
01759             FillRect( (HDC)wParam, &rect, hBrush);
01760         }
01761         return 1;
01762     }
01763 
01764     case WM_PRINT:
01765         return DefWndPrint(wParam,lParam);
01766 
01767     case WM_PAINTICON:
01768     case WM_PAINT:
01769     {
01770         PAINTSTRUCT ps;
01771         HDC hdc = BeginPaint(getWindowHandle(), &ps );
01772         if( hdc )
01773         {
01774             if( (getStyle() & WS_MINIMIZE) && (getWindowClass()->getIcon() || hIcon))
01775             {
01776                 int x = (rectWindow.right - rectWindow.left - GetSystemMetrics(SM_CXICON))/2;
01777                 int y = (rectWindow.bottom - rectWindow.top - GetSystemMetrics(SM_CYICON))/2;
01778                 dprintf(("Painting class icon: vis rect=(%i,%i - %i,%i)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom ));
01779                 DrawIcon(hdc, x, y, hIcon ? hIcon:getWindowClass()->getIcon() );
01780             }
01781             EndPaint(getWindowHandle(), &ps );
01782         }
01783         return 0;
01784     }
01785 
01786     case WM_GETDLGCODE:
01787         return 0;
01788 
01789     case WM_NCPAINT:
01790          return HandleNCPaint((HRGN)wParam);
01791 
01792     case WM_NCACTIVATE:
01793         return HandleNCActivate(wParam);
01794 
01795     case WM_NCCREATE:
01796         return(TRUE);
01797 
01798     case WM_NCDESTROY:
01799         return 0;
01800 
01801     case WM_NCCALCSIZE:
01802         return HandleNCCalcSize((BOOL)wParam,(RECT*)lParam);
01803 
01804     case WM_NCLBUTTONDOWN:
01805         return HandleNCLButtonDown(wParam,lParam);
01806 
01807     case WM_LBUTTONDBLCLK:
01808     case WM_NCLBUTTONDBLCLK:
01809         return HandleNCLButtonDblClk(wParam,lParam);
01810 
01811     case WM_NCRBUTTONDOWN:
01812     case WM_NCRBUTTONDBLCLK:
01813     case WM_NCMBUTTONDOWN:
01814     case WM_NCMBUTTONDBLCLK:
01815         if (lastHitTestVal == HTERROR) MessageBeep(MB_ICONEXCLAMATION);
01816         return 0;
01817 
01818     case WM_NCRBUTTONUP:
01819         return HandleNCRButtonUp(wParam,lParam);
01820 
01821     case WM_NCMBUTTONUP:
01822         return 0;
01823 
01824     case WM_NCHITTEST:
01825     {
01826       POINT point;
01827       LRESULT retvalue;
01828 
01829       point.x = (SHORT)LOWORD(lParam);
01830       point.y = (SHORT)HIWORD(lParam);
01831 
01832       retvalue = HandleNCHitTest(point);
01833 #if 0 //CB: let the Corel people fix the bugs first
01834       if(retvalue == HTMENU)
01835         MENU_TrackMouseMenuBar_MouseMove(Win32Hwnd,point,TRUE);
01836       else
01837         MENU_TrackMouseMenuBar_MouseMove(Win32Hwnd,point,FALSE);
01838 #endif
01839       return retvalue;
01840     }
01841 
01842     case WM_SYSCOMMAND:
01843     {
01844      POINT point;
01845 
01846         point.x = LOWORD(lParam);
01847         point.y = HIWORD(lParam);
01848         return HandleSysCommand(wParam,&point);
01849     }
01850 
01851     case WM_SYSKEYDOWN:
01852     {
01853         if( HIWORD(lParam) & KEYDATA_ALT )
01854         {
01855             /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
01856               if( wParam == VK_MENU && !iMenuSysKey )
01857                 iMenuSysKey = 1;
01858               else
01859                 iMenuSysKey = 0;
01860             
01861             iF10Key = 0;
01862 
01863             if( wParam == VK_F4 )       /* try to close the window */
01864             {
01865                 HWND top = GetTopParent();
01866                 if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
01867                     PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
01868             }
01869         } 
01870         else if( wParam == VK_F10 )
01871                 iF10Key = 1;
01872              else
01873                 if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000))
01874                     SendMessageW(WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE );
01875 
01876         Win32BaseWindow *siblingWindow;
01877         HWND sibling;
01878         char nameBuffer [40], mnemonic;
01879         int nameLength;
01880 
01881         GetWindowTextA (nameBuffer, 40);
01882 
01883         // search all sibling to see it this key is their mnemonic
01884         sibling = GetWindow (GW_HWNDFIRST);
01885         while (sibling != 0) {
01886             siblingWindow = GetWindowFromHandle (sibling);
01887             nameLength = siblingWindow->GetWindowTextA (nameBuffer, 40);
01888 
01889             // find the siblings mnemonic
01890             mnemonic = '\0';
01891             for (int i=0 ; i<nameLength ; i++) {
01892                 if (IsDBCSLeadByte(nameBuffer[i])) {
01893                     // Skip DBCS
01894                     continue;
01895                 }
01896                 if (nameBuffer [i] == '&') {
01897                     mnemonic = nameBuffer [i+1];
01898                     if ((mnemonic >= 'a') && (mnemonic <= 'z'))
01899                         mnemonic -= 32; // make it uppercase
01900                     break;  // stop searching
01901                 }
01902             }
01903 
01904             // key matches siblings mnemonic, send mouseclick
01905             if (mnemonic == (char) wParam) {
01906                 siblingWindow->SendInternalMessageA (BM_CLICK, 0, 0);
01907             }
01908             sibling = siblingWindow->GetNextWindow (GW_HWNDNEXT);
01909             RELEASE_WNDOBJ(siblingWindow);
01910         }
01911 
01912         return 0;
01913     }
01914 
01915     case WM_KEYUP:
01916     case WM_SYSKEYUP:
01917         /* Press and release F10 or ALT */
01918         if (((wParam == VK_MENU) && iMenuSysKey) ||
01919             ((wParam == VK_F10) && iF10Key))
01920               ::SendMessageW( GetTopWindow(), WM_SYSCOMMAND, SC_KEYMENU, 0L );
01921         iMenuSysKey = iF10Key = 0;
01922         break;
01923 
01924     case WM_SYSCHAR:
01925     {
01926         iMenuSysKey = 0;
01927         if (wParam == VK_RETURN && (getStyle() & WS_MINIMIZE))
01928         {
01929                 PostMessageA(getWindowHandle(), WM_SYSCOMMAND,
01930                          (WPARAM)SC_RESTORE, 0L );
01931                 break;
01932         }
01933         if((HIWORD(lParam) & KEYDATA_ALT) && wParam)
01934         {
01935                 if (wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_F4)
01936                         break;
01937                 if (wParam == VK_SPACE && (getStyle() & WS_CHILD)) {
01938                         ::SendMessageW(GetParent(), Msg, wParam, lParam );
01939                 }
01940                 else    SendMessageA(WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam );
01941         }
01942 #if 0
01943         else /* check for Ctrl-Esc */
01944                 if (wParam != VK_ESCAPE) MessageBeep(0);
01945                         break;
01946 #endif
01947     }
01948 
01949     case WM_SETHOTKEY:
01950         hotkey = wParam;
01951         return 1; //CB: always successful
01952 
01953     case WM_GETHOTKEY:
01954         return hotkey;
01955 
01956     case WM_CONTEXTMENU:
01957         if ((dwStyle & WS_CHILD) && getParent())
01958           getParent()->SendInternalMessageA(WM_CONTEXTMENU,wParam,lParam);
01959         return 0;
01960 
01961     case WM_SHOWWINDOW:
01962         if (!lParam) return 0; /* sent from ShowWindow */
01963         if (!(dwStyle & WS_POPUP) || !owner) return 0;
01964         if ((dwStyle & WS_VISIBLE) && wParam) return 0;
01965         else if (!(dwStyle & WS_VISIBLE) && !wParam) return 0;
01966         ShowWindow(wParam ? SW_SHOW:SW_HIDE);
01967         return 0;
01968 
01969     case WM_CANCELMODE:
01970         if (getParent() == windowDesktop) EndMenu();
01971         if (GetCapture() == Win32Hwnd) ReleaseCapture();
01972         return 0;
01973 
01974     case WM_DROPOBJECT:
01975         return DRAG_FILE;
01976 
01977     case WM_QUERYDROPOBJECT:
01978         return (dwExStyle & WS_EX_ACCEPTFILES) ? 1:0;
01979 
01980     case WM_QUERYDRAGICON:
01981         {
01982             HICON hDragIcon = windowClass->getCursor();
01983             UINT len;
01984 
01985             if(hDragIcon) return (LRESULT)hDragIcon;
01986             for(len = 1; len < 64; len++)
01987             {
01988               hDragIcon = LoadIconA(hInstance,MAKEINTRESOURCEA(len));
01989               if(hDragIcon)
01990                 return (LRESULT)hDragIcon;
01991             }
01992             return (LRESULT)LoadIconA(0,IDI_APPLICATIONA);
01993         }
01994 
01995     case WM_QUERYOPEN:
01996     case WM_QUERYENDSESSION:
01997         return 1;
01998 
01999     case WM_NOTIFYFORMAT:
02000         return IsWindowUnicode() ? NFR_UNICODE:NFR_ANSI;
02001 
02002     case WM_SETICON:
02003     case WM_GETICON:
02004         {
02005           LRESULT result = 0;
02006 
02007           /* Set the appropriate icon members in the window structure. */
02008           if (wParam == ICON_SMALL)
02009           {
02010             result = hIconSm;
02011             if (Msg == WM_SETICON)
02012               hIconSm = (HICON)lParam;
02013           }
02014           else
02015           {
02016             result = hIcon;
02017             if (Msg == WM_SETICON)
02018             {
02019               hIcon = (HICON)lParam;
02020               if ((dwStyle & WS_CAPTION) == WS_CAPTION)
02021                 OSLibWinSetIcon(OS2HwndFrame,hIcon);
02022             }
02023           }
02024           if ((Msg == WM_SETICON) && ((dwStyle & WS_CAPTION) == WS_CAPTION))
02025             HandleNCPaint((HRGN)1);
02026 
02027           return result;
02028         }
02029 
02030     case WM_HELP:
02031         if (getParent()) getParent()->SendInternalMessageA(Msg,wParam,lParam);
02032         break;
02033 
02034     case WM_NOTIFY:
02035         return 0; //comctl32 controls expect this
02036 
02037     default:
02038         return 0;
02039     }
02040     return 0;
02041 }
02042 //******************************************************************************
02043 //******************************************************************************
02044 LRESULT Win32BaseWindow::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
02045 {
02046     switch(Msg)
02047     {
02048     case WM_GETTEXTLENGTH:
02049         return windowNameLength;
02050 
02051     case WM_GETTEXT:
02052         if (!lParam || !wParam) 
02053           return 0;
02054         if (!windowNameW)
02055           ((LPWSTR)lParam)[0] = 0;
02056         else 
02057           memcpy((LPSTR)lParam, windowNameW, min( sizeof(WCHAR) * (windowNameLength+1), wParam) );
02058         return min(windowNameLength, wParam);
02059 
02060     case WM_SETTEXT:
02061     {
02062         LPWSTR lpsz = (LPWSTR)lParam;
02063       
02064         // reallocate if new buffer is larger
02065         if (!lParam)
02066         {
02067           free(windowNameA);
02068           free(windowNameW);
02069           windowNameLength = 0;
02070           windowNameA      = NULL;
02071           windowNameW      = NULL;
02072         }
02073         else
02074         {
02075           // determine length of new text
02076           int iTextLength = lstrlenW(lpsz);
02077           
02078           if (windowNameLength < iTextLength)
02079           {
02080             if (windowNameA)
02081             {
02082               free(windowNameA);
02083               windowNameA = NULL;
02084             }
02085           
02086             if (windowNameW)
02087             {
02088               free(windowNameW);
02089               windowNameW = NULL;
02090             }
02091           }
02092       
02093           windowNameLength = iTextLength;
02094           if(!windowNameW)
02095             windowNameW = (LPWSTR)_smalloc((windowNameLength+1)*sizeof(WCHAR));
02096           memcpy(windowNameW, lpsz, (windowNameLength+1) * sizeof(WCHAR));
02097           if(!windowNameA)
02098             windowNameA = (LPSTR)_smalloc(windowNameLength+1);
02099           lstrcpynWtoA(windowNameA, windowNameW, windowNameLength+1);
02100         }
02101 
02102         dprintf(("WM_SETTEXT of %x\n",Win32Hwnd));
02103         if ((dwStyle & WS_CAPTION) == WS_CAPTION)
02104         {
02105             HandleNCPaint((HRGN)1);
02106             if(hTaskList) {
02107                 OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), (getStyle() & WS_VISIBLE) ? 1 : 0);
02108             }
02109             if(fOS2Look) {
02110                 OSLibWinSetTitleBarText(OS2HwndFrame, getWindowNameA());
02111             }
02112         }
02113 
02114         return TRUE;
02115     }
02116 
02117     default:
02118         return DefWindowProcA(Msg, wParam, lParam);
02119     }
02120 }
02121 //******************************************************************************
02122 //******************************************************************************
02123 LRESULT Win32BaseWindow::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
02124 {
02125     //if the destination window is created by this process & thread, call window proc directly
02126     if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
02127         return SendInternalMessageA(Msg, wParam, lParam);
02128     }
02129     //otherwise use WinSendMsg to send it to the right process/thread
02130     dprintf(("SendMessages (inter-process) %x %x %x %x", getWindowHandle(), Msg, wParam, lParam));
02131     return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, FALSE);
02132 }
02133 //******************************************************************************
02134 //******************************************************************************
02135 LRESULT Win32BaseWindow::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
02136 {
02137     //if the destination window is created by this process & thread, call window proc directly
02138     if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
02139         return SendInternalMessageW(Msg, wParam, lParam);
02140     }
02141     //otherwise use WinSendMsg to send it to the right process/thread
02142     return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, TRUE);
02143 }
02144 //******************************************************************************
02145 //Called as a result of an OS/2 message or called from a class method
02146 //******************************************************************************
02147 LRESULT Win32BaseWindow::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
02148 {
02149  LRESULT rc;
02150  HWND    hwnd = getWindowHandle();
02151  BOOL    fInternalMsgBackup = fInternalMsg;
02152 
02153   //if the destination window was created by this process & thread, call window proc directly
02154   if(dwProcessId != currentProcessId || dwThreadId != GetCurrentThreadId()) {
02155         dprintf(("SendMessages (inter-process) %x %x %x %x", getWindowHandle(), Msg, wParam, lParam));
02156         return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, FALSE);
02157   }
02158 
02159   DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, FALSE, TRUE);
02160 
02161   CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, FALSE);
02162 
02163   fInternalMsg = TRUE;
02164   switch(Msg)
02165   {
02166         case WM_CREATE:
02167         {
02168                 if(CallWindowProcA(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
02169                         dprintf(("WM_CREATE returned -1\n"));
02170                         rc = -1; //don't create window
02171                         break;
02172                 }
02173                 rc = 0;
02174                 break;
02175         }
02176         case WM_LBUTTONDOWN:
02177         case WM_MBUTTONDOWN:
02178         case WM_RBUTTONDOWN:
02179         {
02180                 if (getParent())
02181                 {
02182                     POINTS pt = MAKEPOINTS(lParam);
02183                     POINT point;
02184 
02185                     point.x = pt.x;
02186                     point.y = pt.y;
02187                     MapWindowPoints(getWindowHandle(), getParent()->getWindowHandle(), &point, 1);
02188                     NotifyParent(Msg,wParam,MAKELPARAM(point.x,point.y));
02189                 }
02190                 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
02191                 break;
02192         }
02193         case WM_NCHITTEST:
02194                 rc = lastHitTestVal = win32wndproc(getWindowHandle(), WM_NCHITTEST, wParam, lParam);
02195                 break;
02196 
02197         case WM_DESTROY:
02198                 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
02199                 break;
02200 
02201         default:
02202                 rc = CallWindowProcA(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
02203                 break;
02204   }
02205   if(!::IsWindow(hwnd)) {
02206         //window might have been destroyed by now. (this pointer invalid)
02207         //we must return immediately
02208         //(MS Visual C++ install heap corruption)
02209         //TODO: could happen in several places here!!!!
02210         return rc;
02211   }
02212   fInternalMsg = fInternalMsgBackup;
02213   dprintf2(("SendMessageA %x %x %x %x returned %x", getWindowHandle(), Msg, wParam, lParam, rc));
02214   return rc;
02215 }
02216 //******************************************************************************
02217 //Called as a result of an OS/2 message or called from a class method
02218 //******************************************************************************
02219 LRESULT Win32BaseWindow::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
02220 {
02221  LRESULT rc;
02222  HWND    hwnd = getWindowHandle();
02223  BOOL    fInternalMsgBackup = fInternalMsg;
02224 
02225   //if the destination window was created by this process & thread, call window proc directly
02226   if(dwProcessId != currentProcessId || dwThreadId != GetCurrentThreadId()) {
02227         dprintf(("SendMessages (inter-process) %x %x %x %x", getWindowHandle(), Msg, wParam, lParam));
02228         return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, FALSE);
02229   }
02230 
02231   DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, TRUE, TRUE);
02232 
02233   CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, TRUE);
02234 
02235   fInternalMsg = TRUE;
02236   switch(Msg)
02237   {
02238         case WM_CREATE:
02239         {
02240                 if(CallWindowProcW(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
02241                         dprintf(("WM_CREATE returned -1\n"));
02242                         rc = -1; //don't create window
02243                         break;
02244                 }
02245                 rc = 0;
02246                 break;
02247         }
02248         case WM_LBUTTONDOWN:
02249         case WM_MBUTTONDOWN:
02250         case WM_RBUTTONDOWN:
02251                 NotifyParent(Msg, wParam, lParam);
02252                 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
02253                 break;
02254 
02255         case WM_NCHITTEST:
02256                 rc = lastHitTestVal = win32wndproc(getWindowHandle(), WM_NCHITTEST, wParam, lParam);
02257                 break;
02258 
02259         case WM_DESTROY:
02260                 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
02261                 break;
02262         default:
02263                 rc = CallWindowProcW(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
02264                 break;
02265   }
02266   if(!::IsWindow(hwnd)) {
02267         //window might have been destroyed by now. (this pointer invalid)
02268         //we must return immediately
02269         //(MS Visual C++ install heap corruption)
02270         //TODO: could happen in several places here!!!!
02271         return rc;
02272   }
02273   fInternalMsg = fInternalMsgBackup;
02274   dprintf2(("SendMessageW %x %x %x %x returned %x", getWindowHandle(), Msg, wParam, lParam, rc));
02275   return rc;
02276 }
02277 //******************************************************************************
02278 //******************************************************************************
02279 void Win32BaseWindow::CallWindowHookProc(ULONG hooktype, ULONG Msg, WPARAM wParam, LPARAM lParam, BOOL fUnicode)
02280 {
02281  CWPSTRUCT cwp;
02282 
02283     cwp.lParam  = lParam;
02284     cwp.wParam  = wParam;
02285     cwp.message = Msg;
02286     cwp.hwnd    = getWindowHandle();
02287 
02288     switch(hooktype) {
02289     case WH_CALLWNDPROC:
02290         if(fUnicode) {
02291              HOOK_CallHooksW(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
02292         }
02293         else HOOK_CallHooksA(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
02294         break;
02295     }
02296 }
02297 //******************************************************************************
02298 //TODO: Do this more efficiently
02299 //******************************************************************************
02300 LRESULT Win32BaseWindow::BroadcastMessageA(int type, UINT msg, WPARAM wParam, LPARAM lParam)
02301 {
02302  Win32BaseWindow *window;
02303  HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
02304 
02305     dprintf(("BroadCastMessageA %x %x %x %s", msg, wParam, lParam, (type == BROADCAST_SEND) ? "Send" : "Post"));
02306 
02307     for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
02308         window = GetWindowFromHandle(hwnd++);
02309         if(window) {
02310             if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
02311             {
02312                 if(type == BROADCAST_SEND) {
02313                         ::SendMessageA(window->getWindowHandle(), msg, wParam, lParam);
02314                 }
02315                 else    PostMessageA(window->getWindowHandle(), msg, wParam, lParam);
02316             }
02317             RELEASE_WNDOBJ(window);
02318         }
02319     }
02320     return 0;
02321 }
02322 //******************************************************************************
02323 //TODO: Do this more efficiently
02324 //******************************************************************************
02325 LRESULT Win32BaseWindow::BroadcastMessageW(int type, UINT msg, WPARAM wParam, LPARAM lParam)
02326 {
02327  Win32BaseWindow *window;
02328  HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
02329 
02330     dprintf(("BroadCastMessageW %x %x %x %s", msg, wParam, lParam, (type == BROADCAST_SEND) ? "Send" : "Post"));
02331 
02332     for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
02333         window = GetWindowFromHandle(hwnd++);
02334         if(window) {
02335             if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
02336             {
02337                 if(type == BROADCAST_SEND) {
02338                         ::SendMessageW(window->getWindowHandle(), msg, wParam, lParam);
02339                 }
02340                 else    PostMessageW(window->getWindowHandle(), msg, wParam, lParam);
02341             }
02342             RELEASE_WNDOBJ(window);
02343         }
02344     }
02345     return 0;
02346 }
02347 //******************************************************************************
02348 //******************************************************************************
02349 void Win32BaseWindow::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
02350 {
02351  Win32BaseWindow *window = this;
02352  Win32BaseWindow *parentwindow;
02353 
02354    while(window)
02355    {
02356         if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
02357         {
02358                 /* Notify the parent window only */
02359                 parentwindow = window->getParent();
02360                 if(parentwindow) {
02361                         parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, getWindowId()), lParam );
02362                 }
02363         }
02364         else    break;
02365 
02366         window = parentwindow;
02367    }
02368 }
02369 //******************************************************************************
02370 // Returns the big or small icon for the window, falling back to the
02371 // class as windows does.
02372 //******************************************************************************
02373 HICON Win32BaseWindow::IconForWindow(WPARAM fType)
02374 {
02375   HICON hWndIcon;
02376 
02377   if (fType == ICON_BIG)
02378   {
02379     if (hIcon)
02380         hWndIcon = hIcon;
02381     else
02382     if (windowClass && windowClass->getIcon())
02383         hWndIcon = windowClass->getIcon();
02384     else
02385     if (!(dwStyle & DS_MODALFRAME))
02386          hWndIcon = LoadImageA(0,MAKEINTRESOURCEA(OIC_ODINICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR);
02387     else hWndIcon = 0;
02388   }
02389   else
02390   {
02391     if (hIconSm)
02392         hWndIcon = hIconSm;
02393     else
02394     if (hIcon)
02395         hWndIcon = hIcon;
02396     else
02397     if (windowClass && windowClass->getIconSm())
02398         hWndIcon = windowClass->getIconSm();
02399     else
02400     if (windowClass && windowClass->getIcon())
02401         hWndIcon = windowClass->getIcon();
02402     else
02403     if (!(dwStyle & DS_MODALFRAME))
02404          hWndIcon = LoadImageA(0,MAKEINTRESOURCEA(OIC_ODINICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR);
02405     else hWndIcon = 0;
02406   }
02407 
02408   return hWndIcon;
02409 }
02410 //******************************************************************************
02411 //******************************************************************************
02412 BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
02413 {
02414  ULONG swp = 0;
02415  HWND  hWinAfter;
02416  BOOL  rc,wasVisible,showFlag;
02417  RECT  newPos = {0, 0, 0, 0};
02418 
02419     dprintf(("ShowWindow %x %x", getWindowHandle(), nCmdShow));
02420     wasVisible = (getStyle() & WS_VISIBLE) != 0;
02421 
02422     dwOldStyle = getStyle();
02423 
02424     switch(nCmdShow)
02425     {
02426     case SW_HIDE:
02427         if (!wasVisible) goto END;
02428 
02429         swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER;
02430         break;
02431 
02432     case SW_SHOWMINNOACTIVE:
02433         swp |= SWP_NOACTIVATE | SWP_NOZORDER;
02434         /* fall through */
02435     case SW_SHOWMINIMIZED:
02436         swp |= SWP_SHOWWINDOW;
02437         /* fall through */
02438     case SW_MINIMIZE:
02439         swp |= SWP_FRAMECHANGED;
02440         if( !(getStyle() & WS_MINIMIZE) ) {
02441              swp |= MinMaximize(SW_MINIMIZE, &newPos );
02442              fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
02443         }
02444         else swp |= SWP_NOSIZE | SWP_NOMOVE;
02445         break;
02446 
02447     case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
02448         swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
02449         if( !(getStyle() & WS_MAXIMIZE) ) {
02450              swp |= MinMaximize(SW_MAXIMIZE, &newPos );
02451              fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
02452         }
02453         else swp |= SWP_NOSIZE | SWP_NOMOVE;
02454         break;
02455 
02456     case SW_SHOWNA:
02457         swp |= SWP_NOACTIVATE | SWP_NOZORDER;
02458         /* fall through */
02459     case SW_SHOW:
02460         swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
02461 
02462         /*
02463          * ShowWindow has a little peculiar behavior that if the
02464          * window is already the topmost window, it will not
02465          * activate it.
02466          */
02467         if (::GetTopWindow((HWND)0)==getWindowHandle() && (wasVisible || GetActiveWindow() == getWindowHandle()))
02468             swp |= SWP_NOACTIVATE;
02469 
02470         break;
02471 
02472     case SW_SHOWNOACTIVATE:
02473         swp |= SWP_NOZORDER;
02474         if (GetActiveWindow())
02475             swp |= SWP_NOACTIVATE;
02476         /* fall through */
02477     case SW_SHOWNORMAL:  /* same as SW_NORMAL: */
02478     case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
02479     case SW_RESTORE:
02480          swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
02481 
02482          if( getStyle() & (WS_MINIMIZE | WS_MAXIMIZE) ) {
02483               swp |= MinMaximize(SW_RESTORE, &newPos );
02484               fMinMaxChange = TRUE; //-> invalidate entire window in WM_CALCINVALIDRECT
02485          }
02486          else swp |= SWP_NOSIZE | SWP_NOMOVE;
02487          break;
02488     }
02489 
02490     showFlag = (nCmdShow != SW_HIDE);
02491     if (showFlag != wasVisible)
02492     {
02493         SendInternalMessageA(WM_SHOWWINDOW, showFlag, 0 );
02494         if (!::IsWindow( getWindowHandle() )) goto END;
02495     }
02496 
02497     /* We can't activate a child window */
02498     if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_MDICHILD))
02499         swp |= SWP_NOACTIVATE | SWP_NOZORDER;
02500 
02501     SetWindowPos(HWND_TOP, newPos.left, newPos.top, newPos.right, newPos.bottom, LOWORD(swp));
02502 
02503     if(!(swp & SWP_NOACTIVATE)) {
02504         OSLibWinSetActiveWindow(OS2HwndFrame);
02505     }
02506 
02507     if (flags & WIN_NEED_SIZE)
02508     {
02509         /* should happen only in CreateWindowEx() */
02510         int wParam = SIZE_RESTORED;
02511 
02512         flags &= ~WIN_NEED_SIZE;
02513         if (dwStyle & WS_MAXIMIZE)
02514             wParam = SIZE_MAXIMIZED;
02515         else
02516         if (dwStyle & WS_MINIMIZE)
02517             wParam = SIZE_MINIMIZED;
02518 
02519         SendInternalMessageA(WM_SIZE, wParam,
02520                      MAKELONG(rectClient.right-rectClient.left,
02521                               rectClient.bottom-rectClient.top));
02522         SendInternalMessageA(WM_MOVE,0,MAKELONG(rectClient.left,rectClient.top));
02523     }
02524 //testestest
02525     //temporary workaround for file dialogs with template dialog child
02526     //they don't redraw when switching directories
02527     //For some reason the new child's (syslistview32) update rectangle stays
02528     //empty after its parent is made visible with ShowWindow
02529     //TODO: find real cause
02530     if(!wasVisible) {
02531         InvalidateRect(getWindowHandle(), NULL, TRUE);
02532     }
02533 //testestest
02534 END:
02535     fMinMaxChange = FALSE;
02536     return wasVisible;
02537 }
02538 //******************************************************************************
02539 //******************************************************************************
02540 BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
02541 {
02542    BOOL rc = FALSE;
02543    Win32BaseWindow *window;
02544    HWND hParent = 0;
02545    RECT oldClientRect = rectClient;
02546 
02547     if (fuFlags &
02548        ~(SWP_NOSIZE     | SWP_NOMOVE     | SWP_NOZORDER     |
02549          SWP_NOREDRAW   | SWP_NOACTIVATE | SWP_FRAMECHANGED |
02550          SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS   |
02551          SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_DEFERERASE |
02552          SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE))
02553     {
02554         dprintf(("ERROR: SetWindowPos; UNKNOWN flag"));
02555         return FALSE;
02556     }
02557 
02558     if( fuFlags & (SWP_DEFERERASE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)) {
02559         dprintf(("WARNING: SetWindowPos; unsupported flag"));
02560     }
02561 
02562     if(IsWindowDestroyed()) {
02563         //changing the position of a window that's being destroyed can cause crashes in PMMERGE
02564         dprintf(("SetWindowPos; window already destroyed"));
02565         return TRUE;
02566     }
02567 
02568 #if 0
02569     /* Fix redundant flags */
02570     if(getStyle() & WS_VISIBLE) {
02571         fuFlags &= ~SWP_SHOWWINDOW;
02572     }
02573     else
02574     {
02575         if (!(fuFlags & SWP_SHOWWINDOW))
02576               fuFlags |= SWP_NOREDRAW;
02577         fuFlags &= ~SWP_HIDEWINDOW;
02578     }
02579 
02580 ////    if(cx < 0) cx = 0;
02581 ////    if(cy < 0) cy = 0;
02582 
02583     if((rectWindow.right - rectWindow.left == cx) && (rectWindow.bottom - rectWindow.top == cy)) {
02584         fuFlags |= SWP_NOSIZE;    /* Already the right size */
02585     }
02586 
02587     if((rectWindow.left == x) && (rectWindow.top == y)) {
02588         fuFlags |= SWP_NOMOVE;    /* Already the right position */
02589     }
02590 
02591     if(getWindowHandle() == GetActiveWindow()) {
02592         fuFlags |= SWP_NOACTIVATE;   /* Already active */
02593     }
02594     else
02595     if((getStyle() & (WS_POPUP | WS_CHILD)) != WS_CHILD )
02596     {
02597         if(!(fuFlags & SWP_NOACTIVATE)) /* Bring to the top when activating */
02598         {
02599             fuFlags &= ~SWP_NOZORDER;
02600             hwndInsertAfter = HWND_TOP;
02601         }
02602     }
02603     /* TODO: Check hwndInsertAfter */
02604 
02605 #endif
02606 
02607     //Note: Solitaire crashes when receiving WM_SIZE messages before WM_CREATE
02608     if(state < STATE_POST_WMNCCREATE)
02609     {//don't change size; modify internal structures only
02610         //TODO: not 100% correct yet (activate)
02611         dprintf2(("state < STATE_POST_WMNCCREATE"));
02612         if(!(fuFlags & SWP_NOZORDER)) {
02613             hwndLinkAfter = hwndInsertAfter;
02614         }
02615         if(!(fuFlags & SWP_NOMOVE)) {
02616             rectWindow.bottom = (rectWindow.bottom - rectWindow.top) + y;
02617             rectWindow.top    = y;
02618             rectWindow.right  = (rectWindow.right - rectWindow.left) + x;
02619             rectWindow.left   = x;
02620         }
02621         if(!(fuFlags & SWP_NOSIZE)) {
02622             rectWindow.bottom = rectWindow.top + cy;
02623             rectWindow.right  = rectWindow.left + cx;
02624         }
02625         return TRUE;
02626     }
02627 
02628     WINDOWPOS wpos;
02629     SWP swp, swpOld;
02630     wpos.flags            = fuFlags;
02631     wpos.cy               = cy;
02632     wpos.cx               = cx;
02633     wpos.x                = x;
02634     wpos.y                = y;
02635     wpos.hwndInsertAfter  = hwndInsertAfter;
02636     wpos.hwnd             = getWindowHandle();
02637 
02638     if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE))
02639     {
02640         if (isChild())
02641         {
02642             if(!getParent()) {
02643                 dprintf(("WARNING: Win32BaseWindow::SetWindowPos window %x is child but has no parent!!", getWindowHandle()));
02644             }
02645         }
02646         OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
02647     }
02648 
02649     if(getParent()) {
02650           OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, getParent()->getClientHeight(),
02651                                  OS2HwndFrame);
02652     }
02653     else  OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, OSLibQueryScreenHeight(), OS2HwndFrame);
02654 
02655     if (swp.fl == 0) {
02656         dprintf2(("swp.fl == 0"));
02657         if(fuFlags & SWP_FRAMECHANGED)
02658         {
02659             NotifyFrameChanged(&wpos, &oldClientRect);
02660         }
02661         return TRUE;
02662     }
02663 
02664 //   if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
02665     if ((swp.hwndInsertBehind > HWNDOS_BOTTOM))
02666     {
02667         Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
02668         if(wndBehind) {
02669             swp.hwndInsertBehind   = wndBehind->getOS2FrameWindowHandle();
02670             RELEASE_WNDOBJ(wndBehind);
02671         }
02672         else {
02673             dprintf(("ERROR: SetWindowPos: hwndInsertBehind %x invalid!",swp.hwndInsertBehind));
02674             swp.hwndInsertBehind = 0;
02675         }
02676     }
02677     swp.hwnd = OS2HwndFrame;
02678 
02679     if(fuFlags & SWP_SHOWWINDOW && !IsWindowVisible(getWindowHandle())) {
02680         setStyle(getStyle() | WS_VISIBLE);
02681         if(hTaskList) {
02682             dprintf(("Adding window %x to tasklist", getWindowHandle()));
02683             OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), 1);
02684         }
02685     }
02686     else
02687     if((fuFlags & SWP_HIDEWINDOW) && IsWindowVisible(getWindowHandle())) {
02688         setStyle(getStyle() & ~WS_VISIBLE);
02689         if(hTaskList && !(getStyle() & WS_MINIMIZE)) {
02690             dprintf(("Removing window %x from tasklist", getWindowHandle()));
02691             OSLibWinChangeTaskList(hTaskList, OS2HwndFrame, getWindowNameA(), 0);
02692         }
02693     }
02694     dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
02695     rc = OSLibWinSetMultWindowPos(&swp, 1);
02696 
02697     if(rc == FALSE)
02698     {
02699         dprintf(("OSLibWinSetMultWindowPos failed! Error %x",OSLibWinGetLastError()));
02700         return 0;
02701     }
02702 
02703     if((fuFlags & SWP_FRAMECHANGED) && (fuFlags & (SWP_NOMOVE | SWP_NOSIZE) == (SWP_NOMOVE | SWP_NOSIZE)))
02704     {
02705         NotifyFrameChanged(&wpos, &oldClientRect);
02706     }
02707     if(!(getStyle() & (WS_MAXIMIZE|WS_MINIMIZE))) {
02708         //Restore position always changes when the window position is changed
02709         dprintf(("Save new restore position (%d,%d)(%d,%d)", rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom));
02710         windowpos.rcNormalPosition = rectWindow;
02711     }
02712     return (rc);
02713 }
02714 //******************************************************************************
02715 //Called by ScrollWindowEx (dc.cpp) to notify child window that it has moved
02716 //******************************************************************************
02717 BOOL Win32BaseWindow::ScrollWindow(int dx, int dy)
02718 {
02719     rectWindow.left   += dx;
02720     rectWindow.right  += dx;
02721     rectWindow.top    += dy;
02722     rectWindow.bottom += dy;
02723     SendInternalMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
02724     return TRUE;
02725 }
02726 //******************************************************************************
02727 //******************************************************************************
02728 void Win32BaseWindow::NotifyFrameChanged(WINDOWPOS *wpos, RECT *oldClientRect)
02729 {
02730  HRGN hrgn, hrgnClient;
02731  RECT rect;
02732 
02733     MsgFormatFrame(NULL);
02734 
02735     if(RECT_WIDTH(rectClient) != RECT_WIDTH(*oldClientRect) ||
02736        RECT_HEIGHT(rectClient) != RECT_HEIGHT(*oldClientRect))
02737     {
02738          wpos->flags &= ~(SWP_NOSIZE|SWP_NOCLIENTSIZE);
02739          wpos->cx     = RECT_WIDTH(rectWindow);
02740          wpos->cy     = RECT_HEIGHT(rectWindow);
02741     }
02742 
02743     if(rectClient.left != oldClientRect->left ||
02744        rectClient.top != oldClientRect->top)
02745     {
02746          wpos->flags &= ~(SWP_NOMOVE|SWP_NOCLIENTMOVE);
02747          wpos->x      = rectWindow.left;
02748          wpos->y      = rectWindow.top;
02749     }
02750    
02751     WINDOWPOS wpOld = *wpos;
02752     if(!(wpos->flags & SWP_NOSENDCHANGING))
02753         SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, (LPARAM)wpos);
02754 
02755     if ((wpos->hwndInsertAfter != wpOld.hwndInsertAfter) ||
02756         (wpos->x != wpOld.x) || (wpos->y != wpOld.y) || (wpos->cx != wpOld.cx) || (wpos->cy != wpOld.cy) || (wpos->flags != wpOld.flags))
02757     {
02758          dprintf(("WARNING, NotifyFrameChanged: TODO -> adjust flags!!!!"));
02759          SetWindowPos(wpos->hwndInsertAfter, wpos->x, wpos->y, wpos->cx, wpos->cy, wpos->flags | SWP_NOSENDCHANGING);
02760     }
02761     else SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, (LPARAM)wpos);
02762 
02763     //Calculate invalid areas
02764     rect = rectWindow;
02765     OffsetRect(&rect, -rectWindow.left, -rectWindow.top);
02766     hrgn = CreateRectRgnIndirect(&rect);
02767     if (!hrgn) {
02768          dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
02769          return;
02770     }
02771     rect = rectClient;
02772     hrgnClient = CreateRectRgnIndirect(&rect);
02773     if (!hrgn) {
02774          dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
02775          return;
02776     }
02777     CombineRgn(hrgn, hrgn, hrgnClient, RGN_DIFF);
02778     DeleteObject(hrgnClient);
02779 
02780     if(!EqualRect(oldClientRect, &rectClient)) {
02781          UnionRect(oldClientRect, oldClientRect, &rectClient);
02782          hrgnClient = CreateRectRgnIndirect(oldClientRect);
02783          if (!hrgn) {
02784               dprintf(("ERROR: NotifyFrameChanged, CreateRectRgnIndirect failed!!"));
02785               return;
02786          }
02787          CombineRgn(hrgn, hrgn, hrgnClient, RGN_OR);
02788          DeleteObject(hrgnClient);
02789     }
02790     RedrawWindow(getWindowHandle(), NULL, hrgn, RDW_ALLCHILDREN |
02791                  RDW_INVALIDATE | RDW_ERASE | RDW_FRAME);
02792     DeleteObject(hrgn);
02793 }
02794 //******************************************************************************
02795 //TODO: Check how this api really works in NT
02796 //******************************************************************************
02797 BOOL Win32BaseWindow::SetWindowPlacement(WINDOWPLACEMENT *wndpl)
02798 {
02799    dprintf(("SetWindowPlacement %x min  (%d,%d)", getWindowHandle(), wndpl->ptMinPosition.x, wndpl->ptMinPosition.y));
02800    dprintf(("SetWindowPlacement %x max  (%d,%d)", getWindowHandle(), wndpl->ptMaxPosition.x, wndpl->ptMaxPosition.y));
02801    dprintf(("SetWindowPlacement %x norm (%d,%d)(%d,%d)", getWindowHandle(), wndpl->rcNormalPosition.left, wndpl->rcNormalPosition.top, wndpl->rcNormalPosition.right, wndpl->rcNormalPosition.bottom));
02802    windowpos.ptMinPosition    = wndpl->ptMinPosition;
02803    windowpos.ptMaxPosition    = wndpl->ptMaxPosition;
02804    windowpos.rcNormalPosition = wndpl->rcNormalPosition;
02805 
02806    if(getStyle() & WS_MINIMIZE )
02807    {
02808         //TODO: Why can't this be (0,0)?
02809         if(wndpl->flags & WPF_SETMINPOSITION && !(!windowpos.ptMinPosition.x && !windowpos.ptMinPosition.y)) {
02810             SetWindowPos(0, windowpos.ptMinPosition.x, windowpos.ptMinPosition.y,
02811                          0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
02812         }
02813    }
02814    else
02815    if(getStyle() & WS_MAXIMIZE )
02816    {
02817         //TODO: Why can't this be (0,0)?
02818         if(windowpos.ptMaxPosition.x != 0 || windowpos.ptMaxPosition.y != 0 )
02819             SetWindowPos(0, windowpos.ptMaxPosition.x, windowpos.ptMaxPosition.y,
02820                          0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
02821    }
02822    else {
02823         SetWindowPos(0, windowpos.rcNormalPosition.left, windowpos.rcNormalPosition.top,
02824              windowpos.rcNormalPosition.right - windowpos.rcNormalPosition.left,
02825              windowpos.rcNormalPosition.bottom - windowpos.rcNormalPosition.top,
02826              SWP_NOZORDER | SWP_NOACTIVATE );
02827    }
02828    ShowWindow(wndpl->showCmd);
02829    if( ::IsWindow(getWindowHandle()) && getStyle() & WS_MINIMIZE )
02830    {
02831         /* SDK: ...valid only the next time... */
02832         if(wndpl->flags & WPF_RESTORETOMAXIMIZED)
02833             setFlags(getFlags() | WIN_RESTORE_MAX);
02834    }
02835    return TRUE;
02836 }
02837 //******************************************************************************
02838 //******************************************************************************
02839 BOOL Win32BaseWindow::GetWindowPlacement(LPWINDOWPLACEMENT wndpl)
02840 {
02841    wndpl->length = sizeof(*wndpl);
02842    if(getStyle() & WS_MINIMIZE )
02843         wndpl->showCmd = SW_SHOWMINIMIZED;
02844    else wndpl->showCmd = (getStyle() & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
02845 
02846    //TODO: Verify if this is correct -> SDK docs claim this flag must always be set to 0
02847    if(getFlags() & WIN_RESTORE_MAX )
02848         wndpl->flags = WPF_RESTORETOMAXIMIZED;
02849    else wndpl->flags = 0;
02850 
02851    wndpl->ptMinPosition    = windowpos.ptMinPosition;
02852    wndpl->ptMaxPosition    = windowpos.ptMaxPosition;
02853    //Must be in parent coordinates (or screen if no parent); verified in NT4, SP6
02854    wndpl->rcNormalPosition = rectWindow;
02855 
02856    return TRUE;
02857 }
02858 //******************************************************************************
02859 //Also destroys all the child windows (destroy children first, parent last)
02860 //******************************************************************************
02861 BOOL Win32BaseWindow::DestroyWindow()
02862 {
02863   HWND hwnd = getWindowHandle();
02864 
02865     dprintf(("DestroyWindow %x", hwnd));
02866 
02867     /* Call hooks */
02868     if(HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, getWindowHandle(), 0L))
02869     {
02870         return FALSE;
02871     }
02872   
02873     if(!(getStyle() & WS_CHILD) && getOwner() == NULL)
02874     {
02875         HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWDESTROYED, getWindowHandle(), 0L);
02876         /* FIXME: clean up palette - see "Internals" p.352 */
02877     }
02878 
02879     if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
02880     {
02881         if(getParent() && getParent()->IsWindowDestroyed() == FALSE)
02882         {
02883              /* Notify the parent window only */
02884              getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
02885              if(!::IsWindow(hwnd) )
02886              {
02887                 return TRUE;
02888              }
02889         }
02890 ////        else DebugInt3();
02891     }
02892     /* Hide the window */
02893     if(IsWindowVisible(getWindowHandle()))
02894     {
02895         SetWindowPos(0, 0, 0, 0, 0, SWP_HIDEWINDOW |
02896                      SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
02897         if(!::IsWindow(hwnd))
02898         {
02899                 return TRUE;
02900         }
02901     }
02902     dprintf(("DestroyWindow %x -> HIDDEN", hwnd));
02903   
02904     // check the handle for the last active popup window
02905     Win32BaseWindow* owner = getOwner();
02906     if (NULL != owner)
02907     {
02908       if (owner->getLastActive() == hwnd)
02909         owner->setLastActive( owner->getWindowHandle() );
02910     }
02911   
02912     fDestroyWindowCalled = TRUE;
02913     return OSLibWinDestroyWindow(OS2HwndFrame);
02914 }
02915 //******************************************************************************
02916 //******************************************************************************
02917 Win32BaseWindow *Win32BaseWindow::getParent()
02918 {
02919   Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
02920   return ((ULONG)wndparent == (ULONG)windowDesktop) ? NULL : wndparent;
02921 }
02922 //******************************************************************************
02923 //Note: does not set last error if no parent (verified in NT4, SP6)
02924 //******************************************************************************
02925 HWND Win32BaseWindow::GetParent()
02926 {
02927   Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
02928 
02929   if(getStyle() & WS_CHILD) {
02930       if(wndparent) {
02931           return wndparent->getWindowHandle();
02932       }
02933       dprintf(("WARNING: GetParent: WS_CHILD but no parent!!"));
02934       DebugInt3();
02935       return 0;
02936   }
02937   else 
02938   if(getStyle() & WS_POPUP)
02939        return (getOwner()) ? getOwner()->getWindowHandle() : 0;
02940   else return 0;
02941 }
02942 //******************************************************************************
02943 //******************************************************************************
02944 HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
02945 {
02946  HWND oldhwnd;
02947  Win32BaseWindow *newparent;
02948  Win32BaseWindow *oldparent = (Win32BaseWindow *)ChildWindow::getParentOfChild();
02949  BOOL fShow = FALSE;
02950 
02951    if(oldparent) {
02952         oldhwnd = oldparent->getWindowHandle();
02953         oldparent->removeChild(this);
02954    }
02955    else oldhwnd = 0;
02956 
02957    /* Windows hides the window first, then shows it again
02958     * including the WM_SHOWWINDOW messages and all */
02959    if(IsWindowCreated() && (getStyle() & WS_VISIBLE)) {
02960         ShowWindow(SW_HIDE);
02961         fShow = TRUE;
02962    }
02963    if(oldparent) {
02964         //release parent here (increased refcount during creation)
02965         RELEASE_WNDOBJ(oldparent);
02966    }
02967    newparent = GetWindowFromHandle(hwndNewParent);
02968    if(newparent && !newparent->isDesktopWindow())
02969    {
02970         setParent(newparent);
02971         getParent()->addChild(this);
02972         fParentChange = TRUE;
02973 
02974         OSLibWinSetParent(getOS2FrameWindowHandle(), getParent()->getOS2WindowHandle());
02975         if(!(getStyle() & WS_CHILD))
02976         {
02977             //TODO: Send WM_STYLECHANGED msg?
02978             setStyle(getStyle() | WS_CHILD);
02979             if(getWindowId())
02980             {
02981                 DestroyMenu( (HMENU) getWindowId() );
02982                 setWindowId(0);
02983             }
02984         }
02985         //SvL: Even though the win32 coordinates might not change, the PM
02986         //     coordinates can. We must make sure the control stays at the
02987         //     same position (y) relative to the (new) parent.
02988         SetWindowPos(HWND_TOPMOST, rectWindow.left, rectWindow.top, 0, 0,
02989                      SWP_NOACTIVATE|SWP_NOSIZE);
02990         fParentChange = FALSE;
02991    }
02992    else {
02993         if(newparent) RELEASE_WNDOBJ(newparent);
02994 
02995         setParent(windowDesktop);
02996         windowDesktop->addRef();
02997         windowDesktop->addChild(this);
02998         OSLibWinSetParent(getOS2FrameWindowHandle(), OSLIB_HWND_DESKTOP);
02999 
03000         //TODO: Send WM_STYLECHANGED msg?
03001         setStyle(getStyle() & ~WS_CHILD);
03002         setWindowId(0);
03003    }
03004    /* SetParent additionally needs to make hwndChild the topmost window
03005       in the x-order and send the expected WM_WINDOWPOSCHANGING and
03006       WM_WINDOWPOSCHANGED notification messages.
03007    */
03008    if(state >= STATE_PRE_WMNCCREATE) {
03009         SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0,
03010                      SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|(fShow? SWP_SHOWWINDOW : 0));
03011 
03012    /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
03013     * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
03014    }
03015    return oldhwnd;
03016 }
03017 //******************************************************************************
03018 //******************************************************************************
03019 BOOL Win32BaseWindow::IsChild(HWND hwndParent)
03020 {
03021   // PH: Optimizer won't unroll calls to getParent() even
03022   // in release build.
03023   Win32BaseWindow *_parent = getParent();
03024     
03025   if(_parent) 
03026   {
03027     if(_parent->getWindowHandle() == hwndParent)
03028       return TRUE;
03029 
03030     return _parent->IsChild(hwndParent);
03031   }
03032   else 
03033     return 0;
03034 }
03035 //******************************************************************************
03036 //******************************************************************************
03037 HWND Win32BaseWindow::GetTopWindow()
03038 {
03039  HWND             hwndTop;
03040  Win32BaseWindow *topwindow;
03041 
03042     hwndTop = OSLibWinQueryWindow(getOS2WindowHandle(), QWOS_TOP);
03043     if(!isDesktopWindow())
03044     {
03045         topwindow = GetWindowFromOS2FrameHandle(hwndTop);
03046         //Note: GetTopWindow can't return a window that hasn't processed
03047         //      WM_NCCREATE yet (verified in NT4, SP6)
03048         if(topwindow) {
03049             if(topwindow->state >= STATE_POST_WMNCCREATE) {
03050                  hwndTop = topwindow->getWindowHandle();
03051             }
03052             else hwndTop = topwindow->GetWindow(GW_HWNDNEXT);
03053             RELEASE_WNDOBJ(topwindow);
03054             return hwndTop;
03055         }
03056         if(topwindow) RELEASE_WNDOBJ(topwindow);
03057         return 0;
03058     }
03059     while(hwndTop) {
03060         topwindow = GetWindowFromOS2FrameHandle(hwndTop);
03061         //Note: GetTopWindow can't return a window that hasn't processed
03062         //      WM_NCCREATE yet (verified in NT4, SP6)
03063         if(topwindow) {
03064             if(topwindow->state >= STATE_POST_WMNCCREATE) {
03065                  hwndTop = topwindow->getWindowHandle();
03066             }
03067             else hwndTop = topwindow->GetWindow(GW_HWNDNEXT);
03068             RELEASE_WNDOBJ(topwindow);
03069             return hwndTop;
03070         }
03071         if(topwindow) RELEASE_WNDOBJ(topwindow);
03072         hwndTop = OSLibWinQueryWindow(hwndTop, QWOS_NEXT);
03073     }
03074 
03075     return 0;
03076 }
03077 //******************************************************************************
03078 // Get the top-level parent for a child window.
03079 //******************************************************************************
03080 HWND Win32BaseWindow::GetTopParent()
03081 {
03082  Win32BaseWindow *window = this;
03083  HWND             hwndTopParent = 0;
03084 
03085     lock();
03086     while(window && (window->getStyle() & WS_CHILD))
03087     {
03088         window = window->getParent();
03089     }
03090     if(window) {
03091         hwndTopParent = window->getWindowHandle();
03092     }
03093     unlock();
03094     return hwndTopParent;
03095 }
03096 //******************************************************************************
03097 //TODO: Should not enumerate children that are created during the enumeration!
03098 //******************************************************************************
03099 BOOL Win32BaseWindow::EnumChildWindows(WNDENUMPROC lpfn, LPARAM lParam)
03100 {
03101  BOOL rc = TRUE;
03102  HWND hwnd;
03103  Win32BaseWindow *prevchild = 0, *child = 0;
03104 
03105     dprintf(("EnumChildWindows of %x parameter %x %x (%x)", getWindowHandle(), lpfn, lParam, getFirstChild()));
03106     lock();
03107     for (child = (Win32BaseWindow *)getFirstChild(); child != NULL; child = (Win32BaseWindow *)child->getNextChild())
03108     {
03109         dprintf(("EnumChildWindows: enumerating child %x (owner %x; parent %x)", child->getWindowHandle(), (child->getOwner()) ? child->getOwner()->getWindowHandle() : 0, getWindowHandle()));
03110         hwnd = child->getWindowHandle();
03111         if(child->IsWindowDestroyed() || child->getOwner()) {
03112                 continue; //shouldn't have an owner (Wine)
03113         }
03114         child->addRef();
03115         unlock();
03116         if(lpfn(hwnd, lParam) == FALSE)
03117         {
03118                 child->release();
03119                 return FALSE;
03120         }
03121         child->release();
03122         lock();
03123         //check if the window still exists
03124         if(!::IsWindow(hwnd))
03125         {
03126             child = prevchild;
03127             if(child == NULL) break;
03128             continue;
03129         }
03130         if(child->getFirstChild() != NULL)
03131         {
03132             dprintf(("EnumChildWindows: Enumerate children of %x", child->getWindowHandle()));
03133             child->addRef();
03134             unlock();
03135             if(child->EnumChildWindows(lpfn, lParam) == FALSE)
03136             {
03137                 child->release();
03138                 return FALSE;
03139             }
03140             child->release();
03141             lock();
03142         }
03143         prevchild = child;
03144     }
03145     unlock();
03146     return rc;
03147 }
03148 //******************************************************************************
03149 //Enumerate first-level children only and check thread id
03150 //******************************************************************************
03151 BOOL Win32BaseWindow::EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
03152 {
03153  Win32BaseWindow *child = 0;
03154  ULONG  tid, pid;
03155  BOOL   rc;
03156  HWND   hwnd;
03157 
03158     dprintf(("EnumThreadWindows %x %x %x", dwThreadId, lpfn, lParam));
03159 
03160     for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
03161     {
03162         OSLibWinQueryWindowProcess(child->getOS2WindowHandle(), &pid, &tid);
03163 
03164         if(dwThreadId == tid) {
03165             dprintf2(("EnumThreadWindows: Found Window %x", child->getWindowHandle()));
03166             if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
03167                 break;
03168             }
03169         }
03170     }
03171     return TRUE;
03172 }
03173 //******************************************************************************
03174 //Enumerate first-level children only
03175 //******************************************************************************
03176 BOOL Win32BaseWindow::EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
03177 {
03178  Win32BaseWindow *child = 0;
03179  BOOL   rc;
03180  HWND   hwnd;
03181 
03182     dprintf(("EnumWindows %x %x", lpfn, lParam));
03183 
03184     for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
03185     {
03186         hwnd = child->getWindowHandle();
03187 
03188         dprintf2(("EnumWindows: Found Window %x", child->getWindowHandle()));
03189         if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
03190             break;
03191         }
03192     }
03193     return TRUE;
03194 }
03195 //******************************************************************************
03196 //******************************************************************************
03197 HWND Win32BaseWindow::FindWindowById(int id)
03198 {
03199     HWND hwnd;
03200 
03201     lock();
03202     for (Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
03203     {
03204         if (child->getWindowId() == id)
03205         {
03206             hwnd = child->getWindowHandle();
03207             unlock();
03208             return hwnd;
03209         }
03210     }
03211     unlock();
03212     return 0;
03213 }
03214 //******************************************************************************
03215 //TODO:
03216 //We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
03217 //the current process owns them.
03218 //******************************************************************************
03219 HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, ATOM atom, LPSTR lpszWindow)
03220 {
03221  Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
03222  Win32BaseWindow *child  = GetWindowFromHandle(hwndChildAfter);
03223  Win32BaseWindow *firstchild = child;
03224 
03225     dprintf(("FindWindowEx %x %x %x %s", hwndParent, hwndChildAfter, atom, lpszWindow));
03226     if((hwndParent != 0 && !parent) ||
03227        (hwndChildAfter != 0 && !child) ||
03228        (hwndParent == 0 && hwndChildAfter != 0))
03229     {
03230         if(parent)      RELEASE_WNDOBJ(parent);
03231         if(firstchild)  RELEASE_WNDOBJ(firstchild);
03232         dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
03233         SetLastError(ERROR_INVALID_WINDOW_HANDLE);
03234         return 0;
03235     }
03236     SetLastError(0);
03237     if(hwndParent != 0)
03238     {//if the current process owns the window, just do a quick search
03239         lock(&critsect);
03240         child = (Win32BaseWindow *)parent->getFirstChild();
03241         if(hwndChildAfter != 0)
03242         {
03243             while(child)
03244             {
03245                 if(child->getWindowHandle() == hwndChildAfter)
03246                 {
03247                     child = (Win32BaseWindow *)child->getNextChild();
03248                     break;
03249                 }
03250                 child = (Win32BaseWindow *)child->getNextChild();
03251             }
03252         }
03253         while(child)
03254         {
03255             //According to Wine, the class doesn't need to be specified
03256             if((!atom || child->getWindowClass()->getAtom() == atom) &&
03257                (!lpszWindow || child->hasWindowName(lpszWindow)))
03258             {
03259                 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
03260                 HWND hwndChild = child->getWindowHandle();
03261                 unlock(&critsect);
03262                 if(parent)      RELEASE_WNDOBJ(parent);
03263                 if(firstchild)  RELEASE_WNDOBJ(firstchild);
03264                 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
03265                 return hwndChild;
03266             }
03267             child = (Win32BaseWindow *)child->getNextChild();
03268         }
03269         unlock(&critsect);
03270         if(parent)      RELEASE_WNDOBJ(parent);
03271         if(firstchild)  RELEASE_WNDOBJ(firstchild);
03272     }
03273     else {
03274         Win32BaseWindow *wnd;
03275         HWND henum, hwnd;
03276 
03277         henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
03278         hwnd = OSLibWinGetNextWindow(henum);
03279 
03280         while(hwnd)
03281         {
03282             wnd = GetWindowFromOS2FrameHandle(hwnd);
03283             if(wnd == NULL) {
03284                 hwnd = OSLibWinQueryClientWindow(hwnd);
03285                 if(hwnd)  wnd = GetWindowFromOS2Handle(hwnd);
03286             }
03287 
03288             if(wnd) {
03289                 //According to Wine, the class doesn't need to be specified
03290                 if((!atom || wnd->getWindowClass()->getAtom() == atom) &&
03291                    (!lpszWindow || wnd->hasWindowName(lpszWindow)))
03292                 {
03293                     OSLibWinEndEnumWindows(henum);
03294                     dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
03295                     HWND hwndret = wnd->getWindowHandle();
03296                     RELEASE_WNDOBJ(wnd);
03297                     return hwndret;
03298                 }
03299                 RELEASE_WNDOBJ(wnd);
03300             }
03301             hwnd = OSLibWinGetNextWindow(henum);
03302         }
03303         OSLibWinEndEnumWindows(henum);
03304         if(parent)      RELEASE_WNDOBJ(parent);
03305         if(firstchild)  RELEASE_WNDOBJ(firstchild);
03306     }
03307     SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
03308     return 0;
03309 }
03310 //******************************************************************************
03311 //******************************************************************************
03312 HWND Win32BaseWindow::GetWindow(UINT uCmd)
03313 {
03314  HWND hwndRelated = 0;
03315  Win32BaseWindow *window;
03316 
03317     switch(uCmd)
03318     {
03319     case GW_HWNDFIRST:
03320         window = (Win32BaseWindow *)getParent();
03321         if(window)
03322         {
03323             hwndRelated = OSLibWinQueryWindow(window->getOS2WindowHandle(), QWOS_TOP);
03324             window = GetWindowFromOS2FrameHandle(hwndRelated);
03325             if(window) {
03326                  hwndRelated = window->getWindowHandle();
03327                  RELEASE_WNDOBJ(window);
03328             }
03329             else hwndRelated = 0;
03330         }
03331         else {
03332             dprintf(("WARNING: GW_HWNDFIRST not correctly implemented for toplevel/most windows!"));
03333             hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
03334         }
03335         break;
03336 
03337     case GW_HWNDLAST:
03338         window = (Win32BaseWindow *)getParent();
03339         if(window) {
03340             hwndRelated = OSLibWinQueryWindow(window->getOS2WindowHandle(), QWOS_BOTTOM);
03341             dprintf(("os2 handle %x", hwndRelated));
03342             window = GetWindowFromOS2FrameHandle(hwndRelated);
03343             if(window) {
03344                  hwndRelated = window->getWindowHandle();
03345                  RELEASE_WNDOBJ(window);
03346             }
03347             else hwndRelated = 0;
03348         }
03349         else {
03350             dprintf(("WARNING: GW_HWNDLAST not correctly implemented for toplevel/most windows!"));
03351             hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
03352         }
03353         break;
03354 
03355     case GW_HWNDNEXT:
03356         if(getParent()) {
03357             hwndRelated = OSLibWinQueryWindow(getOS2FrameWindowHandle(), QWOS_NEXT);
03358             window = GetWindowFromOS2FrameHandle(hwndRelated);
03359             if(window) {
03360                  hwndRelated = window->getWindowHandle();
03361                  RELEASE_WNDOBJ(window);
03362             }
03363             else hwndRelated = 0;
03364         }
03365         else {
03366             dprintf(("WARNING: GW_HWNDNEXT not correctly implemented for toplevel/most windows!"));
03367             hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
03368         }
03369         break;
03370 
03371     case GW_HWNDPREV:
03372         if(getParent()) {
03373             hwndRelated = OSLibWinQueryWindow(getOS2FrameWindowHandle(), QWOS_PREV);
03374             window = GetWindowFromOS2FrameHandle(hwndRelated);
03375             if(window) {
03376                  hwndRelated = window->getWindowHandle();
03377                  RELEASE_WNDOBJ(window);
03378             }
03379             else hwndRelated = 0;
03380         }
03381         else {
03382             dprintf(("WARNING: GW_HWNDPREV not correctly implemented for toplevel/most windows!"));
03383             hwndRelated = 0; //TODO: not correct; should get first child in z-order of desktop
03384         }
03385         break;
03386 
03387     case GW_OWNER:
03388       {
03389         Win32BaseWindow *owner = getOwner();
03390         if(owner) {
03391             hwndRelated = owner->getWindowHandle();
03392         }
03393         break;
03394       }
03395 
03396     case GW_CHILD:
03397         hwndRelated = OSLibWinQueryWindow(getOS2WindowHandle(), QWOS_TOP);
03398         window = GetWindowFromOS2FrameHandle(hwndRelated);
03399 
03400         //Before a window has processed WM_NCCREATE:
03401         //- GetWindow(parent, GW_CHILD) can't return that window handle
03402         //(verified in NT4, SP6)
03403         if(window) {
03404              if(window->state >= STATE_POST_WMNCCREATE) {
03405                  hwndRelated = window->getWindowHandle();
03406                  RELEASE_WNDOBJ(window); 
03407              }
03408              else {
03409                  hwndRelated = window->GetWindow(GW_HWNDNEXT);
03410                  RELEASE_WNDOBJ(window); 
03411              }
03412         }
03413         else hwndRelated = 0;
03414 
03415         break;
03416 
03417     //for internal use only
03418     case GW_HWNDNEXTCHILD:
03419         lock();
03420         window = (Win32BaseWindow *)getNextChild();
03421         if(window) {
03422              hwndRelated = window->getWindowHandle();
03423         }
03424         else hwndRelated = 0;
03425         unlock();
03426         break;
03427 
03428     case GW_HWNDPREVCHILD:
03429         DebugInt3();
03430         break;
03431 
03432     case GW_HWNDFIRSTCHILD:
03433         lock();
03434         window = (Win32BaseWindow *)getFirstChild();
03435         if(window) {
03436              hwndRelated = window->getWindowHandle();
03437         }
03438         else hwndRelated = 0;
03439         unlock();
03440         break;
03441 
03442     case GW_HWNDLASTCHILD:
03443         lock();
03444         window = (Win32BaseWindow *)getFirstChild();
03445         if(window) {
03446              while (window->getNextChild())
03447              {
03448                 window = (Win32BaseWindow *)window->getNextChild();
03449              }
03450              hwndRelated = window->getWindowHandle();
03451         }
03452         else hwndRelated = 0;
03453         unlock();
03454         break;
03455     }
03456 end:
03457     dprintf(("GetWindow %x %d returned %x", getWindowHandle(), uCmd, hwndRelated));
03458     return hwndRelated;
03459 }
03460 //******************************************************************************
03461 //******************************************************************************
03462 HWND Win32BaseWindow::SetActiveWindow()
03463 {
03464  HWND hwndActive;
03465 
03466     dprintf(("SetActiveWindow %x", getWindowHandle()));
03467     if(getStyle() & WS_CHILD) {
03468 //    if(getStyle() & (WS_DISABLED | WS_CHILD)) {
03469         dprintf(("WARNING: Window is a child or disabled"));
03470         return 0;
03471     }
03472 
03473     if(GetActiveWindow() == getWindowHandle()) {
03474         dprintf(("Window already active"));
03475         return getWindowHandle();
03476     }
03477     if (HOOK_IsHooked( WH_CBT ))
03478     {
03479         CBTACTIVATESTRUCT cbta;
03480         LRESULT ret;
03481 
03482         cbta.fMouse = FALSE;
03483         cbta.hWndActive = GetActiveWindow();
03484         ret = HOOK_CallHooksA(WH_CBT, HCBT_ACTIVATE, getWindowHandle(), (LPARAM)&cbta);
03485         if(ret)
03486         {
03487             dprintf(("SetActiveWindow %x, CBT hook cancelled operation", getWindowHandle()));
03488             return cbta.hWndActive;
03489         }
03490     }
03491     SetWindowPos(HWND_TOP, 0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
03492 
03493 //    if(OSLibWinSetActiveWindow(OS2Hwnd) == FALSE) {
03494 //        dprintf(("OSLibWinSetActiveWindow %x returned FALSE!", OS2Hwnd));
03495 //    }
03496     hwndActive = GetActiveWindow();
03497     return (hwndActive) ? hwndActive : windowDesktop->getWindowHandle(); //pretend the desktop was active
03498 }
03499 //******************************************************************************
03500 //Used to change active status of an mdi window
03501 //******************************************************************************
03502 BOOL Win32BaseWindow::DeactivateChildWindow()
03503 {
03504     /* child windows get a WM_CHILDACTIVATE message */
03505     if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
03506     {
03507         ULONG flags = OSLibWinGetWindowULong(getOS2WindowHandle(), OFFSET_WIN32FLAGS);
03508         OSLibWinSetWindowULong(getOS2WindowHandle(), OFFSET_WIN32FLAGS, (flags & ~WINDOWFLAG_ACTIVE));
03509         return TRUE;
03510     }
03511     DebugInt3();    //should not be called for non-child window
03512     return FALSE;
03513 }
03514 //******************************************************************************
03515 //WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
03516 //******************************************************************************
03517 BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
03518 {
03519  BOOL rc;
03520 
03521     dprintf(("Win32BaseWindow::EnableWindow %x %d", getWindowHandle(), fEnable));
03522     //return true if previous state was disabled, else false (sdk docs)
03523     rc = (getStyle() & WS_DISABLED) != 0;
03524     if(rc && !fEnable) {
03525         SendMessageA(WM_CANCELMODE, 0, 0);
03526     }
03527     OSLibWinEnableWindow(OS2HwndFrame, fEnable);
03528     if(fEnable == FALSE) {
03529         //SvL: No need to clear focus as PM already does this
03530         if(getWindowHandle() == GetCapture()) {
03531                 ReleaseCapture();  /* A disabled window can't capture the mouse */
03532                 dprintf(("Released capture for window %x that is being disabled", getWindowHandle()));
03533         }
03534     }
03535     return rc;
03536 }
03537 //******************************************************************************
03538 //******************************************************************************
03539 BOOL Win32BaseWindow::CloseWindow()
03540 {
03541   return OSLibWinMinimizeWindow(OS2Hwnd);
03542 }
03543 //******************************************************************************
03544 //TODO: Not be 100% correct; should return active window of current thread
03545 //      or NULL when there is none -> WinQueryActiveWindow just returns
03546 //      the current active window
03547 //******************************************************************************
03548 HWND Win32BaseWindow::GetActiveWindow()
03549 {
03550  HWND          hwndActive;
03551 
03552   hwndActive = OSLibWinQueryActiveWindow();
03553   return OS2ToWin32Handle(hwndActive);
03554 }
03555 //******************************************************************************
03556 //******************************************************************************
03557 BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
03558 {
03559     INT len = GetWindowTextLength(fUnicode);
03560     BOOL res;
03561 
03562     if (wndname == NULL)
03563         return (len == 0);
03564 
03565     len++;
03566     if (fUnicode)
03567     {
03568         WCHAR *text = (WCHAR*)malloc(len*sizeof(WCHAR));
03569 
03570         GetWindowTextW(text,len);
03571         res = (lstrcmpW(text,(LPWSTR)wndname) == 0);
03572         free(text);
03573     }
03574     else
03575     {
03576         CHAR *text = (CHAR*)malloc(len*sizeof(CHAR));
03577 
03578         GetWindowTextA(text,len);
03579         res = (strcmp(text,wndname) == 0);
03580         free(text);
03581     }
03582 
03583     return res;
03584 }
03585 //******************************************************************************
03586 //******************************************************************************
03587 CHAR *Win32BaseWindow::getWindowNamePtrA()
03588 {
03589     INT len = GetWindowTextLength(FALSE);
03590     CHAR *text;
03591 
03592     if (len == 0) return NULL;
03593     len++;
03594     text = (CHAR*)malloc(len*sizeof(CHAR));
03595     GetWindowTextA(text,len);
03596 
03597     return text;
03598 }
03599 //******************************************************************************
03600 //******************************************************************************
03601 WCHAR *Win32BaseWindow::getWindowNamePtrW()
03602 {
03603     INT len = GetWindowTextLength(TRUE);
03604     WCHAR *text;
03605 
03606     if (len == 0) return NULL;
03607     len++;
03608     text = (WCHAR*)malloc(len*sizeof(WCHAR));
03609     GetWindowTextW(text,len);
03610 
03611     return text;
03612 }
03613 //******************************************************************************
03614 //******************************************************************************
03615 VOID Win32BaseWindow::freeWindowNamePtr(PVOID namePtr)
03616 {
03617     if (namePtr) free(namePtr);
03618 }
03619 //******************************************************************************
03620 //When using this API for a window that was created by a different process, NT
03621 //does NOT send WM_GETTEXTLENGTH.
03622 //******************************************************************************
03623 int Win32BaseWindow::GetWindowTextLength(BOOL fUnicode)
03624 {
03625     //if the destination window is created by this process, send message
03626     if(dwProcessId == currentProcessId) {
03627         if(fUnicode) {
03628              return SendInternalMessageW(WM_GETTEXTLENGTH,0,0);
03629         }
03630         else return SendInternalMessageA(WM_GETTEXTLENGTH,0,0);
03631     }
03632     //else get data directory from window structure
03633     //TODO: must lock window structure.... (TODO)
03634     return windowNameLength;
03635 }
03636 //******************************************************************************
03637 //When using this API for a window that was created by a different process, NT
03638 //does NOT send WM_GETTEXT.
03639 //******************************************************************************
03640 int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
03641 {
03642     //if the destination window is created by this process, send message
03643     if(dwProcessId == currentProcessId) {
03644         return SendInternalMessageA(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
03645     }
03646   
03647     //else get data directory from window structure
03648     if (!lpsz || !cch) return 0;
03649     if (!windowNameA) lpsz[0] = 0;
03650     else memcpy(lpsz, windowNameA, min(windowNameLength + 1, cch) );
03651     return min(windowNameLength, cch);
03652 }
03653 //******************************************************************************
03654 //When using this API for a window that was created by a different process, NT
03655 //does NOT send WM_GETTEXT.
03656 //******************************************************************************
03657 int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
03658 {
03659     //if the destination window is created by this process, send message
03660     if(dwProcessId == currentProcessId) {
03661         return SendInternalMessageW(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
03662     }
03663     //else get data directory from window structure
03664   if (!lpsz || !cch) 
03665     return 0;
03666   if (!windowNameW) 
03667     lpsz[0] = 0;
03668   else 
03669     memcpy(lpsz, windowNameW, min( sizeof(WCHAR) * (windowNameLength+1), cch));
03670            
03671   return min(windowNameLength, cch);
03672 }
03673 //******************************************************************************
03674 //TODO: How does this work when the target window belongs to a different process???
03675 //******************************************************************************
03676 BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
03677 {
03678     return SendInternalMessageA(WM_SETTEXT,0,(LPARAM)lpsz);
03679 }
03680 //******************************************************************************
03681 //******************************************************************************
03682 BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
03683 {
03684     return SendInternalMessageW(WM_SETTEXT,0,(LPARAM)lpsz);
03685 }
03686 //******************************************************************************
03687 //******************************************************************************
03688 LONG Win32BaseWindow::SetWindowLong(int index, ULONG value, BOOL fUnicode)
03689 {
03690  LONG oldval;
03691 
03692     switch(index) {
03693         case GWL_EXSTYLE:
03694         {
03695            STYLESTRUCT ss;
03696 
03697                 if(dwExStyle == value) {
03698                     oldval = value;
03699                     break;
03700                 }
03701                 ss.styleOld = dwExStyle;
03702                 ss.styleNew = value;
03703                 dprintf(("SetWindowLong GWL_EXSTYLE %x old %x new style %x", getWindowHandle(), dwExStyle, value));
03704                 SendInternalMessageA(WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
03705                 setExStyle(ss.styleNew);
03706                 SendInternalMessageA(WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
03707                 oldval = ss.styleOld;
03708                 break;
03709         }
03710         case GWL_STYLE:
03711         {
03712            STYLESTRUCT ss;
03713 
03714                 //SvL: TODO: Can you change minimize or maximize status here too?
03715 
03716                 if(dwStyle == value) {
03717                     oldval = value;
03718                     break;
03719                 }
03720                 dprintf(("SetWindowLong GWL_STYLE %x old %x new style %x (%x)", getWindowHandle(), dwStyle, value));
03721 #ifdef DEBUG
03722 //                if((value & WS_CHILD) != (dwStyle & WS_CHILD)) {
03723 //                    DebugInt3(); //is this allowed?
03724 //                }
03725 #endif
03726                 value &= ~(WS_CHILD);
03727                 ss.styleOld = getStyle();
03728                 ss.styleNew = value | (ss.styleOld & WS_CHILD);
03729                 SendInternalMessageA(WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
03730                 setStyle(ss.styleNew);
03731                 SendInternalMessageA(WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
03732                 OSLibSetWindowStyle(getOS2FrameWindowHandle(), getOS2WindowHandle(), getStyle(), getExStyle());
03733 
03734                 //TODO: Might not be correct to use ShowWindow here
03735                 if((ss.styleOld & WS_VISIBLE) != (ss.styleNew & WS_VISIBLE)) {
03736                     if(ss.styleNew & WS_VISIBLE)
03737                          ShowWindow(SW_SHOWNOACTIVATE);
03738                     else ShowWindow(SW_HIDE);
03739                 }
03740 #ifdef DEBUG
03741                 PrintWindowStyle(ss.styleNew, 0);
03742 #endif
03743                 oldval = ss.styleOld;
03744                 break;
03745         }
03746         case GWL_WNDPROC:
03747         {
03748                 //Note: Type of SetWindowLong determines new window proc type
03749                 //      UNLESS the new window proc has already been registered
03750                 //      (use the old type in that case)
03751                 //      (VERIFIED in NT 4, SP6)
03752                 WINDOWPROCTYPE type = WINPROC_GetProcType((HWINDOWPROC)value);
03753                 if(type == WIN_PROC_INVALID) {
03754                     type = (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A;
03755                 }
03756                 oldval = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
03757                 dprintf(("SetWindowLong%c GWL_WNDPROC %x old %x new wndproc %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), oldval, value));
03758                 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, type, WIN_PROC_WINDOW);
03759                 break;
03760         }
03761         case GWL_HINSTANCE:
03762                 oldval = hInstance;
03763                 hInstance = value;
03764                 break;
03765 
03766         case GWL_HWNDPARENT:
03767                 oldval = SetParent((HWND)value);
03768                 break;
03769 
03770         case GWL_ID:
03771                 dprintf(("GWL_ID old %x, new %x", getWindowId(), value));
03772                 oldval = getWindowId();
03773                 setWindowId(value);
03774                 break;
03775 
03776         case GWL_USERDATA:
03777                 oldval = userData;
03778                 userData = value;
03779                 break;
03780 
03781         default:
03782                 if(index >= 0 && index + sizeof(ULONG) <= nrUserWindowBytes)
03783                 {
03784                     oldval = *(ULONG *)(userWindowBytes + index);
03785                     *(ULONG *)(userWindowBytes + index) = value;
03786                     break;
03787                 }
03788                 dprintf(("WARNING: SetWindowLong%c %x %d %x returned %x INVALID index!", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
03789                 SetLastError(ERROR_INVALID_INDEX);  //verified in NT4, SP6
03790                 return 0;
03791     }
03792     //Note: NT4, SP6 does not set the last error to 0
03793     SetLastError(ERROR_SUCCESS);
03794     dprintf2(("SetWindowLong%c %x %d %x returned %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value, oldval));
03795     return oldval;
03796 }
03797 //******************************************************************************
03798 //******************************************************************************
03799 ULONG Win32BaseWindow::GetWindowLong(int index, BOOL fUnicode)
03800 {
03801  ULONG value;
03802 
03803     switch(index) {
03804     case GWL_EXSTYLE:
03805         value = dwExStyle;
03806         break;
03807     case GWL_STYLE:
03808         value = dwStyle;
03809         break;
03810     case GWL_WNDPROC:
03811         value = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
03812         break;
03813     case GWL_HINSTANCE:
03814         value = hInstance;
03815         break;
03816     case GWL_HWNDPARENT:
03817         value = GetParent();
03818         break;
03819     case GWL_ID:
03820         value = getWindowId();
03821         break;
03822     case GWL_USERDATA:
03823         value = userData;
03824         break;
03825     default:
03826         if(index >= 0 && index + sizeof(ULONG) <= nrUserWindowBytes)
03827         {
03828             value = *(ULONG *)(userWindowBytes + index);
03829             break;
03830         }
03831         dprintf(("WARNING: GetWindowLong%c %x %d %x returned %x INVALID index!", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
03832         SetLastError(ERROR_INVALID_INDEX);  //verified in NT4, SP6
03833         return 0;
03834     }
03835     dprintf2(("GetWindowLong%c %x %d %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
03836     //Note: NT4, SP6 does not set the last error to 0
03837     SetLastError(ERROR_SUCCESS);
03838     return value;
03839 }
03840 //******************************************************************************
03841 //******************************************************************************
03842 WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
03843 {
03844  WORD oldval;
03845 
03846     if(index >= 0 && index + sizeof(WORD) <= nrUserWindowBytes)
03847     {
03848         oldval = *(WORD *)(userWindowBytes + index);
03849         *(WORD *)(userWindowBytes + index) = value;
03850         //Note: NT4, SP6 does not set the last error to 0
03851         dprintf2(("SetWindowWord %x %d %x returned %x", getWindowHandle(), index, value, oldval));
03852         SetLastError(ERROR_SUCCESS);
03853         return oldval;
03854     }
03855     switch(index)
03856     {
03857     case GWW_HINSTANCE:
03858         oldval = hInstance;
03859         hInstance = value;
03860         break;
03861 
03862     case GWW_HWNDPARENT:
03863         oldval = SetParent((HWND)(WNDHANDLE_MAGIC_HIGHWORD | value));
03864         break;
03865 
03866     case GWW_ID:
03867         oldval = getWindowId();
03868         setWindowId(value);
03869         break;
03870 
03871     default:
03872         dprintf(("WARNING: SetWindowWord %x %d %x returned %x INVALID index!", getWindowHandle(), index, value));
03873         SetLastError(ERROR_INVALID_INDEX);  //verified in NT4, SP6
03874         return 0;
03875     }
03876     //Note: NT4, SP6 does not set the last error to 0
03877     SetLastError(ERROR_SUCCESS);
03878     dprintf2(("SetWindowWord %x %d %x returned %x", getWindowHandle(), index, value, oldval));
03879     return oldval;
03880 }
03881 //******************************************************************************
03882 //******************************************************************************
03883 WORD Win32BaseWindow::GetWindowWord(int index)
03884 {
03885     if(index >= 0 && index + sizeof(WORD) <= nrUserWindowBytes)
03886     {
03887         //Note: NT4, SP6 does not set the last error to 0
03888         SetLastError(ERROR_SUCCESS);
03889         dprintf2(("GetWindowWord %x %d %x", getWindowHandle(), index, *(WORD *)(userWindowBytes + index)));
03890         return *(WORD *)(userWindowBytes + index);
03891     }
03892     switch(index)
03893     {
03894     case GWW_ID:         
03895         if(HIWORD(getWindowId()))
03896             dprintf(("WARNING: GWW_ID: discards high bits of 0x%08x!\n", getWindowId()));
03897         return (WORD)getWindowId();
03898 
03899     case GWW_HWNDPARENT: 
03900         dprintf(("WARNING: GWW_HWNDPARENT: discards high bits of 0x%08x!\n", GetParent()));
03901         return (WORD) GetParent();
03902 
03903     case GWW_HINSTANCE:  
03904         if (HIWORD(hInstance))
03905             dprintf(("WARNING: GWW_HINSTANCE: discards high bits of 0x%08x!\n", hInstance));
03906         return (WORD)hInstance;
03907     }
03908 
03909     dprintf(("WARNING: GetWindowWord %x %d returned %x INVALID index!", getWindowHandle(), index));
03910     SetLastError(ERROR_INVALID_INDEX);  //verified in NT4, SP6
03911     return 0;
03912 }
03913 //******************************************************************************
03914 //Locates window in linked list and increases reference count (if found)
03915 //Window object must be unreferenced after usage
03916 //******************************************************************************
03917 Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
03918 {
03919  Win32BaseWindow *window;
03920 
03921 ////TODO: temporary workaround for crashes in Opera (pmwinx; releasesemaphore)
03922 ////      while browsing
03923 ////      Not thread safe now!
03924 ////    lock(&critsect);
03925     if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
03926          if(window) {
03927 ////             dprintf(("addRef %x; refcount %d", hwnd, window->getRefCount()+1));
03928              window->addRef();
03929          }
03930 ////         unlock(&critsect);
03931          return window;
03932     }
03933 ////    unlock(&critsect);
03934 //    dprintf2(("Win32BaseWindow::GetWindowFromHandle: not a win32 window %x", hwnd));
03935     return NULL;
03936 }
03937 //******************************************************************************
03938 //Locates window in linked list and increases reference count (if found)
03939 //Window object must be unreferenced after usage
03940 //******************************************************************************
03941 Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwndOS2)
03942 {
03943  DWORD            magic;
03944  HWND             hwnd; 
03945 
03946     if(hwndOS2 == OSLIB_HWND_DESKTOP)
03947     {
03948         windowDesktop->addRef();
03949         return windowDesktop;
03950     }
03951 
03952     hwnd  = (HWND)OSLibWinGetWindowULong(hwndOS2, OFFSET_WIN32WNDPTR);
03953     magic = OSLibWinGetWindowULong(hwndOS2, OFFSET_WIN32PM_MAGIC);
03954 
03955     if(hwnd && CheckMagicDword(magic)) {
03956         return GetWindowFromHandle(hwnd);
03957     }
03958 //  dprintf2(("Win32BaseWindow::GetWindowFromOS2Handle: not an Odin os2 window %x", hwndOS2));
03959     return 0;
03960 }
03961 //******************************************************************************
03962 //Locates window in linked list and increases reference count (if found)
03963 //Window object must be unreferenced after usage
03964 //******************************************************************************
03965 Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
03966 {
03967     return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
03968 }
03969 //******************************************************************************
03970 //******************************************************************************
03971 HWND WIN32API Win32ToOS2Handle(HWND hwnd)
03972 {
03973     HWND hwndOS2;
03974 
03975     Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
03976 
03977     if(window) {
03978             hwndOS2 = window->getOS2WindowHandle();
03979             RELEASE_WNDOBJ(window);
03980             return hwndOS2;
03981     }
03982 //    dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
03983     return hwnd;
03984 }
03985 //******************************************************************************
03986 //******************************************************************************
03987 HWND WIN32API Win32ToOS2FrameHandle(HWND hwnd)
03988 {
03989     HWND hwndOS2;
03990 
03991     Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
03992 
03993     if(window) {
03994             hwndOS2 = window->getOS2FrameWindowHandle();
03995             RELEASE_WNDOBJ(window);
03996             return hwndOS2;
03997     }
03998 //    dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
03999     return hwnd;
04000 }
04001 //******************************************************************************
04002 //******************************************************************************
04003 HWND WIN32API OS2ToWin32Handle(HWND hwnd)
04004 {
04005     Win32BaseWindow *window = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
04006     HWND hwndWin32;
04007 
04008     if(window) {
04009             hwndWin32 = window->getWindowHandle();
04010             RELEASE_WNDOBJ(window);
04011             return hwndWin32;
04012     }
04013     window = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwnd);
04014     if(window) {
04015             hwndWin32 = window->getWindowHandle();
04016             RELEASE_WNDOBJ(window);
04017             return hwndWin32;
04018     }
04019 
04020 //    dprintf2(("Win32BaseWindow::OS2ToWin32Handle: not a win32 window %x", hwnd));
04021     return 0;
04022 //    else    return hwnd;    //OS/2 window handle
04023 }
04024 #ifdef DEBUG
04025 LONG  Win32BaseWindow::addRef()
04026 {
04027 //    dprintf2(("addRef %x %d", getWindowHandle(), getRefCount()+1));
04028     return GenericObject::addRef();
04029 }
04030 //******************************************************************************
04031 //******************************************************************************
04032 LONG  Win32BaseWindow::release(char *function, int line)
04033 {
04034 //    dprintf2(("release %s %d %x %d", function, line, getWindowHandle(), getRefCount()-1));
04035     return GenericObject::release();
04036 }
04037 #endif
04038 //******************************************************************************
04039 //******************************************************************************
04040 GenericObject   *Win32BaseWindow::windows  = NULL;
04041 CRITICAL_SECTION Win32BaseWindow::critsect = {0};
04042 
04043 //******************************************************************************
04044 //******************************************************************************
04045 #ifdef DEBUG
04046 void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle)
04047 {
04048  char style[256] = "";
04049  char exstyle[256] = "";
04050 
04051     /* Window styles */
04052     if(dwStyle & WS_CHILD)
04053         strcat(style, "WS_CHILD ");
04054     if(dwStyle & WS_POPUP)
04055         strcat(style, "WS_POPUP ");
04056     if(dwStyle & WS_VISIBLE)
04057         strcat(style, "WS_VISIBLE ");
04058     if(dwStyle & WS_DISABLED)
04059         strcat(style, "WS_DISABLED ");
04060     if(dwStyle & WS_CLIPSIBLINGS)
04061         strcat(style, "WS_CLIPSIBLINGS ");
04062     if(dwStyle & WS_CLIPCHILDREN)
04063         strcat(style, "WS_CLIPCHILDREN ");
04064     if(dwStyle & WS_MAXIMIZE)
04065         strcat(style, "WS_MAXIMIZE ");
04066     if(dwStyle & WS_MINIMIZE)
04067         strcat(style, "WS_MINIMIZE ");
04068     if(dwStyle & WS_GROUP)
04069         strcat(style, "WS_GROUP ");
04070     if(dwStyle & WS_TABSTOP)
04071         strcat(style, "WS_TABSTOP ");
04072 
04073     if((dwStyle & WS_CAPTION) == WS_CAPTION)
04074         strcat(style, "WS_CAPTION ");
04075     if(dwStyle & WS_DLGFRAME)
04076         strcat(style, "WS_DLGFRAME ");
04077     if(dwStyle & WS_BORDER)
04078         strcat(style, "WS_BORDER ");
04079 
04080     if(dwStyle & WS_VSCROLL)
04081         strcat(style, "WS_VSCROLL ");
04082     if(dwStyle & WS_HSCROLL)
04083         strcat(style, "WS_HSCROLL ");
04084     if(dwStyle & WS_SYSMENU)
04085         strcat(style, "WS_SYSMENU ");
04086     if(dwStyle & WS_THICKFRAME)
04087         strcat(style, "WS_THICKFRAME ");
04088     if(dwStyle & WS_MINIMIZEBOX)
04089         strcat(style, "WS_MINIMIZEBOX ");
04090     if(dwStyle & WS_MAXIMIZEBOX)
04091         strcat(style, "WS_MAXIMIZEBOX ");
04092 
04093     if(dwExStyle & WS_EX_DLGMODALFRAME)
04094         strcat(exstyle, "WS_EX_DLGMODALFRAME ");
04095     if(dwExStyle & WS_EX_ACCEPTFILES)
04096         strcat(exstyle, "WS_EX_ACCEPTFILES ");
04097     if(dwExStyle & WS_EX_NOPARENTNOTIFY)
04098         strcat(exstyle, "WS_EX_NOPARENTNOTIFY ");
04099     if(dwExStyle & WS_EX_TOPMOST)
04100         strcat(exstyle, "WS_EX_TOPMOST ");
04101     if(dwExStyle & WS_EX_TRANSPARENT)
04102         strcat(exstyle, "WS_EX_TRANSPARENT ");
04103 
04104     if(dwExStyle & WS_EX_MDICHILD)
04105         strcat(exstyle, "WS_EX_MDICHILD ");
04106     if(dwExStyle & WS_EX_TOOLWINDOW)
04107         strcat(exstyle, "WS_EX_TOOLWINDOW ");
04108     if(dwExStyle & WS_EX_WINDOWEDGE)
04109         strcat(exstyle, "WS_EX_WINDOWEDGE ");
04110     if(dwExStyle & WS_EX_CLIENTEDGE)
04111         strcat(exstyle, "WS_EX_CLIENTEDGE ");
04112     if(dwExStyle & WS_EX_CONTEXTHELP)
04113         strcat(exstyle, "WS_EX_CONTEXTHELP ");
04114     if(dwExStyle & WS_EX_RIGHT)
04115         strcat(exstyle, "WS_EX_RIGHT ");
04116     if(dwExStyle & WS_EX_LEFT)
04117         strcat(exstyle, "WS_EX_LEFT ");
04118     if(dwExStyle & WS_EX_RTLREADING)
04119         strcat(exstyle, "WS_EX_RTLREADING ");
04120     if(dwExStyle & WS_EX_LTRREADING)
04121         strcat(exstyle, "WS_EX_LTRREADING ");
04122     if(dwExStyle & WS_EX_LEFTSCROLLBAR)
04123         strcat(exstyle, "WS_EX_LEFTSCROLLBAR ");
04124     if(dwExStyle & WS_EX_RIGHTSCROLLBAR)
04125         strcat(exstyle, "WS_EX_RIGHTSCROLLBAR ");
04126     if(dwExStyle & WS_EX_CONTROLPARENT)
04127         strcat(exstyle, "WS_EX_CONTROLPARENT ");
04128     if(dwExStyle & WS_EX_STATICEDGE)
04129         strcat(exstyle, "WS_EX_STATICEDGE ");
04130     if(dwExStyle & WS_EX_APPWINDOW)
04131         strcat(exstyle, "WS_EX_APPWINDOW ");
04132 
04133     dprintf(("Window style:   %x %s", dwStyle, style));
04134     dprintf(("Window exStyle: %x %s", dwExStyle, exstyle));
04135 }
04136 #endif
04137 //******************************************************************************
04138 //******************************************************************************

Generated on Wed Jan 23 23:17:47 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001