+#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);
+ }
+
+ LRESULT 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->MSWDefWindowProc(message, wParam, lParam );
+ wnd->SetHWND(0);
+ }
+ else
+ {
+ if ( wnd )
+ rc = wnd->MSWWindowProc(message, wParam, lParam);
+ else
+ rc = DefWindowProc( hWnd, message, wParam, lParam );
+ }
+
+ return rc;
+}
+
+long wxWindowMSW::MSWWindowProc(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;
+
+ 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(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ break;
+
+ case WM_SIZE:
+ switch ( wParam )
+ {
+ case SIZE_MAXHIDE:
+ case SIZE_MAXSHOW:
+ // we're not interested in these messages at all
+ break;
+
+ case SIZE_MINIMIZED:
+ // we shouldn't send sizev events for these messages as the
+ // client size may be negative which breaks existing code
+ //
+ // OTOH we might send another (wxMinimizedEvent?) one or
+ // add an additional parameter to wxSizeEvent if this is
+ // useful to anybody
+ break;
+
+ default:
+ wxFAIL_MSG( _T("unexpected WM_SIZE parameter") );
+ // fall through nevertheless
+
+ case SIZE_MAXIMIZED:
+ case SIZE_RESTORED:
+ processed = HandleSize(LOWORD(lParam), HIWORD(lParam),
+ wParam);
+ }
+ break;
+
+ case WM_ACTIVATEAPP:
+ wxTheApp->SetActive(wParam != 0, FindFocus());
+ 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:
+ processed = HandleMouseMove(GET_X_LPARAM(lParam),
+ GET_Y_LPARAM(lParam),
+ wParam);
+ break;
+
+#if wxUSE_MOUSEWHEEL
+ case WM_MOUSEWHEEL:
+ processed = HandleMouseWheel(wParam, lParam);
+ break;
+#endif
+
+ case WM_LBUTTONDOWN:
+ // set focus to this window
+ if (AcceptsFocus())
+ SetFocus();
+
+ // fall through
+
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_MBUTTONDBLCLK:
+ processed = HandleMouseEvent(message,
+ GET_X_LPARAM(lParam),
+ GET_Y_LPARAM(lParam),
+ wParam);
+ break;
+
+#ifdef MM_JOY1MOVE // __WXMICROWIN__
+ case MM_JOY1MOVE:
+ case MM_JOY2MOVE:
+ case MM_JOY1ZMOVE:
+ case MM_JOY2ZMOVE:
+ case MM_JOY1BUTTONDOWN:
+ case MM_JOY2BUTTONDOWN:
+ case MM_JOY1BUTTONUP:
+ case MM_JOY2BUTTONUP:
+ processed = HandleJoystickEvent(message,
+ GET_X_LPARAM(lParam),
+ GET_Y_LPARAM(lParam),
+ wParam);
+ break;
+#endif
+
+ 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
+#ifdef WM_DRAWITEM // __WXMICROWIN__
+ 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;
+#endif
+ case WM_GETDLGCODE:
+ if ( m_lDlgCode )
+ {
+ rc.result = m_lDlgCode;
+ processed = TRUE;
+ }
+ //else: get the dlg code from the DefWindowProc()
+ break;
+
+ case WM_SYSKEYDOWN:
+ 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:
+ case VK_ADD:
+ case VK_SUBTRACT:
+ // 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:
+ {
+ WPARAM flags;
+ int x, y;
+
+ TranslateKbdEventToMouse(this, &x, &y, &flags);
+ processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags);
+ }
+ 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_SYSKEYUP:
+ case WM_KEYUP:
+#ifdef VK_APPS
+ // special case of VK_APPS: treat it the same as right mouse button
+ if ( wParam == VK_APPS )
+ {
+ WPARAM flags;
+ int x, y;
+
+ TranslateKbdEventToMouse(this, &x, &y, &flags);
+ processed = HandleMouseEvent(WM_RBUTTONUP, x, y, flags);
+ }
+ else
+#endif // VK_APPS
+ {
+ processed = HandleKeyUp((WORD) wParam, lParam);
+ }
+ break;
+
+ case WM_SYSCHAR:
+ 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#ifndef __WXMICROWIN__
+#ifndef __WXMICROWIN__
+#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;
+#endif
+
+ // 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 )