]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/window.cpp
Merged some STC fixes over to the main branch
[wxWidgets.git] / src / os2 / window.cpp
index 5120d55fa2c65eb3b04ce9ca3fcfbd3786852a4a..7a31cfbbda2395e5d5fb447e0979700241c59efd 100644 (file)
     #include <stdio.h>
 #endif
 
+#define DEBUG_PRINTF(NAME)   { static int raz=0; \
+  printf( #NAME " %i\n",raz); fflush(stdout);       \
+   raz++;                                        \
+ }
+
 #if     wxUSE_OWNER_DRAWN
     #include "wx/ownerdrw.h"
 #endif
@@ -99,8 +104,8 @@ QMSG                      s_currentMsg;
 
 wxMenu*                   wxCurrentPopupMenu = NULL;
 extern wxList WXDLLEXPORT wxPendingDelete;
-#if defined(__VISAGECPP__) && (__IBMCPP__ < 400)
-extern wxChar*            wxCanvasClassName;
+#if !defined(__VISAGECPP__) || (__IBMCPP__ < 400)
+extern wxChar             wxCanvasClassName[];
 #endif
 wxList*                   wxWinHandleList = NULL;
 
@@ -111,11 +116,11 @@ wxList*                   wxWinHandleList = NULL;
 //
 // the window proc for all our windows; most gui's have something similar
 //
-MRESULT wxWndProc( HWND hWnd
-                  ,ULONG message
-                  ,MPARAM mp1
-                  ,MPARAM mp2
-                 );
+MRESULT EXPENTRY wxWndProc( HWND hWnd
+                           ,ULONG message
+                           ,MPARAM mp1
+                           ,MPARAM mp2
+                          );
 
 #ifdef  __WXDEBUG__
     const char *wxGetMessageName(int message);
@@ -244,6 +249,9 @@ bool wxWindow::OS2Command(
 , WXWORD                            WXUNUSED(uId)
 )
 {
+
+DEBUG_PRINTF(wxWindow::OS2Command);
+
     return(FALSE);
 }
 
@@ -293,6 +301,9 @@ void wxWindow::Init()
     m_lLastMouseY = -1;
     m_nLastMouseEvent = -1;
 #endif // wxUSE_MOUSEEVENT_HACK
+
+DEBUG_PRINTF(wxWindow::Init-End);
+
 } // wxWindow::Init
 
 //
