int wxColourDialog::ShowModal() { // initialize the struct used by Windows CHOOSECOLOR chooseColorStruct; memset(&chooseColorStruct, 0, sizeof(CHOOSECOLOR)); size_t i; // and transfer data from m_colourData to it COLORREF custColours[16]; for ( i = 0; i < WXSIZEOF(custColours); i++ ) { if ( m_colourData.GetCustomColour(i).IsOk() ) custColours[i] = wxColourToRGB(m_colourData.GetCustomColour(i)); else custColours[i] = RGB(255,255,255); } chooseColorStruct.lStructSize = sizeof(CHOOSECOLOR); if ( m_parent ) chooseColorStruct.hwndOwner = GetHwndOf(m_parent); chooseColorStruct.rgbResult = wxColourToRGB(m_colourData.GetColour()); chooseColorStruct.lpCustColors = custColours; chooseColorStruct.Flags = CC_RGBINIT | CC_ENABLEHOOK; chooseColorStruct.lCustData = (LPARAM)this; chooseColorStruct.lpfnHook = wxColourDialogHookProc; if ( m_colourData.GetChooseFull() ) chooseColorStruct.Flags |= CC_FULLOPEN; // do show the modal dialog if ( !::ChooseColor(&chooseColorStruct) ) { // 0 error means the dialog was simply cancelled, i.e. no real error // occurred const DWORD err = CommDlgExtendedError(); if ( err ) wxLogError(_("Colour selection dialog failed with error %0lx."), err); return wxID_CANCEL; } // transfer the values chosen by user back into m_colourData for ( i = 0; i < WXSIZEOF(custColours); i++ ) { wxRGBToColour(m_colourData.m_custColours[i], custColours[i]); } wxRGBToColour(m_colourData.GetColour(), chooseColorStruct.rgbResult); // this doesn't seem to work (contrary to what MSDN implies) on current // Windows versions: CC_FULLOPEN is never set on return if it wasn't // initially set and vice versa //m_colourData.SetChooseFull((chooseColorStruct.Flags & CC_FULLOPEN) != 0); return wxID_OK; }
int wxColourDialog::ShowModal() { CHOOSECOLOR chooseColorStruct; COLORREF custColours[16]; memset(&chooseColorStruct, 0, sizeof(CHOOSECOLOR)); int i; for (i = 0; i < 16; i++) { if (m_colourData.m_custColours[i].Ok()) custColours[i] = wxColourToRGB(m_colourData.m_custColours[i]); else custColours[i] = RGB(255,255,255); } chooseColorStruct.lStructSize = sizeof(CHOOSECOLOR); if ( m_parent ) chooseColorStruct.hwndOwner = GetHwndOf(m_parent); chooseColorStruct.rgbResult = wxColourToRGB(m_colourData.m_dataColour); chooseColorStruct.lpCustColors = custColours; chooseColorStruct.Flags = CC_RGBINIT | CC_ENABLEHOOK; chooseColorStruct.lCustData = (LPARAM)this; chooseColorStruct.lpfnHook = wxColourDialogHookProc; if (m_colourData.GetChooseFull()) chooseColorStruct.Flags |= CC_FULLOPEN; // Do the modal dialog bool success = ::ChooseColor(&(chooseColorStruct)) != 0; // Try to highlight the correct window (the parent) if (GetParent()) { HWND hWndParent = (HWND) GetParent()->GetHWND(); if (hWndParent) ::BringWindowToTop(hWndParent); } // Restore values for (i = 0; i < 16; i++) { wxRGBToColour(m_colourData.m_custColours[i], custColours[i]); } wxRGBToColour(m_colourData.m_dataColour, chooseColorStruct.rgbResult); return success ? wxID_OK : wxID_CANCEL; }
WXHBRUSH wxControl::DoMSWControlColor(WXHDC pDC, wxColour colBg, WXHWND hWnd) { HDC hdc = (HDC)pDC; WXHBRUSH hbr = 0; if ( !colBg.IsOk() ) { if ( wxWindow *win = wxFindWinFromHandle(hWnd) ) hbr = win->MSWGetBgBrush(pDC); // if the control doesn't have any bg colour, foreground colour will be // ignored as the return value would be 0 -- so forcefully give it a // non default background brush in this case if ( !hbr && m_hasFgCol ) colBg = GetBackgroundColour(); } // use the background colour override if a valid colour is given: this is // used when the control is disabled to grey it out and also if colBg was // set just above if ( colBg.IsOk() ) { wxBrush *brush = wxTheBrushList->FindOrCreateBrush(colBg); hbr = (WXHBRUSH)brush->GetResourceHandle(); } // always set the foreground colour if we changed the background, whether // m_hasFgCol is true or not: if it true, we must do it, of course, but // even if it isn't, we must set the default foreground explicitly as by // default just the simple black is used if ( hbr ) { ::SetTextColor(hdc, wxColourToRGB(GetForegroundColour())); } // finally also set the background colour for text drawing: without this, // the text in an edit control is drawn using the default background even // if we return a valid brush if ( colBg.IsOk() || m_hasBgCol ) { if ( !colBg.IsOk() ) colBg = GetBackgroundColour(); ::SetBkColor(hdc, wxColourToRGB(colBg)); } return hbr; }
// Adds a bitmap, using the specified colour to create the mask bitmap // Note that wxImageList creates new bitmaps, so you may delete // 'bitmap'. int wxImageList::Add(const wxBitmap& bitmap, const wxColour& maskColour) { HBITMAP hbmp; #if wxUSE_WXDIB && wxUSE_IMAGE // See the comment in overloaded Add() above. AutoHBITMAP hbmpRelease; if ( bitmap.HasAlpha() ) { hbmp = wxDIB(bitmap.ConvertToImage(), wxDIB::PixelFormat_NotPreMultiplied).Detach(); hbmpRelease.Init(hbmp); } else #endif // wxUSE_WXDIB && wxUSE_IMAGE hbmp = GetHbitmapOf(bitmap); int index = ImageList_AddMasked(GetHImageList(), hbmp, wxColourToRGB(maskColour)); if ( index == -1 ) { wxLogError(_("Couldn't add an image to the image list.")); } return index; }
bool wxGauge::SetBackgroundColour(const wxColour& col) { if ( !wxControl::SetBackgroundColour(col) ) return false; ::SendMessage(GetHwnd(), PBM_SETBKCOLOR, 0, (LPARAM)wxColourToRGB(col)); return true; }
// Adds a bitmap, using the specified colour to create the mask bitmap // Note that wxImageList creates new bitmaps, so you may delete // 'bitmap'. int wxImageList::Add(const wxBitmap& bitmap, const wxColour& maskColour) { int index = ImageList_AddMasked(GetHImageList(), GetHbitmapOf(bitmap), wxColourToRGB(maskColour)); if ( index == -1 ) { wxLogError(_("Couldn't add an image to the image list.")); } return index; }
WXHBRUSH wxControl::DoMSWControlColor(WXHDC pDC, wxColour colBg, WXHWND hWnd) { HDC hdc = (HDC)pDC; if ( m_hasFgCol ) { ::SetTextColor(hdc, wxColourToRGB(GetForegroundColour())); } WXHBRUSH hbr = 0; if ( !colBg.Ok() ) { hbr = MSWGetBgBrush(pDC, hWnd); // if the control doesn't have any bg colour, foreground colour will be // ignored as the return value would be 0 -- so forcefully give it a // non default background brush in this case if ( !hbr && m_hasFgCol ) colBg = GetBackgroundColour(); } // use the background colour override if a valid colour is given if ( colBg.Ok() ) { ::SetBkColor(hdc, wxColourToRGB(colBg)); // draw children with the same colour as the parent wxBrush *brush = wxTheBrushList->FindOrCreateBrush(colBg, wxSOLID); hbr = (WXHBRUSH)brush->GetResourceHandle(); // if we use custom background, we should set foreground ourselves too if ( !m_hasFgCol ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_WINDOWTEXT)); } //else: already set above } return hbr; }
// Draws the given image on a dc at the specified position. // If 'solidBackground' is true, Draw sets the image list background // colour to the background colour of the wxDC, to speed up // drawing by eliminating masked drawing where possible. bool wxImageList::Draw(int index, wxDC& dc, int x, int y, int flags, bool solidBackground) { wxDCImpl *impl = dc.GetImpl(); wxMSWDCImpl *msw_impl = wxDynamicCast( impl, wxMSWDCImpl ); if (!msw_impl) return false; HDC hDC = GetHdcOf(*msw_impl); wxCHECK_MSG( hDC, false, wxT("invalid wxDC in wxImageList::Draw") ); COLORREF clr = CLR_NONE; // transparent by default if ( solidBackground ) { const wxBrush& brush = dc.GetBackground(); if ( brush.IsOk() ) { clr = wxColourToRGB(brush.GetColour()); } } ImageList_SetBkColor(GetHImageList(), clr); UINT style = 0; if ( flags & wxIMAGELIST_DRAW_NORMAL ) style |= ILD_NORMAL; if ( flags & wxIMAGELIST_DRAW_TRANSPARENT ) style |= ILD_TRANSPARENT; if ( flags & wxIMAGELIST_DRAW_SELECTED ) style |= ILD_SELECTED; if ( flags & wxIMAGELIST_DRAW_FOCUSED ) style |= ILD_FOCUS; bool ok = ImageList_Draw(GetHImageList(), index, hDC, x, y, style) != 0; if ( !ok ) { wxLogLastError(wxT("ImageList_Draw()")); } return ok; }
int wxFontDialog::ShowModal() { // It should be OK to always use GDI simulations DWORD flags = CF_SCREENFONTS /* | CF_NOSIMULATIONS */ ; LOGFONT logFont; CHOOSEFONT chooseFontStruct; wxZeroMemory(chooseFontStruct); chooseFontStruct.lStructSize = sizeof(CHOOSEFONT); if ( m_parent ) chooseFontStruct.hwndOwner = GetHwndOf(m_parent); chooseFontStruct.lpLogFont = &logFont; if ( m_fontData.m_initialFont.IsOk() ) { flags |= CF_INITTOLOGFONTSTRUCT; wxFillLogFont(&logFont, &m_fontData.m_initialFont); } if ( m_fontData.m_fontColour.IsOk() ) { chooseFontStruct.rgbColors = wxColourToRGB(m_fontData.m_fontColour); } // CF_ANSIONLY flag is obsolete for Win32 if ( !m_fontData.GetAllowSymbols() ) { flags |= CF_SELECTSCRIPT; logFont.lfCharSet = ANSI_CHARSET; } if ( m_fontData.GetEnableEffects() ) flags |= CF_EFFECTS; if ( m_fontData.GetShowHelp() ) flags |= CF_SHOWHELP; if ( m_fontData.m_minSize != 0 || m_fontData.m_maxSize != 0 ) { chooseFontStruct.nSizeMin = m_fontData.m_minSize; chooseFontStruct.nSizeMax = m_fontData.m_maxSize; flags |= CF_LIMITSIZE; } chooseFontStruct.Flags = flags; if ( ChooseFont(&chooseFontStruct) != 0 ) { wxRGBToColour(m_fontData.m_fontColour, chooseFontStruct.rgbColors); m_fontData.m_chosenFont = wxCreateFontFromLogFont(&logFont); m_fontData.EncodingInfo().facename = logFont.lfFaceName; m_fontData.EncodingInfo().charset = logFont.lfCharSet; return wxID_OK; } else { DWORD dwErr = CommDlgExtendedError(); if ( dwErr != 0 ) { wxLogError(_("Common dialog failed with error code %0lx."), dwErr); } //else: it was just cancelled return wxID_CANCEL; } }
void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); wxMemoryDC memdc; RECT rc; ::GetClientRect(GetHwnd(), &rc); wxBitmap bmp(rc.right, rc.bottom); memdc.SelectObject(bmp); const wxLayoutDirection dir = dc.GetLayoutDirection(); memdc.SetLayoutDirection(dir); const HDC hdc = GetHdcOf(memdc); // The drawing logic of the native tab control is absolutely impenetrable // but observation shows that in the current Windows versions (XP and 7), // the tab control always erases its entire background in its window proc // when the tabs are top-aligned but does not do it when the tabs are in // any other position. // // This means that we can't rely on our background colour being used for // the blank area in the tab row because this doesn't work in the default // top-aligned case, hence the hack with ExtFloodFill() below. But it also // means that we still do need to erase the DC to account for the other // cases. // // Moreover, just in case some very old or very new (or even future, // although it seems unlikely that this is ever going to change by now) // version of Windows didn't do it like this, do both things in all cases // instead of optimizing away the one of them which doesn't do anything for // the effectively used tab orientation -- better safe than fast. // Notice that we use our own background here, not the background used for // the pages, because the tab row background must blend with the parent and // so the background colour inherited from it (if any) must be used. AutoHBRUSH hbr(wxColourToRGB(GetBackgroundColour())); ::FillRect(hdc, &rc, hbr); MSWDefWindowProc(WM_PAINT, (WPARAM)hdc, 0); // At least for the top-aligned tabs, our background colour was overwritten // and so we now replace the default background with our colour. This is // horribly inefficient, of course, but seems to be the only way to do it. if ( UseBgCol() ) { SelectInHDC selectBrush(hdc, hbr); // Find the point which must contain the default background colour: // this is a hack, of course, but using this point "close" to the // corner seems to work fine in practice. int x = 0, y = 0; switch ( GetWindowStyle() & wxBK_ALIGN_MASK ) { case wxBK_TOP: x = rc.right - 2; y = 2; break; case wxBK_BOTTOM: x = rc.right - 2; y = rc.bottom - 2; break; case wxBK_LEFT: x = 2; y = rc.bottom - 2; break; case wxBK_RIGHT: x = 2; y = rc.bottom - 2; break; } ::ExtFloodFill(hdc, x, y, ::GetSysColor(COLOR_BTNFACE), FLOODFILLSURFACE); } // For some reason in RTL mode, source offset has to be -1, otherwise the // right border (physical) remains unpainted. const wxCoord ofs = dir == wxLayout_RightToLeft ? -1 : 0; dc.Blit(ofs, 0, rc.right, rc.bottom, &memdc, ofs, 0); }
WXHBRUSH wxControl::DoMSWControlColor(WXHDC pDC, wxColour colBg, WXHWND hWnd) { HDC hdc = (HDC)pDC; WXHBRUSH hbr = 0; if ( !colBg.IsOk() ) { wxWindow *win = wxFindWinFromHandle( hWnd ); if ( !win ) { // If this HWND doesn't correspond to a wxWindow, it still might be // one of its children for which we need to set the background // brush, e.g. this is the case for the EDIT control that is part // of wxComboBox. Check for this by asking the parent if it has it: HWND parent = ::GetParent(hWnd); if ( parent ) { wxWindow *winParent = wxFindWinFromHandle( parent ); if( winParent && winParent->ContainsHWND( hWnd ) ) win = winParent; } } if ( win ) hbr = win->MSWGetBgBrush(pDC); // if the control doesn't have any bg colour, foreground colour will be // ignored as the return value would be 0 -- so forcefully give it a // non default background brush in this case if ( !hbr && m_hasFgCol ) colBg = GetBackgroundColour(); } // use the background colour override if a valid colour is given: this is // used when the control is disabled to grey it out and also if colBg was // set just above if ( colBg.IsOk() ) { wxBrush *brush = wxTheBrushList->FindOrCreateBrush(colBg); hbr = (WXHBRUSH)brush->GetResourceHandle(); } // always set the foreground colour if we changed the background, whether // m_hasFgCol is true or not: if it true, we must do it, of course, but // even if it isn't, we must set the default foreground explicitly as by // default just the simple black is used if ( hbr ) { ::SetTextColor(hdc, wxColourToRGB(GetForegroundColour())); } // finally also set the background colour for text drawing: without this, // the text in an edit control is drawn using the default background even // if we return a valid brush if ( colBg.IsOk() || m_hasBgCol ) { if ( !colBg.IsOk() ) colBg = GetBackgroundColour(); ::SetBkColor(hdc, wxColourToRGB(colBg)); } return hbr; }
static void MSWDrawXPBackground(wxButton *button, WXDRAWITEMSTRUCT *wxdis) { LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)wxdis; HDC hdc = lpDIS->hDC; UINT state = lpDIS->itemState; RECT rectBtn; CopyRect(&rectBtn, &lpDIS->rcItem); wxUxThemeHandle theme(button, L"BUTTON"); int iState; if ( state & ODS_SELECTED ) { iState = PBS_PRESSED; } else if ( button->HasCapture() || button->IsMouseInWindow() ) { iState = PBS_HOT; } else if ( state & ODS_FOCUS ) { iState = PBS_DEFAULTED; } else if ( state & ODS_DISABLED ) { iState = PBS_DISABLED; } else { iState = PBS_NORMAL; } // draw parent background if needed if ( wxUxThemeEngine::Get()->IsThemeBackgroundPartiallyTransparent(theme, BP_PUSHBUTTON, iState) ) { wxUxThemeEngine::Get()->DrawThemeParentBackground(GetHwndOf(button), hdc, &rectBtn); } // draw background wxUxThemeEngine::Get()->DrawThemeBackground(theme, hdc, BP_PUSHBUTTON, iState, &rectBtn, NULL); // calculate content area margins MARGINS margins; wxUxThemeEngine::Get()->GetThemeMargins(theme, hdc, BP_PUSHBUTTON, iState, TMT_CONTENTMARGINS, &rectBtn, &margins); RECT rectClient; ::CopyRect(&rectClient, &rectBtn); ::InflateRect(&rectClient, -margins.cxLeftWidth, -margins.cyTopHeight); // if focused and !nofocus rect if ( (state & ODS_FOCUS) && !(state & ODS_NOFOCUSRECT) ) { DrawFocusRect(hdc, &rectClient); } if ( button->UseBgCol() ) { COLORREF colBg = wxColourToRGB(button->GetBackgroundColour()); HBRUSH hbrushBackground = ::CreateSolidBrush(colBg); // don't overwrite the focus rect ::InflateRect(&rectClient, -1, -1); FillRect(hdc, &rectClient, hbrushBackground); ::DeleteObject(hbrushBackground); } }
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; }