void TicTacToe::paintEvent(QPaintEvent * /* event */) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(QPen(Qt::darkGreen, 1)); painter.drawLine(cellWidth(), 0, cellWidth(), height()); painter.drawLine(2 * cellWidth(), 0, 2 * cellWidth(), height()); painter.drawLine(0, cellHeight(), width(), cellHeight()); painter.drawLine(0, 2 * cellHeight(), width(), 2 * cellHeight()); painter.setPen(QPen(Qt::darkBlue, 2)); for (int position = 0; position < 9; ++position) { QRect cell = cellRect(position / 3, position % 3); if (myState.at(position) == Cross) { painter.drawLine(cell.topLeft(), cell.bottomRight()); painter.drawLine(cell.topRight(), cell.bottomLeft()); } else if (myState.at(position) == Nought) { painter.drawEllipse(cell); } } painter.setPen(QPen(Qt::yellow, 3)); for (int position = 0; position < 9; position = position + 3) { if (myState.at(position) != Empty && myState.at(position + 1) == myState.at(position) && myState.at(position + 2) == myState.at(position)) { int y = cellRect((position / 3), 0).center().y(); painter.drawLine(0, y, width(), y); turnNumber = 9; } } for (int position = 0; position < 3; ++position) { if (myState.at(position) != Empty && myState.at(position + 3) == myState.at(position) && myState.at(position + 6) == myState.at(position)) { int x = cellRect(0, position).center().x(); painter.drawLine(x, 0, x, height()); turnNumber = 9; } } if (myState.at(0) != Empty && myState.at(4) == myState.at(0) && myState.at(8) == myState.at(0)) { painter.drawLine(0, 0, width(), height()); turnNumber = 9; } if (myState.at(2) != Empty && myState.at(4) == myState.at(2) && myState.at(6) == myState.at(2)) { painter.drawLine(0, height(), width(), 0); turnNumber = 9; } }
void TCacheResource::release2(const TRect &rect) { //DIAGNOSTICS_NUMBEREDSTRSET(prefix + QString::number((UINT) this) + " | Stack | ", //"crStack", "release", ::traduce(rect)); if (m_locksCount > 0) return; std::map<PointLess, CellData>::iterator it; for (it = m_cellDatas.begin(); it != m_cellDatas.end();) { if (!it->second.m_referenced) { ++it; continue; } TPoint cellPos(getCellPos(it->first)); TRect cellRect(cellPos, TDimension(latticeStep, latticeStep)); if (isEmpty(cellRect * rect)) { ++it; continue; } QRect cellQRect(toQRect(cellRect)); if (--it->second.m_refsCount <= 0) { releaseCell(cellQRect, it->first, it->second.m_modified); std::map<PointLess, CellData>::iterator jt = it++; m_cellDatas.erase(jt); } else ++it; } }
//////////////////////////////////////////////////////////////////////////////// /// CChanceTreeHistoryArtist::paintTable /// /// @description This function paints all the nodes to the screen. /// @pre None /// @post All the nodes are drawn to the screen. /// /// @param painter: This is a pointer to the painter to use. If no value is /// passed, create a painter to use. /// /// @limitations None /// //////////////////////////////////////////////////////////////////////////////// void CChanceTreeHistoryArtist::paintTable( QPainter *painter ) { //Make sure the pointer to the model has been initialized. if (m_model == NULL) return; //Make sure the root node of the tree isn't NULL, then call the //paintModelHelper function to pain the model. if ( m_model->getRootNode() == NULL ) return; //This variable is used for painting to the canvas if no painter was //specified. QPainter localPainter( m_canvas ); //Check if the calling function did not pass a painter and use //the local one in that case. if ( painter == NULL ) painter = &localPainter; //Create the QPainter object to paint the model. painter->setPen( m_style->getPen() ); painter->setBrush( m_style->getBrush() ); painter->setFont( m_style->getFont() ); painter->setRenderHint( QPainter::Antialiasing ); HistoryTable historyTable = m_model->getHistoryTable(); HistoryTable::const_iterator i = historyTable.constBegin(); QRect cellRect( painter->boundingRect( 0,0,0,0,0,"WW-WW" ) ); cellRect.adjust( -4,-4,4,4 ); cellRect.moveTopLeft( m_model->getHistoryPosition() ); while ( i != historyTable.constEnd() ) { painter->drawRect( cellRect ); painter->drawText( cellRect, Qt::AlignCenter, moveName(i->first) ); cellRect.moveTopLeft( cellRect.bottomLeft() ); painter->drawRect( cellRect ); painter->drawText( cellRect, Qt::AlignCenter, QString::number(i->second) ); cellRect.moveBottomLeft( cellRect.topRight() ); ++i; } }
//This virtual function is called to draw the individual columns. In the case of // non-CBS_HASSTRINGS this has to be implimented in derived classes void COXMultiComboBox::DrawColumnItem(HDC hDC, int nIndex, int nColIndex, const CRect& rectColumn, int ItemState) // --- In : hDC : the DC into which to draw the column // nIndex : The row index // nColIndex : The Column Index // rectColumn : The rectangle into which we can draw // ItemState : Gives the state of the item(Selected or not) // --- Out : // --- Returns : // --- Effect : The column text is drawn in the case of CBS_HASSTRINGS { ASSERT(GetStyle()&CBS_HASSTRINGS); CDC dc; dc.Attach(hDC); // Sets the foreground color of the text based on its selection state COLORREF clrOldForeground = dc.SetTextColor(::GetSysColor(IsWindowEnabled() ? (ItemState&ODS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT) : COLOR_GRAYTEXT)); COLORREF clrBackground = ::GetSysColor(IsWindowEnabled() ? (ItemState & ODS_SELECTED ? COLOR_HIGHLIGHT : COLOR_WINDOW) : COLOR_BTNFACE); // Sets the background color of text based on selection state COLORREF clrOldBackground = dc.SetBkColor( clrBackground); // Gets the column text to draw CString strText; if(nIndex!=-1) GetLBText(nIndex,nColIndex,strText); else strText.Empty(); CRect cellRect(rectColumn); dc.FillSolidRect(cellRect, clrBackground); // give left margin cellRect.left += LOWORD(GetDialogBaseUnits()) / 2; // Draw text dc.DrawText(strText, cellRect, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); // Seperators are drawn in list boxe between columns and rows DrawColumnBorder(&dc,rectColumn,ItemState); // Reset the actual DC colors dc.SetTextColor(clrOldForeground); dc.SetBkColor(clrOldBackground); dc.Detach(); }
//! Copies the passed tile in the tile complex. The passed tile \b must //! possess integer geometry (ie tile.m_pos must have integer coordinates), //! otherwise this function is a no-op. bool TCacheResource::upload(const TPoint &pos, TRasterP ras) { int tileType; if (!checkRasterType(ras, tileType)) return false; if (m_tileType == NONE) m_tileType = tileType; //For all cells of the lattice which intersect the tile, upload the content in the //complex TRect tileRect(ras->getBounds() + pos); TPoint initialPos(getCellPos(tileRect.getP00())); //DIAGNOSTICS_NUMBEREDSTRSET(prefix + QString::number((UINT) this) + " | Stack | ", //"crStack", "upload", ::traduce(TRect(pos, ras->getSize()))); TPoint currPos; for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep) for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) { //Copy tile's content into the cell's raster. TRect cellRect(currPos, TDimension(latticeStep, latticeStep)); TRect overlapRect(tileRect * cellRect); assert(!overlapRect.isEmpty()); PointLess cellIndex(getCellIndex(currPos)); std::pair<TRasterP, CellData *> cellInfos(touch(cellIndex)); TRasterP cellRas(cellInfos.first); TRect temp(overlapRect - currPos); TRasterP overlappingCellRas(cellRas->extract(temp)); temp = TRect(overlapRect - tileRect.getP00()); TRasterP overlappingTileRas(ras->extract(temp)); assert(overlappingCellRas->getBounds() == overlappingTileRas->getBounds()); TRop::copy(overlappingCellRas, overlappingTileRas); cellInfos.second->m_modified = true; } //Update the complex's content region m_region += toQRect(tileRect); return true; }
void ChromaticMask::calculateGridImage(const aruco::Board &board ) { // project corner points to image cv::projectPoints(_objCornerPoints, board.Rvec, board.Tvec, _CP.CameraMatrix, _CP.Distorsion, _imgCornerPoints); //obtain the perspective transform cv::Point2f pointsRes[4],pointsIn[4]; for ( int i=0;i<4;i++ ) pointsIn[i]=_imgCornerPoints[i]; pointsRes[0]= ( cv::Point2f ( 0,0 ) ); pointsRes[1]= cv::Point2f ( _cellSize*_mc-1, 0 ); pointsRes[2]= cv::Point2f ( _cellSize*_mc-1, _cellSize*_nc-1 ); pointsRes[3]= cv::Point2f ( 0, _cellSize*_nc-1 ); _perpTrans=cv::getPerspectiveTransform ( pointsIn,pointsRes ); double tick = (double)cv::getTickCount(); vector<cv::Point2f> transformedPixels; cv::perspectiveTransform(_pixelsVector, transformedPixels, _perpTrans); AvrgTime.first+=((double)cv::getTickCount()-tick)/cv::getTickFrequency(); AvrgTime.second++; cout<<"Time cc detection="<<1000*AvrgTime.first/AvrgTime.second<<" milliseconds"<<endl; cv::Rect cellRect(0,0,_mc,_nc); for(unsigned int i=0; i<transformedPixels.size(); i++) { //_canonicalPos.at<cv::Vec2b>(_pixelsVector[i].y, _pixelsVector[i].x) = cv::Vec2b(transformedPixels[i].x, transformedPixels[i].y); transformedPixels[i].x /= _cellSize; transformedPixels[i].y /= _cellSize; if( !transformedPixels[i].inside(cellRect) ) { _cellMap.at<uchar>( _pixelsVector[i].y, _pixelsVector[i].x ) = 0; _cellMap.at<uchar>( _pixelsVector[i].y+1, _pixelsVector[i].x ) = 0; _cellMap.at<uchar>( _pixelsVector[i].y, _pixelsVector[i].x+1 ) = 0; _cellMap.at<uchar>( _pixelsVector[i].y+1, _pixelsVector[i].x+1 ) = 0; } else { uchar cellNum = (unsigned int)transformedPixels[i].y*_nc + (unsigned int)transformedPixels[i].x; _cellMap.at<uchar>( _pixelsVector[i].y, _pixelsVector[i].x ) = 1+cellNum; _cellMap.at<uchar>( _pixelsVector[i].y+1, _pixelsVector[i].x ) = 1+cellNum; _cellMap.at<uchar>( _pixelsVector[i].y, _pixelsVector[i].x+1 ) = 1+cellNum; _cellMap.at<uchar>( _pixelsVector[i].y+1, _pixelsVector[i].x+1 ) = 1+cellNum; } } }
bool TCacheResource::downloadAll(const TPoint &pos, TRasterP ras) { int tileType; if (!checkRasterType(ras, tileType)) return false; //Build the tile's rect TRect tileRect(ras->getBounds() + pos); if (!contains(m_region, tileRect)) return false; //DIAGNOSTICS_NUMBEREDSTRSET(prefix + QString::number((UINT) this) + " | Stack | ", //"crStack", "downloadAll", ::traduce(TRect(pos, ras->getSize()))); //For all cells intersecting the tile's rect, copy all those intersecting the //complex's content region. TPoint initialPos(getCellPos(tileRect.getP00())); TPoint currPos; for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep) for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) { TRect cellRect(currPos, TDimension(latticeStep, latticeStep)); TRect overlapRect(tileRect * cellRect); assert(!overlapRect.isEmpty()); QRect overlapQRect(toQRect(overlapRect)); if (m_region.intersects(overlapQRect)) { //Extract the associated rasters and perform the copy to the input tile. std::pair<TRasterP, CellData *> cellInfos(touch(getCellIndex(currPos))); TRasterP cellRas(cellInfos.first); TRect temp(overlapRect - currPos); TRasterP overlappingCellRas(cellRas->extract(temp)); temp = TRect(overlapRect - tileRect.getP00()); TRasterP overlappingTileRas(ras->extract(temp)); TRop::copy(overlappingTileRas, overlappingCellRas); } } return true; }
TRect TGridLayout::GetControlRect(size_t col, size_t row) const { TRect cellRect(colDefs[col].left, rowDefs[row].top, colDefs[col].Right(), rowDefs[row].Bottom()); for (size_t iCol = col; iCol+1 < colCount && cells[iCol][row].isMergedRight; ++iCol) { cellRect.Right = colDefs[iCol+1].Right(); } for (size_t iRow = row; iRow < rowCount && cells[col][iRow].isMergedBottom; ++iRow) { cellRect.Bottom = rowDefs[iRow+1].Bottom(); } // On retranche la marge intérieure des cellules cellRect.Left += cellMargin; cellRect.Right -= cellMargin; cellRect.Top += cellMargin; cellRect.Bottom -= cellMargin; return cellRect; }
//! Fills the passed tile with the data contained in the complex, returning //! the copied region. //! The same restriction of the upload() method applies here. QRegion TCacheResource::download(const TPoint &pos, TRasterP ras) { int tileType; if (!checkRasterType(ras, tileType)) return QRegion(); //Build the tile's rect TRect tileRect(ras->getBounds() + pos); if (!m_region.intersects(toQRect(tileRect))) return QRegion(); //For all cells intersecting the tile's rect, copy all those intersecting the //complex's content region. TPoint initialPos(getCellPos(tileRect.getP00())); TPoint currPos; for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep) for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) { TRect cellRect(currPos, TDimension(latticeStep, latticeStep)); TRect overlapRect(tileRect * cellRect); assert(!overlapRect.isEmpty()); QRect overlapQRect(toQRect(overlapRect)); if (m_region.intersects(overlapQRect)) { //Extract the associated rasters and perform the copy to the input tile. std::pair<TRasterP, CellData *> cellInfos(touch(getCellIndex(currPos))); TRasterP cellRas(cellInfos.first); TRect temp(overlapRect - currPos); TRasterP overlappingCellRas(cellRas->extract(temp)); temp = TRect(overlapRect - tileRect.getP00()); TRasterP overlappingTileRas(ras->extract(temp)); TRop::copy(overlappingTileRas, overlappingCellRas); } } return m_region.intersected(QRegion(toQRect(tileRect))); }
void TicTacToe::mousePressEvent(QMouseEvent *event) { if (turnNumber == 9) { clearBoard(); update(); } else { for (int position = 0; position < 9; ++position) { QRect cell = cellRect(position / 3, position % 3); if (cell.contains(event->pos())) { if (myState.at(position) == Empty) { if (turnNumber % 2 == 0) myState.replace(position, 1, Cross); else myState.replace(position, 1, Nought); ++turnNumber; update(); } } } } }
void Grid::Paint(Graphics* gfx, int offX, int offY) { CrashIf(!IsVisible()); CachedStyle* s = cachedStyle; RectF bbox((REAL)offX, (REAL)offY, (REAL)pos.Width, (REAL)pos.Height); Brush* brBgColor = BrushFromColorData(s->bgColor, bbox); gfx->FillRectangle(brBgColor, bbox); Rect r(offX, offY, pos.Width, pos.Height); DrawBorder(gfx, r, s); for (Grid::CellData& d : els) { if (!d.cachedStyle) continue; Rect cellRect(GetCellBbox(&d)); cellRect.X += offX; cellRect.Y += offY; s = d.cachedStyle; DrawBorder(gfx, cellRect, s); } }
void paintCell( QPainter *p, int row, int col ) { p->drawLine( cellWidth()-1, 0, cellWidth()-1, cellHeight()-1 ); p->drawLine( 0, cellHeight()-1, cellWidth()-1, cellHeight()-1 ); p->drawText( cellRect(), AlignCenter, QString("%1 / %1").arg(row).arg(col) ); }
void CalendarWidget::calculateAndDrawMonth(int j_y, int j_m, int j_d) { monthPixmap = QPixmap(this->size()); //Must be done. //`Qt::transparent` is equivalent to `QColor::fromRgb(0,0,0,0)` or `QColor::fromRgba(0)`. //We could also have used `palette().color(QPalette::Window)`. monthPixmap.fill(Qt::transparent); QPainter p(&monthPixmap); QPen blackPen(QColor(0, 0, 0)); QPen grayPen(QColor(192, 192, 192)); QPen blueThickPen(QColor(0, 0, 255), 2); p.setPen(blackPen); int hUnit = this->width() / 7; int vUnit = this->height() / 7; QString title = Ct::Date::PersianDate::nameOfMonth(j_m) + " " + QString::number(j_y); QRect titleRect(0, 0, this->width(), vUnit); titleRect.adjust(1, 1, -1, -1); p.fillRect(titleRect, QColor(64, 128, 255)); QFont boldFont = this->font(); boldFont.setBold(true); p.setFont(boldFont); p.drawText(titleRect, Qt::AlignCenter, title); for (int i = 0; i < 7; i++) { QRect cellRect((6 - i) * hUnit, vUnit, hUnit, vUnit); cellRect.adjust(1, 1, -1, -1); if (i == 6) p.fillRect(cellRect, QColor(96, 160, 255)); else p.fillRect(cellRect, QColor(128, 192, 255)); p.drawText(cellRect, Qt::AlignCenter, Ct::Date::PersianDate::nameOfPersianWeekDay(i + 1)); for (int j = 0; j < 7; j++) datestamps[j][i] = 0; } QDate firstDayOfJalaliMonth; Ct::Date::PersianDate::JalaliToGregorian(firstDayOfJalaliMonth, j_y, j_m, 1); //Without the QTime of 12 P.M, we got problems on 26/27 Esfand 1391 = 16/17 March 2013: // Both shows the same date! This was on Win7. On WinXP it was on the same month at different // days and in linux I did not test. QDateTime dateStamp(firstDayOfJalaliMonth, QTime(12, 0, 0)); int hPos = 0; int vPos = 2; int mapWeekStartDayFromMondayToSaturday[] = { 0, 3, 4, 5, 6, 7, 1, 2 }; int PersianWeekStartDay = mapWeekStartDayFromMondayToSaturday[firstDayOfJalaliMonth.dayOfWeek()]; hPos = PersianWeekStartDay - 1; int modFridays = (8 - PersianWeekStartDay) % 7; int jalaliMonthDayCount = Ct::Date::PersianDate::numberOfDaysInJalaliMonth(j_y, j_m); QFont smallEnglishFont("Tahoma", 8, QFont::Bold); for (int i = 1; i <= jalaliMonthDayCount; i++) { QRect cellRect((6 - hPos) * hUnit, vPos * vUnit, hUnit, vUnit); cellRect.adjust(1, 1, -1, -1); if (i % 7 == modFridays) p.fillRect(cellRect, QColor(128, 192, 255)); else p.fillRect(cellRect, Qt::white); if (i == j_d) //Today { p.setPen(blueThickPen); p.drawRect(cellRect); } //Draw the Gregorian number FIRST so that it goes lower than the Persian day in high-DPI. if (settings.showGregorianDates) { p.setPen(grayPen); p.setFont(smallEnglishFont); QString dayText = ""; //In case either Persian or Gregorian day is 1, we add the short month name (MMM). Since // in Persian locale the month name is localized, we also add space before it to have // some right margin. if (i == 1 || dateStamp.date().day() == 1) dayText = " " + dateStamp.date().toString("MMM") + " "; //We add space after the day because some right margin is always useful! Of course this space // is used if a localized month name wasn't added to the day number. dayText += QString::number(dateStamp.date().day()) + " "; p.drawText(cellRect, Qt::AlignRight | Qt::AlignBottom, dayText); } p.setPen(blackPen); p.setFont(this->font()); p.drawText(cellRect, Qt::AlignCenter, QString::number(i)); //FIRST save the datestamps datestamps[(6 - hPos)][vPos] = dateStamp.toMSecsSinceEpoch(); dateStamp = dateStamp.addDays(1); //THEN 'increase' hPos/vPos hPos++; if (hPos == 7) { hPos = 0; vPos++; if (vPos == 7) vPos = 2; //Draw the excess 30th and 31th day in the top row. } } }
void LcdWidget::paintEvent( QPaintEvent* ) { QPainter p( this ); QSize cellSize( m_cellWidth, m_cellHeight ); QRect cellRect( 0, 0, m_cellWidth, m_cellHeight ); int margin = 1; // QStyle::PM_DefaultFrameWidth; //int lcdWidth = m_cellWidth * m_numDigits + (margin*m_marginWidth)*2; // p.translate( width() / 2 - lcdWidth / 2, 0 ); p.save(); p.translate( margin, margin ); // Left Margin p.drawPixmap( cellRect, *m_lcdPixmap, QRect( QPoint( charsPerPixmap*m_cellWidth, isEnabled()?0:m_cellHeight ), cellSize ) ); p.translate( m_marginWidth, 0 ); // Padding for( int i=0; i < m_numDigits - m_display.length(); i++ ) { p.drawPixmap( cellRect, *m_lcdPixmap, QRect( QPoint( 10 * m_cellWidth, isEnabled()?0:m_cellHeight) , cellSize ) ); p.translate( m_cellWidth, 0 ); } // Digits for( int i=0; i < m_display.length(); i++ ) { int val = m_display[i].digitValue(); if( val < 0 ) { if( m_display[i] == '-' ) val = 11; else val = 10; } p.drawPixmap( cellRect, *m_lcdPixmap, QRect( QPoint( val*m_cellWidth, isEnabled()?0:m_cellHeight ), cellSize ) ); p.translate( m_cellWidth, 0 ); } // Right Margin p.drawPixmap( QRect( 0, 0, m_marginWidth-1, m_cellHeight ), *m_lcdPixmap, QRect( charsPerPixmap*m_cellWidth, isEnabled()?0:m_cellHeight, m_cellWidth / 2, m_cellHeight ) ); p.restore(); // Border QStyleOptionFrame opt; opt.initFrom( this ); opt.state = QStyle::State_Sunken; opt.rect = QRect( 0, 0, m_cellWidth * m_numDigits + (margin+m_marginWidth)*2 - 1, m_cellHeight + (margin*2) ); style()->drawPrimitive( QStyle::PE_Frame, &opt, &p, this ); p.resetTransform(); // Label if( !m_label.isEmpty() ) { p.setFont( pointSizeF( p.font(), 6.5 ) ); p.setPen( QColor( 64, 64, 64 ) ); p.drawText( width() / 2 - p.fontMetrics().width( m_label ) / 2 + 1, height(), m_label ); p.setPen( QColor( 255, 255, 255 ) ); p.drawText( width() / 2 - p.fontMetrics().width( m_label ) / 2, height() - 1, m_label ); } }
//@mFunc draws the listbox items in their proper state void CQSLItemList::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ) { CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); QSLItemData itemData; GetItemData( lpDrawItemStruct->itemID, itemData ); #ifdef USECACHE RImage* pImage = GetCachedBitmap( lpDrawItemStruct->itemID ) ; #else RImage* pImage = itemData.GetImage(); if (!itemData.m_pImage) { itemData.m_pImage = pImage; SetItemData( lpDrawItemStruct->itemID, itemData ); } // HBITMAP hBitmap = itemData.m_hBitmap ; // HPALETTE hPalette = itemData.m_hPalette ; // if (!itemData.m_pImage) // { // hBitmap = itemData.m_hBitmap = // LoadBitmapPreview( lpDrawItemStruct->itemID, &itemData.m_hPalette ) ; // hPalette = itemData.m_hPalette; // // // Save the new data into the control // SetItemData( lpDrawItemStruct->itemID, itemData ); // } // // // If we have a palette with the bitmap, realize it into the DC prior to painting. // if (hPalette != NULL) // { // CPalette palBitmap; // palBitmap.Attach( hPalette ); // CPalette *pOldPal = pDC->SelectPalette( &palBitmap, TRUE ); // pDC->RealizePalette(); // pDC->SelectPalette( pOldPal, TRUE ); // palBitmap.Detach(); // } #endif BITMAP bm= { 0, 0, 0, 0, 0, 0, NULL }; HBITMAP hBitmap = NULL; if (pImage) { hBitmap = (HBITMAP) pImage->GetSystemHandle(); ::GetObject( hBitmap, sizeof( bm ), &bm ); } // Determine colors to use for drawing text and selection // COLORREF crFillColor = GetSysColor( COLOR_WINDOW ) ; COLORREF crTextColor = GetSysColor( COLOR_WINDOWTEXT ) ; if (lpDrawItemStruct->itemState & ODS_SELECTED) { crFillColor = GetSysColor( COLOR_HIGHLIGHT ) ; crTextColor = GetSysColor( COLOR_HIGHLIGHTTEXT ) ; } // Handle drawing according to action // // Setup DC COLORREF oldTextColor = pDC->SetTextColor( crTextColor ); COLORREF oldBkColor = pDC->SetBkColor( crFillColor ); CFont* pOldFont = pDC->SelectObject( GetParent()->GetFont() ); // Determine location to draw bitmap. This information // is needed for all drawing modes, so might as well // just determine it once, and in one place. CSize szExtent = pDC->GetTextExtent( itemData.m_strDesc ); RIntRect cellRect( lpDrawItemStruct->rcItem ); cellRect.Inset( RIntSize( 4, 4 ) ); cellRect.m_Bottom -= szExtent.cy + 2; // + 2 is for spacing between graphic & text RIntRect imgRect( 0, 0, bm.bmWidth - 1, bm.bmHeight - 1 ); imgRect.ShrinkToFit( cellRect ); imgRect.CenterRectInRect( cellRect ); CSize szImage( imgRect.Width(), imgRect.Height() ); // CPoint centerPt( cellRect.CenterPoint() ); // CPoint ptTopLeft( centerPt.x - szImage.cx / 2, centerPt.y - szImage.cy / 2 - 2 ); switch (lpDrawItemStruct->itemAction) { case ODA_DRAWENTIRE: { CDC memDC; memDC.CreateCompatibleDC( pDC ); // Get the bitmap CBitmap* pBmp = CBitmap::FromHandle( hBitmap ); CBitmap* pOldBmp = memDC.SelectObject( pBmp ); pDC->StretchBlt( imgRect.m_Left, imgRect.m_Top, imgRect.Width(), imgRect.Height(), &memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY ); memDC.SelectObject( pOldBmp ); if (!(lpDrawItemStruct->itemState & ODS_SELECTED)) { break ; } // Fall through } case ODA_SELECT: { // Draw/Clear the highlight rect // CRect bmpRect( ptTopLeft.x, ptTopLeft.y, ptTopLeft.x + bm.bmWidth, ptTopLeft.y + bm.bmHeight); CRect bmpRect( imgRect ); bmpRect.InflateRect( 2, 2 ); CPen pen( PS_SOLID, 2, crFillColor ); CPen* pOldPen = pDC->SelectObject( &pen ); pDC->MoveTo( bmpRect.left, bmpRect.top ); pDC->LineTo( bmpRect.right, bmpRect.top ); pDC->LineTo( bmpRect.right, bmpRect.bottom ); pDC->LineTo( bmpRect.left, bmpRect.bottom ); pDC->LineTo( bmpRect.left, bmpRect.top ); pDC->SelectObject( pOldPen ); } } // switch // Draw the text CPoint ptText( cellRect.m_Left + (cellRect.Width() - szExtent.cx) / 2, cellRect.m_Bottom + 4 ); pDC->TextOut( ptText.x, ptText.y, itemData.m_strDesc ); // pDC->DrawText( itemData.m_strDesc, &textRect, DT_CALCRECT | DT_SINGLELINE ); // textRect.OffsetRect( -textRect.Width() / 2, 2 ); // pDC->DrawText( itemData.m_strDesc, &textRect, DT_CENTER | DT_VCENTER ); // restore DC pDC->SelectObject( pOldFont ); pDC->SetTextColor( oldTextColor ); pDC->SetBkColor( oldBkColor ); }