#endif // __WXUNIVERSAL__/__WXMSW__
BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase)
- EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground)
EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
+ EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground)
#ifdef __WXWINCE__
EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
#endif
// here we try to do all the job which ::IsDialogMessage() usually does
// internally
-#if 1
if ( msg->message == WM_KEYDOWN )
{
bool bCtrlDown = wxIsCtrlDown();
}
}
}
-#else // 0
- // let ::IsDialogMessage() do almost everything and handle just the
- // things it doesn't here: Ctrl-TAB for switching notebook pages
- if ( msg->message == WM_KEYDOWN )
- {
- // don't process system keys here
- if ( !(HIWORD(msg->lParam) & KF_ALTDOWN) )
- {
- if ( (msg->wParam == VK_TAB) && wxIsCtrlDown() )
- {
- // find the first notebook parent and change its page
- wxWindow *win = this;
- wxNotebook *nbook = NULL;
- while ( win && !nbook )
- {
- nbook = wxDynamicCast(win, wxNotebook);
- win = win->GetParent();
- }
-
- if ( nbook )
- {
- bool forward = !wxIsShiftDown();
-
- nbook->AdvanceSelection(forward);
- }
- }
- }
- }
-#endif // 1/0
// don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the
// message even when there is no cancel button and when the message is
}
void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
- WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd)
+ WXHDC *hdc, WXHWND *hwnd)
{
-#ifndef __WXMICROWIN__
- *nCtlColor = CTLCOLOR_BTN;
*hwnd = (WXHWND)lParam;
*hdc = (WXHDC)wParam;
-#endif
}
void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
// this should never happen
wxCHECK_MSG( win, 0,
_T("FindWindowForMouseEvent() returned NULL") );
+ }
+ processed = win->HandleMouseEvent(message, x, y, wParam);
+
+ // if the app didn't eat the event, handle it in the default
+ // way, that is by giving this window the focus
+ if ( !processed )
+ {
// 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
+ // problems, so don't do it for them (unnecessary anyhow)
if ( !win->IsOfStandardClass() )
{
if ( message == WM_LBUTTONDOWN && win->AcceptsFocus() )
win->SetFocus();
}
}
-
- processed = win->HandleMouseEvent(message, x, y, wParam);
}
break;
break;
// CTLCOLOR messages are sent by children to query the parent for their
- // colors#ifndef __WXMICROWIN__
+ // colors
#ifndef __WXMICROWIN__
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC:
{
- WXWORD nCtlColor;
WXHDC hdc;
WXHWND hwnd;
- UnpackCtlColor(wParam, lParam, &nCtlColor, &hdc, &hwnd);
-
- processed = HandleCtlColor(&rc.hBrush,
- (WXHDC)hdc,
- (WXHWND)hwnd,
- nCtlColor,
- message,
- wParam,
- lParam);
+ UnpackCtlColor(wParam, lParam, &hdc, &hwnd);
+
+ processed = HandleCtlColor(&rc.hBrush, (WXHDC)hdc, (WXHWND)hwnd);
}
break;
#endif // !__WXMICROWIN__
// do create the window
wxWindowCreationHook hook(this);
- // VZ: anyonce cares to explain why is this done for CE?
+ // VZ: anyone care to explain why this is done for CE?
#ifdef __WXWINCE__
if (extendedStyle == 0)
{
{
wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
- wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+ wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)),
+ false, _T("MSWOnDrawItem: bad wxMenuItem pointer") );
// prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
// the DC from being released
{
wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
- wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+ wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)),
+ false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") );
size_t w, h;
bool rc = pMenuItem->OnMeasureItem(&w, &h);
return GetEventHandler()->ProcessEvent(event);
}
-bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush,
- WXHDC pDC,
- WXHWND pWnd,
- WXUINT nCtlColor,
- WXUINT message,
- WXWPARAM wParam,
- WXLPARAM lParam)
-{
#ifndef __WXMICROWIN__
- WXHBRUSH hBrush = 0;
-#ifdef __WXWINCE__
- if (false)
-#else
- if ( nCtlColor == CTLCOLOR_DLG )
-#endif
- {
- hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
- }
+bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd)
+{
#if wxUSE_CONTROLS
+ wxWindow *item = FindItemByHWND(pWnd, true);
+ if ( item )
+ *brush = item->MSWControlColor(pDC);
else
- {
- wxControl *item = (wxControl *)FindItemByHWND(pWnd, true);
- if ( item )
- hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
- }
#endif // wxUSE_CONTROLS
+ *brush = NULL;
- if ( hBrush )
- *brush = hBrush;
-
- return hBrush != 0;
-#else // __WXMICROWIN__
- return false;
-#endif
+ return *brush != NULL;
}
-// Define for each class of dialog and control
-WXHBRUSH wxWindowMSW::OnCtlColor(WXHDC WXUNUSED(hDC),
- WXHWND WXUNUSED(hWnd),
- WXUINT WXUNUSED(nCtlColor),
- WXUINT WXUNUSED(message),
- WXWPARAM WXUNUSED(wParam),
- WXLPARAM WXUNUSED(lParam))
+#endif // __WXMICROWIN__
+
+WXHBRUSH wxWindowMSW::MSWControlColor(WXHDC WXUNUSED(hDC))
{
return (WXHBRUSH)0;
}
bool wxWindowMSW::HandlePaint()
{
-// if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
-// return false;
-
HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
if ( !hRegion )
wxLogLastError(wxT("CreateRectRgn"));
bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
{
- // Prevents flicker when dragging
- if ( ::IsIconic(GetHwnd()) )
- return true;
-
-#if 0
- if (GetParent() && GetParent()->GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
- {
- return false;
- }
-
- if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
- {
- if (wxUxThemeEngine::Get())
- {
- WXHTHEME hTheme = wxUxThemeEngine::Get()->m_pfnOpenThemeData(GetHWND(), L"TAB");
- if (hTheme)
- {
- WXURECT rect;
- ::GetClientRect((HWND) GetHWND(), (RECT*) & rect);
- wxUxThemeEngine::Get()->m_pfnDrawThemeBackground(hTheme, hdc, 10 /* TABP_BODY */, 0, &rect, &rect);
- wxUxThemeEngine::Get()->m_pfnCloseThemeData(hTheme);
- return true;
- }
- }
- }
-#endif
-
wxDCTemp dc(hdc);
dc.SetHDC(hdc);
void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
{
- RECT rect;
- ::GetClientRect(GetHwnd(), &rect);
+ // standard controls always erase their background themselves (although the
+ // user may try to override it in a derived class)
+ if ( IsOfStandardClass() )
+ {
+ event.Skip();
+ return;
+ }
- wxColour backgroundColour( GetBackgroundColour());
- COLORREF ref = PALETTERGB(backgroundColour.Red(),
- backgroundColour.Green(),
- backgroundColour.Blue());
- HBRUSH hBrush = ::CreateSolidBrush(ref);
- if ( !hBrush )
- wxLogLastError(wxT("CreateSolidBrush"));
+ if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM )
+ {
+ // don't skip the event here, custom background means that the app
+ // is drawing it itself in its OnPaint(), so don't draw it at all
+ // now to avoid flicker
+ return;
+ }
- HDC hdc = (HDC)event.GetDC()->GetHDC();
-#ifndef __WXWINCE__
- int mode = ::SetMapMode(hdc, MM_TEXT);
-#endif
+ // do default background painting
+ wxDC& dc = *event.GetDC();
+ HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
+ if ( hBrush )
+ {
+ RECT rc;
+ ::GetClientRect(GetHwnd(), &rc);
+ ::FillRect(GetHdcOf(dc), &rc, hBrush);
+ }
+ else
+ {
+ // let the system paint the background
+ event.Skip();
+ }
+}
- ::FillRect(hdc, &rect, hBrush);
- ::DeleteObject(hBrush);
+WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child)
+{
+ wxColour col = MSWGetBgColourForChild(child);
+ if ( col.Ok() )
+ {
+ // draw children with the same colour as the parent
+ wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID);
-#ifndef __WXWINCE__
- ::SetMapMode(hdc, mode);
-#endif
+ return (WXHBRUSH)brush->GetResourceHandle();
+ }
+
+ return 0;
+}
+
+wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow * WXUNUSED(child))
+{
+ return m_hasBgCol ? GetBackgroundColour() : wxNullColour;
+}
+
+WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC)
+{
+ return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this);
+}
+
+WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC)
+{
+ for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() )
+ {
+ // background is not inherited beyond the containing TLW
+ if ( win->IsTopLevel() )
+ break;
+
+ WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC);
+ if ( hBrush )
+ return hBrush;
+ }
+
+ return 0;
}
// ---------------------------------------------------------------------------
bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
{
// the mouse events take consecutive IDs from WM_MOUSEFIRST to
- // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
+ // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
// from the message id and take the value in the table to get wxWin event
// id
static const wxEventType eventsMouse[] =
event.m_eventObject = (wxWindow *)this; // const_cast
event.m_keyCode = id;
#if wxUSE_UNICODE
- event.m_uniChar = wParam;
+ event.m_uniChar = (wxChar) wParam;
#endif
event.m_rawCode = (wxUint32) wParam;
event.m_rawFlags = (wxUint32) lParam;
case VK_NUMLOCK: id = WXK_NUMLOCK; break;
case VK_SCROLL: id = WXK_SCROLL; break;
+ // the mapping for these keys may be incorrect on non-US keyboards so
+ // maybe we shouldn't map them to ASCII values at all
case VK_OEM_1: id = ';'; break;
case VK_OEM_PLUS: id = '+'; break;
case VK_OEM_COMMA: id = ','; break;
bool wxGetKeyState(wxKeyCode key)
{
bool bVirtual;
- WORD vkey = wxCharCodeWXToMSW(key, &bVirtual);
- SHORT state;
- switch (key)
+//High order with GetAsyncKeyState only available on WIN32
+#ifdef __WIN32__
+ //If the requested key is a LED key, return
+ //true if the led is pressed
+ if (key == WXK_NUMLOCK ||
+ key == WXK_CAPITAL ||
+ key == WXK_SCROLL)
{
- case WXK_NUMLOCK:
- case WXK_CAPITAL:
- case WXK_SCROLL:
- // get the toggle state of the special key
- state = GetKeyState(vkey);
- break;
+#endif
+ //low order bit means LED is highlighted,
+ //high order means key is down
+ //Here, for compat with other ports we want both
+ return GetKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) != 0;
- default:
- // Get the current state of the physical key
- state = GetAsyncKeyState(vkey);
- break;
+#ifdef __WIN32__
+ }
+ else
+ {
+ //normal key
+ //low order bit means key pressed since last call
+ //high order means key is down
+ //We want only the high order bit - the key may not be down if only low order
+ return ( GetAsyncKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) & (1<<15) ) != 0;
}
- // if the most significant bit is set then the key is down
- return ( state & 0x0001 ) != 0;
+#endif
}
wxWindow *wxGetActiveWindow()
static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MSG *msg = (MSG*)lParam;
- if ( msg->message == WM_NULL )
+
+ // only process the message if it is actually going to be removed from
+ // the message queue, this prevents that the same event from being
+ // processed multiple times if now someone just called PeekMessage()
+ if ( msg->message == WM_NULL && wParam == PM_REMOVE )
{
wxTheApp->ProcessPendingEvents();
}