void wxFileDialog::MSWOnInitDone(WXHWND hDlg) { // note the dialog is the parent window: hDlg is a child of it when // OFN_EXPLORER is used HWND hFileDlg = ::GetParent((HWND)hDlg); // set HWND so that our DoMoveWindow() works correctly SetHWND((WXHWND)hFileDlg); if ( m_centreDir ) { // now we have the real dialog size, remember it RECT rect; GetWindowRect(hFileDlg, &rect); gs_rectDialog = wxRectFromRECT(rect); // and position the window correctly: notice that we must use the base // class version as our own doesn't do anything except setting flags wxFileDialogBase::DoCentre(m_centreDir); } else // need to just move it to the correct place { SetPosition(gs_rectDialog.GetPosition()); } // we shouldn't destroy this HWND SetHWND(NULL); }
// TODO: handle WM_WININICHANGE wxSize wxCalendarCtrl::DoGetBestSize() const { RECT rc; if ( !GetHwnd() || !MonthCal_GetMinReqRect(GetHwnd(), &rc) ) { return wxCalendarCtrlBase::DoGetBestSize(); } return wxRectFromRECT(rc).GetSize() + GetWindowBorderSize(); }
void wxDialog::ResizeGripper() { wxASSERT_MSG( m_hGripper, wxT("shouldn't be called if we have no gripper") ); HWND hwndGripper = (HWND)m_hGripper; const wxRect rectGripper = wxRectFromRECT(wxGetWindowRect(hwndGripper)); const wxSize size = GetClientSize() - rectGripper.GetSize(); ::SetWindowPos(hwndGripper, HWND_BOTTOM, size.x, size.y, rectGripper.width, rectGripper.height, SWP_NOACTIVATE); }
bool wxBitmapComboBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT) item; int pos = lpDrawItem->itemID; // Draw default for item -1, which means 'focus rect only' if ( pos == -1 ) return false; int flags = 0; if ( lpDrawItem->itemState & ODS_COMBOBOXEDIT ) flags |= wxODCB_PAINTING_CONTROL; if ( lpDrawItem->itemState & ODS_SELECTED ) flags |= wxODCB_PAINTING_SELECTED; wxPaintDCEx dc(this, lpDrawItem->hDC); wxRect rect = wxRectFromRECT(lpDrawItem->rcItem); wxBitmapComboBoxBase::DrawBackground(dc, rect, pos, flags); wxString text; if ( flags & wxODCB_PAINTING_CONTROL ) { // Don't draw anything in the editable selection field. if ( !HasFlag(wxCB_READONLY) ) return true; pos = GetSelection(); // Skip drawing if there is nothing selected. if ( pos < 0 ) return true; text = GetValue(); } else { text = GetString(pos); } wxBitmapComboBoxBase::DrawItem(dc, rect, pos, text, flags); // If the item has the focus, draw focus rectangle. // Commented out since regular combo box doesn't // seem to do it either. //if ( lpDrawItem->itemState & ODS_FOCUS ) // DrawFocusRect(lpDrawItem->hDC, &lpDrawItem->rcItem); return true; }
bool wxListBox::GetItemRect(size_t n, wxRect& rect) const { wxCHECK_MSG( IsValid(n), false, wxT("invalid index in wxListBox::GetItemRect") ); RECT rc; if ( ListBox_GetItemRect(GetHwnd(), n, &rc) != LB_ERR ) { rect = wxRectFromRECT(rc); return true; } else { // couldn't retrieve rect: for example, item isn't visible return false; } }
// forward the message to the appropriate item bool wxListBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { // only owner-drawn control should receive this message wxCHECK( HasFlag(wxLB_OWNERDRAW), false ); DRAWITEMSTRUCT *pStruct = (DRAWITEMSTRUCT *)item; // the item may be -1 for an empty listbox if ( pStruct->itemID == (UINT)-1 ) return false; wxListBoxItem *pItem = (wxListBoxItem *)m_aItems[pStruct->itemID]; wxDCTemp dc((WXHDC)pStruct->hDC); return pItem->OnDrawItem(dc, wxRectFromRECT(pStruct->rcItem), (wxOwnerDrawn::wxODAction)pStruct->itemAction, (wxOwnerDrawn::wxODStatus)(pStruct->itemState | wxOwnerDrawn::wxODHidePrefix)); }
bool wxNativeWindow::Create(wxWindow* parent, wxWindowID winid, wxNativeWindowHandle hwnd) { wxCHECK_MSG( hwnd, false, wxS("Invalid null HWND") ); wxCHECK_MSG( parent, false, wxS("Must have a valid parent") ); wxASSERT_MSG( ::GetParent(hwnd) == GetHwndOf(parent), wxS("The native window has incorrect parent") ); const wxRect r = wxRectFromRECT(wxGetWindowRect(hwnd)); // Skip wxWindow::Create() which would try to create a new HWND, we don't // want this as we already have one. if ( !CreateBase(parent, winid, r.GetPosition(), r.GetSize(), 0, wxDefaultValidator, wxS("nativewindow")) ) return false; parent->AddChild(this); SubclassWin(hwnd); if ( winid == wxID_ANY ) { // We allocated a new ID to the control, use it at Windows level as // well because we assume that our and MSW IDs are the same in many // places and it seems prudent to avoid breaking this assumption. SetId(GetId()); } else // We used a fixed ID. { // For the same reason as above, check that it's the same as the one // used by the native HWND. wxASSERT_MSG( ::GetWindowLong(hwnd, GWL_ID) == winid, wxS("Mismatch between wx and native IDs") ); } InheritAttributes(); return true; }
bool wxSpinCtrl::Reparent(wxWindowBase *newParent) { // Reparenting both the updown control and its buddy does not seem to work: // they continue to be connected somehow, but visually there is no feedback // on the buddy edit control. To avoid this problem, we reparent the buddy // window normally, but we recreate the updown control and reassign its // buddy. if ( !wxWindowBase::Reparent(newParent) ) return false; newParent->GetChildren().DeleteObject(this); // preserve the old values const wxSize size = GetSize(); int value = GetValue(); const wxRect btnRect = wxRectFromRECT(wxGetWindowRect(GetHwnd())); // destroy the old spin button UnsubclassWin(); if ( !::DestroyWindow(GetHwnd()) ) { wxLogLastError(wxT("DestroyWindow")); } // create and initialize the new one if ( !wxSpinButton::Create(GetParent(), GetId(), btnRect.GetPosition(), btnRect.GetSize(), GetWindowStyle(), GetName()) ) return false; SetValue(value); SetRange(m_min, m_max); SetInitialSize(size); // associate it with the buddy control again ::SetParent(GetBuddyHwnd(), GetHwndOf(GetParent())); (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)GetBuddyHwnd(), 0); return true; }
void wxColourDialog::MSWOnInitDone(WXHWND hDlg) { // set HWND so that our DoMoveWindow() works correctly SetHWND(hDlg); if ( m_centreDir ) { // now we have the real dialog size, remember it RECT rect; ::GetWindowRect((HWND)hDlg, &rect); gs_rectDialog = wxRectFromRECT(rect); // and position the window correctly: notice that we must use the base // class version as our own doesn't do anything except setting flags wxDialog::DoCentre(m_centreDir); } else if ( m_movedWindow ) // need to just move it to the correct place { SetPosition(GetPosition()); } // we shouldn't destroy hDlg, so disassociate from it SetHWND(NULL); }
// forward the message to the appropriate item bool wxListBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { // only owner-drawn control should receive this message wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), false ); DRAWITEMSTRUCT *pStruct = (DRAWITEMSTRUCT *)item; UINT itemID = pStruct->itemID; // the item may be -1 for an empty listbox if ( itemID == (UINT)-1 ) return false; LRESULT data = ListBox_GetItemData(GetHwnd(), pStruct->itemID); wxCHECK( data && (data != LB_ERR), false ); wxListBoxItem *pItem = (wxListBoxItem *)data; wxDCTemp dc((WXHDC)pStruct->hDC); return pItem->OnDrawItem(dc, wxRectFromRECT(pStruct->rcItem), (wxOwnerDrawn::wxODAction)pStruct->itemAction, (wxOwnerDrawn::wxODStatus)pStruct->itemState); }
bool wxCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return wxCheckBoxBase::MSWOnDraw(item); // calculate the rectangles for the check mark itself and the label HDC hdc = dis->hDC; RECT& rect = dis->rcItem; RECT rectCheck, rectLabel; rectLabel.top = rect.top + (rect.bottom - rect.top - GetBestSize().y) / 2; rectLabel.bottom = rectLabel.top + GetBestSize().y; const int MARGIN = 3; const int CXMENUCHECK = ::GetSystemMetrics(SM_CXMENUCHECK); // the space between the checkbox and the label is included in the // check-mark bitmap const int checkSize = wxMin(CXMENUCHECK - MARGIN, GetSize().y); rectCheck.top = rect.top + (rect.bottom - rect.top - checkSize) / 2; rectCheck.bottom = rectCheck.top + checkSize; const bool isRightAligned = HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectLabel.right = rect.right - CXMENUCHECK; rectLabel.left = rect.left; rectCheck.left = rectLabel.right + ( CXMENUCHECK + MARGIN - checkSize ) / 2; rectCheck.right = rectCheck.left + checkSize; } else // normal, left-aligned checkbox { rectCheck.left = rect.left + ( CXMENUCHECK - MARGIN - checkSize ) / 2; rectCheck.right = rectCheck.left + checkSize; rectLabel.left = rect.left + CXMENUCHECK; rectLabel.right = rect.right; } // shall we draw a focus rect? const bool isFocused = m_isPressed || FindFocus() == this; // draw the checkbox itself wxDCTemp dc(hdc); int flags = 0; if ( !IsEnabled() ) flags |= wxCONTROL_DISABLED; switch ( Get3StateValue() ) { case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED; break; case wxCHK_UNDETERMINED: flags |= wxCONTROL_PRESSED; break; default: wxFAIL_MSG( wxT("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: // no extra styles needed break; } if ( wxFindWindowAtPoint(wxGetMousePosition()) == this ) flags |= wxCONTROL_CURRENT; wxRendererNative::Get(). DrawCheckBox(this, dc, wxRectFromRECT(rectCheck), flags); // draw the text const wxString& label = GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { RECT oldLabelRect = rectLabel; // needed if right aligned if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(wxT("DrawText(DT_CALCRECT)")); } if ( isRightAligned ) { // move the label rect to the right const int labelWidth = rectLabel.right - rectLabel.left; rectLabel.right = oldLabelRect.right; rectLabel.left = rectLabel.right - labelWidth; } } if ( !IsEnabled() ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt) ) { wxLogLastError(wxT("DrawText()")); } // finally draw the focus if ( isFocused ) { rectLabel.left--; rectLabel.right++; if ( !::DrawFocusRect(hdc, &rectLabel) ) { wxLogLastError(wxT("DrawFocusRect()")); } } return true; }
bool gcCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return wxCheckBoxBase::MSWOnDraw(item); // calculate the rectangles for the check mark itself and the label HDC hdc = dis->hDC; RECT& rect = dis->rcItem; RECT rectCheck, rectLabel; rectCheck.top = rectLabel.top = rect.top; rectCheck.bottom = rectLabel.bottom = rect.bottom; const int checkSize = GetBestSize().y; const int MARGIN = 3; const bool isRightAligned = HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectCheck.right = rect.right; rectCheck.left = rectCheck.right - checkSize; rectLabel.right = rectCheck.left - MARGIN; rectLabel.left = rect.left; } else // normal, left-aligned checkbox { rectCheck.left = rect.left; rectCheck.right = rectCheck.left + checkSize; rectLabel.left = rectCheck.right + MARGIN; rectLabel.right = rect.right; } // show we draw a focus rect? const bool isFocused = IsChecked() || FindFocus() == this; // draw the checkbox itself wxDCTemp dc(hdc); int flags = 0; if ( !IsEnabled() ) flags |= wxCONTROL_DISABLED; switch ( Get3StateValue() ) { case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED; break; case wxCHK_UNDETERMINED: flags |= wxCONTROL_PRESSED; break; default: wxFAIL_MSG( _T("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: // no extra styles needed break; } if ( wxFindWindowAtPoint(wxGetMousePosition()) == this ) flags |= wxCONTROL_CURRENT; wxRendererNative::Get(). DrawCheckBox(this, dc, wxRectFromRECT(rectCheck), flags); // draw the text const wxString& label = GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { if ( !::DrawText(hdc, label.wx_str(), label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(_T("DrawText(DT_CALCRECT)")); } } if ( !IsEnabled() ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label.wx_str(), label.length(), &rectLabel, fmt) ) { wxLogLastError(_T("DrawText()")); } //// finally draw the focus if ( isFocused ) { COLORREF colBg = wxColourToRGB(wxColor(GetGCThemeManager()->getColor("checkbox", "focus-fg"))); HBRUSH hbrush = ::CreateSolidBrush(colBg); rectLabel.left--; rectLabel.right++; ::FrameRect(hdc, &rectLabel, hbrush); ::DeleteObject(hbrush); } return true; }
bool wxMSWOwnerDrawnButtonBase::MSWDrawButton(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !MSWIsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return false; // shall we draw a focus rect? const bool isFocused = m_isPressed || m_win->HasFocus(); int flags = MSWGetButtonCheckedFlag(); if ( dis->itemState & ODS_SELECTED ) flags |= wxCONTROL_SELECTED | wxCONTROL_PRESSED; if ( !m_win->IsEnabled() ) flags |= wxCONTROL_DISABLED; if ( m_isPressed ) flags |= wxCONTROL_PRESSED; if ( wxFindWindowAtPoint(wxGetMousePosition()) == m_win ) flags |= wxCONTROL_CURRENT; // calculate the rectangles for the button itself and the label HDC hdc = dis->hDC; const RECT& rect = dis->rcItem; // calculate the rectangles for the button itself and the label const wxSize bestSize = m_win->GetBestSize(); RECT rectButton, rectLabel; rectLabel.top = rect.top + (rect.bottom - rect.top - bestSize.y) / 2; rectLabel.bottom = rectLabel.top + bestSize.y; // choose the values consistent with those used for native, non // owner-drawn, buttons static const int MARGIN = 3; int CXMENUCHECK = ::GetSystemMetrics(SM_CXMENUCHECK) + 1; // the buttons were even bigger under Windows XP if ( wxGetWinVersion() < wxWinVersion_6 ) CXMENUCHECK += 2; // The space between the button and the label // is included in the button bitmap. const int buttonSize = wxMin(CXMENUCHECK - MARGIN, m_win->GetSize().y); rectButton.top = rect.top + (rect.bottom - rect.top - buttonSize) / 2; rectButton.bottom = rectButton.top + buttonSize; const bool isRightAligned = m_win->HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectLabel.right = rect.right - CXMENUCHECK; rectLabel.left = rect.left; rectButton.left = rectLabel.right + ( CXMENUCHECK + MARGIN - buttonSize ) / 2; rectButton.right = rectButton.left + buttonSize; } else // normal, left-aligned button { rectButton.left = rect.left + ( CXMENUCHECK - MARGIN - buttonSize ) / 2; rectButton.right = rectButton.left + buttonSize; rectLabel.left = rect.left + CXMENUCHECK; rectLabel.right = rect.right; } // Erase the background. ::FillRect(hdc, &rect, m_win->MSWGetBgBrush(hdc)); // draw the button itself wxDCTemp dc(hdc); MSWDrawButtonBitmap(dc, wxRectFromRECT(rectButton), flags); // draw the text const wxString& label = m_win->GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { RECT oldLabelRect = rectLabel; // needed if right aligned if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(wxT("DrawText(DT_CALCRECT)")); } if ( isRightAligned ) { // move the label rect to the right const int labelWidth = rectLabel.right - rectLabel.left; rectLabel.right = oldLabelRect.right; rectLabel.left = rectLabel.right - labelWidth; } } if ( flags & wxCONTROL_DISABLED ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt) ) { wxLogLastError(wxT("DrawText()")); } // finally draw the focus if ( isFocused ) { rectLabel.left--; rectLabel.right++; if ( !::DrawFocusRect(hdc, &rectLabel) ) { wxLogLastError(wxT("DrawFocusRect()")); } } return true; }