+    if ( !eliminateBorders )
+    {
+        if ( style & wxSUNKEN_BORDER )
+            exStyle |= WS_EX_CLIENTEDGE;
+        if ( style & wxDOUBLE_BORDER )
+            exStyle |= WS_EX_DLGMODALFRAME;
+        if ( style & wxRAISED_BORDER )
+            exStyle |= WS_EX_WINDOWEDGE;
+        if ( style & wxSTATIC_BORDER )
+            exStyle |= WS_EX_STATICEDGE;
+    }
+*/
+    return exStyle;
+}
+
+// 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 defaultBorderStyle,
+                                     bool *want3D) const
+{
+   DWORD exStyle; // remove after implementation doe
+/* TODO:  this ought to be fun
+*
+    // If matches certain criteria, then assume no 3D effects
+    // unless specifically requested (dealt with in MakeExtendedStyle)
+    if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) )
+    {
+        *want3D = FALSE;
+        return MakeExtendedStyle(m_windowStyle, FALSE);
+    }
+
+    // Determine whether we should be using 3D effects or not.
+    bool nativeBorder = FALSE; // by default, we don't want a Win95 effect
+
+    // 1) App can specify global 3D effects
+    *want3D = wxTheApp->GetAuto3D();
+
+    // 2) If the parent is being drawn with user colours, or simple border specified,
+    // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
+    if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER) )
+        *want3D = FALSE;
+
+    // 3) Control can override this global setting by defining
+    // a border style, e.g. wxSUNKEN_BORDER
+    if ( m_windowStyle & wxSUNKEN_BORDER  )
+        *want3D = TRUE;
+
+    // 4) If it's a special border, CTL3D can't cope so we want a native border
+    if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
+        (m_windowStyle & wxSTATIC_BORDER) )
+    {
+        *want3D = TRUE;
+        nativeBorder = TRUE;
+    }
+
+    // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
+    // effects from extended style
+#if wxUSE_CTL3D
+    if ( *want3D )
+        nativeBorder = FALSE;
+#endif
+
+    DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder);
+
+    // If we want 3D, but haven't specified a border here,
+    // apply the default border style specified.
+    // TODO what about non-Win95 WIN32? Does it have borders?
+#if defined(__WIN95__) && !wxUSE_CTL3D
+    if ( defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) ||
+        (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
+        exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE;
+#endif
+*/
+    return exStyle;
+}
+
+#if WXWIN_COMPATIBILITY
+void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event)
+{
+    // TODO:
+}
+
+wxObject* wxWindow::GetChild(int number) const
+{
+    // TODO:
+    return((wxObject*)this);
+}
+
+void wxWindow::OnDefaultAction(wxControl *initiatingItem)
+{
+    // TODO:
+}
+
+#endif // WXWIN_COMPATIBILITY
+
+// Setup background and foreground colours correctly
+void wxWindow::SetupColours()
+{
+    if ( GetParent() )
+        SetBackgroundColour(GetParent()->GetBackgroundColour());
+}
+
+void wxWindow::OnIdle(wxIdleEvent& event)
+{
+    // TODO:
+}
+
+// Set this window to be the child of 'parent'.
+bool wxWindow::Reparent(wxWindow *parent)
+{
+    if ( !wxWindowBase::Reparent(parent) )
+        return FALSE;
+   // TODO:
+    return FALSE;
+}
+
+void wxWindow::Clear()
+{
+    // TODO:
+}
+
+void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
+{
+    // TODO:
+}
+
+// ---------------------------------------------------------------------------
+// drag and drop
+// ---------------------------------------------------------------------------
+
+#if wxUSE_DRAG_AND_DROP
+void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
+{
+    // TODO:
+}
+#endif
+
+// old style file-manager drag&drop support: we retain the old-style
+// DragAcceptFiles in parallel with SetDropTarget.
+void wxWindow::DragAcceptFiles(bool accept)
+{
+    // TODO:
+}
+
+// ----------------------------------------------------------------------------
+// tooltips
+// ----------------------------------------------------------------------------
+
+#if wxUSE_TOOLTIPS
+
+void wxWindow::DoSetToolTip(wxToolTip *tooltip)
+{
+    wxWindowBase::DoSetToolTip(tooltip);
+
+    if ( m_tooltip )
+        m_tooltip->SetWindow(this);
+}
+
+#endif // wxUSE_TOOLTIPS
+
+// ---------------------------------------------------------------------------
+// moving and resizing
+// ---------------------------------------------------------------------------
+
+// Get total size
+void wxWindow::DoGetSize( int *width, int *height ) const
+{
+    // TODO:
+}
+
+void wxWindow::DoGetPosition( int *x, int *y ) const
+{
+    // TODO:
+}
+
+void wxWindow::DoScreenToClient( int *x, int *y ) const
+{
+    // TODO:
+}
+
+void wxWindow::DoClientToScreen( int *x, int *y ) const
+{
+    // TODO:
+}
+
+// Get size *available for subwindows* i.e. excluding menu bar etc.
+void wxWindow::DoGetClientSize( int *width, int *height ) const
+{
+    // TODO:
+}
+
+void wxWindow::DoMoveWindow(int x, int y, int width, int height)
+{
+   // TODO:
+}
+
+// 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)
+{
+    // TODO:
+}
+
+// for a generic window there is no natural best size - just use the current one
+wxSize wxWindow::DoGetBestSize()
+{
+    return GetSize();
+}
+
+void wxWindow::DoSetClientSize(int width, int height)
+{
+    // TODO:
+}
+
+wxPoint wxWindow::GetClientAreaOrigin() const
+{
+    return wxPoint(0, 0);
+}
+
+void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
+{
+    // TODO:
+}
+
+// ---------------------------------------------------------------------------
+// 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(HWND hwnd, 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, UINT 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(hWnd, message, wParam, lParam );
+        wnd->SetHWND(0);
+    }
+    else
+    {
+        if ( wnd )
+            rc = wnd->OS2WindowProc(hWnd, message, wParam, lParam);
+        else
+            rc = 0; //TODO: DefWindowProc( hWnd, message, wParam, lParam );
+    }
+
+    return rc;
+}
+
+MRESULT wxWindow::OS2WindowProc(HWND hWnd, 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))
+{
+#if wxUSE_CARET
+    // Deal with caret
+    if ( m_caret )
+    {
+        m_caret->OnKillFocus();
+    }
+#endif // wxUSE_CARET
+
+    wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+// ---------------------------------------------------------------------------
+// miscellaneous
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleShow(bool show, int status)
+{
+    wxShowEvent event(GetId(), show);
+    event.m_eventObject = this;
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
+{
+    wxInitDialogEvent event(GetId());
+    event.m_eventObject = this;
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleDropFiles(WXWPARAM wParam)
+{
+   // TODO:
+    return FALSE;
+}
+
+bool wxWindow::HandleSetCursor(WXHWND hWnd,
+                               short nHitTest,
+                               int WXUNUSED(mouseMsg))
+{
+    // don't set cursor for other windows, only for this one: this prevents
+    // children of this window from getting the same cursor as the parent has
+    // (don't forget that this message is propagated by default up the window
+    // parent-child hierarchy)
+    if ( GetHWND() == hWnd )
+    {
+        // don't set cursor when the mouse is not in the client part
+// TODO
+/*
+        if ( nHitTest == HTCLIENT || nHitTest == HTERROR )
+        {
+            HCURSOR hcursor = 0;
+            if ( wxIsBusy() )
+            {
+                // from msw\utils.cpp
+                extern HCURSOR gs_wxBusyCursor;
+
+                hcursor = gs_wxBusyCursor;
+            }
+            else
+            {
+                wxCursor *cursor = NULL;
+
+                if ( m_cursor.Ok() )
+                {
+                    cursor = &m_cursor;
+                }
+                else
+                {
+                    // from msw\data.cpp
+                    extern wxCursor *g_globalCursor;
+
+                    if ( g_globalCursor && g_globalCursor->Ok() )
+                        cursor = g_globalCursor;
+                }
+
+                if ( cursor )
+                    hcursor = (HCURSOR)cursor->GetHCURSOR();
+            }
+
+            if ( hcursor )
+            {
+//                ::SetCursor(hcursor);
+
+                return TRUE;
+            }
+        }
+*/
+    }
+
+    return FALSE;
+}
+
+// ---------------------------------------------------------------------------
+// owner drawn stuff
+// ---------------------------------------------------------------------------
+
+bool wxWindow::OS2OnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
+{
+   // TODO:
+/*
+#if wxUSE_OWNER_DRAWN
+    // is it a menu item?
+    if ( id == 0 )
+    {
+        DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct;
+        wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
+
+        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+
+        // prepare to call OnDrawItem()
+        wxDC dc;
+        dc.SetHDC((WXHDC)pDrawStruct->hDC, FALSE);
+        wxRect rect(pDrawStruct->rcItem.left, pDrawStruct->rcItem.top,
+                    pDrawStruct->rcItem.right - pDrawStruct->rcItem.left,
+                    pDrawStruct->rcItem.bottom - pDrawStruct->rcItem.top);
+
+        return pMenuItem->OnDrawItem
+                          (
+                            dc, rect,
+                            (wxOwnerDrawn::wxODAction)pDrawStruct->itemAction,
+                            (wxOwnerDrawn::wxODStatus)pDrawStruct->itemState
+                          );
+    }
+
+    wxWindow *item = FindItem(id);
+    if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
+    {
+        return ((wxControl *)item)->MSWOnDraw(itemStruct);
+    }
+    else
+#endif
+        return FALSE;
+*/
+    return FALSE;
+}