+void wxWindow::UnsubclassWin()
+{
+    HAB                             hab;
+
+    wxRemoveHandleAssociation(this);
+
+    //
+    // Restore old Window proc
+    //
+    HWND                            hwnd = GetHwnd();
+
+    if (hwnd)
+    {
+        m_hWnd = 0;
+
+        wxCHECK_RET( ::WinIsWindow(hab, hwnd), wxT("invalid HWND in UnsubclassWin") );
+
+        PFNWP                       fnProc = (PFNWP)::WinQueryWindowULong(hwnd, QWS_USER);
+        if ( (m_fnOldWndProc != 0) && (fnProc != (PFNWP) m_fnOldWndProc))
+        {
+            WinSubclassWindow(hwnd, (PFNWP)m_fnOldWndProc);
+            m_fnOldWndProc = 0;
+        }
+    }
+} // end of wxWindow::UnsubclassWin
+
+//
+// Make a Windows extended style from the given wxWindows window style
+//
+WXDWORD wxWindow::MakeExtendedStyle(
+  long                              lStyle
+, bool                              bEliminateBorders
+)
+{
+   //
+   // PM does not support extended style
+   //
+    WXDWORD                         exStyle = 0;
+    return exStyle;
+} // end of wxWindow::MakeExtendedStyle
+
+//
+// Determines whether native 3D effects or CTL3D should be used,
+// applying a default border style if required, and returning an extended
+// style to pass to CreateWindowEx.
+//
+WXDWORD wxWindow::Determine3DEffects(
+  WXDWORD                           dwDefaultBorderStyle
+, YBool*                            pbWant3D
+) const
+{
+    WXDWORD                         dwStyle = 0L; 
+   
+    //
+    // Native PM does not have any specialize 3D effects like WIN32 does
+    //
+    *pbWant3D = FALSE;
+    return dwStyle;
+} // end of wxWindow::Determine3DEffects
+
+#if WXWIN_COMPATIBILITY
+void wxWindow::OnCommand(
+  wxWindow&                         rWin
+, wxCommandEvent&                   rEvent
+)
+{
+    if (GetEventHandler()->ProcessEvent(rEvent))
+        return;
+    if (m_parent)
+        m_parent->GetEventHandler()->OnCommand( rWin
+                                               ,rEvent
+                                              );
+} // end of wxWindow::OnCommand
+
+wxObject* wxWindow::GetChild(
+  int                               nNumber
+) const
+{
+    //
+    // Return a pointer to the Nth object in the Panel
+    //
+    wxNode*                         pNode = GetChildren().First();
+    int                             n = nNumber;
+
+    while (pNode && n--)
+        pNode = pNode->Next();
+    if (pNode)
+    {
+        wxObject*                   pObj = (wxObject*)pNode->Data();
+        return(pObj);
+    }
+    else
+        return NULL;
+} // end of wxWindow::GetChild
+
+#endif // WXWIN_COMPATIBILITY
+
+//
+// Setup background and foreground colours correctly
+//
+void wxWindow::SetupColours()
+{
+    if ( GetParent() )
+        SetBackgroundColour(GetParent()->GetBackgroundColour());
+} // end of wxWindow::SetupColours
+
+void wxWindow::OnIdle(
+  wxIdleEvent&                      rEvent
+)
+{
+    //
+    // Check if we need to send a LEAVE event
+    //
+    if (m_bMouseInWindow)
+    {
+        POINTL                      vPoint;
+
+        ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
+        if (::WinWindowFromPoint(HWND_DESKTOP, &vPoint, FALSE) != (HWND)GetHwnd())
+        {
+            //
+            // Generate a LEAVE event
+            //
+            m_bMouseInWindow = FALSE;
+
+            //
+            // Unfortunately the mouse button and keyboard state may have changed
+            // by the time the OnIdle function is called, so 'state' may be
+            // meaningless.
+            //
+            int                     nState = 0;
+
+            if (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) != 0)
+                nState |= VK_SHIFT;
+            if (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) != 0;
+                nState |= VK_CTRL;
+
+            wxMouseEvent            rEvent(wxEVT_LEAVE_WINDOW);
+
+            InitMouseEvent( rEvent
+                           ,vPoint.x
+                           ,vPoint.y
+                           ,nState
+                          );
+            (void)GetEventHandler()->ProcessEvent(event);
+        }
+    }
+    UpdateWindowUI();
+} // end of wxWindow::OnIdle
+
+//
+// Set this window to be the child of 'parent'.
+//
+bool wxWindow::Reparent(
+  wxWindow*                         pParent
+)
+{
+    if (!wxWindowBase::Reparent(pParent))
+        return FALSE;
+
+    HWND                            hWndChild = GetHwnd();
+    HWND                            hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
+
+    ::WinSetParent(hWndChild, hWndParent, TRUE);
+    return TRUE;
+} // end of wxWindow::Reparent
+
+void wxWindow::Clear()
+{
+    wxClientDC                      vDc(this);
+    wxBrush                         vBrush( GetBackgroundColour()
+                                           ,wxSOLID
+                                          );
+
+    vDc.SetBackground(vBrush);
+    vDc.Clear();
+} // end of wxWindow::Clear
+
+void wxWindow::Refresh(
+  bool                              bEraseBack
+, const wxRect*                     pRect
+)
+{
+    HWND                            hWnd = GetHwnd();
+
+    if (hWnd)
+    {
+        if (pRect)
+        {
+            RECTL                   vOs2Rect;
+
+            vOs2Rect.xLeft   = pRect->x;
+            vOS2Rect.yTop    = pRect->y;
+            vOs2Rect.xRight  = pRect->x + pRect->width;
+            vOs2Rect.yBottom = pRect->y + pRect->height;
+
+            ::WinInvalidateRect(hWnd, &vOs2Rect, bEraseBack);
+        }
+        else
+            ::WinInvalidateRect(hWnd, NULL, bEraseBack);
+    }
+} // end of wxWindow::Refresh
+
+// ---------------------------------------------------------------------------
+// drag and drop
+// ---------------------------------------------------------------------------
+
+#if wxUSE_DRAG_AND_DROP
+void wxWindow::SetDropTarget(
+  wxDropTarget*                     pDropTarget
+)
+{
+    if (m_dropTarget != 0) 
+    {
+        m_dropTarget->Revoke(m_hWnd);
+        delete m_dropTarget;
+    }
+    m_dropTarget = pDropTarget;
+    if (m_dropTarget != 0)
+        m_dropTarget->Register(m_hWnd);
+} // end of wxWindow::SetDropTarget
+#endif
+
+//
+// old style file-manager drag&drop support: we retain the old-style
+// DragAcceptFiles in parallel with SetDropTarget.
+//
+void wxWindow::DragAcceptFiles(
+  bool                              bAccept
+)
+{
+    HWND                            hWnd = GetHwnd();
+
+    if (hWnd && bAccept)
+        ::DragAcceptDroppedFiles(hWnd, NULL, NULL, DO_COPY, 0L);
+} // end of wxWindow::DragAcceptFiles
+
+// ----------------------------------------------------------------------------
+// tooltips
+// ----------------------------------------------------------------------------
+
+#if wxUSE_TOOLTIPS
+
+void wxWindow::DoSetToolTip(
+  wxToolTip*                        pTooltip
+)
+{
+    wxWindowBase::DoSetToolTip(pTooltip);
+
+    if (m_pTooltip)
+        m_tooltip->SetWindow(this);
+} // end of wxWindow::DoSetToolTip
+
+#endif // wxUSE_TOOLTIPS
+
+// ---------------------------------------------------------------------------
+// moving and resizing
+// ---------------------------------------------------------------------------
+
+// Get total size
+void wxWindow::DoGetSize( int *width, int *height ) const
+{
+    HWND hWnd = GetHwnd();
+    RECT rect;
+    GetWindowRect(hWnd, &rect);
+
+    if ( x )
+        *x = rect.right - rect.left;
+    if ( y )
+        *y = rect.bottom - rect.top;
+}
+
+void wxWindow::DoGetPosition( int *x, int *y ) const
+{
+    HWND hWnd = GetHwnd();
+
+    RECT rect;
+    GetWindowRect(hWnd, &rect);
+
+    POINT point;
+    point.x = rect.left;
+    point.y = rect.top;
+
+    // we do the adjustments with respect to the parent only for the "real"
+    // children, not for the dialogs/frames
+    if ( !IsTopLevel() )
+    {
+        HWND hParentWnd = 0;
+        wxWindow *parent = GetParent();
+        if ( parent )
+            hParentWnd = GetWinHwnd(parent);
+
+        // Since we now have the absolute screen coords, if there's a parent we
+        // must subtract its top left corner
+        if ( hParentWnd )
+        {
+            ::ScreenToClient(hParentWnd, &point);
+        }
+
+        // We may be faking the client origin. So a window that's really at (0,
+        // 30) may appear (to wxWin apps) to be at (0, 0).
+        wxPoint pt(parent->GetClientAreaOrigin());
+        point.x -= pt.x;
+        point.y -= pt.y;
+    }
+
+    if ( x )
+        *x = point.x;
+    if ( y )
+        *y = point.y;
+}
+
+void wxWindow::DoScreenToClient( int *x, int *y ) const
+{
+    POINT pt;
+    if ( x )
+        pt.x = *x;
+    if ( y )
+        pt.y = *y;
+
+    HWND hWnd = GetHwnd();
+    ::ScreenToClient(hWnd, &pt);
+
+    if ( x )
+        *x = pt.x;
+    if ( y )
+        *y = pt.y;
+}
+
+void wxWindow::DoClientToScreen( int *x, int *y ) const
+{
+    POINT pt;
+    if ( x )
+        pt.x = *x;
+    if ( y )
+        pt.y = *y;
+
+    HWND hWnd = GetHwnd();
+    ::ClientToScreen(hWnd, &pt);
+
+    if ( x )
+        *x = pt.x;
+    if ( y )
+        *y = pt.y;
+}
+
+// Get size *available for subwindows* i.e. excluding menu bar etc.
+void wxWindow::DoGetClientSize( int *width, int *height ) const
+{
+    HWND hWnd = GetHwnd();
+    RECT rect;
+    ::GetClientRect(hWnd, &rect);
+    if ( x )
+        *x = rect.right;
+    if ( y )
+        *y = rect.bottom;
+}
+
+void wxWindow::DoMoveWindow(int x, int y, int width, int height)
+{
+    if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
+    {
+        wxLogLastError("MoveWindow");
+    }
+}
+
+//
+// Set the size of the window: if the dimensions are positive, just use them,
+// but if any of them is equal to -1, it means that we must find the value for
+// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
+// which case -1 is a valid value for x and y)
+//
+// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
+// the width/height to best suit our contents, otherwise we reuse the current
+// width/height
+//
+void wxWindow::DoSetSize(int x, int y,
+                         int width, int height,
+                         int sizeFlags)
+{
+    // get the current size and position...
+    int currentX, currentY;
+    GetPosition(¤tX, ¤tY);
+    int currentW,currentH;
+    GetSize(¤tW, ¤tH);
+
+    // ... and don't do anything (avoiding flicker) if it's already ok
+    if ( x == currentX && y == currentY &&
+         width == currentW && height == currentH )
+    {
+        return;
+    }
+
+    if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+        x = currentX;
+    if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+        y = currentY;
+
+    AdjustForParentClientOrigin(x, y, sizeFlags);
+
+    wxSize size(-1, -1);
+    if ( width == -1 )
+    {
+        if ( sizeFlags & wxSIZE_AUTO_WIDTH )
+        {
+            size = DoGetBestSize();
+            width = size.x;
+        }
+        else
+        {
+            // just take the current one
+            width = currentW;
+        }
+    }
+
+    if ( height == -1 )
+    {
+        if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
+        {
+            if ( size.x == -1 )
+            {
+                size = DoGetBestSize();
+            }
+            //else: already called DoGetBestSize() above
+
+            height = size.y;
+        }
+        else
+        {
+            // just take the current one
+            height = currentH;
+        }
+    }
+
+    DoMoveWindow(x, y, width, height);
+}
+
+void wxWindow::DoSetClientSize(int width, int height)
+{
+    wxWindow *parent = GetParent();
+    HWND hWnd = GetHwnd();
+    HWND hParentWnd = (HWND) 0;
+    if ( parent )
+        hParentWnd = (HWND) parent->GetHWND();
+
+    RECT rect;
+    ::GetClientRect(hWnd, &rect);
+
+    RECT rect2;
+    GetWindowRect(hWnd, &rect2);
+
+    // Find the difference between the entire window (title bar and all)
+    // and the client area; add this to the new client size to move the
+    // window
+    int actual_width = rect2.right - rect2.left - rect.right + width;
+    int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
+
+    // If there's a parent, must subtract the parent's top left corner
+    // since MoveWindow moves relative to the parent
+
+    POINT point;
+    point.x = rect2.left;
+    point.y = rect2.top;
+    if ( parent )
+    {
+        ::ScreenToClient(hParentWnd, &point);
+    }
+
+    DoMoveWindow(point.x, point.y, actual_width, actual_height);
+
+    wxSizeEvent event(wxSize(width, height), m_windowId);
+    event.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(event);
+}
+
+wxPoint wxWindow::GetClientAreaOrigin() const
+{
+    return wxPoint(0, 0);
+}
+
+void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
+{
+    // don't do it for the dialogs/frames - they float independently of their
+    // parent
+    if ( !IsTopLevel() )
+    {
+        wxWindow *parent = GetParent();
+        if ( !(sizeFlags & wxSIZE_NO_ADJUSTMENTS) && parent )
+        {
+            wxPoint pt(parent->GetClientAreaOrigin());
+            x += pt.x; y += pt.y;
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// text metrics
+// ---------------------------------------------------------------------------
+
+int  wxWindow::GetCharHeight() const
+{
+    // TODO:
+    return(1);
+}
+
+int  wxWindow::GetCharWidth() const
+{
+    // TODO:
+    return(1);
+}
+
+void wxWindow::GetTextExtent( const wxString& string
+                             ,int*            x
+                             ,int*            y
+                             ,int*            descent
+                             ,int*            externalLeading
+                             ,const wxFont*   theFont
+                            ) const
+{
+    // TODO:
+}
+
+#if wxUSE_CARET && WXWIN_COMPATIBILITY
+// ---------------------------------------------------------------------------
+// Caret manipulation
+// ---------------------------------------------------------------------------
+
+void wxWindow::CreateCaret(int w, int h)
+{
+    // TODO:
+}
+
+void wxWindow::CreateCaret(const wxBitmap *bitmap)
+{
+    // TODO:
+}
+
+void wxWindow::ShowCaret(bool show)
+{
+    // TODO:
+}
+
+void wxWindow::DestroyCaret()
+{
+    // TODO:
+}
+
+void wxWindow::SetCaretPos(int x, int y)
+{
+    // TODO:
+}
+
+void wxWindow::GetCaretPos(int *x, int *y) const
+{
+    // TODO:
+}
+
+#endif //wxUSE_CARET
+
+// ---------------------------------------------------------------------------
+// popup menu
+// ---------------------------------------------------------------------------
+
+bool wxWindow::DoPopupMenu( wxMenu *menu, int x, int y )
+{
+    // TODO:
+    return(TRUE);
+}
+
+// ===========================================================================
+// pre/post message processing
+// ===========================================================================
+
+MRESULT wxWindow::OS2DefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+   // TODO:
+   return (MRESULT)0;
+}
+
+bool wxWindow::OS2ProcessMessage(WXMSG* pMsg)
+{
+   // TODO:
+    return FALSE;
+}
+
+bool wxWindow::OS2TranslateMessage(WXMSG* pMsg)
+{
+    return m_acceleratorTable.Translate(this, pMsg);
+}
+
+// ---------------------------------------------------------------------------
+// message params unpackers (different for Win16 and Win32)
+// ---------------------------------------------------------------------------
+
+void wxWindow::UnpackCommand(WXWPARAM wParam, WXLPARAM lParam,
+                             WORD *id, WXHWND *hwnd, WORD *cmd)
+{
+    *id = LOWORD(wParam);
+    *hwnd = (WXHWND)lParam;
+    *cmd = HIWORD(wParam);
+}
+
+void wxWindow::UnpackActivate(WXWPARAM wParam, WXLPARAM lParam,
+                              WXWORD *state, WXWORD *minimized, WXHWND *hwnd)
+{
+    *state = LOWORD(wParam);
+    *minimized = HIWORD(wParam);
+    *hwnd = (WXHWND)lParam;
+}
+
+void wxWindow::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam,
+                            WXWORD *code, WXWORD *pos, WXHWND *hwnd)
+{
+    *code = LOWORD(wParam);
+    *pos = HIWORD(wParam);
+    *hwnd = (WXHWND)lParam;
+}
+
+void wxWindow::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
+                              WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd)
+{
+    *nCtlColor = 0; // TODO: CTLCOLOR_BTN;
+    *hwnd = (WXHWND)lParam;
+    *hdc = (WXHDC)wParam;
+}
+
+void wxWindow::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
+                                WXWORD *item, WXWORD *flags, WXHMENU *hmenu)
+{
+    *item = (WXWORD)LOWORD(wParam);
+    *flags = HIWORD(wParam);
+    *hmenu = (WXHMENU)lParam;
+}
+
+// ---------------------------------------------------------------------------
+// Main wxWindows window proc and the window proc for wxWindow
+// ---------------------------------------------------------------------------
+
+// Hook for new window just as it's being created, when the window isn't yet
+// associated with the handle
+wxWindow *wxWndHook = NULL;
+
+// Main window proc
+MRESULT wxWndProc(HWND hWnd, ULONG message, MPARAM wParam, MPARAM lParam)
+{
+    // trace all messages - useful for the debugging
+#ifdef __WXDEBUG__
+    wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
+               wxGetMessageName(message), wParam, lParam);
+#endif // __WXDEBUG__
+
+    wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
+
+    // when we get the first message for the HWND we just created, we associate
+    // it with wxWindow stored in wxWndHook
+    if ( !wnd && wxWndHook )
+    {
+#if 0 // def __WXDEBUG__
+        char buf[512];
+        ::GetClassNameA((HWND) hWnd, buf, 512);
+        wxString className(buf);
+#endif
+
+        wxAssociateWinWithHandle(hWnd, wxWndHook);
+        wnd = wxWndHook;
+        wxWndHook = NULL;
+        wnd->SetHWND((WXHWND)hWnd);
+    }
+
+    MRESULT rc;
+
+    // Stop right here if we don't have a valid handle in our wxWindow object.
+    if ( wnd && !wnd->GetHWND() )
+    {
+        // FIXME: why do we do this?
+        wnd->SetHWND((WXHWND) hWnd);
+        rc = wnd->OS2DefWindowProc(message, wParam, lParam );
+        wnd->SetHWND(0);
+    }
+    else
+    {
+        if ( wnd )
+            rc = wnd->OS2WindowProc(message, wParam, lParam);
+        else
+            rc = 0; //TODO: DefWindowProc( hWnd, message, wParam, lParam );
+    }
+
+    return rc;
+}
+
+MRESULT wxWindow::OS2WindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+{
+    // did we process the message?
+    bool processed = FALSE;
+
+    // the return value
+    union
+    {
+        bool        allow;
+        long        result;
+        WXHICON     hIcon;
+        WXHBRUSH    hBrush;
+    } rc;
+
+    // for most messages we should return 0 when we do process the message
+    rc.result = 0;
+    // TODO:
+/*
+    switch ( message )
+    {
+        case WM_CREATE:
+            {
+                bool mayCreate;
+                processed = HandleCreate((WXLPCREATESTRUCT)lParam, &mayCreate);
+                if ( processed )
+                {
+                    // return 0 to allow window creation
+                    rc.result = mayCreate ? 0 : -1;
+                }
+            }
+            break;
+
+        case WM_DESTROY:
+            processed = HandleDestroy();
+            break;
+
+        case WM_MOVE:
+            processed = HandleMove(LOWORD(lParam), HIWORD(lParam));
+            break;
+
+        case WM_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+            break;
+
+        case WM_ACTIVATE:
+            {
+                WXWORD state, minimized;
+                WXHWND hwnd;
+                UnpackActivate(wParam, lParam, &state, &minimized, &hwnd);
+
+                processed = HandleActivate(state, minimized != 0, (WXHWND)hwnd);
+            }
+            break;
+
+        case WM_SETFOCUS:
+            processed = HandleSetFocus((WXHWND)(HWND)wParam);
+            break;
+
+        case WM_KILLFOCUS:
+            processed = HandleKillFocus((WXHWND)(HWND)wParam);
+            break;
+
+        case WM_PAINT:
+            processed = HandlePaint();
+            break;
+
+        case WM_CLOSE:
+            // don't let the DefWindowProc() destroy our window - we'll do it
+            // ourselves in ~wxWindow
+            processed = TRUE;
+            rc.result = TRUE;
+            break;
+
+        case WM_SHOWWINDOW:
+            processed = HandleShow(wParam != 0, (int)lParam);
+            break;
+
+        case WM_MOUSEMOVE:
+        case WM_LBUTTONDOWN:
+        case WM_LBUTTONUP:
+        case WM_LBUTTONDBLCLK:
+        case WM_RBUTTONDOWN:
+        case WM_RBUTTONUP:
+        case WM_RBUTTONDBLCLK:
+        case WM_MBUTTONDOWN:
+        case WM_MBUTTONUP:
+        case WM_MBUTTONDBLCLK:
+            {
+                short x = LOWORD(lParam);
+                short y = HIWORD(lParam);
+
+                processed = HandleMouseEvent(message, x, y, wParam);
+            }
+            break;
+
+        case MM_JOY1MOVE:
+        case MM_JOY2MOVE:
+        case MM_JOY1ZMOVE:
+        case MM_JOY2ZMOVE:
+        case MM_JOY1BUTTONDOWN:
+        case MM_JOY2BUTTONDOWN:
+        case MM_JOY1BUTTONUP:
+        case MM_JOY2BUTTONUP:
+            {
+                int x = LOWORD(lParam);
+                int y = HIWORD(lParam);
+
+                processed = HandleJoystickEvent(message, x, y, wParam);
+            }
+            break;
+
+        case WM_SYSCOMMAND:
+            processed = HandleSysCommand(wParam, lParam);
+            break;
+
+        case WM_COMMAND:
+            {
+                WORD id, cmd;
+                WXHWND hwnd;
+                UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
+
+                processed = HandleCommand(id, cmd, hwnd);
+            }
+            break;
+
+#ifdef __WIN95__
+        case WM_NOTIFY:
+            processed = HandleNotify((int)wParam, lParam, &rc.result);
+            break;
+#endif  // Win95
+
+            // for these messages we must return TRUE if process the message
+        case WM_DRAWITEM:
+        case WM_MEASUREITEM:
+            {
+                int idCtrl = (UINT)wParam;
+                if ( message == WM_DRAWITEM )
+                {
+                    processed = MSWOnDrawItem(idCtrl,
+                                              (WXDRAWITEMSTRUCT *)lParam);
+                }
+                else
+                {
+                    processed = MSWOnMeasureItem(idCtrl,
+                                                 (WXMEASUREITEMSTRUCT *)lParam);
+                }
+
+                if ( processed )
+                    rc.result = TRUE;
+            }
+            break;
+
+        case WM_GETDLGCODE:
+            if ( m_lDlgCode )
+            {
+                rc.result = m_lDlgCode;
+                processed = TRUE;
+            }
+            //else: get the dlg code from the DefWindowProc()
+            break;
+
+        case WM_KEYDOWN:
+            // If this has been processed by an event handler,
+            // return 0 now (we've handled it).
+            if ( HandleKeyDown((WORD) wParam, lParam) )
+            {
+                processed = TRUE;
+
+                break;
+            }
+
+            // we consider these message "not interesting" to OnChar
+            if ( wParam == VK_SHIFT || wParam == VK_CONTROL )
+            {
+                processed = TRUE;
+
+                break;
+            }
+
+            switch ( wParam )
+            {
+                // avoid duplicate messages to OnChar for these ASCII keys: they
+                // will be translated by TranslateMessage() and received in WM_CHAR
+                case VK_ESCAPE:
+                case VK_SPACE:
+                case VK_RETURN:
+                case VK_BACK:
+                case VK_TAB:
+                    // but set processed to FALSE, not TRUE to still pass them to
+                    // the control's default window proc - otherwise built-in
+                    // keyboard handling won't work
+                    processed = FALSE;
+
+                    break;
+
+#ifdef VK_APPS
+                // special case of VK_APPS: treat it the same as right mouse
+                // click because both usually pop up a context menu
+                case VK_APPS:
+                    {
+                        // construct the key mask
+                        WPARAM fwKeys = MK_RBUTTON;
+                        if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
+                            fwKeys |= MK_CONTROL;
+                        if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 )
+                            fwKeys |= MK_SHIFT;
+
+                        // simulate right mouse button click
+                        DWORD dwPos = ::GetMessagePos();
+                        int x = GET_X_LPARAM(dwPos),
+                            y = GET_Y_LPARAM(dwPos);
+
+                        ScreenToClient(&x, &y);
+                        processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, fwKeys);
+                    }
+                    break;
+#endif // VK_APPS
+
+                case VK_LEFT:
+                case VK_RIGHT:
+                case VK_DOWN:
+                case VK_UP:
+                default:
+                    processed = HandleChar((WORD)wParam, lParam);
+            }
+            break;
+
+        case WM_KEYUP:
+            processed = HandleKeyUp((WORD) wParam, lParam);
+            break;
+
+        case WM_CHAR: // Always an ASCII character
+            processed = HandleChar((WORD)wParam, lParam, TRUE);
+            break;
+
+        case WM_HSCROLL:
+        case WM_VSCROLL:
+            {
+                WXWORD code, pos;
+                WXHWND hwnd;
+                UnpackScroll(wParam, lParam, &code, &pos, &hwnd);
+
+                processed = MSWOnScroll(message == WM_HSCROLL ? wxHORIZONTAL
+                                                              : wxVERTICAL,
+                                        code, pos, hwnd);
+            }
+            break;
+
+        // CTLCOLOR messages are sent by children to query the parent for their
+        // colors
+#ifdef __WIN32__
+        case WM_CTLCOLORMSGBOX:
+        case WM_CTLCOLOREDIT:
+        case WM_CTLCOLORLISTBOX:
+        case WM_CTLCOLORBTN:
+        case WM_CTLCOLORDLG:
+        case WM_CTLCOLORSCROLLBAR:
+        case WM_CTLCOLORSTATIC:
+#else // Win16
+        case WM_CTLCOLOR:
+#endif // Win32/16
+            {
+                WXWORD nCtlColor;
+                WXHDC hdc;
+                WXHWND hwnd;
+                UnpackCtlColor(wParam, lParam, &nCtlColor, &hdc, &hwnd);
+
+                processed = HandleCtlColor(&rc.hBrush,
+                                           (WXHDC)hdc,
+                                           (WXHWND)hwnd,
+                                           nCtlColor,
+                                           message,
+                                           wParam,
+                                           lParam);
+            }
+            break;
+
+            // the return value for this message is ignored
+        case WM_SYSCOLORCHANGE:
+            processed = HandleSysColorChange();
+            break;
+
+        case WM_PALETTECHANGED:
+            processed = HandlePaletteChanged((WXHWND) (HWND) wParam);
+            break;
+
+        case WM_QUERYNEWPALETTE:
+            processed = HandleQueryNewPalette();
+            break;
+
+        case WM_ERASEBKGND:
+            processed = HandleEraseBkgnd((WXHDC)(HDC)wParam);
+            if ( processed )
+            {
+                // we processed the message, i.e. erased the background
+                rc.result = TRUE;
+            }
+            break;
+
+        case WM_DROPFILES:
+            processed = HandleDropFiles(wParam);
+            break;
+
+        case WM_INITDIALOG:
+            processed = HandleInitDialog((WXHWND)(HWND)wParam);
+
+            if ( processed )
+            {
+                // we never set focus from here
+                rc.result = FALSE;
+            }
+            break;
+
+        case WM_QUERYENDSESSION:
+            processed = HandleQueryEndSession(lParam, &rc.allow);
+            break;
+
+        case WM_ENDSESSION:
+            processed = HandleEndSession(wParam != 0, lParam);
+            break;
+
+        case WM_GETMINMAXINFO:
+            processed = HandleGetMinMaxInfo((MINMAXINFO*)lParam);
+            break;
+
+        case WM_SETCURSOR:
+            processed = HandleSetCursor((WXHWND)(HWND)wParam,
+                                        LOWORD(lParam),     // hit test
+                                        HIWORD(lParam));    // mouse msg
+
+            if ( processed )
+            {
+                // returning TRUE stops the DefWindowProc() from further
+                // processing this message - exactly what we need because we've
+                // just set the cursor.
+                rc.result = TRUE;
+            }
+            break;
+    }
+
+    if ( !processed )
+    {
+#ifdef __WXDEBUG__
+        wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
+                   wxGetMessageName(message));
+#endif // __WXDEBUG__
+        rc.result = MSWDefWindowProc(message, wParam, lParam);
+    }
+*/
+    return (MRESULT)0;
+}
+
+// Dialog window proc
+MRESULT wxDlgProc(HWND hWnd, UINT message, MPARAM wParam, MPARAM lParam)
+{
+   // TODO:
+/*
+    if ( message == WM_INITDIALOG )
+    {
+        // for this message, returning TRUE tells system to set focus to the
+        // first control in the dialog box
+        return TRUE;
+    }
+    else
+    {
+        // for all the other ones, FALSE means that we didn't process the
+        // message
+        return 0;
+    }
+*/
+    return (MRESULT)0;
+}
+
+wxWindow *wxFindWinFromHandle(WXHWND hWnd)
+{
+    wxNode *node = wxWinHandleList->Find((long)hWnd);
+    if ( !node )
+        return NULL;
+    return (wxWindow *)node->Data();
+}
+
+void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
+{
+    // adding NULL hWnd is (first) surely a result of an error and
+    // (secondly) breaks menu command processing
+    wxCHECK_RET( hWnd != (HWND)NULL,
+                 wxT("attempt to add a NULL hWnd to window list ignored") );
+
+
+    wxWindow *oldWin = wxFindWinFromHandle((WXHWND) hWnd);
+    if ( oldWin && (oldWin != win) )
+    {
+        wxString str(win->GetClassInfo()->GetClassName());
+        wxLogError("Bug! Found existing HWND %X for new window of class %s", (int) hWnd, (const char*) str);
+    }
+    else if (!oldWin)
+    {
+        wxWinHandleList->Append((long)hWnd, win);
+    }
+}
+
+void wxRemoveHandleAssociation(wxWindow *win)
+{
+    wxWinHandleList->DeleteObject(win);
+}
+
+// Default destroyer - override if you destroy it in some other way
+// (e.g. with MDI child windows)
+void wxWindow::OS2DestroyWindow()
+{
+}
+
+void wxWindow::OS2DetachWindowMenu()
+{
+    if ( m_hMenu )
+    {
+        HMENU hMenu = (HMENU)m_hMenu;
+
+        int N = (int)WinSendMsg(hMenu, MM_QUERYITEMCOUNT, 0, 0);
+        int i;
+        for (i = 0; i < N; i++)
+        {
+            wxChar buf[100];
+            int chars = (int)WinSendMsg(hMenu, MM_QUERYITEMTEXT, MPFROM2SHORT(i, N), buf);
+            if ( !chars )
+            {
+                wxLogLastError(wxT("GetMenuString"));
+
+                continue;
+            }
+
+            if ( wxStrcmp(buf, wxT("&Window")) == 0 )
+            {
+                WinSendMsg(hMenu, MM_DELETEITEM, MPFROM2SHORT(i, TRUE), 0);
+                break;
+            }
+        }
+    }
+}
+
+bool wxWindow::OS2Create(int id,
+                         wxWindow *parent,
+                         const wxChar *wclass,
+                         wxWindow *wx_win,
+                         const wxChar *title,
+                         int x,
+                         int y,
+                         int width,
+                         int height,
+                         WXDWORD style,
+                         const wxChar *dialog_template,
+                         WXDWORD extendedStyle)
+{
+   // TODO:
+/*
+    int x1 = CW_USEDEFAULT;
+    int y1 = 0;
+    int width1 = CW_USEDEFAULT;
+    int height1 = 100;
+
+    // Find parent's size, if it exists, to set up a possible default
+    // panel size the size of the parent window
+    RECT parent_rect;
+    if ( parent )
+    {
+        ::GetClientRect((HWND) parent->GetHWND(), &parent_rect);
+
+        width1 = parent_rect.right - parent_rect.left;
+        height1 = parent_rect.bottom - parent_rect.top;
+    }
+
+    if ( x > -1 ) x1 = x;
+    if ( y > -1 ) y1 = y;
+    if ( width > -1 ) width1 = width;
+    if ( height > -1 ) height1 = height;
+
+    HWND hParent = (HWND)NULL;
+    if ( parent )
+        hParent = (HWND) parent->GetHWND();
+
+    wxWndHook = this;
+
+    if ( dialog_template )
+    {
+        m_hWnd = (WXHWND)::CreateDialog(wxGetInstance(),
+                                        dialog_template,
+                                        hParent,
+                                        (DLGPROC)wxDlgProc);
+
+        if ( m_hWnd == 0 )
+        {
+            wxLogError(_("Can't find dummy dialog template!\n"
+                         "Check resource include path for finding wx.rc."));
+
+            return FALSE;
+        }
+
+        // ::SetWindowLong(GWL_EXSTYLE) doesn't work for the dialogs, so try
+        // to take care of (at least some) extended style flags ourselves
+        if ( extendedStyle & WS_EX_TOPMOST )
+        {
+            if ( !::SetWindowPos(GetHwnd(), HWND_TOPMOST, 0, 0, 0, 0,
+                                 SWP_NOSIZE | SWP_NOMOVE) )
+            {
+                wxLogLastError(wxT("SetWindowPos"));
+            }
+        }
+
+        // move the dialog to its initial position without forcing repainting
+        if ( !::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE) )
+        {
+            wxLogLastError(wxT("MoveWindow"));
+        }
+    }
+    else
+    {
+        int controlId = 0;
+        if ( style & WS_CHILD )
+            controlId = id;
+
+        wxString className(wclass);
+        if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE )
+        {
+            className += wxT("NR");
+        }
+
+        m_hWnd = (WXHWND)CreateWindowEx(extendedStyle,
+                                        className,
+                                        title ? title : wxT(""),
+                                        style,
+                                        x1, y1,
+                                        width1, height1,
+                                        hParent, (HMENU)controlId,
+                                        wxGetInstance(),
+                                        NULL);
+
+        if ( !m_hWnd )
+        {
+            wxLogError(_("Can't create window of class %s!\n"
+                         "Possible Windows 3.x compatibility problem?"),
+                       wclass);
+
+            return FALSE;
+        }
+    }
+
+    wxWndHook = NULL;
+#ifdef __WXDEBUG__
+    wxNode* node = wxWinHandleList->Member(this);
+    if (node)
+    {
+        HWND hWnd = (HWND) node->GetKeyInteger();
+        if (hWnd != (HWND) m_hWnd)
+        {
+            wxLogError("A second HWND association is being added for the same window!");
+        }
+    }
+#endif
+*/
+    wxAssociateWinWithHandle((HWND) m_hWnd, this);
+
+    return TRUE;
+}
+
+// ===========================================================================
+// OS2 PM message handlers
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// WM_NOTIFY
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
+{
+   // TODO:
+   return FALSE;
+}
+
+bool wxWindow::OS2OnNotify(int WXUNUSED(idCtrl),
+                           WXLPARAM lParam,
+                           WXLPARAM* WXUNUSED(result))
+{
+    // TODO:
+    return FALSE;
+}
+
+// ---------------------------------------------------------------------------
+// end session messages
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleQueryEndSession(long logOff, bool *mayEnd)
+{
+    wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
+    event.SetEventObject(wxTheApp);
+    event.SetCanVeto(TRUE);
+    event.SetLoggingOff(logOff == ENDSESSION_LOGOFF);
+
+    bool rc = wxTheApp->ProcessEvent(event);
+
+    if ( rc )
+    {
+        // we may end only if the app didn't veto session closing (double
+        // negation...)
+        *mayEnd = !event.GetVeto();
+    }
+
+    return rc;
+}
+
+bool wxWindow::HandleEndSession(bool endSession, long logOff)
+{
+    // do nothing if the session isn't ending
+    if ( !endSession )
+        return FALSE;
+
+    wxCloseEvent event(wxEVT_END_SESSION, -1);
+    event.SetEventObject(wxTheApp);
+    event.SetCanVeto(FALSE);
+    event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
+    if ( (this == wxTheApp->GetTopWindow()) && // Only send once
+        wxTheApp->ProcessEvent(event))
+    {
+    }
+    return TRUE;
+}
+
+// ---------------------------------------------------------------------------
+// window creation/destruction
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
+{
+    // TODO: should generate this event from WM_NCCREATE
+    wxWindowCreateEvent event(this);
+    (void)GetEventHandler()->ProcessEvent(event);
+
+    *mayCreate = TRUE;
+
+    return TRUE;
+}
+
+bool wxWindow::HandleDestroy()
+{
+    wxWindowDestroyEvent event(this);
+    (void)GetEventHandler()->ProcessEvent(event);
+
+    // delete our drop target if we've got one
+#if wxUSE_DRAG_AND_DROP
+    if ( m_dropTarget != NULL )
+    {
+//        m_dropTarget->Revoke(m_hWnd);
+
+        delete m_dropTarget;
+        m_dropTarget = NULL;
+    }
+#endif // wxUSE_DRAG_AND_DROP
+
+    // WM_DESTROY handled
+    return TRUE;
+}
+
+// ---------------------------------------------------------------------------
+// activation/focus
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleActivate(int state,
+                              bool WXUNUSED(minimized),
+                              WXHWND WXUNUSED(activate))
+{
+    // TODO:
+    /*
+    wxActivateEvent event(wxEVT_ACTIVATE,
+                          (state == WA_ACTIVE) || (state == WA_CLICKACTIVE),
+                          m_windowId);
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
+    */
+    return FALSE;
+}
+
+bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd))
+{
+#if wxUSE_CARET
+    // Deal with caret
+    if ( m_caret )
+    {
+        m_caret->OnSetFocus();
+    }
+#endif // wxUSE_CARET
+
+    // panel wants to track the window which was the last to have focus in it
+    wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
+    if ( panel )
+    {
+        panel->SetLastFocus(this);
+    }
+
+    wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleKillFocus(WXHWND WXUNUSED(hwnd))