@@ -300,14 +311,18 @@ void wxWindow::Init()
 //
 wxWindow::~wxWindow()
 {
+DEBUG_PRINTF(wxWindow::~wxWindow-Start);
     m_isBeingDeleted = TRUE;
 
     OS2DetachWindowMenu();
     if (m_parent)
         m_parent->RemoveChild(this);
     DestroyChildren();
+
     if (m_hWnd)
     {
+//      UnsubclassWin();
+
         if(!::WinDestroyWindow(GetHWND()))
             wxLogLastError(wxT("DestroyWindow"));
         //
@@ -315,6 +330,7 @@ wxWindow::~wxWindow()
         //
         wxRemoveHandleAssociation(this);
     }
+DEBUG_PRINTF(wxWindow::~wxWindow-End);
 } // end of wxWindow::~wxWindow
 
 bool wxWindow::Create(
@@ -326,6 +342,8 @@ bool wxWindow::Create(
 , const wxString&                   rName
 )
 {
+    HWND                            hParent = NULLHANDLE;
+
     wxCHECK_MSG(pParent, FALSE, wxT("can't create wxWindow without parent"));
 
     if ( !CreateBase( pParent
@@ -338,54 +356,49 @@ bool wxWindow::Create(
                     ))
         return(FALSE);
 
-    pParent->AddChild(this);
+    if (pParent)
+    {
+        pParent->AddChild(this);
+        hParent = GetWinHwnd(pParent);
+    }
+    else
+       hParent = HWND_DESKTOP;
 
-    ULONG                           ulFlags = 0L;
+    ULONG                           ulCreateFlags = 0L;
 
-    //
-    // Frame windows and their derivatives only
-    //
-    if (lStyle & wxBORDER)
-        ulFlags |= FCF_BORDER;
-    if (lStyle & wxTHICK_FRAME )
-        ulFlags |= FCF_SIZEBORDER;
 
     //
-    // Some generic window styles
+    // Most wxSTYLES are really PM Class specific styles and will be
+    // set in those class create procs.  PM's basic windows styles are
+    // very limited.
     //
-    ulFlags |= WS_VISIBLE;
     if (lStyle & wxCLIP_CHILDREN )
-        ulFlags |= WS_CLIPCHILDREN;
+        ulCreateFlags |= WS_CLIPCHILDREN;
 
+    //
+    // Empty stuff for now since PM has no custome 3D effects
+    // Doesn't mean someone cannot make some up though
+    //
     bool                            bWant3D;
     WXDWORD                         dwExStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &bWant3D);
 
     //
-    // OS/2 PM doesn't have "extended" styles but if the library specifies
-    // them and we are creating a frame window then at least give it a border
+    // Generic OS/2 Windows are created with no owner, no Z Order, no Control data,
+    // and no presentation parameters
     //
-    if ( bWant3D ||
-        (m_windowStyle & wxSIMPLE_BORDER) ||
-        (m_windowStyle & wxRAISED_BORDER ) ||
-        (m_windowStyle & wxSUNKEN_BORDER) ||
-        (m_windowStyle & wxDOUBLE_BORDER)
-       )
-    {
-        ulFlags |= FCF_BORDER;
-    }
-    OS2Create( m_windowId
-              ,pParent
-              ,wxCanvasClassName
-              ,this
-              ,NULL
+    OS2Create( hParent
+              ,(PSZ)wxCanvasClassName
+              ,rName.c_str()
+              ,ulCreateFlags
               ,rPos.x
               ,rPos.y
               ,WidthDefault(rSize.x)
               ,HeightDefault(rSize.y)
-              ,ulFlags
-              ,NULL
-              ,dwExStyle
+              ,NULLHANDLE
+              ,NULLHANDLE
+              ,m_windowId
              );
+
     return(TRUE);
 } // end of wxWindow::Create
 
@@ -500,6 +513,7 @@ bool wxWindow::SetFont(
   const wxFont&                     rFont
 )
 {
+DEBUG_PRINTF(wxWindow::SetFont);
     if (!wxWindowBase::SetFont(rFont))
     {
         // nothing to do
@@ -718,28 +732,28 @@ void wxWindow::SubclassWin(
 
     wxCHECK_RET(::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in SubclassWin") );
 
-    wxAssociateWinWithHandle(hwnd, this);
+//  wxAssociateWinWithHandle(hwnd, this);
 
     m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(hwnd, (PFNWP)wxWndProc);
-    ::WinSetWindowULong(hwnd, QWS_USER, (ULONG)wxWndProc);
+//    ::WinSetWindowULong(hwnd, QWL_USER, (ULONG)wxWndProc);
 } // end of wxWindow::SubclassWin
 
 void wxWindow::UnsubclassWin()
 {
-    wxRemoveHandleAssociation(this);
+//    wxRemoveHandleAssociation(this);
 
     //
     // Restore old Window proc
     //
-    HWND                            hwnd = GetHwnd();
+    HWND                            hwnd = GetHWND();
 
-    if (hwnd)
+    if (m_hWnd)
     {
-        m_hWnd = 0;
+//        m_hWnd = 0;
 
         wxCHECK_RET( ::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in UnsubclassWin") );
 
-        PFNWP                       fnProc = (PFNWP)::WinQueryWindowULong(hwnd, QWS_USER);
+        PFNWP                       fnProc = (PFNWP)::WinQueryWindowPtr(hwnd, QWP_PFNWP);
         if ( (m_fnOldWndProc != 0) && (fnProc != (PFNWP) m_fnOldWndProc))
         {
             WinSubclassWindow(hwnd, (PFNWP)m_fnOldWndProc);
@@ -1505,10 +1519,12 @@ MRESULT wxWindow::OS2DefWindowProc(
 , WXLPARAM                          lParam
 )
 {
+DEBUG_PRINTF(wxWindow::OS2DefWindowProc);
+
     if (m_fnOldWndProc)
-        return ((MRESULT)m_fnOldWndProc());
+        return (MRESULT)m_fnOldWndProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam);
     else
-        return (::WinDefWindowProc(GetHwnd(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam));
+        return ::WinDefWindowProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam);
 } // end of wxWindow::OS2DefWindowProc
 
 bool wxWindow::OS2ProcessMessage(
@@ -1517,6 +1533,8 @@ bool wxWindow::OS2ProcessMessage(
 {
     QMSG*                           pQMsg = (QMSG*)pMsg;
 
+DEBUG_PRINTF(OS2ProcessMessage);
+
     if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
     {
         //
@@ -1678,12 +1696,12 @@ bool wxWindow::OS2ProcessMessage(
                 }
             }
         }
+        //
+        // Let Dialogs process
+        //
+        if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
+            return TRUE;
     }
-    //
-    // Let Dialogs process
-    //
-    if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
-        return TRUE;
 
 #if wxUSE_TOOLTIPS
     if ( m_tooltip )
@@ -1703,7 +1721,11 @@ bool wxWindow::OS2TranslateMessage(
   WXMSG*                            pMsg
 )
 {
-    return m_acceleratorTable.Translate(this, pMsg);
+#if wxUSE_ACCEL
+  return m_acceleratorTable.Translate(m_hWnd, pMsg);
+#else
+  return FALSE;
+#endif //wxUSE_ACCEL
 } // end of wxWindow::OS2TranslateMessage
 
 // ---------------------------------------------------------------------------
@@ -1718,9 +1740,14 @@ void wxWindow::UnpackCommand(
 , WORD*                             pCmd
 )
 {
+/*
     *pId = LOWORD(wParam);
     *phWnd = (WXHWND)lParam;
     *pCmd = HIWORD(wParam);
+*/
+    *pId = LOWORD(wParam);
+    *phWnd = NULL;  // or may be GetHWND() ?
+    *pCmd = LOWORD(lParam);
 } // end of wxWindow::UnpackCommand
 
 void wxWindow::UnpackActivate(
@@ -1773,7 +1800,7 @@ wxWindow*                           wxWndHook = NULL;
 //
 // Main window proc
 //
-MRESULT wxWndProc(
+MRESULT EXPENTRY wxWndProc(
   HWND                              hWnd
 , ULONG                             ulMsg
 , MPARAM                            wParam
@@ -1784,6 +1811,7 @@ MRESULT wxWndProc(
     // Trace all ulMsgs - useful for the debugging
     //
 #ifdef __WXDEBUG__
+DEBUG_PRINTF(__WXDEBUG__wxWndProc);
     wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
                wxGetMessageName(ulMsg), wParam, lParam);
 #endif // __WXDEBUG__
@@ -1802,7 +1830,8 @@ MRESULT wxWndProc(
         pWnd->SetHWND((WXHWND)hWnd);
     }
 
-    MRESULT                         rc;
+    MRESULT                         rc = (MRESULT)0;
+
 
     //
     // Stop right here if we don't have a valid handle in our wxWindow object.
@@ -1820,6 +1849,7 @@ MRESULT wxWndProc(
         else
             rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
     }
+
     return rc;
 } // end of wxWndProc
 
@@ -1837,22 +1867,26 @@ MRESULT wxWindow::OS2WindowProc(
     // Did we process the uMsg?
     //
     bool                            bProcessed = FALSE;
+    bool                            bAllow;
+    MRESULT                         mResult;
+    WXHICON                         hIcon;
+    WXHBRUSH                        hBrush;
 
     //
     // The return value
     //
-    union
-    {
-        bool                        bAllow;
-        MRESULT                     mResult;
-        WXHICON                     hIcon;
-        WXHBRUSH                    hBrush;
-    } vRc;
+//  union
+//  {
+//      bool                        bAllow;
+//      MRESULT                     mResult;
+//      WXHICON                     hIcon;
+//      WXHBRUSH                    hBrush;
+//  } vRc;
 
     //
     // For most messages we should return 0 when we do process the message
     //
-    vRc.mResult = (MRESULT)0;
+    mResult = (MRESULT)0;
 
     switch (uMsg)
     {
@@ -1868,14 +1902,15 @@ MRESULT wxWindow::OS2WindowProc(
                     //
                     // Return 0 to bAllow window creation
                     //
-                    vRc.mResult = (MRESULT)(bMayCreate ? 0 : -1);
+                    mResult = (MRESULT)(bMayCreate ? 0 : -1);
                 }
             }
             break;
 
         case WM_DESTROY:
-            bProcessed = HandleDestroy();
-            break;
+             HandleDestroy();
+             bProcessed = TRUE;
+             break;
 
         case WM_MOVE:
             bProcessed = HandleMove( LOWORD(lParam)
@@ -1904,6 +1939,7 @@ MRESULT wxWindow::OS2WindowProc(
                 bProcessed = HandleActivate( wState
                                             ,(WXHWND)hWnd
                                            );
+                bProcessed = FALSE;
             }
             break;
 
@@ -1915,6 +1951,7 @@ MRESULT wxWindow::OS2WindowProc(
             break;
 
         case WM_PAINT:
+DEBUG_PRINTF(WM_PAINT)
             bProcessed = HandlePaint();
             break;
 
@@ -1924,10 +1961,12 @@ MRESULT wxWindow::OS2WindowProc(
             // ourselves in ~wxWindow
             //
             bProcessed = TRUE;
-            vRc.mResult = (MRESULT)TRUE;
+            mResult = (MRESULT)TRUE;
+DEBUG_PRINTF(WM_CLOSE)
             break;
 
         case WM_SHOW:
+DEBUG_PRINTF(WM_SHOW)
             bProcessed = HandleShow(wParam != 0, (int)lParam);
             break;
 
@@ -1958,7 +1997,6 @@ MRESULT wxWindow::OS2WindowProc(
                 bProcessed = HandleMouseEvent(uMsg, x, y, (WXUINT)wParam);
             }
             break;
-
         case WM_SYSCOMMAND:
             bProcessed = HandleSysCommand(wParam, lParam);
             break;
@@ -1967,9 +2005,11 @@ MRESULT wxWindow::OS2WindowProc(
             {
                 WORD id, cmd;
                 WXHWND hwnd;
+DEBUG_PRINTF(WM_COMMAND-in)
                 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
 
                 bProcessed = HandleCommand(id, cmd, hwnd);
+DEBUG_PRINTF(WM_COMMAND-out)
             }
             break;
 
@@ -1992,14 +2032,14 @@ MRESULT wxWindow::OS2WindowProc(
                 }
 
                 if ( bProcessed )
-                    vRc.mResult = (MRESULT)TRUE;
+                    mResult = (MRESULT)TRUE;
             }
             break;
 
         case WM_QUERYDLGCODE:
             if ( m_lDlgCode )
             {
-                vRc.mResult = (MRESULT)m_lDlgCode;
+                mResult = (MRESULT)m_lDlgCode;
                 bProcessed = TRUE;
             }
             //
@@ -2098,7 +2138,7 @@ MRESULT wxWindow::OS2WindowProc(
 #if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
         case WM_CTLCOLORCHANGE:
             {
-                bProcessed = HandleCtlColor(&vRc.hBrush);
+                bProcessed = HandleCtlColor(&hBrush);
             }
             break;
 #endif
@@ -2137,7 +2177,7 @@ MRESULT wxWindow::OS2WindowProc(
                 //
                 // We processed the message, i.e. erased the background
                 //
-                vRc.mResult = (MRESULT)TRUE;
+                mResult = (MRESULT)TRUE;
             }
             break;
 
@@ -2152,18 +2192,18 @@ MRESULT wxWindow::OS2WindowProc(
             if ( bProcessed )
             {
                 // we never set focus from here
-                vRc.mResult = FALSE;
+                mResult = FALSE;
             }
             break;
 
         // wxFrame specific message
         case WM_MINMAXFRAME:
-            bProcessed = HandleGetMinMaxInfo((PSWP)lParam);
+            bProcessed = HandleGetMinMaxInfo((PSWP)wParam);
             break;
 
         case WM_SYSVALUECHANGED:
             // TODO: do something
-            vRc.mResult = (MRESULT)TRUE;
+            mResult = (MRESULT)TRUE;
             break;
 
         //
@@ -2180,7 +2220,7 @@ MRESULT wxWindow::OS2WindowProc(
                 // processing this message - exactly what we need because we've
                 // just set the cursor.
                 //
-                vRc.mResult = (MRESULT)TRUE;
+                mResult = (MRESULT)TRUE;
             }
             break;
     }
@@ -2191,9 +2231,9 @@ MRESULT wxWindow::OS2WindowProc(
         wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
                    wxGetMessageName(uMsg));
 #endif // __WXDEBUG__
-        vRc.mResult = OS2DefWindowProc(uMsg, wParam, lParam);
+        mResult = OS2DefWindowProc(uMsg, wParam, lParam);
     }
-    return vRc.mResult;
+    return mResult;
 } // end of wxWindow::OS2WindowProc
 
 //
@@ -2313,26 +2353,28 @@ void wxWindow::OS2DetachWindowMenu()
 } // end of wxWindow::OS2DetachWindowMenu
 
 bool wxWindow::OS2Create(
-  int                               vId
-, wxWindow*                         pParent
-, const wxChar*                     zWclass
-, wxWindow*                         pWxWin
+  WXHWND                            hParent
+, PSZ                               zClass
 , const wxChar*                     zTitle
-, int                               nX
-, int                               nY
-, int                               nWidth
-, int                               nHeight
 , WXDWORD                           dwStyle
-, const wxChar*                     zDialogTemplate
-, WXDWORD                           dwExtendedStyle // Port compatability only
+, long                              lX
+, long                              lY
+, long                              lWidth
+, long                              lHeight
+, WXHWND                            hOwner
+, WXHWND                            hZOrder
+, unsigned long                     ulId
+, void*                             pCtlData
+, void*                             pPresParams
 )
 {
     ERRORID                         vError;
     wxString                        sError;
-    int                             nX1      = CW_USEDEFAULT;
-    int                             nY1      = 0;
-    int                             nWidth1  = CW_USEDEFAULT;
-    int                             nHeight1 = 100;
+    long                            lX1      = 0L;
+    long                            lY1      = 0L;
+    long                            lWidth1  = 20L;
+    long                            lHeight1 = 20L;
+    int                             nControlId = 0;
 
     //
     // Find parent's size, if it exists, to set up a possible default
@@ -2341,127 +2383,63 @@ bool wxWindow::OS2Create(
     RECTL                           vParentRect;
     HWND                            hWndClient;
 
-    HWND                            hParent = (HWND)NULL;
-
-    if (pParent)
-    {
-        hParent = (HWND)pParent->GetHWND();
-        hWndClient = ::WinWindowFromID(hParent, FID_CLIENT);
-        ::WinQueryWindowRect(hWndClient, &vParentRect);
-
-        nWidth1  = vParentRect.xRight - vParentRect.xLeft;
-        nHeight1 = vParentRect.yTop - vParentRect.yBottom;
-    }
-    else
-        hParent = HWND_DESKTOP;
-
-    if (nX > -1)
-        nX1 = nX;
-    if (nY > -1)
-        nY1 = nY;
-    if (nWidth > -1)
-        nWidth1   = nWidth;
-    if (nHeight > -1)
-        nHeight1 = nHeight;
+    if (lX > -1L)
+        lX1 = lX;
+    if (lY > -1L)
+        lY1 = lY;
+    if (lWidth > -1L)
+        lWidth1 = lWidth;
+    if (lHeight > -1L)
+        lHeight1 = lHeight;
 
     wxWndHook = this;
 
-    if (zDialogTemplate)
+    //
+    // check to see if the new window is a standard control
+    //
+    if ((ULONG)zClass == (ULONG)WC_BUTTON ||
+        (ULONG)zClass == (ULONG)WC_COMBOBOX ||
+        (ULONG)zClass == (ULONG)WC_CONTAINER ||
+        (ULONG)zClass == (ULONG)WC_ENTRYFIELD ||
+        (ULONG)zClass == (ULONG)WC_FRAME ||
+        (ULONG)zClass == (ULONG)WC_LISTBOX ||
+        (ULONG)zClass == (ULONG)WC_MENU ||
+        (ULONG)zClass == (ULONG)WC_NOTEBOOK ||
+        (ULONG)zClass == (ULONG)WC_SCROLLBAR ||
+        (ULONG)zClass == (ULONG)WC_SPINBUTTON ||
+        (ULONG)zClass == (ULONG)WC_STATIC ||
+        (ULONG)zClass == (ULONG)WC_TITLEBAR ||
+        (ULONG)zClass == (ULONG)WC_VALUESET
+       )
     {
-        //
-        // We can use extended styles for custom default user config params
-        // These can be processed in the dialog proc's WM_INITDLG
-        // Dialog template is defined by vId and should be loaded from the
-        // resource file in the current .exe
-        //
-        PDLGTEMPLATE                 pDlgt;
-
-        ::DosGetResource(0L, RT_DIALOG, vId, (PPVOID)&pDlgt);
-        m_hWnd = (WXHWND)::WinCreateDlg( hParent
-                                        ,NULLHANDLE
-                                        ,(PFNWP)wxDlgProc
-                                        ,pDlgt
-                                        ,(PVOID)&dwExtendedStyle
-                                       );
-        if (m_hWnd == 0)
-        {
-            vError = ::WinGetLastError(vHabmain);
-            sError = wxPMErrorToStr(vError);
-            wxLogError("Can't find dummy dialog template!\n"
-                       "Check resource include path for finding wx.rc.\n"
-                       "Error: %s\n", sError);
-            return FALSE;
-        }
-
-        //
-        // Move the dialog to its initial position without forcing repainting
-        //
-        if (!::WinSetWindowPos( m_hWnd
-                               ,HWND_TOP
-                               ,nX1
-                               ,nY1
-                               ,nWidth1
-                               ,nHeight1
-                               ,SWP_MOVE | SWP_SIZE | SWP_NOREDRAW
-                              ));
-        {
-            vError = ::WinGetLastError(vHabmain);
-            sError = wxPMErrorToStr(vError);
-            wxLogError("MoveWindow, error: %s\n", sError);
-        }
+            nControlId = ulId;
     }
-    else
-    {
-        int                         nControlId = 0;
-        WXDWORD                     dwClass = dwStyle | 0xffff0000;
 
-        //
-        // check to see if the new window is a standard control
-        //
-        if (dwClass & (ULONG)WC_BUTTON ||
-            dwClass & (ULONG)WC_COMBOBOX ||
-            dwClass & (ULONG)WC_CONTAINER ||
-            dwClass & (ULONG)WC_ENTRYFIELD ||
-            dwClass & (ULONG)WC_LISTBOX ||
-            dwClass & (ULONG)WC_MENU ||
-            dwClass & (ULONG)WC_NOTEBOOK ||
-            dwClass & (ULONG)WC_SCROLLBAR ||
-            dwClass & (ULONG)WC_SPINBUTTON ||
-            dwClass & (ULONG)WC_STATIC ||
-            dwClass & (ULONG)WC_TITLEBAR ||
-            dwClass & (ULONG)WC_VALUESET
-           )
-            nControlId = vId;
-
-        wxString                    sClassName(zWclass);
-
-        if (GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE )
-        {
-            sClassName += wxT("NR");
-        }
-
-        m_hWnd = (WXHWND)::WinCreateWindow( hParent
-                                           ,(PSZ)sClassName.c_str()
-                                           ,zTitle ? zTitle : wxT("")
-                                           ,dwStyle
-                                           ,nX1
-                                           ,nY1
-                                           ,nWidth
-                                           ,nHeight
-                                           ,NULLHANDLE
-                                           ,HWND_TOP
-                                           ,vId
-                                           ,NULL
-                                           ,NULL
-                                          );
-        if (!m_hWnd)
-        {
-            vError = ::WinGetLastError(vHabmain);
-            sError = wxPMErrorToStr(vError);
-            wxLogError("Can't create window of class %s!. Error: %s\n", zWclass, sError);
-            return FALSE;
-        }
+    //
+    // We will either have a registered class via string name or a standard PM Class via a long
+    //
+    m_hWnd = (WXHWND)::WinCreateWindow( (HWND)hParent
+                                       ,zClass
+                                       ,(PSZ)zTitle ? zTitle : wxT("")
+                                       ,(ULONG)dwStyle
+                                       ,(LONG)lX1
+                                       ,(LONG)lY1
+                                       ,(LONG)lWidth
+                                       ,(LONG)lHeight
+                                       ,NULLHANDLE
+                                       ,HWND_TOP
+                                       ,(ULONG)ulId
+                                       ,pCtlData
+                                       ,pPresParams
+                                      );
+    if (!m_hWnd)
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+        wxLogError("Can't create window of class %s!. Error: %s\n", zClass, sError);
+        return FALSE;
     }
+    ::WinSetWindowULong(m_hWnd, QWL_USER, (ULONG) this);
     wxWndHook = NULL;
 
 #ifdef __WXDEBUG__
@@ -2481,6 +2459,12 @@ bool wxWindow::OS2Create(
     wxAssociateWinWithHandle((HWND)m_hWnd
                              ,this
                             );
+    //
+    // Now need to subclass window.
+    //
+
+    SubclassWin(GetHWND());
+
     return TRUE;
 } // end of wxWindow::OS2Create
 
@@ -2863,16 +2847,30 @@ void wxWindow::OnSysColourChanged(
 bool wxWindow::HandlePaint()
 {
     HRGN                            hRgn = NULLHANDLE;
+    wxPaintEvent                    vEvent;
+    HPS                             hPS;
+    RECTL                           vRect;
 
     if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_NULL)
     {
          wxLogLastError("CreateRectRgn");
          return FALSE;
     }
-    m_updateRegion = wxRegion(hRgn);
+    //
+    // Debug code
+    //
+#ifdef __WXDEBUG__
+    {
+        HWND                        hWnd;
+        HWND                        hWnd0 = NULLHANDLE;
 
-    wxPaintEvent                    vEvent;
+        hWnd = GetHwnd();
+        if(hWnd != hWnd0)
+            printf("HandlePaint hWnd=%x  ",hWnd);
+    }
+#endif
 
+    m_updateRegion = wxRegion(hRgn);
     vEvent.SetEventObject(this);
     return (GetEventHandler()->ProcessEvent(vEvent));
 } // end of wxWindow::HandlePaint
@@ -4012,3 +4010,45 @@ static void TranslateKbdEventToMouse(
     pWin->ScreenToClient(pX, pY);
 } // end of TranslateKbdEventToMouse
 
+// Find the wxWindow at the current mouse position, returning the mouse
+// position.
+wxWindow* wxFindWindowAtPointer(
+  wxPoint&                          rPt
+)
+{
+    return wxFindWindowAtPoint(wxGetMousePosition());
+}
+
+wxWindow* wxFindWindowAtPoint(
+  const wxPoint&                    rPt
+)
+{
+    POINTL                          vPt2;
+
+    vPt2.x = rPt.x;
+    vPt2.y = rPt.y;
+
+    HWND                            hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE);
+    wxWindow*                       pWin = wxFindWinFromHandle((WXHWND)hWndHit) ;
+    HWND                            hWnd = hWndHit;
+
+    //
+    // Try to find a window with a wxWindow associated with it
+    //
+    while (!pWin && (hWnd != 0))
+    {
+        hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
+        pWin = wxFindWinFromHandle((WXHWND)hWnd) ;
+    }
+    return pWin;
+}
+
+// Get the current mouse position.
+wxPoint wxGetMousePosition()
+{
+    POINTL                          vPt;
+
+    ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
+    return wxPoint(vPt.x, vPt.y);
+}
+