extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
wxWindow *wxFindWinFromHandle(WXHWND hWnd);
-// this magical function is used to translate VK_APPS key presses to right
-// mouse clicks
-static void TranslateKbdEventToMouse(wxWindowMSW *win,
- int *x, int *y, WPARAM *flags);
-
// get the text metrics for the current font
static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
wxFLAGS_MEMBER(wxBORDER_RAISED)
wxFLAGS_MEMBER(wxBORDER_STATIC)
wxFLAGS_MEMBER(wxBORDER_NONE)
-
+
// old style border flags
wxFLAGS_MEMBER(wxSIMPLE_BORDER)
wxFLAGS_MEMBER(wxSUNKEN_BORDER)
#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
END_EVENT_TABLE()
// ===========================================================================
msflags |= WS_VISIBLE;
}
- return MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle);
+ if ( !MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle) )
+ return false;
+
+ InheritAttributes();
+
+ return true;
}
// ---------------------------------------------------------------------------
}
// Get the window with the focus
-wxWindow *wxWindowBase::FindFocus()
+wxWindow *wxWindowBase::DoFindFocus()
{
HWND hWnd = ::GetFocus();
if ( hWnd )
HWND hwnd = GetHwnd();
if ( hwnd )
{
- m_hWnd = 0;
+ SetHWND(0);
wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in UnsubclassWin") );
}
}
+void wxWindowMSW::AssociateHandle(WXWidget handle)
+{
+ if ( m_hWnd )
+ {
+ if ( !::DestroyWindow(GetHwnd()) )
+ wxLogLastError(wxT("DestroyWindow"));
+ }
+
+ WXHWND wxhwnd = (WXHWND)handle;
+
+ SetHWND(wxhwnd);
+ SubclassWin(wxhwnd);
+}
+
+void wxWindowMSW::DissociateHandle()
+{
+ // this also calls SetHWND(0) for us
+ UnsubclassWin();
+}
+
+
bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
{
// Unicows note: the code below works, but only because WNDCLASS contains
HWND hWnd = GetHwnd();
if ( hWnd )
::DragAcceptFiles(hWnd, (BOOL)accept);
+#else
+ wxUnusedVar(accept);
#endif
}
return;
}
- if ( x == wxDefaultPosition.x && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+ if ( x == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
x = currentX;
- if ( y == wxDefaultPosition.y && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+ if ( y == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
y = currentY;
AdjustForParentClientOrigin(x, y, sizeFlags);
wxSize size = wxDefaultSize;
- if ( width == wxDefaultSize.x )
+ if ( width == wxDefaultCoord )
{
if ( sizeFlags & wxSIZE_AUTO_WIDTH )
{
}
}
- if ( height == wxDefaultSize.y )
+ if ( height == wxDefaultCoord )
{
if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
{
- if ( size.x == wxDefaultSize.x )
+ if ( size.x == wxDefaultCoord )
{
size = DoGetBestSize();
}
::GetClientRect(GetHwnd(), &rectClient);
// if the size is already ok, stop here (rectClient.left = top = 0)
- if ( (rectClient.right == width || width == wxDefaultSize.x) &&
- (rectClient.bottom == height || height == wxDefaultSize.y) )
+ if ( (rectClient.right == width || width == wxDefaultCoord) &&
+ (rectClient.bottom == height || height == wxDefaultCoord) )
{
break;
}
int *descent, int *externalLeading,
const wxFont *theFont) const
{
- const wxFont *fontToUse = theFont;
- if ( !fontToUse )
- fontToUse = &m_font;
+ wxASSERT_MSG( !theFont || theFont->Ok(),
+ _T("invalid font in GetTextExtent()") );
- HWND hWnd = GetHwnd();
- HDC dc = ::GetDC(hWnd);
+ wxFont fontToUse;
+ if (theFont)
+ fontToUse = *theFont;
+ else
+ fontToUse = GetFont();
- HFONT fnt = 0;
- HFONT hfontOld = 0;
- if ( fontToUse && fontToUse->Ok() )
- {
- fnt = (HFONT)((wxFont *)fontToUse)->GetResourceHandle(); // const_cast
- if ( fnt )
- hfontOld = (HFONT)SelectObject(dc,fnt);
- }
+ WindowHDC hdc(GetHwnd());
+ SelectInHDC selectFont(hdc, GetHfontOf(fontToUse));
SIZE sizeRect;
TEXTMETRIC tm;
- GetTextExtentPoint(dc, string, (int)string.Length(), &sizeRect);
- GetTextMetrics(dc, &tm);
-
- if ( fontToUse && fnt && hfontOld )
- SelectObject(dc, hfontOld);
-
- ReleaseDC(hWnd, dc);
+ GetTextExtentPoint(hdc, string, string.length(), &sizeRect);
+ GetTextMetrics(hdc, &tm);
if ( x )
*x = sizeRect.cx;
menu->SetInvokingWindow(this);
menu->UpdateUI();
- if ( x == -1 && y == -1 )
+ if ( x == wxDefaultCoord && y == wxDefaultCoord )
{
wxPoint mouse = ScreenToClient(wxGetMousePosition());
x = mouse.x; y = mouse.y;
point.y = y;
::ClientToScreen(hWnd, &point);
wxCurrentPopupMenu = menu;
+#if defined(__WXWINCE__)
UINT flags = 0;
-#if !defined(__WXWINCE__)
- flags = TPM_RIGHTBUTTON;
+#else
+ UINT flags = TPM_RIGHTBUTTON;
#endif
::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
// 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,
#endif
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);
- }
+ processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
break;
#if !defined(__WXWINCE__)
case WM_MOUSELEAVE:
{
wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
-
+
// only process this message if the mouse is not in the window,
- // This can also check for children in composite windows.
+ // This can also check for children in composite windows.
// however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
- // if the mouse does not enter the window from it's child before
+ // if the mouse does not enter the window from it's child before
// leaving the scope of the window. ( perhaps this can be picked
// up in the OnIdle code as before, for this special case )
if ( /*IsComposite() && */ !IsMouseInWindow() )
{
m_mouseInWindow = false;
- // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
+ // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
int state = 0;
if ( wxIsShiftDown() )
state |= MK_SHIFT;
break;
#endif
// __WXWINCE__
-
+
#if wxUSE_MOUSEWHEEL
case WM_MOUSEWHEEL:
processed = HandleMouseWheel(wParam, 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;
// 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);
- }
+ processed = HandleMouseEvent(WM_RBUTTONDOWN, -1, -1, 0);
break;
#endif // 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);
+ processed = HandleMouseEvent(WM_RBUTTONUP, -1, -1, 0);
}
else
#endif // VK_APPS
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__
bool nonDefault = false;
- if ( pos.x == wxDefaultPosition.x )
+ if ( pos.x == wxDefaultCoord )
{
// if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we
// can just as well set it to CW_USEDEFAULT as well
// neither because it is not handled as a special value by Windows then
// and so we have to choose some default value for it
x = pos.x;
- y = pos.y == wxDefaultPosition.y ? DEFAULT_Y : pos.y;
+ y = pos.y == wxDefaultCoord ? DEFAULT_Y : pos.y;
nonDefault = true;
}
already has - so no WM_SIZE would be sent.
*/
-
+
// we don't use CW_USEDEFAULT here for several reasons:
//
// 1. it results in huge frames on modern screens (1000*800 is not
// However, on PocketPC devices, we must use the default
// size if possible.
#ifdef _WIN32_WCE
- if (size.x == wxDefaultSize.x)
+ if (size.x == wxDefaultCoord)
w = CW_USEDEFAULT;
else
w = size.x;
- if (size.y == wxDefaultSize.y)
+ if (size.y == wxDefaultCoord)
h = CW_USEDEFAULT;
else
h = size.y;
#else
- if ( size.x == wxDefaultSize.x || size.y == wxDefaultSize.y)
+ if ( size.x == wxDefaultCoord || size.y == wxDefaultCoord)
{
nonDefault = true;
}
// 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)
{
return true;
}
}
+#else
+ wxUnusedVar(lParam);
#endif // wxUSE_TOOLTIPS
return false;
#ifndef __WXWINCE__
if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT )
EnsureParentHasControlParentStyle(GetParent());
+#else
+ wxUnusedVar(cs);
#endif // !__WXWINCE__
// TODO: should generate this event from WM_NCCREATE
bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
{
+ // Strangly enough, some controls get set focus events when they are being
+ // deleted, even if they already had focus before.
+ if ( m_isBeingDeleted )
+ {
+ return false;
+ }
+
// notify the parent keeping track of focus for the kbd navigation
// purposes that we got it
wxChildFocusEvent eventFocus((wxWindow *)this);
bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
{
#if defined (__WXMICROWIN__) || defined(__WXWINCE__)
+ wxUnusedVar(wParam);
return false;
#else // __WXMICROWIN__
HDROP hFilesInfo = (HDROP) wParam;
{
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
#else // !wxUSE_OWNER_DRAWN
// we may still have owner-drawn buttons internally because we have to make
// them owner-drawn to support colour change
- wxControl *item = wxDynamicCast(FindItem(id), wxButton);
+ wxControl *item =
+# if wxUSE_BUTTON
+ wxDynamicCast(FindItem(id), wxButton)
+# else
+ NULL
+# endif
+ ;
#endif // USE_OWNER_DRAWN
if ( item )
}
bool
-wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id),
- WXMEASUREITEMSTRUCT *
- WXUNUSED_UNLESS_ODRAWN(itemStruct))
+wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
{
#if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE
// is it a menu item?
{
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 item->MSWOnMeasure(itemStruct);
}
-#endif // wxUSE_OWNER_DRAWN
+#else
+ wxUnusedVar(id);
+ wxUnusedVar(itemStruct);
+#endif // wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE
return false;
}
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;
}
node = node->GetNext();
}
-
- // update the colours we use if they were not set explicitly by the user:
- // this must be done or OnCtlColor() would continue to use the old colours
- if ( !m_hasFgCol || !m_hasBgCol )
- {
- wxVisualAttributes attrs = GetDefaultAttributes();
- if ( !m_hasFgCol )
- m_foregroundColour = attrs.colFg;
-
- if ( !m_hasBgCol )
- m_backgroundColour = attrs.colBg;
- }
}
extern wxCOLORMAP *wxGetStdColourMap()
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);
-
- wxColour backgroundColour( GetBackgroundColour());
- COLORREF ref = PALETTERGB(backgroundColour.Red(),
- backgroundColour.Green(),
- backgroundColour.Blue());
- HBRUSH hBrush = ::CreateSolidBrush(ref);
- if ( !hBrush )
- wxLogLastError(wxT("CreateSolidBrush"));
-
- HDC hdc = (HDC)event.GetDC()->GetHDC();
+ // standard controls always erase their background themselves (although the
+ // user may try to override it in a derived class)
+ if ( IsOfStandardClass() )
+ {
+ event.Skip();
+ return;
+ }
-#ifndef __WXWINCE__
- int mode = ::SetMapMode(hdc, MM_TEXT);
-#endif
+ 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;
+ }
- ::FillRect(hdc, &rect, hBrush);
- ::DeleteObject(hBrush);
-#ifndef __WXWINCE__
- ::SetMapMode(hdc, mode);
-#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();
+ }
+}
+
+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);
+
+ 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::HandleMove(int x, int y)
{
- wxMoveEvent event(wxPoint(x, y), m_windowId);
+ wxPoint point(x,y);
+ wxMoveEvent event(point, m_windowId);
event.SetEventObject(this);
return GetEventHandler()->ProcessEvent(event);
return rc;
}
-bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h),
- WXUINT WXUNUSED(flag))
+bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
{
- // don't use w and h parameters as they specify the client size while
- // according to the docs EVT_SIZE handler is supposed to receive the total
- // size
- wxSizeEvent event(GetSize(), m_windowId);
- event.SetEventObject(this);
+ bool processed = false;
- return GetEventHandler()->ProcessEvent(event);
+ switch ( wParam )
+ {
+ default:
+ wxFAIL_MSG( _T("unexpected WM_SIZE parameter") );
+ // fall through nevertheless
+
+ case SIZE_MAXHIDE:
+ case SIZE_MAXSHOW:
+ // we're not interested in these messages at all
+ break;
+
+ case SIZE_MINIMIZED:
+ processed = HandleMinimize();
+ break;
+
+ case SIZE_MAXIMIZED:
+ /* processed = */ HandleMaximize();
+ // fall through to send a normal size event as well
+
+ case SIZE_RESTORED:
+ // don't use w and h parameters as they specify the client size
+ // while according to the docs EVT_SIZE handler is supposed to
+ // receive the total size
+ wxSizeEvent event(GetSize(), m_windowId);
+ event.SetEventObject(this);
+
+ processed = GetEventHandler()->ProcessEvent(event);
+ }
+
+ return processed;
}
bool wxWindowMSW::HandleSizing(wxRect& rect)
bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
{
#ifdef __WXWINCE__
+ wxUnusedVar(mmInfo);
return false;
#else
MINMAXINFO *info = (MINMAXINFO *)mmInfo;
maxWidth = GetMaxWidth(),
maxHeight = GetMaxHeight();
- if ( minWidth != wxDefaultSize.x )
+ if ( minWidth != wxDefaultCoord )
{
info->ptMinTrackSize.x = minWidth;
rc = true;
}
- if ( minHeight != wxDefaultSize.y )
+ if ( minHeight != wxDefaultCoord )
{
info->ptMinTrackSize.y = minHeight;
rc = true;
}
- if ( maxWidth != wxDefaultSize.x )
+ if ( maxWidth != wxDefaultCoord )
{
info->ptMaxTrackSize.x = maxWidth;
rc = true;
}
- if ( maxHeight != wxDefaultSize.y )
+ if ( maxHeight != wxDefaultCoord )
{
info->ptMaxTrackSize.y = maxHeight;
rc = true;
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[] =
trackinfo.hwndTrack = GetHwnd();
//Use the commctrl.h _TrackMouseEvent, which will call the
// appropriate TrackMouseEvent or emulate it ( win95 )
- // else we need _WIN32_WINNT >= 0x0400
+ // else we need _WIN32_WINNT >= 0x0400
_TrackMouseEvent(&trackinfo);
#endif
#endif
event.m_eventObject = (wxWindow *)this; // const_cast
event.m_keyCode = id;
+#if wxUSE_UNICODE
+ event.m_uniChar = (wxChar) wParam;
+#endif
event.m_rawCode = (wxUint32) wParam;
event.m_rawFlags = (wxUint32) lParam;
#ifndef __WXWINCE__
// FIXME-UNICODE: this comparison doesn't risk to work
// for non ASCII accelerator characters I'm afraid, but
// what can we do?
- if ( wxToupper(*p) == chAccel )
+ if ( (wchar_t)wxToupper(*p) == (wchar_t)chAccel )
{
return i;
}
bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
WXWORD pos, WXHWND control)
-{
+{
if ( control && control != m_hWnd ) // Prevent infinite recursion
{
wxWindow *child = wxFindWinFromHandle(control);
// global functions
// ===========================================================================
-void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font)
+void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font)
{
TEXTMETRIC tm;
HDC dc = ::GetDC((HWND) wnd);
- HFONT fnt =0;
HFONT was = 0;
- if ( the_font )
- {
- // the_font->UseResource();
- // the_font->RealizeResource();
- fnt = (HFONT)((wxFont *)the_font)->GetResourceHandle(); // const_cast
- if ( fnt )
- was = (HFONT) SelectObject(dc,fnt);
- }
+
+ // the_font.UseResource();
+ // the_font.RealizeResource();
+ HFONT fnt = (HFONT)the_font.GetResourceHandle(); // const_cast
+ if ( fnt )
+ was = (HFONT) SelectObject(dc,fnt);
+
GetTextMetrics(dc, &tm);
- if ( the_font && fnt && was )
+ if ( fnt && was )
{
SelectObject(dc,was);
}
if ( y )
*y = tm.tmHeight + tm.tmExternalLeading;
- // if ( the_font )
- // the_font->ReleaseResource();
+ // the_font.ReleaseResource();
}
// Returns 0 if was a normal ASCII value, not a special key. This indicates that
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;
return id;
}
-int wxCharCodeWXToMSW(int id, bool *isVirtual)
+WXWORD wxCharCodeWXToMSW(int id, bool *isVirtual)
{
*isVirtual = true;
- int keySym;
+ WXWORD keySym;
switch (id)
{
case WXK_CANCEL: keySym = VK_CANCEL; break;
default:
{
*isVirtual = false;
- keySym = id;
+ keySym = (WORD)id;
break;
}
}
bool wxGetKeyState(wxKeyCode key)
{
bool bVirtual;
- int 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;
-
- default:
- // Get the current state of the physical key
- state = GetAsyncKeyState(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;
+
+#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()
}
#endif //__WXDEBUG__
-static void TranslateKbdEventToMouse(wxWindowMSW *win,
- int *x, int *y, WPARAM *flags)
-{
- // construct the key mask
- WPARAM& fwKeys = *flags;
-
- fwKeys = MK_RBUTTON;
- if ( wxIsCtrlDown() )
- fwKeys |= MK_CONTROL;
- if ( wxIsShiftDown() )
- fwKeys |= MK_SHIFT;
-
- // simulate right mouse button click
- DWORD dwPos = ::GetMessagePos();
- *x = GET_X_LPARAM(dwPos);
- *y = GET_Y_LPARAM(dwPos);
-
- win->ScreenToClient(x, y);
-}
-
static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win)
{
// prepare the DC
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();
}
#endif // __WXWINCE__
+#ifdef __WXWINCE__
+
+#if wxUSE_STATBOX
+static void wxAdjustZOrder(wxWindow* parent)
+{
+ if (parent->IsKindOf(CLASSINFO(wxStaticBox)))
+ {
+ // Set the z-order correctly
+ SetWindowPos((HWND) parent->GetHWND(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ }
+
+ wxWindowList::compatibility_iterator current = parent->GetChildren().GetFirst();
+ while (current)
+ {
+ wxWindow *childWin = current->GetData();
+ wxAdjustZOrder(childWin);
+ current = current->GetNext();
+ }
+}
+#endif
+
+// We need to adjust the z-order of static boxes in WinCE, to
+// make 'contained' controls visible
+void wxWindowMSW::OnInitDialog( wxInitDialogEvent& event )
+{
+#if wxUSE_STATBOX
+ wxAdjustZOrder(this);
+#endif
+
+ event.Skip();
+}
+#endif
+