void wxMetafileDCImpl::DoGetTextExtent(const wxString& string, wxCoord *x, wxCoord *y, wxCoord *descent, wxCoord *externalLeading, const wxFont *theFont) const { const wxFont *fontToUse = theFont; if (!fontToUse) fontToUse = &m_font; ScreenHDC dc; SelectInHDC selFont(dc, GetHfontOf(*fontToUse)); SIZE sizeRect; TEXTMETRIC tm; ::GetTextExtentPoint32(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect); ::GetTextMetrics(dc, &tm); if ( x ) *x = sizeRect.cx; if ( y ) *y = sizeRect.cy; if ( descent ) *descent = tm.tmDescent; if ( externalLeading ) *externalLeading = tm.tmExternalLeading; }
static void FrameRatePaint(FrameRateWnd *w, HDC hdc, PAINTSTRUCT& ps) { RECT rc = GetClientRect(w->hwnd); ScopedGdiObj<HBRUSH> brush(CreateSolidBrush(COL_BLACK)); FillRect(hdc, &rc, brush); SetTextColor(hdc, COL_WHITE); ScopedHdcSelect selFont(hdc, w->font); WCHAR *txt = str::Format(L"%d", w->frameRate); DrawCenteredText(hdc, rc, txt); free(txt); }
void wxListBox::SetHorizontalExtent(const wxString& s) { // in any case, our best size could have changed InvalidateBestSize(); // the rest is only necessary if we want a horizontal scrollbar if ( !HasFlag(wxHSCROLL) ) return; WindowHDC dc(GetHwnd()); SelectInHDC selFont(dc, GetHfontOf(GetFont())); TEXTMETRIC lpTextMetric; ::GetTextMetrics(dc, &lpTextMetric); int largestExtent = 0; SIZE extentXY; if ( s.empty() ) { // set extent to the max length of all strings for ( unsigned int i = 0; i < m_noItems; i++ ) { const wxString str = GetString(i); ::GetTextExtentPoint32(dc, str.c_str(), str.length(), &extentXY); int extentX = (int)(extentXY.cx + lpTextMetric.tmAveCharWidth); if ( extentX > largestExtent ) largestExtent = extentX; } } else // just increase the extent to the length of this string { int existingExtent = (int)SendMessage(GetHwnd(), LB_GETHORIZONTALEXTENT, 0, 0L); ::GetTextExtentPoint32(dc, s.c_str(), s.length(), &extentXY); int extentX = (int)(extentXY.cx + lpTextMetric.tmAveCharWidth); if ( extentX > existingExtent ) largestExtent = extentX; } if ( largestExtent ) SendMessage(GetHwnd(), LB_SETHORIZONTALEXTENT, LOWORD(largestExtent), 0L); //else: it shouldn't change }
// draw the item bool wxOwnerDrawn::OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction, wxODStatus stat) { // we do nothing if item isn't ownerdrawn if ( !IsOwnerDrawn() ) return true; wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); HDC hdc = GetHdcOf(*impl); RECT rect; wxCopyRectToRECT(rc, rect); { // set the font and colors wxFont font; GetFontToUse(font); wxColour colText, colBack; GetColourToUse(stat, colText, colBack); SelectInHDC selFont(hdc, GetHfontOf(font)); wxMSWImpl::wxTextColoursChanger textCol(hdc, colText, colBack); wxMSWImpl::wxBkModeChanger bkMode(hdc, wxBRUSHSTYLE_TRANSPARENT); AutoHBRUSH hbr(wxColourToPalRGB(colBack)); SelectInHDC selBrush(hdc, hbr); ::FillRect(hdc, &rect, hbr); // using native API because it recognizes '&' wxString text = GetName(); SIZE sizeRect; ::GetTextExtentPoint32(hdc, text.c_str(), text.length(), &sizeRect); int flags = DST_PREFIXTEXT; if ( (stat & wxODDisabled) && !(stat & wxODSelected) ) flags |= DSS_DISABLED; if ( (stat & wxODHidePrefix) ) flags |= DSS_HIDEPREFIX; int x = rc.x + GetMarginWidth(); int y = rc.y + (rc.GetHeight() - sizeRect.cy) / 2; int cx = rc.GetWidth() - GetMarginWidth(); int cy = sizeRect.cy; ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(text), text.length(), x, y, cx, cy, flags); } // reset to default the font, colors and brush if (stat & wxODHasFocus) ::DrawFocusRect(hdc, &rect); return true; }
bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction WXUNUSED(act), wxODStatus stat) { const MenuDrawData* data = MenuDrawData::Get(); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); HDC hdc = GetHdcOf(*impl); RECT rect; wxCopyRectToRECT(rc, rect); int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx); if ( IsOwnerDrawn() ) { // font and colors to use wxFont font; GetFontToUse(font); wxColour colText, colBack; GetColourToUse(stat, colText, colBack); // calculate metrics of item parts RECT rcSelection = rect; data->ItemMargin.ApplyTo(rcSelection); RECT rcSeparator = rcSelection; data->SeparatorMargin.ApplyTo(rcSeparator); RECT rcGutter = rcSelection; rcGutter.right = data->ItemMargin.cxLeftWidth + data->CheckBgMargin.cxLeftWidth + data->CheckMargin.cxLeftWidth + imgWidth + data->CheckMargin.cxRightWidth + data->CheckBgMargin.cxRightWidth; RECT rcText = rcSelection; rcText.left = rcGutter.right + data->TextBorder; // we draw the text label vertically centered, but this results in it // being 1px too low compared to native menus for some reason, fix it if ( data->MenuLayout() != MenuDrawData::FullTheme ) rcText.top--; #if wxUSE_UXTHEME // If a custom background colour is explicitly specified, we should use // it instead of the default theme background. wxUxThemeEngine* const theme = GetBackgroundColour().IsOk() ? NULL : MenuDrawData::GetUxThemeEngine(); if ( theme ) { POPUPITEMSTATES state; if ( stat & wxODDisabled ) { state = (stat & wxODSelected) ? MPI_DISABLEDHOT : MPI_DISABLED; } else if ( stat & wxODSelected ) { state = MPI_HOT; } else { state = MPI_NORMAL; } wxUxThemeHandle hTheme(GetMenu()->GetWindow(), L"MENU"); if ( theme->IsThemeBackgroundPartiallyTransparent(hTheme, MENU_POPUPITEM, state) ) { theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPBACKGROUND, 0, &rect, NULL); } theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPGUTTER, 0, &rcGutter, NULL); if ( IsSeparator() ) { rcSeparator.left = rcGutter.right; theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPSEPARATOR, 0, &rcSeparator, NULL); return true; } theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPITEM, state, &rcSelection, NULL); } else #endif // wxUSE_UXTHEME { if ( IsSeparator() ) { DrawEdge(hdc, &rcSeparator, EDGE_ETCHED, BF_TOP); return true; } AutoHBRUSH hbr(colBack.GetPixel()); SelectInHDC selBrush(hdc, hbr); ::FillRect(hdc, &rcSelection, hbr); } // draw text label // using native API because it recognizes '&' HDCTextColChanger changeTextCol(hdc, colText.GetPixel()); HDCBgColChanger changeBgCol(hdc, colBack.GetPixel()); HDCBgModeChanger changeBgMode(hdc, TRANSPARENT); SelectInHDC selFont(hdc, GetHfontOf(font)); // item text name without mnemonic for calculating size wxString text = GetName(); SIZE textSize; ::GetTextExtentPoint32(hdc, text.c_str(), text.length(), &textSize); // item text name with mnemonic text = GetItemLabel().BeforeFirst('\t'); int flags = DST_PREFIXTEXT; // themes menu is using specified color for disabled labels if ( data->MenuLayout() == MenuDrawData::Classic && (stat & wxODDisabled) && !(stat & wxODSelected) ) flags |= DSS_DISABLED; if ( (stat & wxODHidePrefix) && !data->AlwaysShowCues ) flags |= DSS_HIDEPREFIX; int x = rcText.left; int y = rcText.top + (rcText.bottom - rcText.top - textSize.cy) / 2; ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(text), text.length(), x, y, 0, 0, flags); // ::SetTextAlign(hdc, TA_RIGHT) doesn't work with DSS_DISABLED or DSS_MONO // as the last parameter in DrawState() (at least with Windows98). So we have // to take care of right alignment ourselves. wxString accel = GetItemLabel().AfterFirst(wxT('\t')); if ( !accel.empty() ) { SIZE accelSize; ::GetTextExtentPoint32(hdc, accel.c_str(), accel.length(), &accelSize); flags = DST_TEXT; // themes menu is using specified color for disabled labels if ( data->MenuLayout() == MenuDrawData::Classic && (stat & wxODDisabled) && !(stat & wxODSelected) ) flags |= DSS_DISABLED; x = rcText.right - data->ArrowMargin.GetTotalX() - data->ArrowSize.cx - data->ArrowBorder; // right align accel on FullTheme menu, left otherwise if ( data->MenuLayout() == MenuDrawData::FullTheme) x -= accelSize.cx; else x -= m_parentMenu->GetMaxAccelWidth(); y = rcText.top + (rcText.bottom - rcText.top - accelSize.cy) / 2; ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(accel), accel.length(), x, y, 0, 0, flags); } } // draw the bitmap RECT rcImg; SetRect(&rcImg, rect.left + data->ItemMargin.cxLeftWidth + data->CheckBgMargin.cxLeftWidth + data->CheckMargin.cxLeftWidth, rect.top + data->ItemMargin.cyTopHeight + data->CheckBgMargin.cyTopHeight + data->CheckMargin.cyTopHeight, rect.left + data->ItemMargin.cxLeftWidth + data->CheckBgMargin.cxLeftWidth + data->CheckMargin.cxLeftWidth + imgWidth, rect.bottom - data->ItemMargin.cyBottomHeight - data->CheckBgMargin.cyBottomHeight - data->CheckMargin.cyBottomHeight); if ( IsCheckable() && !m_bmpChecked.IsOk() ) { if ( stat & wxODChecked ) { DrawStdCheckMark((WXHDC)hdc, &rcImg, stat); } } else { wxBitmap bmp; if ( stat & wxODDisabled ) { bmp = GetDisabledBitmap(); } if ( !bmp.IsOk() ) { // for not checkable bitmaps we should always use unchecked one // because their checked bitmap is not set bmp = GetBitmap(!IsCheckable() || (stat & wxODChecked)); #if wxUSE_IMAGE if ( bmp.IsOk() && stat & wxODDisabled ) { // we need to grey out the bitmap as we don't have any specific // disabled bitmap wxImage imgGrey = bmp.ConvertToImage().ConvertToGreyscale(); if ( imgGrey.IsOk() ) bmp = wxBitmap(imgGrey); } #endif // wxUSE_IMAGE } if ( bmp.IsOk() ) { wxMemoryDC dcMem(&dc); dcMem.SelectObjectAsSource(bmp); // center bitmap int nBmpWidth = bmp.GetWidth(), nBmpHeight = bmp.GetHeight(); int x = rcImg.left + (imgWidth - nBmpWidth) / 2; int y = rcImg.top + (rcImg.bottom - rcImg.top - nBmpHeight) / 2; dc.Blit(x, y, nBmpWidth, nBmpHeight, &dcMem, 0, 0, wxCOPY, true); } } return true; }
void QIMPenWidget::paintEvent( QPaintEvent * ) { QPainter paint( this ); // draw guidelines paint.setPen( Qt::gray ); paint.drawLine( 0, 0, width(), 0 ); int y = height() / 3; paint.drawLine( 0, y, width(), y ); y *= 2; paint.setPen( blue ); paint.drawLine( 0, y, width(), y ); paint.setPen( Qt::gray ); if ( !charSets.count() ) return; // draw the character set titles QFont selFont( "helvetica", 8, QFont::Bold ); QFont font( "helvetica", 8 ); CharSetEntryIterator it( charSets ); int spos = 0; for ( ; it.current(); ++it ) { int setWidth = width() * it.current()->stretch / totalStretch; spos += setWidth; if ( it.current() != charSets.getLast() ) { paint.drawLine( spos, 0, spos, 5 ); paint.drawLine( spos, height()-1, spos, height()-6 ); } paint.setFont( font ); int w = paint.fontMetrics().width( it.current()->cs->title() ); int tpos = spos - setWidth / 2; paint.drawText( tpos - w/2, 0, w, 12, QPainter::AlignCenter, it.current()->cs->title() ); } // draw any character that should be displayed when repainted. QPoint off; const QIMPenStrokeList *stk = 0; if ( outputChar && mode == Waiting ) { stk = &outputChar->penStrokes(); QPoint p( outputChar->startingPoint() ); QRect br( outputChar->boundingRect() ); p.setX( (width() - br.width()) / 2 + (p.x () - br.left()) ); off = p - outputChar->startingPoint(); } else if ( mode == Waiting ) { stk = &strokes; strokeColor = gray; } if ( stk && !stk->isEmpty() ) { paint.setPen( strokeColor ); paint.setBrush( strokeColor ); QIMPenStrokeIterator it( *stk ); while ( it.current() ) { QPoint p = it.current()->startingPoint() + off; paint.drawRect( p.x()-1, p.y()-1, 2, 2 ); const QArray<QIMPenGlyphLink> &chain = it.current()->chain(); for ( unsigned i = 0; i < chain.count(); i++ ) { p.rx() += chain[i].dx; p.ry() += chain[i].dy; paint.drawRect( p.x()-1, p.y()-1, 2, 2 ); } ++it; if ( it.atLast() && mode == Waiting ) strokeColor = black; } } dirtyRect = QRect(); // debug /* if ( input ) { QArray<int> sig = input->sig(); for ( unsigned i = 0; i < sig.count(); i++ ) { paint.drawPoint( 200 + i, height()/2 - sig[i] / 8 ); } } */ }