Ignore:
Timestamp:
Aug 30, 1999, 2:00:12 PM (26 years ago)
Author:
sandervl
Message:

Redesign; base class for all window types

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/new/win32wnd.cpp

    r740 r741  
    1 /* $Id: win32wnd.cpp,v 1.35 1999-08-29 20:05:07 sandervl Exp $ */
     1/* $Id: win32wnd.cpp,v 1.36 1999-08-30 11:59:53 sandervl Exp $ */
    22/*
    3  * Win32 Window Code for OS/2
    4  *
     3 * Win32 Window Class for OS/2
    54 *
    65 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
    76 * Copyright 1999      Daniela Engert (dani@ngrt.de)
    87 *
    9  * Parts based on Wine Windows code (windows\win.c)
     8 * Parts based on Wine (windows\mdi.c) (990815)
    109 *
    11  * Copyright 1993, 1994 Alexandre Julliard
    12  *
    13  * TODO: Not thread/process safe
     10 * Copyright 1994, Bob Amstadt
     11 *           1995,1996 Alex Korobka
    1412 *
    1513 * Project Odin Software License can be found in LICENSE.TXT
     
    3836#include "heapshared.h"
    3937
    40 #define HAS_DLGFRAME(style,exStyle) \
    41     (((exStyle) & WS_EX_DLGMODALFRAME) || \
    42      (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
    43 
    44 #define HAS_THICKFRAME(style) \
    45     (((style) & WS_THICKFRAME) && \
    46      !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
    47 
    48 #define HAS_BORDER(style, exStyle) \
    49     ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
    50 
    51 #define IS_OVERLAPPED(style) \
    52     !(style & (WS_CHILD | WS_POPUP))
    5338
    5439//******************************************************************************
    5540//******************************************************************************
    56 Win32Window::Win32Window(DWORD objType) : GenericObject(&windows, objType)
     41Win32Window::Win32Window(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
     42                : Win32BaseWindow(lpCreateStructA, classAtom, isUnicode)
    5743{
    58   Init();
    5944}
    6045//******************************************************************************
    6146//******************************************************************************
    62 Win32Window::Win32Window(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
    63                         : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
     47Win32Window::~Win32Window()
    6448{
    65   Init();
    66   this->isUnicode = isUnicode;
    67   CreateWindowExA(lpCreateStructA, classAtom);
    6849}
    6950//******************************************************************************
    7051//******************************************************************************
    71 void Win32Window::Init()
     52LRESULT Win32Window::DefFrameProcA(HWND hwndMDIClient, UINT Msg, WPARAM wParam, LPARAM lParam)
    7253{
    73   isUnicode        = FALSE;
    74   fCreated         = FALSE;
    75   fFirstShow       = TRUE;
     54 Win32Window *window = NULL;
    7655
    77   windowNameA      = NULL;
    78   windowNameW      = NULL;
    79   wndNameLength    = 0;
     56    if(hwndMDIClient)
     57        window = (Win32Window *)GetWindowFromHandle(hwndMDIClient);
    8058
    81   userWindowLong   = NULL;;
    82   nrUserWindowLong = 0;
     59    if(window)
     60    {
     61        switch(Msg)
     62        {
     63        case WM_NCACTIVATE:
     64            window->SendMessageA(Msg, wParam, lParam);
     65            break;
    8366
    84   magic            = WIN32PM_MAGIC;
    85   OS2Hwnd          = 0;
    86   OS2HwndFrame     = 0;
    87   OS2HwndMenu      = 0;
    88   Win32Hwnd        = 0;
     67#if 0
     68        case WM_COMMAND:
     69            ci = (MDICLIENTINFO*)wndPtr->wExtra;
    8970
    90   if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
    91   {
    92         dprintf(("Win32Window::Init HwAllocateWindowHandle failed!!"));
    93         DebugInt3();
    94   }
     71            /* check for possible syscommands for maximized MDI child */
     72            WIN_ReleaseWndPtr(wndPtr);
    9573
    96   posx = posy      = 0;
    97   width = height   = 0;
     74            if( ci && (
     75                wParam <  ci->idFirstChild ||
     76                wParam >= ci->idFirstChild + ci->nActiveChildren
     77            )){
     78                if( (wParam - 0xF000) & 0xF00F ) break;
     79                switch( wParam )
     80                {
     81                case SC_SIZE:
     82                case SC_MOVE:
     83                case SC_MINIMIZE:
     84                case SC_MAXIMIZE:
     85                case SC_NEXTWINDOW:
     86                case SC_PREVWINDOW:
     87                case SC_CLOSE:
     88                case SC_RESTORE:
     89                    if( ci->hwndChildMaximized )
     90                    return SendMessage16( ci->hwndChildMaximized, WM_SYSCOMMAND,
     91                           wParam, lParam);
     92                }
     93            }
     94            else
     95            {
     96                wndPtr = WIN_FindWndPtr(hwndMDIClient);
     97                childHwnd = MDI_GetChildByID(wndPtr,wParam );
     98                WIN_ReleaseWndPtr(wndPtr);
    9899
    99   dwExStyle        = 0;
    100   dwStyle          = 0;
    101   win32wndproc     = 0;
    102   hInstance        = 0;
    103   windowId         = 0xFFFFFFFF;        //default = -1
    104   userData         = 0;
     100                if( childHwnd )
     101                    SendMessage16(hwndMDIClient, WM_MDIACTIVATE,
     102                                      (WPARAM16)childHwnd , 0L);
     103            }
     104            break;
     105#endif
    105106
    106   hwndLinkAfter    = HWND_BOTTOM;
    107   flags            = 0;
    108   isIcon           = FALSE;
    109   lastHitTestVal   = 0;
    110   owner            = NULL;
    111   windowClass      = 0;
     107        case WM_SETFOCUS:
     108            SetFocus(hwndMDIClient);
     109            break;
    112110
    113   acceltableResource = NULL;
    114   menuResource       = NULL;
    115   iconResource       = NULL;
    116 }
    117 //******************************************************************************
    118 //todo get rid of resources (menu, accel, icon etc)
    119 //******************************************************************************
    120 Win32Window::~Win32Window()
    121 {
    122   OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
    123   OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
     111        case WM_SIZE:
     112            MoveWindow(hwndMDIClient, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
     113            break;
    124114
    125   if(Win32Hwnd)
    126         HwFreeWindowHandle(Win32Hwnd);
     115#if 0
     116        case WM_NEXTMENU:
     117            ci     = (MDICLIENTINFO*)wndPtr->wExtra;
    127118
    128   if(userWindowLong)
    129         free(userWindowLong);
    130   if(windowNameA) {
    131         free(windowNameA);
    132         windowNameA = NULL;
    133   }
    134   if(windowNameW) {
    135         free(windowNameW);
    136         windowNameW = NULL;
    137   }
     119            if( !(wndPtr->parent->dwStyle & WS_MINIMIZE)
     120            && ci->hwndActiveChild && !ci->hwndChildMaximized )
     121            {
     122            /* control menu is between the frame system menu and
     123            * the first entry of menu bar */
     124
     125                if( (wParam == VK_LEFT &&
     126                 wndPtr->parent->wIDmenu == LOWORD(lParam)) ||
     127                (wParam == VK_RIGHT &&
     128                GetSubMenu16(wndPtr->parent->hSysMenu, 0) == LOWORD(lParam)) )
     129                {
     130                    LRESULT retvalue;
     131                    wndPtr = WIN_FindWndPtr(ci->hwndActiveChild);
     132                    retvalue = MAKELONG( GetSubMenu16(wndPtr->hSysMenu, 0),
     133                                      ci->hwndActiveChild);
     134                    return retvalue;
     135                }
     136            }
     137            break;
     138#endif
     139        }
     140    }
     141    return DefWindowProcA(Msg, wParam, lParam);
    138142}
    139143//******************************************************************************
    140144//******************************************************************************
    141 BOOL Win32Window::isChild()
     145LRESULT Win32Window::DefFrameProcW(HWND hwndMDIClient, UINT Msg, WPARAM wParam, LPARAM lParam)
    142146{
    143     return (dwStyle & WS_CHILD) != 0;
     147 Win32Window *window = NULL;
     148
     149    if(hwndMDIClient)
     150        window = (Win32Window *)GetWindowFromHandle(hwndMDIClient);
     151
     152    if(window)
     153    {
     154        switch(Msg)
     155        {
     156        case WM_NCACTIVATE:
     157            window->SendMessageW(Msg, wParam, lParam);
     158            break;
     159
     160        case WM_SETTEXT:
     161        {
     162            LPSTR txt = HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR)lParam);
     163            LRESULT ret = DefFrameProcA(hwndMDIClient, Msg, wParam, (DWORD)txt );
     164            HeapFree(GetProcessHeap(),0,txt);
     165            return ret;
     166        }
     167        case WM_NEXTMENU:
     168        case WM_SETFOCUS:
     169        case WM_SIZE:
     170            return DefFrameProcA(hwndMDIClient, Msg, wParam, lParam );
     171        }
     172    }
     173    return DefWindowProcW(Msg, wParam, lParam);
    144174}
    145175//******************************************************************************
    146176//******************************************************************************
    147 BOOL Win32Window::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
    148 {
    149  char  buffer[256];
    150  INT   sw = SW_SHOW;
    151  POINT maxSize, maxPos, minTrack, maxTrack;
    152 
    153     SetLastError(0);
    154 
    155     /* Find the parent window */
    156     if (cs->hwndParent)
    157     {
    158             Win32Window *window = GetWindowFromHandle(cs->hwndParent);
    159             if(!window) {
    160                     dprintf(("Bad parent %04x\n", cs->hwndParent ));
    161                     SetLastError(ERROR_INVALID_PARAMETER);
    162                     return FALSE;
    163             }
    164             /* Make sure parent is valid */
    165             if (!window->IsWindow() )
    166             {
    167                     dprintf(("Bad parent %04x\n", cs->hwndParent ));
    168                     SetLastError(ERROR_INVALID_PARAMETER);
    169                     return FALSE;
    170             }
    171     }
    172     else
    173     if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
    174             dprintf(("No parent for child window\n" ));
    175             SetLastError(ERROR_INVALID_PARAMETER);
    176             return FALSE;  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
    177     }
    178 
    179   /* Find the window class */
    180   windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
    181   if (!windowClass)
    182   {
    183         GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
    184         dprintf(("Bad class '%s'\n", buffer ));
    185         return 0;
    186   }
    187 
    188   /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
    189    * with an atom as the class name, put some programs expect to have a *REAL* string in
    190    * lpszClass when the CREATESTRUCT is sent with WM_CREATE
    191    */
    192   if (!HIWORD(cs->lpszClass) ) {
    193         if (isUnicode) {
    194                 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
    195         }
    196         else {
    197                 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
    198         }
    199         cs->lpszClass = buffer;
    200   }
    201 
    202   /* Fix the coordinates */
    203   if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
    204   {
    205 //        PDB *pdb = PROCESS_Current();
    206 
    207        /* Never believe Microsoft's documentation... CreateWindowEx doc says
    208         * that if an overlapped window is created with WS_VISIBLE style bit
    209         * set and the x parameter is set to CW_USEDEFAULT, the system ignores
    210         * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
    211         * reveals that
    212         *
    213         * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
    214         * 2) it does not ignore the y parameter as the docs claim; instead, it
    215         *    uses it as second parameter to ShowWindow() unless y is either
    216         *    CW_USEDEFAULT or CW_USEDEFAULT16.
    217         *
    218         * The fact that we didn't do 2) caused bogus windows pop up when wine
    219         * was running apps that were using this obscure feature. Example -
    220         * calc.exe that comes with Win98 (only Win98, it's different from
    221         * the one that comes with Win95 and NT)
    222         */
    223         if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) sw = cs->y;
    224 
    225         /* We have saved cs->y, now we can trash it */
    226 #if 0
    227         if (   !(cs->style & (WS_CHILD | WS_POPUP))
    228             &&  (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
    229         {
    230             cs->x = pdb->env_db->startup_info->dwX;
    231             cs->y = pdb->env_db->startup_info->dwY;
    232         }
    233 #endif
    234             cs->x = 0;
    235             cs->y = 0;
    236 //        }
    237   }
    238   if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
    239   {
    240 #if 0
    241         PDB *pdb = PROCESS_Current();
    242         if (   !(cs->style & (WS_CHILD | WS_POPUP))
    243             &&  (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
    244         {
    245             cs->cx = pdb->env_db->startup_info->dwXSize;
    246             cs->cy = pdb->env_db->startup_info->dwYSize;
    247         }
    248         else
    249         {
    250 #endif
    251             cs->cx = 600; /* FIXME */
    252             cs->cy = 400;
    253 //        }
    254   }
    255 
    256   if (cs->x < 0) cs->x = 0;
    257   if (cs->y < 0) cs->y = 0;
    258 
    259   //Allocate window words
    260   nrUserWindowLong = windowClass->getExtraWndWords();
    261   if(nrUserWindowLong) {
    262         userWindowLong = (ULONG *)_smalloc(nrUserWindowLong);
    263         memset(userWindowLong, 0, nrUserWindowLong);
    264   }
    265 
    266   if ((cs->style & WS_CHILD) && cs->hwndParent)
    267   {
    268         SetParent(cs->hwndParent);
    269         owner = GetWindowFromHandle(cs->hwndParent);
    270         if(owner == NULL)
    271         {
    272             dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
    273             return FALSE;
    274         }
    275   }
    276   else
    277   {
    278         if (!cs->hwndParent) {
    279             owner = NULL;
    280         }
    281         else
    282         {
    283             owner = GetWindowFromHandle(cs->hwndParent);
    284             if(owner == NULL)
    285             {
    286                 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
    287                 return FALSE;
    288             }
    289         }
    290   }
    291 
    292   setWindowProc(windowClass->getWindowProc());
    293   hInstance = cs->hInstance;
    294   dwStyle   = cs->style & ~WS_VISIBLE;
    295   dwExStyle = cs->dwExStyle;
    296 
    297   hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
    298                   ? HWND_BOTTOM : HWND_TOP;
    299 
    300 #if 0
    301 //TODO
    302     /* Call the WH_CBT hook */
    303 
    304     if (HOOK_IsHooked( WH_CBT ))
    305     {
    306     CBT_CREATEWNDA cbtc;
    307         LRESULT ret;
    308 
    309     cbtc.lpcs = cs;
    310     cbtc.hwndInsertAfter = hwndLinkAfter;
    311         ret = unicode ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc)
    312                       : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc);
    313         if (ret)
    314     {
    315         TRACE_(win)("CBT-hook returned 0\n");
    316         wndPtr->pDriver->pFinalize(wndPtr);
    317             retvalue =  0;
    318             goto end;
    319     }
    320     }
    321 #endif
    322 
    323   /* Increment class window counter */
    324   windowClass->IncreaseWindowCount();
    325 
    326   /* Correct the window style */
    327   if (!(cs->style & WS_CHILD))
    328   {
    329         dwStyle |= WS_CLIPSIBLINGS;
    330         if (!(cs->style & WS_POPUP))
    331         {
    332             dwStyle |= WS_CAPTION;
    333             flags |= WIN_NEED_SIZE;
    334         }
    335   }
    336   if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
    337 
    338   //TODO?
    339 #if 0
    340   /* Get class or window DC if needed */
    341   if (classPtr->style & CS_OWNDC) dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
    342   else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
    343   else wndPtr->dce = NULL;
    344 #endif
    345 
    346   /* Send the WM_GETMINMAXINFO message and fix the size if needed */
    347   if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
    348   {
    349         GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
    350         if (maxSize.x < cs->cx) cs->cx = maxSize.x;
    351         if (maxSize.y < cs->cy) cs->cy = maxSize.y;
    352         if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
    353         if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
    354   }
    355 
    356   if(cs->style & WS_CHILD)
    357   {
    358         if(cs->cx < 0) cs->cx = 0;
    359         if(cs->cy < 0) cs->cy = 0;
    360   }
    361   else
    362   {
    363         if (cs->cx <= 0) cs->cx = 1;
    364         if (cs->cy <= 0) cs->cy = 1;
    365   }
    366 
    367   rectWindow.left   = cs->x;
    368   rectWindow.top    = cs->y;
    369   rectWindow.right  = cs->x + cs->cx;
    370   rectWindow.bottom = cs->y + cs->cy;
    371   rectClient        = rectWindow;
    372 
    373   DWORD dwOSWinStyle, dwOSFrameStyle;
    374 
    375   OSLibWinConvertStyle(cs->style, cs->dwExStyle, &dwOSWinStyle, &dwOSFrameStyle);
    376 
    377   //TODO: Test
    378 #if 1
    379   if(cs->style & WS_CHILD) {
    380         dwOSFrameStyle = 0;
    381   }
    382 #endif
    383 
    384   if(cs->lpszName)
    385         SetWindowText((LPSTR)cs->lpszName);
    386 
    387   OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
    388                                  dwOSWinStyle, dwOSFrameStyle, (char *)windowNameA,
    389                                  (owner) ? owner->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
    390                                  (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
    391                                  &OS2HwndFrame);
    392 
    393   if(OS2Hwnd == 0) {
    394         dprintf(("Window creation failed!!"));
    395         return FALSE;
    396   }
    397 
    398   if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
    399         dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
    400         return FALSE;
    401   }
    402   if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
    403         dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
    404         return FALSE;
    405   }
    406   //SvL: Need to store the shared memory base, or else other apps can map it into their memory space
    407   if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_SHAREDMEM, HeapGetSharedMemBase()) == FALSE) {
    408         dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
    409         return FALSE;
    410   }
    411 #if 0
    412   if(OS2Hwnd != OS2HwndFrame) {
    413     if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
    414             dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2HwndFrame));
    415             return FALSE;
    416     }
    417     if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
    418             dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2HwndFrame));
    419             return FALSE;
    420     }
    421     //SvL: Need to store the shared memory base, or else other apps can map it into their memory space
    422     if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32PM_SHAREDMEM, HeapGetSharedMemBase()) == FALSE) {
    423             dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2HwndFrame));
    424             return FALSE;
    425     }
    426   }
    427 #endif
    428 
    429   /* Set the window menu */
    430   if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
    431   {
    432         if (cs->hMenu) SetMenu(cs->hMenu);
    433         else
    434         {
    435                 if (windowClass->getMenuNameA()) {
    436                         cs->hMenu = LoadMenuA(cs->hInstance, windowClass->getMenuNameA());
    437                         if (cs->hMenu) SetMenu(cs->hMenu );
    438                 }
    439         }
    440   }
    441   else  windowId = (UINT)cs->hMenu;
    442 
    443   //Set icon from class
    444   if(windowClass->getIcon())
    445         SetIcon(windowClass->getIcon());
    446 
    447   if(getParent()) {
    448         SetWindowPos(getParent()->getWindowHandle(), rectClient.left, rectClient.top,
    449                      rectClient.right-rectClient.left,
    450                      rectClient.bottom-rectClient.top,
    451                      SWP_NOACTIVATE | SWP_NOZORDER);
    452   }
    453   else {
    454         SetWindowPos(HWND_TOP, rectClient.left, rectClient.top,
    455                      rectClient.right-rectClient.left,
    456                      rectClient.bottom-rectClient.top,
    457                      SWP_NOACTIVATE);
    458   }
    459   //Get the client window rectangle
    460   GetClientRect(Win32Hwnd, &rectClient);
    461 
    462   /* Send the WM_CREATE message
    463    * Perhaps we shouldn't allow width/height changes as well.
    464    * See p327 in "Internals".
    465    */
    466   maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
    467 
    468   fCreated = TRUE; //Allow WM_SIZE messages now
    469   if(SendInternalMessage(WM_NCCREATE, 0, (LPARAM)cs) )
    470   {
    471         //doesn't work right, messes up client rectangle
    472 #if 0
    473         SendNCCalcSize(FALSE, &rectWindow, NULL, NULL, 0, &rectClient );
    474 #endif
    475         OffsetRect(&rectWindow, maxPos.x - rectWindow.left, maxPos.y - rectWindow.top);
    476         dprintf(("Sending WM_CREATE"));
    477         if( (SendInternalMessage(WM_CREATE, 0, (LPARAM)cs )) != -1 )
    478         {
    479             if(!(flags & WIN_NEED_SIZE)) {
    480                 SendMessageA(WM_SIZE, SIZE_RESTORED,
    481                                 MAKELONG(rectClient.right-rectClient.left,
    482                                          rectClient.bottom-rectClient.top));
    483                 SendMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
    484             }
    485             if (cs->style & WS_VISIBLE) ShowWindow( sw );
    486 
    487 #if 0
    488             /* Call WH_SHELL hook */
    489 
    490             if (!(dwStyle & WS_CHILD) && !owner)
    491                 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
    492 #endif
    493             SetLastError(0);
    494             return TRUE;
    495         }
    496   }
    497   fCreated = FALSE;
    498   OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
    499   OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
    500   DestroyWindow();
    501   return FALSE;
    502 }
    503 #if 0
    504 /***********************************************************************
    505  *           WINPOS_MinMaximize
    506  *
    507  * Fill in lpRect and return additional flags to be used with SetWindowPos().
    508  * This function assumes that 'cmd' is different from the current window
    509  * state.
    510  */
    511 UINT Win32Window::MinMaximize(UINT cmd, LPRECT lpRect )
    512 {
    513     UINT swpFlags = 0;
    514     POINT pt, size;
    515     LPINTERNALPOS lpPos;
    516 
    517     size.x = rectWindow.left; size.y = rectWindow.top;
    518     lpPos = WINPOS_InitInternalPos( wndPtr, size, &rectWindow );
    519 
    520     if (lpPos && !HOOK_CallHooks16(WH_CBT, HCBT_MINMAX, hwndSelf, cmd))
    521     {
    522     if( dwStyle & WS_MINIMIZE )
    523     {
    524         if( !SendInternalMessageA(WM_QUERYOPEN, 0, 0L ) )
    525         return (SWP_NOSIZE | SWP_NOMOVE);
    526         swpFlags |= SWP_NOCOPYBITS;
    527     }
    528     switch( cmd )
    529     {
    530         case SW_MINIMIZE:
    531          if( dwStyle & WS_MAXIMIZE)
    532          {
    533              flags |= WIN_RESTORE_MAX;
    534              dwStyle &= ~WS_MAXIMIZE;
    535                  }
    536                  else
    537              flags &= ~WIN_RESTORE_MAX;
    538              dwStyle |= WS_MINIMIZE;
    539 
    540 #if 0
    541          if( flags & WIN_NATIVE )
    542              if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
    543              swpFlags |= MINMAX_NOSWP;
    544 #endif
    545 
    546          lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
    547 
    548          SetRect(lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
    549              GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
    550          swpFlags |= SWP_NOCOPYBITS;
    551          break;
    552 
    553         case SW_MAXIMIZE:
    554                 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
    555 
    556          if( dwStyle & WS_MINIMIZE )
    557          {
    558              if( flags & WIN_NATIVE )
    559              if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
    560                  swpFlags |= MINMAX_NOSWP;
    561 
    562              WINPOS_ShowIconTitle( wndPtr, FALSE );
    563              dwStyle &= ~WS_MINIMIZE;
    564          }
    565                  dwStyle |= WS_MAXIMIZE;
    566 
    567          SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
    568                     size.x, size.y );
    569          break;
    570 
    571         case SW_RESTORE:
    572          if( dwStyle & WS_MINIMIZE )
    573          {
    574              if( flags & WIN_NATIVE )
    575              if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
    576                  swpFlags |= MINMAX_NOSWP;
    577 
    578              dwStyle &= ~WS_MINIMIZE;
    579              WINPOS_ShowIconTitle( wndPtr, FALSE );
    580 
    581              if( flags & WIN_RESTORE_MAX)
    582              {
    583              /* Restore to maximized position */
    584                          CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
    585                          WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
    586                          CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
    587              dwStyle |= WS_MAXIMIZE;
    588              SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
    589              break;
    590              }
    591          }
    592          else
    593              if( !(dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
    594              else dwStyle &= ~WS_MAXIMIZE;
    595 
    596          /* Restore to normal position */
    597 
    598         *lpRect = lpPos->rectNormal;
    599          lpRect->right -= lpRect->left;
    600          lpRect->bottom -= lpRect->top;
    601 
    602          break;
    603     }
    604     } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
    605     return swpFlags;
    606 }
    607 #endif
    608 /*******************************************************************
    609  *           GetMinMaxInfo
    610  *
    611  * Get the minimized and maximized information for a window.
    612  */
    613 void Win32Window::GetMinMaxInfo(POINT *maxSize, POINT *maxPos,
    614                                 POINT *minTrack, POINT *maxTrack )
    615 {
    616     MINMAXINFO MinMax;
    617     INT xinc, yinc;
    618 
    619     /* Compute default values */
    620 
    621     MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
    622     MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
    623     MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
    624     MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
    625     MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
    626     MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
    627 
    628     if (flags & WIN_MANAGED) xinc = yinc = 0;
    629     else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
    630     {
    631         xinc = GetSystemMetrics(SM_CXDLGFRAME);
    632         yinc = GetSystemMetrics(SM_CYDLGFRAME);
    633     }
    634     else
    635     {
    636         xinc = yinc = 0;
    637         if (HAS_THICKFRAME(dwStyle))
    638         {
    639             xinc += GetSystemMetrics(SM_CXFRAME);
    640             yinc += GetSystemMetrics(SM_CYFRAME);
    641         }
    642         if (dwStyle & WS_BORDER)
    643         {
    644             xinc += GetSystemMetrics(SM_CXBORDER);
    645             yinc += GetSystemMetrics(SM_CYBORDER);
    646         }
    647     }
    648     MinMax.ptMaxSize.x += 2 * xinc;
    649     MinMax.ptMaxSize.y += 2 * yinc;
    650 
    651 #if 0
    652     lpPos = (LPINTERNALPOS)GetPropA( hwndSelf, atomInternalPos );
    653     if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
    654         CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
    655     else
    656     {
    657 #endif
    658         MinMax.ptMaxPosition.x = -xinc;
    659         MinMax.ptMaxPosition.y = -yinc;
    660 //    }
    661 
    662     SendInternalMessageA(WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
    663 
    664       /* Some sanity checks */
    665 
    666     dprintf(("GetMinMaxInfo: %ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
    667                       MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
    668                       MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
    669                       MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
    670                       MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y));
    671     MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
    672                                    MinMax.ptMinTrackSize.x );
    673     MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
    674                                    MinMax.ptMinTrackSize.y );
    675 
    676     if (maxSize)    *maxSize  = MinMax.ptMaxSize;
    677     if (maxPos)     *maxPos   = MinMax.ptMaxPosition;
    678     if (minTrack)   *minTrack = MinMax.ptMinTrackSize;
    679     if (maxTrack)   *maxTrack = MinMax.ptMaxTrackSize;
    680 }
    681 /***********************************************************************
    682  *           WINPOS_SendNCCalcSize
    683  *
    684  * Send a WM_NCCALCSIZE message to a window.
    685  * All parameters are read-only except newClientRect.
    686  * oldWindowRect, oldClientRect and winpos must be non-NULL only
    687  * when calcValidRect is TRUE.
    688  */
    689 LONG Win32Window::SendNCCalcSize(BOOL calcValidRect, RECT *newWindowRect, RECT *oldWindowRect,
    690                                  RECT *oldClientRect, WINDOWPOS *winpos,
    691                                  RECT *newClientRect )
    692 {
    693    NCCALCSIZE_PARAMS params;
    694    WINDOWPOS winposCopy;
    695    LONG result;
    696 
    697    params.rgrc[0] = *newWindowRect;
    698    if (calcValidRect)
    699    {
    700         winposCopy = *winpos;
    701         params.rgrc[1] = *oldWindowRect;
    702         params.rgrc[2] = *oldClientRect;
    703         params.lppos = &winposCopy;
    704    }
    705    result = SendInternalMessageA(WM_NCCALCSIZE, calcValidRect,
    706                                  (LPARAM)&params );
    707    *newClientRect = params.rgrc[0];
    708    return result;
    709 }
    710 //******************************************************************************
    711 //******************************************************************************
    712 ULONG Win32Window::MsgCreate(HWND hwndOS2, ULONG initParam)
    713 {
    714   OS2Hwnd = hwndOS2;
    715   return SendInternalMessageA(WM_CREATE, 0, initParam);
    716 }
    717 //******************************************************************************
    718 //******************************************************************************
    719 ULONG Win32Window::MsgQuit()
    720 {
    721   return SendInternalMessageA(WM_QUIT, 0, 0);
    722 }
    723 //******************************************************************************
    724 //******************************************************************************
    725 ULONG Win32Window::MsgClose()
    726 {
    727   if(SendInternalMessageA(WM_CLOSE, 0, 0) == 0) {
    728         return 0; //app handles this message
    729   }
    730   delete this;
    731   return 1;
    732 }
    733 //******************************************************************************
    734 //******************************************************************************
    735 ULONG Win32Window::MsgDestroy()
    736 {
    737  ULONG rc;
    738 
    739   rc = SendInternalMessageA(WM_DESTROY, 0, 0);
    740   delete this;
    741   return rc;
    742 }
    743 //******************************************************************************
    744 //******************************************************************************
    745 ULONG Win32Window::MsgEnable(BOOL fEnable)
    746 {
    747     return SendInternalMessageA(WM_ENABLE, fEnable, 0);
    748 }
    749 //******************************************************************************
    750 //TODO: SW_PARENTCLOSING/OPENING flag (lParam)
    751 //******************************************************************************
    752 ULONG Win32Window::MsgShow(BOOL fShow)
    753 {
    754     return SendInternalMessageA(WM_SHOWWINDOW, fShow, 0);
    755 }
    756 //******************************************************************************
    757 //******************************************************************************
    758 ULONG Win32Window::MsgPosChanging(LPARAM lp)
    759 {
    760     dprintf(("MsgPosChanging"));
    761 #if 1
    762     if(fCreated == FALSE) {
    763         return 1;
    764     }
    765 #endif
    766     return SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, lp);
    767 }
    768 //******************************************************************************
    769 //******************************************************************************
    770 ULONG Win32Window::MsgPosChanged(LPARAM lp)
    771 {
    772     dprintf(("MsgPosChanged"));
    773 #if 1
    774     if(fCreated == FALSE) {
    775         return 1;
    776     }
    777 #endif
    778     return SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, lp);
    779 }
    780 //******************************************************************************
    781 //******************************************************************************
    782 ULONG Win32Window::MsgMove(ULONG x, ULONG y)
    783 {
    784     dprintf(("MsgMove to (%d,%d)", x, y));
    785     if(fCreated == FALSE) {
    786         return 1;
    787     }
    788 
    789     return SendInternalMessageA(WM_MOVE, 0, MAKELONG((USHORT)x, (USHORT)y));
    790 }
    791 //******************************************************************************
    792 //******************************************************************************
    793 ULONG Win32Window::MsgCommand(ULONG cmd, ULONG Id, HWND hwnd)
    794 {
    795   switch(cmd) {
    796     case CMD_MENU:
    797         return SendInternalMessageA(WM_COMMAND, MAKELONG(Id, 0), 0);
    798     case CMD_CONTROL:
    799         return 0; //todo
    800     case CMD_ACCELERATOR:
    801         dprintf(("accelerator command"));
    802         return 0; //todo
    803   }
    804   return 0;
    805 }
    806 //******************************************************************************
    807 //******************************************************************************
    808 ULONG Win32Window::MsgHitTest(ULONG x, ULONG y)
    809 {
    810   lastHitTestVal = SendInternalMessageA(WM_NCHITTEST, 0, MAKELONG((USHORT)x, (USHORT)y));
    811   return 1; //TODO: May need to change this
    812 }
    813 //******************************************************************************
    814 //TODO: Send WM_NCCALCSIZE message here and correct size if necessary
    815 //******************************************************************************
    816 ULONG Win32Window::MsgSize(ULONG width, ULONG height, BOOL fMinimize, BOOL fMaximize)
    817 {
    818  WORD fwSizeType = 0;
    819 
    820     if(fCreated == FALSE) {//Solitaire crashes if it receives a WM_SIZE during CreateWindowEx (normal or our fault?)
    821         return 1;
    822     }
    823 
    824     if(fMinimize) {
    825             fwSizeType = SIZE_MINIMIZED;
    826     }
    827     else
    828     if(fMaximize) {
    829             fwSizeType = SIZE_MAXIMIZED;
    830     }
    831     else    fwSizeType = SIZE_RESTORED;
    832 
    833     return SendInternalMessageA(WM_SIZE, fwSizeType, MAKELONG((USHORT)width, (USHORT)height));
    834 }
    835 //******************************************************************************
    836 //******************************************************************************
    837 ULONG Win32Window::MsgActivate(BOOL fActivate, HWND hwnd)
    838 {
    839     if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE)
    840     {
    841         if(!fActivate) {
    842             return 1;
    843         }
    844     }
    845     return SendInternalMessageA(WM_ACTIVATE, (fActivate) ? WA_ACTIVE : WA_INACTIVE, hwnd);
    846 }
    847 //******************************************************************************
    848 //******************************************************************************
    849 ULONG Win32Window::MsgSysCommand(ULONG win32sc, ULONG x, ULONG y)
    850 {
    851     return SendInternalMessageA(WM_SYSCOMMAND, win32sc, MAKELONG((USHORT)x, (USHORT)y));
    852 }
    853 //******************************************************************************
    854 //TODO: virtual key & (possibly) scancode translation, extended keyboard bit & Unicode
    855 //******************************************************************************
    856 ULONG Win32Window::MsgChar(ULONG cmd, ULONG repeatcnt, ULONG scancode, ULONG vkey, ULONG keyflags)
    857 {
    858  ULONG lParam = 0;
    859 
    860     lParam  = repeatcnt;
    861     lParam |= (scancode << 16);
    862     if(keyflags & KEY_ALTDOWN)
    863         lParam |= (1<<29);
    864     if(keyflags & KEY_PREVDOWN)
    865         lParam |= (1<<30);
    866     if(keyflags & KEY_UP)
    867         lParam |= (1<<31);
    868     if(keyflags & KEY_DEADKEY) {
    869         dprintf(("WM_DEADCHAR: %x %x %08x", OS2Hwnd, cmd, lParam));
    870         return SendInternalMessageA(WM_DEADCHAR, cmd, lParam);
    871     }
    872     else {
    873         dprintf(("WM_CHAR: %x %x %08x", OS2Hwnd, cmd, lParam));
    874         return SendInternalMessageA(WM_CHAR, cmd, lParam);
    875     }
    876 }
    877 //******************************************************************************
    878 //******************************************************************************
    879 ULONG Win32Window::MsgSetFocus(HWND hwnd)
    880 {
    881     if(hwnd == 0) {
    882             //other app lost focus
    883             SendInternalMessageA(WM_ACTIVATEAPP, TRUE, 0); //TODO: Need thread id from hwnd app
    884     }
    885     return  SendInternalMessageA(WM_SETFOCUS, hwnd, 0);
    886 }
    887 //******************************************************************************
    888 //******************************************************************************
    889 ULONG Win32Window::MsgKillFocus(HWND hwnd)
    890 {
    891     if(hwnd == 0) {
    892             //other app lost focus
    893             SendInternalMessageA(WM_ACTIVATEAPP, FALSE, 0); //TODO: Need thread id from hwnd app
    894     }
    895     return  SendInternalMessageA(WM_KILLFOCUS, hwnd, 0);
    896 }
    897 //******************************************************************************
    898 //******************************************************************************
    899 ULONG Win32Window::MsgButton(ULONG msg, ULONG ncx, ULONG ncy, ULONG clx, ULONG cly)
    900 {
    901  ULONG win32msg;
    902  ULONG win32ncmsg;
    903 
    904     dprintf(("MsgButton to (%d,%d)", ncx, ncy));
    905     switch(msg) {
    906         case BUTTON_LEFTDOWN:
    907                 win32msg = WM_LBUTTONDOWN;
    908                 win32ncmsg = WM_NCLBUTTONDOWN;
    909                 break;
    910         case BUTTON_LEFTUP:
    911                 win32msg = WM_LBUTTONUP;
    912                 win32ncmsg = WM_NCLBUTTONUP;
    913                 break;
    914         case BUTTON_LEFTDBLCLICK:
    915                 win32msg = WM_LBUTTONDBLCLK;
    916                 win32ncmsg = WM_NCLBUTTONDBLCLK;
    917                 break;
    918         case BUTTON_RIGHTUP:
    919                 win32msg = WM_RBUTTONUP;
    920                 win32ncmsg = WM_NCRBUTTONUP;
    921                 break;
    922         case BUTTON_RIGHTDOWN:
    923                 win32msg = WM_RBUTTONDOWN;
    924                 win32ncmsg = WM_NCRBUTTONDOWN;
    925                 break;
    926         case BUTTON_RIGHTDBLCLICK:
    927                 win32msg = WM_RBUTTONDBLCLK;
    928                 win32ncmsg = WM_NCRBUTTONDBLCLK;
    929                 break;
    930         case BUTTON_MIDDLEUP:
    931                 win32msg = WM_MBUTTONUP;
    932                 win32ncmsg = WM_NCMBUTTONUP;
    933                 break;
    934         case BUTTON_MIDDLEDOWN:
    935                 win32msg = WM_MBUTTONDOWN;
    936                 win32ncmsg = WM_NCMBUTTONDOWN;
    937                 break;
    938         case BUTTON_MIDDLEDBLCLICK:
    939                 win32msg = WM_MBUTTONDBLCLK;
    940                 win32ncmsg = WM_NCMBUTTONDBLCLK;
    941                 break;
    942         default:
    943                 dprintf(("Win32Window::Button: invalid msg!!!!"));
    944                 return 1;
    945     }
    946     if(win32msg == WM_MBUTTONDBLCLK || win32msg == WM_RBUTTONDBLCLK || win32msg == WM_LBUTTONDBLCLK) {
    947         if(!(windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS)) {
    948             return 1;
    949         }
    950     }
    951     SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, win32ncmsg));
    952 
    953     //WM_NC*BUTTON* is posted when the cursor is in a non-client area of the window
    954     if(lastHitTestVal != HTCLIENT) {
    955             SendInternalMessageA(win32ncmsg, lastHitTestVal, MAKELONG(ncx, ncy)); //TODO:
    956     }
    957     return  SendInternalMessageA(win32msg, 0, MAKELONG(clx, cly));
    958 }
    959 //******************************************************************************
    960 //******************************************************************************
    961 ULONG Win32Window::MsgMouseMove(ULONG keystate, ULONG x, ULONG y)
    962 {
    963  ULONG winstate = 0;
    964  ULONG setcursormsg = WM_MOUSEMOVE;
    965 
    966     if(keystate & WMMOVE_LBUTTON)
    967         winstate |= MK_LBUTTON;
    968     if(keystate & WMMOVE_RBUTTON)
    969         winstate |= MK_RBUTTON;
    970     if(keystate & WMMOVE_MBUTTON)
    971         winstate |= MK_MBUTTON;
    972     if(keystate & WMMOVE_SHIFT)
    973         winstate |= MK_SHIFT;
    974     if(keystate & WMMOVE_CTRL)
    975         winstate |= MK_CONTROL;
    976 
    977     if(lastHitTestVal != HTCLIENT) {
    978         setcursormsg = WM_NCMOUSEMOVE;
    979     }
    980     //TODO: hiword should be 0 if window enters menu mode (SDK docs)
    981     SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, setcursormsg));
    982 
    983     //WM_NCMOUSEMOVE is posted when the cursor moves into a non-client area of the window
    984     if(lastHitTestVal != HTCLIENT) {
    985             SendInternalMessageA(WM_NCMOUSEMOVE, lastHitTestVal, MAKELONG(x, y));
    986     }
    987     return  SendInternalMessageA(WM_MOUSEMOVE, keystate, MAKELONG(x, y));
    988 }
    989 //******************************************************************************
    990 //******************************************************************************
    991 ULONG Win32Window::MsgPaint(ULONG tmp1, ULONG tmp2)
    992 {
    993     return SendInternalMessageA(WM_PAINT, 0, 0);
    994 }
    995 //******************************************************************************
    996 //TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
    997 //      (or are we simply erasing too much here)
    998 //******************************************************************************
    999 ULONG Win32Window::MsgEraseBackGround(HDC hdc)
    1000 {
    1001     ULONG rc;
    1002     HDC   hdcErase = hdc;
    1003 
    1004     if (hdcErase == 0)
    1005         hdcErase = O32_GetDC(OS2Hwnd);
    1006 
    1007     if(isIcon)
    1008         rc = SendInternalMessageA(WM_ICONERASEBKGND, hdcErase, 0);
    1009     else
    1010         rc = SendInternalMessageA(WM_ERASEBKGND, hdcErase, 0);
    1011     if (hdc == 0)
    1012         O32_ReleaseDC(OS2Hwnd, hdcErase);
    1013     return (rc);
    1014 }
    1015 //******************************************************************************
    1016 //******************************************************************************
    1017 ULONG Win32Window::MsgSetText(LPSTR lpsz, LONG cch)
    1018 {
    1019     if(isUnicode) {
    1020             return SendInternalMessageW(WM_SETTEXT, 0, (LPARAM)lpsz);
    1021     }
    1022     else    return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
    1023 }
    1024 //******************************************************************************
    1025 //TODO: in- or excluding terminating 0?
    1026 //******************************************************************************
    1027 ULONG Win32Window::MsgGetTextLength()
    1028 {
    1029     return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
    1030 }
    1031 //******************************************************************************
    1032 //******************************************************************************
    1033 char *Win32Window::MsgGetText()
    1034 {
    1035     if(isUnicode) {
    1036         SendInternalMessageW(WM_GETTEXT, wndNameLength, (LPARAM)windowNameW);
    1037     }
    1038     else {
    1039         SendInternalMessageA(WM_GETTEXT, wndNameLength, (LPARAM)windowNameA);
    1040     }
    1041     return windowNameA;
    1042 }
    1043 //******************************************************************************
    1044 //******************************************************************************
    1045 LRESULT Win32Window::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
    1046 {
    1047     switch(Msg)
    1048     {
    1049     case WM_GETTEXTLENGTH:
    1050         return wndNameLength;
    1051 
    1052     case WM_GETTEXT:   //TODO: SS_ICON controls
    1053         strncpy((LPSTR)lParam, windowNameA, wParam);
    1054         return min(wndNameLength, wParam);
    1055 
    1056     case WM_SETTEXT:
    1057         return 0;
    1058 
    1059     case WM_SETREDRAW:
    1060         if(wParam)
    1061                 SetWindowLongA (GWL_STYLE, GetWindowLongA (GWL_STYLE) | WS_VISIBLE);
    1062         else    SetWindowLongA (GWL_STYLE, GetWindowLongA (GWL_STYLE) & ~WS_VISIBLE);
    1063 
    1064         return 0; //TODO
    1065 
    1066     case WM_NCCREATE:
    1067         return(TRUE);
    1068 
    1069     case WM_CTLCOLORMSGBOX:
    1070     case WM_CTLCOLOREDIT:
    1071     case WM_CTLCOLORLISTBOX:
    1072     case WM_CTLCOLORBTN:
    1073     case WM_CTLCOLORDLG:
    1074     case WM_CTLCOLORSTATIC:
    1075     case WM_CTLCOLORSCROLLBAR:
    1076          SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
    1077          SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
    1078          return GetSysColorBrush(COLOR_BTNFACE);
    1079 
    1080     case WM_PARENTNOTIFY:
    1081         return 0;
    1082 
    1083     case WM_MOUSEACTIVATE:
    1084     {
    1085         DWORD dwStyle = GetWindowLongA(GWL_STYLE);
    1086         DWORD dwExStyle = GetWindowLongA(GWL_EXSTYLE);
    1087         dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
    1088         if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
    1089         {
    1090             if(getParent()) {
    1091                 LRESULT rc = getParent()->SendMessageA(WM_MOUSEACTIVATE, wParam, lParam );
    1092                 if(rc)  return rc;
    1093             }
    1094         }
    1095         return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
    1096     }
    1097     case WM_SETCURSOR:
    1098     {
    1099         DWORD dwStyle = GetWindowLongA(GWL_STYLE);
    1100         DWORD dwExStyle = GetWindowLongA(GWL_EXSTYLE);
    1101         dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
    1102         if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
    1103         {
    1104             if(getParent()) {
    1105                 LRESULT rc = getParent()->SendMessageA(WM_SETCURSOR, wParam, lParam);
    1106                 if(rc)  return rc;
    1107             }
    1108         }
    1109         return 1;
    1110     }
    1111     case WM_MOUSEMOVE:
    1112         return 0;
    1113 
    1114     case WM_WINDOWPOSCHANGED:
    1115     {
    1116 
    1117 /* undocumented SWP flags - from SDK 3.1 */
    1118 #define SWP_NOCLIENTSIZE        0x0800
    1119 #define SWP_NOCLIENTMOVE        0x1000
    1120 
    1121         PWINDOWPOS wpos = (PWINDOWPOS)lParam;
    1122         WPARAM     wp   = SIZE_RESTORED;
    1123 
    1124         if (!(wpos->flags & SWP_NOCLIENTMOVE))
    1125             SendMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
    1126 
    1127         if (!(wpos->flags & SWP_NOCLIENTSIZE))
    1128         {
    1129             if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
    1130             else if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
    1131 
    1132            SendMessageA(WM_SIZE, wp, MAKELONG(rectClient.right  - rectClient.left,
    1133                                               rectClient.bottom - rectClient.top));
    1134         }
    1135         return 0;
    1136     }
    1137     case WM_ERASEBKGND:
    1138     case WM_ICONERASEBKGND:
    1139     {
    1140       RECT rect;
    1141 
    1142         if (!windowClass->getBackgroundBrush()) return 0;
    1143 
    1144         /*  Since WM_ERASEBKGND may receive either a window dc or a    */
    1145         /*  client dc, the area to be erased has to be retrieved from  */
    1146         /*  the device context.                                    */
    1147         GetClipBox( (HDC)wParam, &rect );
    1148 
    1149         FillRect( (HDC)wParam, &rect, windowClass->getBackgroundBrush());
    1150 
    1151         return 1;
    1152     }
    1153 
    1154     case WM_NCLBUTTONDOWN:
    1155     case WM_NCLBUTTONUP:
    1156     case WM_NCLBUTTONDBLCLK:
    1157     case WM_NCRBUTTONUP:
    1158     case WM_NCRBUTTONDOWN:
    1159     case WM_NCRBUTTONDBLCLK:
    1160     case WM_NCMBUTTONDOWN:
    1161     case WM_NCMBUTTONUP:
    1162     case WM_NCMBUTTONDBLCLK:
    1163         return 0;           //TODO: Send WM_SYSCOMMAND if required
    1164 
    1165     case WM_NCHITTEST: //TODO: Calculate position of
    1166         return HTCLIENT;
    1167 
    1168     default:
    1169         return 1;
    1170     }
    1171 }
    1172 //******************************************************************************
    1173 //******************************************************************************
    1174 LRESULT Win32Window::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
    1175 {
    1176     switch(Msg)
    1177     {
    1178     case WM_GETTEXTLENGTH:
    1179         return wndNameLength;
    1180 
    1181     case WM_GETTEXT:   //TODO: SS_ICON controls
    1182         lstrcpynW((LPWSTR)lParam, windowNameW, wParam);
    1183         return min(wndNameLength, wParam);
    1184 
    1185     default:
    1186         return DefWindowProcA(Msg, wParam, lParam);
    1187     }
    1188 }
    1189 //******************************************************************************
    1190 //******************************************************************************
    1191 LRESULT Win32Window::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
    1192 {
    1193   if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
    1194         dprintf(("SendMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
    1195 
    1196   if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
    1197         return(0);
    1198   }
    1199   switch(Msg)
    1200   {
    1201         case WM_CREATE:
    1202         {
    1203                 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
    1204                         dprintf(("WM_NCCREATE returned FALSE\n"));
    1205                         return(-1); //don't create window
    1206                 }
    1207                 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
    1208                         dprintf(("WM_CREATE returned -1\n"));
    1209                         return(-1); //don't create window
    1210                 }
    1211                 NotifyParent(Msg, wParam, lParam);
    1212 
    1213                 return(0);
    1214         }
    1215         case WM_SETTEXT: //TODO: Nothing happens if passed to DefWindowProc
    1216                 return win32wndproc(getWindowHandle(), WM_SETTEXT, wParam, lParam);
    1217 
    1218         case WM_LBUTTONDOWN:
    1219         case WM_MBUTTONDOWN:
    1220         case WM_RBUTTONDOWN:
    1221                 NotifyParent(Msg, wParam, lParam);
    1222                 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
    1223 
    1224         case WM_DESTROY:
    1225                 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
    1226                 NotifyParent(Msg, wParam, lParam);
    1227                 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
    1228         default:
    1229                 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
    1230   }
    1231 }
    1232 //******************************************************************************
    1233 //******************************************************************************
    1234 LRESULT Win32Window::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
    1235 {
    1236   if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
    1237         dprintf(("SendMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
    1238 
    1239   if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
    1240         return(0);
    1241   }
    1242   switch(Msg)
    1243   {
    1244         case WM_CREATE:
    1245         {
    1246                 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
    1247                         dprintf(("WM_NCCREATE returned FALSE\n"));
    1248                         return(0); //don't create window
    1249                 }
    1250                 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
    1251                         dprintf(("WM_CREATE returned FALSE\n"));
    1252                         return(0); //don't create window
    1253                 }
    1254                 NotifyParent(Msg, wParam, lParam);
    1255 
    1256                 return(1);
    1257         }
    1258         case WM_SETTEXT: //TODO: Nothing happens if passed to DefWindowProc
    1259                 return win32wndproc(getWindowHandle(), WM_SETTEXT, wParam, lParam);
    1260 
    1261         case WM_LBUTTONDOWN:
    1262         case WM_MBUTTONDOWN:
    1263         case WM_RBUTTONDOWN:
    1264                 NotifyParent(Msg, wParam, lParam);
    1265                 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
    1266 
    1267         case WM_DESTROY:
    1268                 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
    1269                 NotifyParent(Msg, wParam, lParam);
    1270                 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
    1271 
    1272         default:
    1273                 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
    1274   }
    1275 }
    1276 //******************************************************************************
    1277 //Called as a result of an OS/2 message
    1278 //******************************************************************************
    1279 LRESULT Win32Window::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
    1280 {
    1281   if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
    1282         dprintf(("SendInternalMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
    1283 
    1284   if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
    1285         return(0);
    1286   }
    1287   switch(Msg)
    1288   {
    1289         case WM_CREATE:
    1290         {
    1291                 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
    1292                         dprintf(("WM_NCCREATE returned FALSE\n"));
    1293                         return(0); //don't create window
    1294                 }
    1295                 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
    1296                         dprintf(("WM_CREATE returned FALSE\n"));
    1297                         return(0); //don't create window
    1298                 }
    1299                 NotifyParent(Msg, wParam, lParam);
    1300 
    1301                 return(1);
    1302         }
    1303         case WM_LBUTTONDOWN:
    1304         case WM_MBUTTONDOWN:
    1305         case WM_RBUTTONDOWN:
    1306                 NotifyParent(Msg, wParam, lParam);
    1307                 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
    1308 
    1309         case WM_DESTROY:
    1310                 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
    1311                 NotifyParent(Msg, wParam, lParam);
    1312                 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
    1313         default:
    1314                 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
    1315   }
    1316 }
    1317 //******************************************************************************
    1318 //Called as a result of an OS/2 message
    1319 //todo, unicode msgs (WM_SETTEXT etc)
    1320 //******************************************************************************
    1321 LRESULT Win32Window::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
    1322 {
    1323   if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
    1324         dprintf(("SendInternalMessageW %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
    1325 
    1326   if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
    1327         return(0);
    1328   }
    1329   switch(Msg)
    1330   {
    1331         case WM_CREATE:
    1332         {
    1333                 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
    1334                         dprintf(("WM_NCCREATE returned FALSE\n"));
    1335                         return(0); //don't create window
    1336                 }
    1337                 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
    1338                         dprintf(("WM_CREATE returned FALSE\n"));
    1339                         return(0); //don't create window
    1340                 }
    1341                 NotifyParent(Msg, wParam, lParam);
    1342 
    1343                 return(1);
    1344         }
    1345         case WM_LBUTTONDOWN:
    1346         case WM_MBUTTONDOWN:
    1347         case WM_RBUTTONDOWN:
    1348                 NotifyParent(Msg, wParam, lParam);
    1349                 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
    1350 
    1351         case WM_DESTROY:
    1352                 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
    1353                 NotifyParent(Msg, wParam, lParam);
    1354                 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
    1355         default:
    1356                 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
    1357   }
    1358 }
    1359 //******************************************************************************
    1360 //******************************************************************************
    1361 BOOL Win32Window::PostMessageA(ULONG msg, WPARAM wParam, LPARAM lParam)
    1362 {
    1363   return OSLibPostMessage(OS2Hwnd, WIN32APP_USERMSGBASE+msg, wParam, lParam);
    1364 }
    1365 //******************************************************************************
    1366 //******************************************************************************
    1367 BOOL Win32Window::PostMessageW(ULONG msg, WPARAM wParam, LPARAM lParam)
    1368 {
    1369   return OSLibPostMessage(OS2Hwnd, WIN32APP_USERMSGBASE+msg, wParam, lParam);
    1370 }
    1371 //******************************************************************************
    1372 //TODO: do we need to inform the parent of the parent (etc) of the child window?
    1373 //******************************************************************************
    1374 void Win32Window::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
    1375 {
    1376  Win32Window *window = this;
    1377  Win32Window *parentwindow;
    1378 
    1379    while(window)
    1380    {
    1381         if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
    1382         {
    1383                 /* Notify the parent window only */
    1384                 parentwindow = window->getParent();
    1385                 if(parentwindow) {
    1386                         if(Msg == WM_CREATE || Msg == WM_DESTROY) {
    1387                                 parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), (LPARAM)window->getWindowHandle());
    1388                         }
    1389                         else    parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), lParam );
    1390                 }
    1391         }
    1392         else    break;
    1393 
    1394         window = parentwindow;
    1395    }
    1396 }
    1397 //******************************************************************************
    1398 //******************************************************************************
    1399 BOOL Win32Window::SetMenu(HMENU hMenu)
    1400 {
    1401  PVOID          menutemplate;
    1402  Win32Resource *winres = (Win32Resource *)hMenu;
    1403 
    1404     dprintf(("SetMenu %x", hMenu));
    1405     if(HIWORD(winres) == 0) {
    1406         dprintf(("Win32Window:: Win32Resource *winres == 0"));
    1407         SetLastError(ERROR_INVALID_PARAMETER);
    1408         return FALSE;
    1409     }
    1410     menutemplate = winres->lockOS2Resource();
    1411     if(menutemplate == NULL)
    1412     {
    1413         dprintf(("Win32Window::SetMenu menutemplate == 0"));
    1414         return FALSE;
    1415     }
    1416     OS2HwndMenu = OSLibWinCreateMenu(OS2HwndFrame, menutemplate);
    1417     if(OS2HwndMenu == 0) {
    1418         dprintf(("Win32Window::SetMenu OS2HwndMenu == 0"));
    1419         return FALSE;
    1420     }
    1421     menuResource = winres;
    1422     return TRUE;
    1423 }
    1424 //******************************************************************************
    1425 //******************************************************************************
    1426 BOOL Win32Window::SetAccelTable(HACCEL hAccel)
    1427 {
    1428  Win32Resource *winres = (Win32Resource *)hAccel;
    1429  HANDLE         accelhandle;
    1430 
    1431     if(HIWORD(hAccel) == 0) {
    1432         dprintf(("SetAccelTable: hAccel %x invalid", hAccel));
    1433         SetLastError(ERROR_INVALID_PARAMETER);
    1434         return FALSE;
    1435     }
    1436     acceltableResource = winres;
    1437     accelhandle = OSLibWinSetAccelTable(OS2HwndFrame, winres->getOS2Handle(), winres->lockOS2Resource());
    1438     winres->setOS2Handle(accelhandle);
    1439     return(accelhandle != 0);
    1440 }
    1441 //******************************************************************************
    1442 //******************************************************************************
    1443 BOOL Win32Window::SetIcon(HICON hIcon)
    1444 {
    1445     dprintf(("Win32Window::SetIcon %x", hIcon));
    1446     return OSLibWinSetIcon(OS2HwndFrame, hIcon);
    1447 }
    1448 //******************************************************************************
    1449 //******************************************************************************
    1450 BOOL Win32Window::ShowWindow(ULONG nCmdShow)
    1451 {
    1452  ULONG showstate = 0;
    1453 
    1454     dprintf(("ShowWindow %x", nCmdShow));
    1455     if(fFirstShow) {
    1456         if(isFrameWindow() && IS_OVERLAPPED(getStyle())) {
    1457                 SendMessageA(WM_SIZE, SIZE_RESTORED,
    1458                                 MAKELONG(rectClient.right-rectClient.left,
    1459                                          rectClient.bottom-rectClient.top));
    1460                 SendMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
    1461 
    1462         }
    1463         fFirstShow = FALSE;
    1464     }
    1465     switch(nCmdShow)
    1466     {
    1467     case SW_SHOW:
    1468     case SW_SHOWDEFAULT: //todo
    1469         showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
    1470         break;
    1471     case SW_HIDE:
    1472         showstate = SWPOS_HIDE;
    1473         break;
    1474     case SW_RESTORE:
    1475         showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
    1476         break;
    1477     case SW_MINIMIZE:
    1478         showstate = SWPOS_MINIMIZE;
    1479         break;
    1480     case SW_SHOWMAXIMIZED:
    1481         showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
    1482         break;
    1483     case SW_SHOWMINIMIZED:
    1484         showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
    1485         break;
    1486     case SW_SHOWMINNOACTIVE:
    1487         showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
    1488         break;
    1489     case SW_SHOWNA:
    1490         showstate = SWPOS_SHOW;
    1491         break;
    1492     case SW_SHOWNOACTIVATE:
    1493         showstate = SWPOS_SHOW;
    1494         break;
    1495     case SW_SHOWNORMAL:
    1496         showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
    1497         break;
    1498     }
    1499     return OSLibWinShowWindow(OS2HwndFrame, showstate);
    1500 }
    1501 //******************************************************************************
    1502 //******************************************************************************
    1503 BOOL Win32Window::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
    1504 {
    1505    BOOL rc = FALSE;
    1506    Win32Window *window;
    1507    HWND hParent = 0;
    1508 
    1509    dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
    1510 
    1511    /* Validate the flags passed in ...                   */
    1512    if ( fuFlags &
    1513         ~(SWP_NOSIZE     | SWP_NOMOVE     | SWP_NOZORDER     |
    1514           SWP_NOREDRAW   | SWP_NOACTIVATE | SWP_FRAMECHANGED |
    1515           SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS   |
    1516           SWP_NOOWNERZORDER) )
    1517    {
    1518       return FALSE;
    1519    }
    1520 
    1521    WINDOWPOS wpos;
    1522    SWP swp, swpOld;
    1523 
    1524    //****************************
    1525    // Set up with Windows values.
    1526    //****************************
    1527    wpos.flags            = fuFlags;
    1528    wpos.cy               = cy;
    1529    wpos.cx               = cx;
    1530    wpos.x                = x;
    1531    wpos.y                = y;
    1532    wpos.hwndInsertAfter  = hwndInsertAfter;
    1533    wpos.hwnd             = getWindowHandle();
    1534 
    1535    //**********************************************
    1536    // Convert from Windows to PM coords and flags.
    1537    //**********************************************
    1538    if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE)) {
    1539        if (isChild())
    1540        {
    1541            hParent = getParent()->getOS2WindowHandle();
    1542            OSLibWinQueryWindowPos(OS2Hwnd, &swpOld);
    1543        } else
    1544            OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
    1545    }
    1546    OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
    1547 
    1548    /* MapSWP can clear the SWP_MOVE and SWP_SIZE flags if the window is not
    1549     * being moved or sized.  If these were the only operations to be done
    1550     * and they have been cleared, return now.
    1551     */
    1552    if (swp.fl == 0)
    1553       return TRUE;
    1554 
    1555    //*********************************************************************
    1556    //On Windows, a WM_GETMINMAXINFO is made to the app from within this API.
    1557    //We'll send a WM_QUERYTRACKINFO which is translated into a WM_GETMINMAXINFO
    1558    //and passed on to the app. Compare the values returned with the SWP cx and
    1559    //cy values.  They cannot be bigger than the max nor smaller than the min.
    1560    //*********************************************************************
    1561 
    1562    if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
    1563    {
    1564       Win32Window *wndBehind = Win32Window::GetWindowFromHandle(swp.hwndInsertBehind);
    1565       swp.hwndInsertBehind   = wndBehind->getOS2WindowHandle();
    1566    }
    1567    if (isFrameWindow())
    1568    {
    1569       POINT maxSize, maxPos, minTrack, maxTrack;
    1570 
    1571       GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
    1572 
    1573       if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
    1574       if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
    1575       if (swp.cx < minTrack.x) swp.cx = minTrack.x;
    1576       if (swp.cy < minTrack.y) swp.cy = minTrack.y;
    1577       swp.hwnd = OS2HwndFrame;
    1578    } else
    1579       swp.hwnd = OS2Hwnd;
    1580    dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
    1581 
    1582    //*****************************************************************************
    1583    // Squibble the window.  (WinSetMultWindowPos is faster than WinSetWindowPos.)
    1584    //*****************************************************************************
    1585    rc = OSLibWinSetMultWindowPos(&swp, 1);
    1586 
    1587    if (rc == FALSE)
    1588    {
    1589 //      SET_ERROR_LAST();
    1590    }
    1591    else
    1592    {
    1593       /* To implement support for SWP_FRAMECHANGED_W correctly, we would need
    1594       ** to send a WM_NCCALCSIZE message. This means DAX would have to support
    1595       ** the WM_NCCALCSIZE message. I don't think DAX can support this
    1596       ** message because it is tightly bound with the architecture of
    1597       ** overlapped windows (the "just one window" architecture). However,
    1598       ** we *can* support the SWP_FRAMECHANGED flag by sending the window
    1599       ** a WM_UPDATEFRAME, which will provide the behavior of WM_NCCALCSIZE.
    1600       */
    1601 //      if (fuFlags & SWP_FRAMECHANGED_W)
    1602 //         WinSendMsg(hWindow, WM_UPDATEFRAME, (MPARAM)-1, 0);
    1603    }
    1604 
    1605    return (rc);
    1606 }
    1607 //******************************************************************************
    1608 //Also destroys all the child windows (destroy parent, destroy children)
    1609 //******************************************************************************
    1610 BOOL Win32Window::DestroyWindow()
    1611 {
    1612   return OSLibWinDestroyWindow(OS2HwndFrame);
    1613 }
    1614 //******************************************************************************
    1615 //******************************************************************************
    1616 HWND Win32Window::GetParent()
    1617 {
    1618   if(getParent()) {
    1619     return getParent()->getWindowHandle();
    1620   }
    1621   else  return 0;
    1622 }
    1623 //******************************************************************************
    1624 //******************************************************************************
    1625 HWND Win32Window::SetParent(HWND hwndNewParent)
    1626 {
    1627  HWND oldhwnd;
    1628  Win32Window *newparent;
    1629 
    1630    if(getParent()) {
    1631         oldhwnd = getParent()->getWindowHandle();
    1632    }
    1633    else oldhwnd = 0;
    1634 
    1635    if(hwndNewParent == 0) {//desktop window = parent
    1636     setParent(NULL);
    1637         OSLibWinSetParent(getOS2WindowHandle(), OSLIB_HWND_DESKTOP);
    1638         return oldhwnd;
    1639    }
    1640    newparent = GetWindowFromHandle(hwndNewParent);
    1641    if(newparent)
    1642    {
    1643         setParent(newparent);
    1644         OSLibWinSetParent(getOS2WindowHandle(), getParent()->getOS2WindowHandle());
    1645         return oldhwnd;
    1646    }
    1647    SetLastError(ERROR_INVALID_PARAMETER);
    1648    return 0;
    1649 }
    1650 //******************************************************************************
    1651 //******************************************************************************
    1652 BOOL Win32Window::IsChild(HWND hwndParent)
    1653 {
    1654   if(getParent()) {
    1655     return getParent()->getWindowHandle() == hwndParent;
    1656   }
    1657   else  return 0;
    1658 }
    1659 //******************************************************************************
    1660 //******************************************************************************
    1661 HWND Win32Window::GetTopWindow()
    1662 {
    1663   return GetWindow(GW_CHILD);
    1664 }
    1665 //******************************************************************************
    1666 //Don't call WinUpdateWindow as that one also updates the child windows
    1667 //Also need to send WM_PAINT directly to the window procedure, which doesn't
    1668 //always happen with WinUpdateWindow (could be posted if thread doesn't own window)
    1669 //******************************************************************************
    1670 BOOL Win32Window::UpdateWindow()
    1671 {
    1672  RECT rect;
    1673 
    1674     if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
    1675     {//update region not empty
    1676         HDC hdc;
    1677 
    1678         hdc = O32_GetDC(OS2Hwnd);
    1679         if (isIcon)
    1680         {
    1681             SendInternalMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
    1682             SendInternalMessageA(WM_PAINTICON, 0, 0);
    1683         } else
    1684         {
    1685             SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
    1686             SendInternalMessageA(WM_PAINT, 0, 0);
    1687         }
    1688         O32_ReleaseDC(OS2Hwnd, hdc);
    1689     }
    1690     return TRUE;
    1691 }
    1692 //******************************************************************************
    1693 //******************************************************************************
    1694 BOOL Win32Window::IsIconic()
    1695 {
    1696     return OSLibWinIsIconic(OS2Hwnd);
    1697 }
    1698 //******************************************************************************
    1699 //TODO:
    1700 //We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
    1701 //the current process owns them.
    1702 //******************************************************************************
    1703 HWND Win32Window::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
    1704                                BOOL fUnicode)
    1705 {
    1706  Win32Window *parent = GetWindowFromHandle(hwndParent);
    1707  Win32Window *child  = GetWindowFromHandle(hwndChildAfter);
    1708 
    1709     if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
    1710        (hwndChildAfter != 0 && !child) ||
    1711        (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
    1712     {
    1713         dprintf(("Win32Window::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
    1714         SetLastError(ERROR_INVALID_WINDOW_HANDLE);
    1715         return 0;
    1716     }
    1717     if(hwndParent != OSLIB_HWND_DESKTOP)
    1718     {//if the current process owns the window, just do a quick search
    1719         child = (Win32Window *)parent->GetFirstChild();
    1720         if(hwndChildAfter != 0)
    1721         {
    1722             while(child)
    1723             {
    1724                 if(child->getWindowHandle() == hwndChildAfter)
    1725                 {
    1726                     child = (Win32Window *)child->GetNextChild();
    1727                     break;
    1728                 }
    1729                 child = (Win32Window *)child->GetNextChild();
    1730             }
    1731         }
    1732         while(child)
    1733         {
    1734             if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
    1735                (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
    1736             {
    1737                 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
    1738                 return child->getWindowHandle();
    1739             }
    1740             child = (Win32Window *)child->GetNextChild();
    1741         }
    1742     }
    1743     else {
    1744         Win32Window *wnd;
    1745         HWND henum, hwnd;
    1746 
    1747         henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
    1748         hwnd = OSLibWinGetNextWindow(henum);
    1749 
    1750         while(hwnd)
    1751         {
    1752             wnd = GetWindowFromOS2Handle(hwnd);
    1753             if(wnd == NULL) {
    1754                 hwnd = OSLibWinQueryClientWindow(hwnd);
    1755                 if(hwnd)  wnd = GetWindowFromOS2Handle(hwnd);
    1756             }
    1757 
    1758             if(wnd) {
    1759                 LPVOID sharedmembase = (LPVOID)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_SHAREDMEM);
    1760 
    1761                 if(OSLibDosGetSharedMem(sharedmembase, MAX_HEAPSIZE, OSLIB_PAG_READ) != 0) {
    1762                     dprintf(("OSLibDosGetSharedMem returned error for %x", wnd));
    1763                     break;
    1764                 }
    1765                 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
    1766                    (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
    1767                 {
    1768                     OSLibWinEndEnumWindows(henum);
    1769                     dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
    1770                     return wnd->getWindowHandle();
    1771                 }
    1772             }
    1773             hwnd = OSLibWinGetNextWindow(henum);
    1774         }
    1775         OSLibWinEndEnumWindows(henum);
    1776     }
    1777     SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
    1778     return 0;
    1779 }
    1780 //******************************************************************************
    1781 //TODO: not complete nor correct (distinction be    tween top-level, top-most & child windows)
    1782 //******************************************************************************
    1783 HWND Win32Window::GetWindow(UINT uCmd)
    1784 {
    1785  Win32Window  *win32wnd;
    1786  ULONG         magic;
    1787  ULONG         getcmd = 0;
    1788  HWND          hwndRelated;
    1789 
    1790     dprintf(("GetWindow %x %d NOT COMPLETE", getWindowHandle(), uCmd));
    1791     switch(uCmd)
    1792     {
    1793         case GW_CHILD:
    1794             getcmd = QWOS_TOP;
    1795             break;
    1796         case GW_HWNDFIRST:
    1797             if(getParent()) {
    1798                     getcmd = QWOS_TOP; //top of child windows
    1799             }
    1800             else    getcmd = QWOS_TOP; //TODO
    1801             break;
    1802         case GW_HWNDLAST:
    1803             if(getParent()) {
    1804                     getcmd = QWOS_BOTTOM; //bottom of child windows
    1805             }
    1806             else    getcmd = QWOS_BOTTOM; //TODO
    1807             break;
    1808         case GW_HWNDNEXT:
    1809             getcmd = QWOS_NEXT;
    1810             break;
    1811         case GW_HWNDPREV:
    1812             getcmd = QWOS_PREV;
    1813             break;
    1814         case GW_OWNER:
    1815             if(owner) {
    1816                     return owner->getWindowHandle();
    1817             }
    1818             else    return 0;
    1819     }
    1820     hwndRelated = OSLibWinQueryWindow(OS2Hwnd, getcmd);
    1821     if(hwndRelated)
    1822     {
    1823         win32wnd = (Win32Window *)OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32WNDPTR);
    1824         magic    = OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32PM_MAGIC);
    1825         if(CheckMagicDword(magic) && win32wnd)
    1826         {
    1827             return win32wnd->getWindowHandle();
    1828         }
    1829     }
    1830     return 0;
    1831 }
    1832 //******************************************************************************
    1833 //******************************************************************************
    1834 HWND Win32Window::SetActiveWindow()
    1835 {
    1836   return OSLibWinSetActiveWindow(OS2Hwnd);
    1837 }
    1838 //******************************************************************************
    1839 //WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
    1840 //******************************************************************************
    1841 BOOL Win32Window::EnableWindow(BOOL fEnable)
    1842 {
    1843   return OSLibWinEnableWindow(OS2Hwnd, fEnable);
    1844 }
    1845 //******************************************************************************
    1846 //******************************************************************************
    1847 BOOL Win32Window::CloseWindow()
    1848 {
    1849   return OSLibWinMinimizeWindow(OS2Hwnd);
    1850 }
    1851 //******************************************************************************
    1852 //******************************************************************************
    1853 HWND Win32Window::GetActiveWindow()
    1854 {
    1855  HWND          hwndActive;
    1856  Win32Window  *win32wnd;
    1857  ULONG         magic;
    1858 
    1859   hwndActive = OSLibWinQueryActiveWindow();
    1860 
    1861   win32wnd = (Win32Window *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
    1862   magic    = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
    1863   if(CheckMagicDword(magic) && win32wnd)
    1864   {
    1865     return win32wnd->getWindowHandle();
    1866   }
    1867   return hwndActive;
    1868 }
    1869 //******************************************************************************
    1870 //******************************************************************************
    1871 BOOL Win32Window::IsWindow()
    1872 {
    1873   return TRUE;
    1874 }
    1875 //******************************************************************************
    1876 //******************************************************************************
    1877 BOOL Win32Window::IsWindowEnabled()
    1878 {
    1879     return OSLibWinIsWindowEnabled(OS2Hwnd);
    1880 }
    1881 //******************************************************************************
    1882 //******************************************************************************
    1883 BOOL Win32Window::IsWindowVisible()
    1884 {
    1885     return OSLibWinIsWindowVisible(OS2Hwnd);
    1886 }
    1887 //******************************************************************************
    1888 //******************************************************************************
    1889 BOOL Win32Window::GetWindowRect(PRECT pRect)
    1890 {
    1891     return OSLibWinQueryWindowRect(OS2Hwnd, pRect, RELATIVE_TO_SCREEN);
    1892 }
    1893 //******************************************************************************
    1894 //******************************************************************************
    1895 BOOL Win32Window::hasWindowName(LPSTR wndname, BOOL fUnicode)
    1896 {
    1897     if(fUnicode) {
    1898             return (lstrcmpW(windowNameW, (LPWSTR)wndname) == 0);
    1899     }
    1900     else    return (strcmp(windowNameA, wndname) == 0);
    1901 }
    1902 //******************************************************************************
    1903 //******************************************************************************
    1904 int Win32Window::GetWindowTextLengthA()
    1905 {
    1906     return OSLibWinQueryWindowTextLength(OS2Hwnd);
    1907 }
    1908 //******************************************************************************
    1909 //******************************************************************************
    1910 int Win32Window::GetWindowTextA(LPSTR lpsz, int cch)
    1911 {
    1912     return OSLibWinQueryWindowText(OS2Hwnd, cch, lpsz);
    1913 }
    1914 //******************************************************************************
    1915 //******************************************************************************
    1916 BOOL Win32Window::SetWindowText(LPSTR lpsz)
    1917 {
    1918     if(lpsz == NULL)
    1919         return FALSE;
    1920 
    1921     if(isUnicode == FALSE) {
    1922         windowNameA = (LPSTR)_smalloc(strlen(lpsz)+1);
    1923         strcpy(windowNameA, lpsz);
    1924         windowNameW = (LPWSTR)_smalloc((strlen(lpsz)+1)*sizeof(WCHAR));
    1925         lstrcpyAtoW(windowNameW, windowNameA);
    1926     }
    1927     else {
    1928         windowNameW = (LPWSTR)_smalloc((lstrlenW((LPWSTR)lpsz)+1)*sizeof(WCHAR));
    1929         lstrcpyW(windowNameW, (LPWSTR)lpsz);
    1930         windowNameA = (LPSTR)_smalloc(lstrlenW((LPWSTR)lpsz)+1);
    1931         lstrcpyWtoA(windowNameA, windowNameW);
    1932     }
    1933     wndNameLength = strlen(windowNameA)+1; //including 0 terminator
    1934 
    1935     if(OS2Hwnd)
    1936         return OSLibWinSetWindowText(OS2Hwnd, (LPSTR)windowNameA);
    1937 
    1938     return TRUE;
    1939 }
    1940 //******************************************************************************
    1941 //******************************************************************************
    1942 LONG Win32Window::SetWindowLongA(int index, ULONG value)
    1943 {
    1944  LONG oldval;
    1945 
    1946    switch(index) {
    1947         case GWL_EXSTYLE:
    1948                 oldval = dwExStyle;
    1949                 dwExStyle = value;
    1950                 return oldval;
    1951         case GWL_STYLE:
    1952                 oldval = dwStyle;
    1953                 dwStyle = value;
    1954                 return oldval;
    1955         case GWL_WNDPROC:
    1956                 oldval = (LONG)getWindowProc();
    1957                 setWindowProc((WNDPROC)value);
    1958                 return oldval;
    1959         case GWL_HINSTANCE:
    1960                 oldval = hInstance;
    1961                 hInstance = value;
    1962                 return oldval;
    1963         case GWL_HWNDPARENT:
    1964                 return SetParent((HWND)value);
    1965 
    1966         case GWL_ID:
    1967                 oldval = getWindowId();
    1968                 setWindowId(value);
    1969                 return oldval;
    1970         case GWL_USERDATA:
    1971                 oldval = userData;
    1972                 userData = value;
    1973                 return oldval;
    1974         default:
    1975                 if(index >= 0 && index/4 < nrUserWindowLong)
    1976                 {
    1977                         oldval = userWindowLong[index/4];
    1978                         userWindowLong[index/4] = value;
    1979                         return oldval;
    1980                 }
    1981                 SetLastError(ERROR_INVALID_PARAMETER);
    1982                 return 0;
    1983    }
    1984 }
    1985 //******************************************************************************
    1986 //******************************************************************************
    1987 ULONG Win32Window::GetWindowLongA(int index)
    1988 {
    1989    switch(index) {
    1990         case GWL_EXSTYLE:
    1991                 return dwExStyle;
    1992         case GWL_STYLE:
    1993                 return dwStyle;
    1994         case GWL_WNDPROC:
    1995                 return (ULONG)getWindowProc();
    1996         case GWL_HINSTANCE:
    1997                 return hInstance;
    1998         case GWL_HWNDPARENT:
    1999                 if(getParent()) {
    2000                         return getParent()->getWindowHandle();
    2001                 }
    2002                 else    return 0;
    2003         case GWL_ID:
    2004                 return getWindowId();
    2005         case GWL_USERDATA:
    2006                 return userData;
    2007         default:
    2008                 if(index >= 0 && index/4 < nrUserWindowLong)
    2009                 {
    2010                         return userWindowLong[index/4];
    2011                 }
    2012                 SetLastError(ERROR_INVALID_PARAMETER);
    2013                 return 0;
    2014    }
    2015 }
    2016 //******************************************************************************
    2017 //******************************************************************************
    2018 WORD Win32Window::SetWindowWord(int index, WORD value)
    2019 {
    2020  WORD oldval;
    2021 
    2022    if(index >= 0 && index/4 < nrUserWindowLong)
    2023    {
    2024         oldval = ((WORD *)userWindowLong)[index/2];
    2025         ((WORD *)userWindowLong)[index/2] = value;
    2026         return oldval;
    2027    }
    2028    SetLastError(ERROR_INVALID_PARAMETER);
    2029    return 0;
    2030 }
    2031 //******************************************************************************
    2032 //******************************************************************************
    2033 WORD Win32Window::GetWindowWord(int index)
    2034 {
    2035    if(index >= 0 && index/4 < nrUserWindowLong)
    2036    {
    2037         return ((WORD *)userWindowLong)[index/2];
    2038    }
    2039    SetLastError(ERROR_INVALID_PARAMETER);
    2040    return 0;
    2041 }
    2042 //******************************************************************************
    2043 //******************************************************************************
    2044 Win32Window *Win32Window::GetWindowFromHandle(HWND hwnd)
    2045 {
    2046  Win32Window *window;
    2047 
    2048    if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
    2049         return window;
    2050    }
    2051    else return NULL;
    2052 }
    2053 //******************************************************************************
    2054 //******************************************************************************
    2055 Win32Window *Win32Window::GetWindowFromOS2Handle(HWND hwnd)
    2056 {
    2057  Win32Window *win32wnd;
    2058  DWORD        magic;
    2059 
    2060   win32wnd = (Win32Window *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
    2061   magic    = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
    2062 
    2063   if(win32wnd && CheckMagicDword(magic)) {
    2064         return win32wnd;
    2065   }
    2066   return 0;
    2067 }
    2068 //******************************************************************************
    2069 //******************************************************************************
    2070 GenericObject *Win32Window::windows  = NULL;
Note: See TracChangeset for help on using the changeset viewer.