How to work with a moving cursor in a DC?
void CCompass::DrawCompass(CRect *pRect, CDC *pDCa)
{
//
// Get DC if no DC is passed
//
CDC *pDC = pDCa;
if(pDCa == NULL) pDC = GetDC();
//
// Create temporary work DC (memory DC) and bitmap
//
CDC dcMem;
CDC dcOriginalMem;
int IniDC;
CBitmap bmTemp;
dcMem.CreateCompatibleDC(pDC);
dcOriginalMem.CreateCompatibleDC(pDC);
bmTemp.CreateCompatibleBitmap( pDC,pRect->Width(),pRect->Height() );
CBitmap *pbmOld = dcMem.SelectObject(&bmTemp);
dcOriginalMem.SelectObject(&bmTemp);
CRect rect = *pRect;
//
// Draw background rectangle
//
CBrush WorkSpaceBrush( RGB(255, 255, 255));//GetSysColor( COLOR_BTNFACE ) );
CBrush *pOldBrush = dcMem.SelectObject(&WorkSpaceBrush);
dcOriginalMem.SelectObject(&WorkSpaceBrush);
CPen *pOldPen = (CPen *)dcMem.SelectStockObject( NULL_PEN );
dcOriginalMem.SelectStockObject( NULL_PEN );
dcMem.Rectangle(&rect);
dcOriginalMem.Rectangle(&rect);
dcMem.Draw3dRect(&rect,(COLORREF)GetSysColor(COLOR_3DSHADOW),
(COLORREF)GetSysColor(COLOR_3DHILIGHT));
dcOriginalMem.Draw3dRect(&rect,(COLORREF)GetSysColor(COLOR_3DSHADOW),
(COLORREF)GetSysColor(COLOR_3DHILIGHT));
dcMem.SelectStockObject( BLACK_PEN);
dcOriginalMem.SelectStockObject( BLACK_PEN);
//
// Create rgn
//
rect.InflateRect(-1,0);
CRgn rgnRect;
rgnRect.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
dcMem.SelectClipRgn(&rgnRect);
dcOriginalMem.SelectClipRgn(&rgnRect);
rect = *pRect;
rect.InflateRect(30,0);
//
// Calculate some ratios
//
float fDegreePerDeltaPixel = (float)rect.Width()/(float)DEGREES_IN_VIEW;
if((int)fDegreePerDeltaPixel < 2) fDegreePerDeltaPixel = 2.0;
//
// Calculate most left degree point
//
int nStartDegree = (int)m_fHeading - rect.Width()/2 / (int)fDegreePerDeltaPixel;
//
// If nStartDegree is < 0 or > 360, adjust to reflect a valid compass heading
//
if( nStartDegree < 0 ) nStartDegree = 360 + (nStartDegree % 360);
else if( nStartDegree > 360 ) nStartDegree %= 360;
//
// Create a font and set color
//
CFont cFont,*cpOldFont;
cFont.CreatePointFont(70,_T("Arial"));
cpOldFont = (CFont *)dcMem.SelectObject(&cFont);
dcOriginalMem.SelectObject(&cFont);
COLORREF crOldBkColor = dcMem.SetBkColor( GetSysColor( COLOR_BTNFACE ) );
dcOriginalMem.SetBkColor( GetSysColor( COLOR_BTNFACE ) );
TEXTMETRIC tm;
dcMem.GetTextMetrics(&tm);
dcOriginalMem.GetTextMetrics(&tm);
//
// Draw compass
//
int nTextYPosition;
UINT y;
int numDivisions = 0;
for(int i = 0; i < rect.Width(); i += (int)fDegreePerDeltaPixel)
{
//
// Calculate height of tick mark amd draw it. This is based on the
// m_wTicAlign flag.
if( (nStartDegree % 10) == 0)
y = rect.bottom - rect.Height()/2;
else if( (nStartDegree % 5) == 0)
y = rect.bottom - rect.Height()/3;
else
y = rect.bottom - rect.Height()/5;
dcMem.MoveTo(rect.left+i,rect.bottom-1);
dcOriginalMem.MoveTo(rect.left+i,rect.bottom-1);
dcMem.LineTo(rect.left+i,y);
dcOriginalMem.LineTo(rect.left+i,y);
nTextYPosition = rect.Height()/2 - tm.tmHeight;
// Draw text
//
if( (nStartDegree % 15) == 0)
{
CString s;
switch(nStartDegree)
{
case 0 : s = _T("N") ; break;
case 45 : s = _T("NE"); break;
case 90 : s = _T("E") ; break;
case 135: s = _T("SE"); break;
case 180: s = _T("S") ; break;
case 225: s = _T("SW"); break;
case 270: s = _T("W") ; break;
case 315: s = _T("NW"); break;
default: s.Format(_T("%d"),nStartDegree); break;
}
dcMem.ExtTextOut(
rect.left+i-dcMem.GetTextExtent(s).cx/2,
nTextYPosition,
ETO_OPAQUE,
NULL,
s,
NULL
);
dcOriginalMem.ExtTextOut(
rect.left+i-dcMem.GetTextExtent(s).cx/2,
nTextYPosition,
ETO_OPAQUE,
NULL,
s,
NULL
);
}
/*
//
// Wrap around
//
if(++nStartDegree >= 360) nStartDegree = 0; */
}
//
// Draw center line
//
CPen MarkerPen( PS_SOLID, 1, RGB(100, 200, 200) );
dcMem.SelectObject( &MarkerPen );
dcOriginalMem.SelectObject( &MarkerPen );
// This code doesn't belong to here... only from Draw center line ... or maybe it belongs
// Create a copy of the original ruler, so that we can redraw it before altering the cursor position
IniDC = dcMem.SaveDC();
dcOriginalMem.BitBlt(0, 0, rect.Width(), rect.Height(), &dcMem, 1, 0, SRCCOPY);
for (int j = rect.left; j <= rect.right; j++)
{
// Create a copy of the original ruler, so that we can redraw it before altering the cursor position
dcMem.RestoreDC(IniDC);
dcMem.BitBlt(0,0,rect.Width(),rect.Height(),&dcOriginalMem,0,0,SRCCOPY);
/*wait*/for(int k = 0; k<1000000; k++);
Pump();
dcMem.MoveTo(j, rect.top);
dcMem.LineTo(j, rect.bottom);
Invalidate();
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);
}
//int cx = rect.left+(rect.Width()/2 / (int)fDegreePerDeltaPixel) * (int)fDegreePerDeltaPixel;
//dcMem.MoveTo( cx,rect.top);
//dcMem.LineTo( cx,rect.bottom);
//pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);
//
// finally draw to screen from temperary dc
//
// pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcOriginalMem,0,0,SRCCOPY);
///////////////////////////////////////////////////////////////////////////
pDC->SelectClipRgn(NULL);
rgnRect.DeleteObject();
dcOriginalMem.SelectObject(pOldBrush);
WorkSpaceBrush.DeleteObject();
dcOriginalMem.SetBkColor( crOldBkColor );
dcOriginalMem.SelectObject(pbmOld);
bmTemp.DeleteObject();
dcOriginalMem.SelectObject(cpOldFont);
cFont.DeleteObject();
dcOriginalMem.SelectObject(pOldPen);
dcOriginalMem.SelectObject(cpOldFont);
///////////////////////////////////////////////////////////////////////////
if(pDCa == NULL) ReleaseDC(pDC);
}

