+ 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:
+ // never set processed to TRUE and *always* pass WM_DESTROY to
+ // DefWindowProc() as Windows may do some internal cleanup when
+ // processing it and failing to pass the message along may cause
+ // memory and resource leaks!
+ (void)HandleDestroy();
+ break;
+
+ case WM_MOVE:
+ processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ break;
+
+ case WM_MOVING:
+ {
+ LPRECT pRect = (LPRECT)lParam;
+ wxRect rc;
+ rc.SetLeft(pRect->left);
+ rc.SetTop(pRect->top);
+ rc.SetRight(pRect->right);
+ rc.SetBottom(pRect->bottom);
+ processed = HandleMoving(rc);
+ if (processed) {
+ pRect->left = rc.GetLeft();
+ pRect->top = rc.GetTop();
+ pRect->right = rc.GetRight();
+ pRect->bottom = rc.GetBottom();
+ }
+ }
+ 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_SIZING:
+ {
+ LPRECT pRect = (LPRECT)lParam;
+ wxRect rc;
+ rc.SetLeft(pRect->left);
+ rc.SetTop(pRect->top);
+ rc.SetRight(pRect->right);
+ rc.SetBottom(pRect->bottom);
+ processed = HandleSizing(rc);
+ if (processed) {
+ pRect->left = rc.GetLeft();
+ pRect->top = rc.GetTop();
+ pRect->right = rc.GetRight();
+ pRect->bottom = rc.GetBottom();
+ }
+ }
+ break;
+
+#ifndef __WXMICROWIN__
+ case WM_ACTIVATEAPP:
+ wxTheApp->SetActive(wParam != 0, FindFocus());
+ break;
+#endif
+
+ 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:
+#ifdef __WXUNIVERSAL__
+ // Universal uses its own wxFrame/wxDialog, so we don't receive
+ // close events unless we have this.
+ Close();
+ processed = TRUE;
+ rc.result = TRUE;
+#else
+ // don't let the DefWindowProc() destroy our window - we'll do it
+ // ourselves in ~wxWindow
+ processed = TRUE;
+ rc.result = TRUE;
+#endif
+ 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:
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_MBUTTONDBLCLK:
+ {
+#ifdef __WXMICROWIN__
+ // MicroWindows seems to ignore the fact that a window is
+ // disabled. So catch mouse events and throw them away if
+ // necessary.
+ wxWindowMSW* win = this;
+ for ( ;; )
+ {
+ if (!win->IsEnabled())
+ {
+ processed = TRUE;
+ break;
+ }
+
+ win = win->GetParent();
+ if ( !win || win->IsTopLevel() )
+ break;
+ }
+
+ if ( processed )
+ break;
+
+#endif // __WXMICROWIN__
+ int x = GET_X_LPARAM(lParam),
+ y = GET_Y_LPARAM(lParam);
+
+ // redirect the event to a static control if necessary by
+ // finding one under mouse
+ wxWindowMSW *win;
+ if ( GetCapture() == this )
+ {
+ // but don't do it if the mouse is captured by this window
+ // because then it should really get this event itself
+ win = this;
+ }
+ else
+ {
+ win = FindWindowForMouseEvent(this, &x, &y);
+
+ // this should never happen
+ wxCHECK_MSG( win, 0,
+ _T("FindWindowForMouseEvent() returned NULL") );
+
+ // for the standard classes their WndProc sets the focus to
+ // them anyhow and doing it from here results in some weird
+ // problems, but for our windows we want them to acquire
+ // focus when clicked
+ if ( !win->IsOfStandardClass() )
+ {
+ if ( message == WM_LBUTTONDOWN && win->AcceptsFocus() )
+ win->SetFocus();
+ }
+ }
+
+ processed = win->HandleMouseEvent(message, x, y, wParam);
+ }
+ break;
+
+#ifdef MM_JOY1MOVE
+ 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 // __WXMICROWIN__
+
+ 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
+ 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 // defined(WM_DRAWITEM)
+
+ case WM_GETDLGCODE:
+ if ( !IsOfStandardClass() )
+ {
+ // we always want to get the char events
+ rc.result = DLGC_WANTCHARS;
+
+ if ( GetWindowStyleFlag() & wxWANTS_CHARS )
+ {
+ // in fact, we want everything
+ rc.result |= DLGC_WANTARROWS |
+ DLGC_WANTTAB |
+ DLGC_WANTALLKEYS;
+ }
+
+ 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).
+ m_lastKeydownProcessed = HandleKeyDown((WORD) wParam, lParam);
+ if ( m_lastKeydownProcessed )
+ {
+ processed = TRUE;
+ }
+
+ if ( !processed )
+ {
+ switch ( wParam )
+ {
+ // we consider these message "not interesting" to OnChar, so
+ // just don't do anything more with them
+ case VK_SHIFT:
+ case VK_CONTROL:
+ case VK_MENU:
+ case VK_CAPITAL:
+ case VK_NUMLOCK:
+ case VK_SCROLL:
+ processed = TRUE;
+ break;
+
+ // 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:
+ case VK_MULTIPLY:
+ case VK_DIVIDE:
+ case VK_OEM_1:
+ case VK_OEM_2:
+ case VK_OEM_3:
+ case VK_OEM_4:
+ case VK_OEM_5:
+ case VK_OEM_6:
+ case VK_OEM_7:
+ case VK_OEM_PLUS:
+ case VK_OEM_COMMA:
+ case VK_OEM_MINUS:
+ case VK_OEM_PERIOD:
+ // 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
+
+ default:
+ // do generate a CHAR event
+ processed = HandleChar((WORD)wParam, lParam);
+ }
+ }
+ if (message == WM_SYSKEYDOWN) // Let Windows still handle the SYSKEYs
+ processed = FALSE;
+ 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);
+ }