www.pudn.com > realtime.rar > Graphics.cpp, change:2000-05-10,size:19267b


#include "stdafx.h" 
//#include <windows.h> 
//#include <stdio.h> 
#include "graphics.h" 
 
/////////////////////////////////////////////////////////////////////////////// 
// class CGroupLines 
 
CGraphics::CGraphics() 
{ 
	m_Ratio.xmin	= 0; 
	m_Ratio.ymin	= 0; 
	m_Ratio.xmax	= 1; 
	m_Ratio.ymax	= 1; 
	m_nBackColor	= RGB(255, 255, 255); 
	m_nGridColor	= RGB(192, 192, 192); 
	m_nBorderColor	= RGB(0, 0, 0); 
	m_nTickColor	= RGB(0, 0, 255); 
	m_nTitleColor	= RGB(255, 0, 0); 
	m_nXDecimal		= 0; 
	m_nYDecimal		= 0; 
	XGridTicks		= 10; 
	YGridTicks		= 10; 
	XTicks			= 50; 
	YTicks			= 50; 
	m_bEnableLegend = true; 
	m_bPrinting		= false; 
	m_bLegendShadow = true; 
	m_bMemoryDraw	= true; 
	m_nPrintScale	= 8; 
	m_nAxesType		= XY; 
	m_nXStep		= 0; 
	m_nYStep		= 0; 
 
	m_LogFont.lfWidth			= 0; 
	m_LogFont.lfItalic			= false; 
	m_LogFont.lfUnderline		= false; 
	m_LogFont.lfStrikeOut		= false; 
	m_LogFont.lfCharSet			= ANSI_CHARSET; 
	m_LogFont.lfOutPrecision	= OUT_DEFAULT_PRECIS; 
	m_LogFont.lfClipPrecision	= CLIP_DEFAULT_PRECIS; 
	m_LogFont.lfQuality			= PROOF_QUALITY; 
	m_LogFont.lfPitchAndFamily	= DEFAULT_PITCH; 
	strcpy(m_LogFont.lfFaceName,"Ariel"); 
 
	crTable[0]  = RGB(255, 255, 255);     // White                   
    crTable[1]  = RGB(  0,   0,   0);     // Black 
	crTable[2]  = RGB(255,   0,   0);     // Red 
	crTable[3]  = RGB(  0, 255,   0);     // Green 
	crTable[4]  = RGB(  0,   0, 255);     // Blue 
	crTable[5]  = RGB(255,   0, 255);     // Magenta 
	crTable[6]  = RGB(  0, 255, 255);     // Cyan 
	crTable[7]  = RGB(128, 128, 128);     // Grey 
	crTable[8]  = RGB(128, 128,   0);     // Brown 
	crTable[9]  = RGB(128,   0, 128);     // Purple 
	crTable[10] = RGB(  0, 128, 128);     // Aqua 
	crTable[11] = RGB(128,   0,   0);     //  
	crTable[12] = RGB(  0, 128,   0);     //  
	crTable[13] = RGB(  0,   0, 128);     //  
	crTable[14] = RGB(192, 192, 192);     //  
	crTable[15] = RGB(255, 255,   0);     // Yellow 
 
	m_Bitmap    = 0; 
} 
 
void CGraphics::SetPrintScale(HDC& hDC, RECT& rect) 
{ 
	int Width     = ::GetDeviceCaps(hDC, HORZRES); 
	int Height    = ::GetDeviceCaps(hDC, VERTRES); 
	int wd		  = abs(rect.right - rect.left); 
	int ht		  = abs(rect.bottom - rect.top); 
	m_nPrintScale = (wd + ht) / (Width + Height); 
	m_bPrinting	  = true; 
	RecalcRects(rect); 
} 
 
void CGraphics::RecalcRects(RECT& rt) 
{ 
	//m_Rect = rt; 
	m_ClientRect = rt; 
	SetPixelRect(rt); 
	m_bM = (m_Rect.bottom - m_Rect.top) / 6; 
	m_tM = (m_Rect.bottom - m_Rect.top) / 10; 
	m_lM = m_rM = (m_Rect.right - m_Rect.left) / 8; 
 
	m_PlotRect.left		= m_Rect.left + m_lM; 
	if (m_bEnableLegend) 
		m_PlotRect.right= m_Rect.right - 3 * m_rM / 2; 
	else 
		m_PlotRect.right= m_Rect.right - m_rM; 
	m_PlotRect.top		= m_Rect.top + m_tM; 
	m_PlotRect.bottom	= m_Rect.bottom - m_bM; 
 
	GL = m_PlotRect.left; 
	GR = m_PlotRect.right; 
	GT = m_PlotRect.top; 
	GB = m_PlotRect.bottom; 
	PX = GR - GL; 
	PY = GB - GT; 
	m_Scale.dx   = (m_Scale.xmax- m_Scale.xmin) / PX; 
	m_Scale.dy   = (m_Scale.ymax- m_Scale.ymin) / PY; 
	m_Size.cx = (PY < PX) ? PY : PX; 
} 
 
void CGraphics::BeginDraw(HDC hDC)						 
{  
	if (m_bPrinting || !m_bMemoryDraw) 
		m_hDC = hDC; 
	else 
	{ 
		::GetClipBox(hDC, &m_ClipBox); 
		m_hDC    = ::CreateCompatibleDC(hDC); 
		m_Bitmap = ::CreateCompatibleBitmap(hDC, m_ClipBox.right - m_ClipBox.left,  
											m_ClipBox.bottom - m_ClipBox.top); 
		m_OldBitmap = (HBITMAP)::SelectObject(m_hDC, m_Bitmap); 
		::SetWindowOrgEx(m_hDC, m_ClipBox.left, m_ClipBox.top, NULL); 
	} 
	DrawBkGround(); 
} 
 
void CGraphics::EndDraw(HDC hDC) 
{ 
	if (m_bPrinting || !m_bMemoryDraw) 
	{ 
		m_bPrinting = false; 
		return; 
	} 
 
	::BitBlt(hDC, m_ClipBox.left, m_ClipBox.top, m_ClipBox.right - m_ClipBox.left, 
			 m_ClipBox.bottom - m_ClipBox.top, m_hDC, m_ClipBox.left, m_ClipBox.top, SRCCOPY); 
	::SelectObject(m_hDC, m_OldBitmap); 
	::DeleteObject(m_Bitmap); 
	::DeleteDC(m_hDC); 
} 
 
void CGraphics::DrawBkGround() 
{ 
	HBRUSH hBrush = ::CreateSolidBrush(m_nBackColor); 
    HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush); 
	::Rectangle(m_hDC, m_ClientRect.left, m_ClientRect.top,  
				m_ClientRect.right, m_ClientRect.bottom); 
    ::SelectObject(m_hDC, hBrold); 
    ::DeleteObject(hBrush); 
} 
 
void CGraphics::SetRatio(double xmin, double ymin, double xmax, double ymax) 
{ 
	m_Ratio.xmin = xmin; 
	m_Ratio.ymin = ymin; 
	m_Ratio.xmax = xmax; 
	m_Ratio.ymax = ymax; 
} 
 
void CGraphics::GetPixelRect(RECT& rt) 
{ 
	rt.left	  = m_Rect.left; 
	rt.top	  = m_Rect.top; 
	rt.right  = m_Rect.right; 
	rt.bottom = m_Rect.bottom; 
} 
 
void CGraphics::SetPixelRect(RECT rt) 
{ 
	LONG Width    = rt.right  - rt.left; 
    LONG Height   = rt.bottom - rt.top;  
	m_Rect.left   = (LONG)(rt.left + m_Ratio.xmin * Width); 
	m_Rect.top	  = (LONG)(rt.top + m_Ratio.ymin * Height); 
	m_Rect.right  = (LONG)(rt.right - (1 - m_Ratio.xmax) * Width); 
	m_Rect.bottom = (LONG)(rt.bottom - (1 - m_Ratio.ymax) * Height); 
} 
 
void CGraphics::Title(const char* Title, int Pos) 
{ 
	m_LogFont.lfHeight = (int)(m_Size.cx / -15.0); 
	if (m_LogFont.lfHeight > -10)  
		m_LogFont.lfHeight = -10; 
	m_LogFont.lfWeight	   = 700; 
	m_LogFont.lfOrientation= 0; 
	m_LogFont.lfEscapement = 0; 
	m_Font = ::CreateFontIndirect(&m_LogFont); 
	if (m_Font) 
	{ 
	  	int bm  = ::SetBkMode(m_hDC, TRANSPARENT); 
		HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font); 
		::SetTextColor(m_hDC, RGB(0, 0, 0));  
		SetStringAlign(CENTER, CENTER); 
		if (Pos == TOP) 
		{ 
			PrintString((GL + GR) / 2, (m_Rect.top + GT ) / 2 + 1, 0, Title); 
			::SetTextColor(m_hDC, m_nTitleColor);  
			PrintString((GL + GR) / 2, (m_Rect.top + GT ) / 2, 0, Title); 
		} 
		else 
		{ 
			int n = m_Rect.bottom - (m_Rect.bottom - GB) / 3; 
			PrintString((GL + GR) / 2, n + 1, 0, Title); 
			::SetTextColor(m_hDC, m_nTitleColor);  
			PrintString((GL + GR) / 2, n, 0, Title); 
		} 
		::SelectObject(m_hDC, hOldFont); 
		::DeleteObject(m_Font); 
		::SetBkMode(m_hDC, bm); 
	} 
} 
 
void CGraphics::XAxisTitle(const char* Title, int Pos) 
{ 
	m_LogFont.lfHeight = (int)(m_Size.cx / -20.0); 
	if (m_LogFont.lfHeight > -10)  
		m_LogFont.lfHeight = -10; 
	m_LogFont.lfWeight	   = 700; 
	m_LogFont.lfOrientation= 0; 
	m_LogFont.lfEscapement = 0; 
	m_Font = ::CreateFontIndirect(&m_LogFont); 
	if (m_Font) 
	{ 
	  	int bm  = ::SetBkMode(m_hDC, TRANSPARENT); 
		HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font); 
		::SetTextColor(m_hDC, m_nTitleColor);  
		SetStringAlign(CENTER, CENTER); 
		if (Pos == TOP) 
			PrintString((GL + GR) / 2, (m_Rect.top + GT ) / 2, 0, Title); 
		else 
			PrintString((GL + GR) / 2, m_Rect.bottom - (m_Rect.bottom - GB) / 3, 0, Title); 
		::SelectObject(m_hDC, hOldFont); 
		::DeleteObject(m_Font); 
		::SetBkMode(m_hDC, bm); 
	} 
} 
 
void CGraphics::YAxisTitle(const char* Title, int Pos) 
{ 
	m_LogFont.lfHeight = (int)(m_Size.cx / -20.0); 
	if (m_LogFont.lfHeight > -10)  
		m_LogFont.lfHeight = -10; 
	m_LogFont.lfWeight	   = 700; 
	if (Pos == LEFT) 
	{ 
		m_LogFont.lfOrientation= 900; 
		m_LogFont.lfEscapement = 900; 
	} 
	else 
	{ 
		m_LogFont.lfOrientation= -900; 
		m_LogFont.lfEscapement = -900; 
	} 
	m_Font = ::CreateFontIndirect(&m_LogFont); 
	if (m_Font) 
	{ 
	  	int bm  = ::SetBkMode(m_hDC, TRANSPARENT); 
		HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font); 
		::SetTextColor(m_hDC, m_nTitleColor);  
		SetStringAlign(CENTER, CENTER); 
		if (Pos == LEFT) 
			PrintString(m_Rect.left + (GL - m_Rect.left) / 3, (GT + GB) / 2, 90, Title); 
		else 
			PrintString(m_Rect.right - (m_Rect.right - GR) / 3, (GT + GB) / 2, -90, Title); 
		::SelectObject(m_hDC, hOldFont); 
		::DeleteObject(m_Font); 
		::SetBkMode(m_hDC, bm); 
	} 
} 
 
void CGraphics::DrawBoundary(COLORREF cr, int size) 
{ 
	HPEN hPen	= ::CreatePen(PS_SOLID, size, cr); 
	HPEN hOldPen = (HPEN)::SelectObject(m_hDC, hPen); 
	 
	int n = 5; 
	if (m_bPrinting)	n *= m_nPrintScale; 
	DrawRectangle(m_Rect.left + n, m_Rect.top + n,  
				  m_Rect.right - n, m_Rect.bottom - n); 
 
    ::SelectObject(m_hDC, hOldPen); 
    ::DeleteObject(hPen);   
} 
 
void CGraphics::Legend(COLORREF cr, int Index, const char* Name) 
{ 
	m_LogFont.lfHeight = (int)(m_Size.cx / -25.0); 
	if (m_LogFont.lfHeight > -10)  
		m_LogFont.lfHeight = -10; 
	m_LogFont.lfWeight	   = 500; 
	m_LogFont.lfOrientation= 0; 
	m_LogFont.lfEscapement = 0; 
	m_Font = ::CreateFontIndirect(&m_LogFont); 
	if (m_Font) 
	{ 
		int n  = (m_Rect.right - GR) / 20 + 1; 
		int xb = GR + 2 * n; 
		int xe = xb + 4 * n; 
		int y  = GT - 3 * Index * m_LogFont.lfHeight / 2; 
		DrawLine(xb, y, xe, y); 
	  	int bm  = ::SetBkMode(m_hDC, TRANSPARENT); 
		HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font); 
		::SetTextColor(m_hDC, cr);  
		SetStringAlign(LEFT, CENTER); 
		PrintString(xe + n, y, 0, Name); 
		::SelectObject(m_hDC, hOldFont); 
		::DeleteObject(m_Font); 
		::SetBkMode(m_hDC, bm); 
	} 
} 
 
void CGraphics::DrawCircle(int x, int y, int radius) 
{ 
    int x1 = x - radius; 
    int y1 = y - radius; 
    int x2 = x + radius; 
    int y2 = y + radius; 
	::Arc(m_hDC, x1, y1, x2, y2, x, y2, x, y2); 
} 
 
void CGraphics::DrawFilledCircle(int x, int y, int radius) 
{ 
    int x1 = x - radius; 
    int y1 = y - radius; 
    int x2 = x + radius; 
    int y2 = y + radius; 
    ::Ellipse(m_hDC, x1, y1, x2, y2); 
} 
 
void CGraphics::DrawRectangle(int x1, int y1, int x2, int y2) 
{ 
	::MoveToEx(m_hDC, x1, y1, NULL); 
	::LineTo(m_hDC, x1, y2); 
	::LineTo(m_hDC, x2, y2); 
	::LineTo(m_hDC, x2, y1); 
	::LineTo(m_hDC, x1, y1); 
} 
 
void CGraphics::PrintString(int x, int y, int theta, const char* fmt) 
{ 
	WORD    Height, Width; 
	UINT    PreSet; 
	double  thta; 
	 
	PreSet = ::SetTextAlign(m_hDC, TA_LEFT|TA_TOP); 
 
	SIZE  size; 
	::GetTextExtentPoint32(m_hDC, fmt, lstrlen(fmt), &size); 
	Height = (WORD)size.cy; 
	Width  = (WORD)size.cx; 
                                              
    thta   = PiV*theta/ConstV; 
    if(m_StrAlign.HAlign == LEFT && m_StrAlign.VAlign == TOP) 
	{ 
	}  
    else if(m_StrAlign.HAlign == LEFT && m_StrAlign.VAlign == CENTER) 
	{      
		x = (int)(x - Height/2.*sin(thta)); 
		y = (int)(y - Height/2.*cos(thta)); 
	} 
    else if(m_StrAlign.HAlign == CENTER && m_StrAlign.VAlign == TOP) 
	{ 
		x = (int)(x - Width/2. * cos(thta)); 
		y = (int)(y + Width/2. * sin(thta)); 
	} 
    else if(m_StrAlign.HAlign == CENTER && m_StrAlign.VAlign == CENTER) 
	{ 
		x = (int)(x - Width/2. * cos(thta) - Height/2.*sin(thta)); 
		y = (int)(y + Width/2. * sin(thta) - Height/2.*cos(thta)); 
	} 
    else if(m_StrAlign.HAlign == CENTER && m_StrAlign.VAlign == BOTTOM) 
	{ 
		x = (int)(x - Width/2. * cos(thta) - Height*sin(thta)); 
		y = (int)(y + Width/2. * sin(thta) - Height*cos(thta)); 
	} 
    else if(m_StrAlign.HAlign == RIGHT && m_StrAlign.VAlign == TOP) 
	{ 
		x = (int)(x - Width * cos(thta)); 
		y = (int)(y + Width * sin(thta)); 
	} 
    else if(m_StrAlign.HAlign == RIGHT && m_StrAlign.VAlign == CENTER) 
	{ 
		x = (int)(x - Width * cos(thta) - Height/2.*sin(thta)); 
		y = (int)(y + Width * sin(thta) - Height/2.*cos(thta)); 
	} 
    else if(m_StrAlign.HAlign == RIGHT && m_StrAlign.VAlign == BOTTOM) 
	{ 
		x = (int)(x - Width * cos(thta) - Height*sin(thta)); 
		y = (int)(y + Width * sin(thta) - Height*cos(thta)); 
	} 
    else //if(m_StrAlign.HAlign == LEFT && m_StrAlign.VAlign == BOTTOM) 
	{              
		x = (int)(x - Height*sin(thta)); 
		y = (int)(y - Height*cos(thta)); 
	}                  
	::TextOut(m_hDC, x, y, fmt, lstrlen(fmt)); 
	::SetTextAlign(m_hDC, PreSet); 
} 
 
void CGraphics::Format(int decimal, char* str, float value) 
{ 
	char tstr[24]; 
	switch(decimal) 
	{ 
	case 0: 
		sprintf(str, "%.f", value); 
		return; 
	case 1: 
		sprintf(tstr, "%.1f", value); 
		break; 
	case 2: 
		sprintf(tstr, "%.2f", value); 
		break; 
	case 3: 
		sprintf(tstr, "%.3f", value); 
		break; 
	case 4: 
		sprintf(tstr, "%.4f", value); 
		break; 
	default: 
		sprintf(tstr, "%.5f", value); 
		break; 
	} 
 
	if (fabs(value) > 0.99999) 
	{ 
		_gcvt(atof(tstr), 12, str); 
		if (str[lstrlen(str)-1] == '.') 
			str[lstrlen(str)-1] = '\0'; 
	} 
	else 
	{ 
		if (fabs(value) <1.0e-10) 
			lstrcpy(str, "0"); 
		else 
		{ 
			lstrcpy(str, tstr); 
			int n = lstrlen(str) - 1; 
			while(str[n] == '0' && n >= 0) 
				str[n--] = '\0'; 
		} 
	} 
} 
 
void CGraphics::Grid() 
{ 
	int i, j;                                     
                 
	HPEN hPen	= ::CreatePen(PS_DOT, 0, m_nGridColor); 
	HPEN hOldPen = (HPEN)::SelectObject(m_hDC, hPen); 
 
	for(i = 1; i < XGridTicks; i ++) 
	{ 
		j = GL + (int)(1.0 * i * (GR-GL) / XGridTicks); 
		DrawLine(j, GT + 1, j, GB - 1); 
	} 
 
	for(i = 1; i < YGridTicks; i ++)  
	{ 
		j = GT + (int)(1.0 * i * (GB-GT) / YGridTicks); 
		DrawLine(GL + 1, j, GR - 1, j); 
	} 
 
	::SelectObject(m_hDC, hOldPen); 
	::DeleteObject(hPen); 
} 
 
void CGraphics::XAxis() 
{ 
	int	  xb, yb, xe, ye;    
    int   i, j;                                   
	char  str[32]; 
	float value; 
 
	yb=GB; 
	j = XTicks / 10; 
	for(i = 0; i <= XTicks; i ++)  
	{ 
		xb = xe = (int)(GL + 1.0 * PX * i / XTicks ); 
		if((i % j) == 0) 
		{ 
			ye = GB + m_bM / 7; 
			value = (float)(m_Scale.xmin + i * (m_Scale.xmax - m_Scale.xmin) / XTicks); 
			Format(m_nXDecimal, str, value); 
			PrintString(xb, GB + m_bM / 5, 0, str); 
		} 
		else  
			ye = GB + m_bM / 14; 
		if (i > 0 && i < XTicks) 
			DrawLine(xb, yb, xe, ye); 
	} 
} 
 
void CGraphics::YAxis() 
{ 
    int	  xb, yb, xe, ye;    
    int   i, j;                                   
	char  str[32]; 
	float value; 
 
	xe = GL; 
	j = YTicks / 10; 
	for(i = 0; i <= YTicks; i ++)      
	{ 
		yb = ye = (int)(GT + 1.0 * PY * i / YTicks ); 
		if((i % j) == 0)  
		{ 
			xb = GL - m_lM / 10; 
			value = (float)(m_Scale.ymax - i * (m_Scale.ymax - m_Scale.ymin) / YTicks); 
			Format(m_nYDecimal, str, value); 
			PrintString(GL - m_lM / 6, yb, 0, str); 
		} 
		else 
			xb = GL - m_lM / 20; 
		if (i > 0 && i < YTicks) 
			DrawLine(xb, yb, xe, ye); 
	}     
} 
 
void CGraphics::Ticks() 
{ 
	SetStringAlign(CENTER, TOP); 
	XAxis(); 
	SetStringAlign(RIGHT, CENTER); 
	YAxis(); 
} 
 
void CGraphics::RightYTick() 
{ 
	if (m_bEnableLegend) 
		return; 
 
    int	  xb, yb, xe, ye;    
    int   i, j, k;                                   
	char  str[32]; 
	float value; 
 
	xb = GR; 
	SetStringAlign(LEFT, CENTER); 
	if (m_nAxesType == XY || m_nAxesType == XLOG) 
	{ 
		j = YTicks / 10; 
		for(i = 0; i <= YTicks; i ++)      
		{ 
			yb = ye = (int)(GT + 1.0 * PY * i / YTicks ); 
			if((i % j) == 0)  
			{ 
				xe = GR + m_rM / 10; 
				value = (float)(m_Scale.ymax - i * (m_Scale.ymax - m_Scale.ymin) / YTicks); 
				Format(m_nYDecimal, str, value); 
				PrintString(GR + m_rM / 6, yb, 0, str); 
			} 
			else 
				xe = GR + m_rM / 20; 
			if (i > 0 && i < YTicks) 
				DrawLine(xb, yb, xe, ye); 
		} 
	} 
	else 
	{ 
		for(i = 1; i <= m_nYStep; i ++) 
		{ 
			for(j = 1; j <= 10; j ++) 
			{ 
				if (k == 0)    
					xe = GR + m_rM / 10; 
				else 
					xe = GR + m_rM / 20; 
				yb = ye = GB - (int)(log10(j) * PY / m_nYStep + 1.0 * (i - 1) * PY / m_nYStep); 
				if (j == 1) 
				{ 
					value = (float)(pow(10.0, m_Scale.ymin) * pow(10.0, i - 1)); 
					Format(m_nYDecimal, str, value); 
					PrintString(GR + m_rM / 6, yb, 0, str); 
				} 
				if ((i != 1 || j != 1) && (i != m_nYStep || j != 10)) 
					DrawLine(xb, yb, xe, ye); 
				k = 1; 
			} 
			k=0; 
		} 
 
		value = (float)(pow(10.0, m_Scale.ymin) * pow(10.0, i - 1)); 
		Format(m_nYDecimal, str, value); 
		PrintString(GR + m_rM / 6, yb, 0, str); 
	} 
} 
 
void CGraphics::Axes() 
{ 
  	int bm		 = ::SetBkMode(m_hDC, TRANSPARENT); 
    HPEN hPen    = ::CreatePen(PS_SOLID, 0, m_nBorderColor); 
    HPEN hOldPen = (HPEN)::SelectObject(m_hDC, hPen); 
 
	DrawRectangle(GL, GT, GR, GB); 
	m_LogFont.lfHeight = (int)(m_Size.cx / -25.0); 
	if (m_LogFont.lfHeight > -10)  
		m_LogFont.lfHeight = -10; 
	m_LogFont.lfWeight     = 500; 
	m_LogFont.lfOrientation= 0; 
	m_LogFont.lfEscapement = 0; 
	m_Font = ::CreateFontIndirect(&m_LogFont); 
	if (m_Font) 
	{ 
		HFONT hOldFont = (HFONT)::SelectObject(m_hDC, m_Font); 
		SetTextColor(m_hDC, m_nTickColor);  
		Ticks(); 
		RightYTick(); 
		::SelectObject(m_hDC, hOldFont); 
		::DeleteObject(m_Font); 
	} 
 
    ::SelectObject(m_hDC, hOldPen); 
    ::DeleteObject(hPen);   
	::SetBkMode(m_hDC, bm); 
} 
 
void CGraphics::DrawMarker(int x, int y, int mode, int n) 
{ 
	if (m_bPrinting)	n *= m_nPrintScale; 
    switch(mode) 
	{ 
		case CROSS: 
			DrawLine(x - n, y, x + n, y ); 
			DrawLine(x, y - n, x, y + n ); 
			break; 
 
		case STAR: 
			DrawLine(x - n, y, x + n, y ); 
			DrawLine(x - n / 2, (int)(y + n * sqrt(3.) / 2), x + n / 2,  
					(int)(y - n * sqrt(3.) / 2)); 
			DrawLine(x - n / 2, (int)(y - n * sqrt(3.) / 2), x + n / 2,  
					(int)(y + n * sqrt(3.) / 2)); 
			break; 
 
		case FCIRCLE: 
			DrawFilledCircle(x, y, n); 
			break; 
 
		case FTRIANGLE: 
		{ 
			POINT  p[3]; 
			p[0].x = x - n; 
			p[0].y = (int)(y + n * sqrt(3.) / 3); 
			p[1].x = x + n; 
			p[1].y = (int)(y + n * sqrt(3.) / 3); 
			p[2].x = x; 
			p[2].y = (int)(y - 2 * n * sqrt(3.) / 3); 
			::Polygon(m_hDC, p, 3); 
			break; 
		} 
 
		case XCROSS: 
			DrawLine((int)(x + n * sqrt(2.) / 2), 
					 (int)(y - n * sqrt(2.) / 2),  
					 (int)(x - n * sqrt(2.) / 2), 
					 (int)(y + n * sqrt(2.) / 2)); 
			DrawLine((int)(x - n * sqrt(2.) / 2), 
					 (int)(y - n * sqrt(2.) / 2),  
					 (int)(x + n * sqrt(2.) / 2), 
					 (int)(y + n * sqrt(2.) / 2)); 
			break; 
 
		case CIRCLE: 
			DrawCircle(x, y, n); 
			break; 
 
		case TRIANGLE: 
			DrawLine(x - n, (int)(y + n * sqrt(3.) / 3), 
					 x + n, (int)(y + n * sqrt(3.) / 3)); 
			DrawLine(x + n, (int)(y + n * sqrt(3.) / 3), 
					 x, (int)(y - 2 * n * sqrt(3.) / 3)); 
			DrawLine(x, (int)(y - 2 * n * sqrt(3.) / 3), 
					 x - n, (int)(y + n * sqrt(3.) / 3));   
			break; 
 
		case FSQUARE: 
			::Rectangle(m_hDC, x - n, y - n, x + n, y + n); 
			break; 
 
		case SQUARE:       
			DrawRectangle(x - n, y - n, x + n, y + n ); 
			break; 
 
		case FDIAMOND: 
		{ 
			POINT  p[4]; 
			p[0].x = x - n; 
			p[0].y = y; 
			p[1].x = x; 
			p[1].y = y + n; 
			p[2].x = x + n; 
			p[2].y = y; 
			p[3].x = x; 
			p[3].y = y - n; 
			::Polygon(m_hDC, p, 4); 
			break; 
		} 
 
		case DIAMOND: 
			::MoveToEx(m_hDC, x - n, y, NULL); 
			::LineTo(m_hDC, x, y + n); 
			::LineTo(m_hDC, x + n, y); 
			::LineTo(m_hDC, x, y - n); 
			::LineTo(m_hDC, x - n, y); 
			break; 
	} 
} 
 
void CGraphics::DrawShadow(int n) 
{ 
	HPEN m_CurPen = ::CreatePen(PS_SOLID, 0, RGB(127,127,127)); 
	HPEN m_OldPen = (HPEN)::SelectObject(m_hDC, m_CurPen); 
	HBRUSH hBrush = ::CreateSolidBrush(RGB(127,127,127)); 
	HBRUSH hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush); 
	int w  = (m_Rect.right - GR) / 20 + 1; 
	int xb = GR + 2 * n; 
	::Rectangle(m_hDC, GR + (int)(2.2 * w), GT - m_LogFont.lfHeight,  
				m_Rect.right - (int)(0.8 * w), GT - 2 * (n + 1) * m_LogFont.lfHeight); 
	::SelectObject(m_hDC, hBrold); 
	::DeleteObject(hBrush); 
	::SelectObject(m_hDC, m_OldPen); 
	::DeleteObject(m_CurPen); 
 
	hBrush = ::CreateSolidBrush(RGB(255, 255, 255)); 
	hBrold = (HBRUSH)::SelectObject(m_hDC, hBrush); 
	::Rectangle(m_hDC, GR + w, GT, m_Rect.right - 2 * w,  
				GT - 2 * (n + 1) * m_LogFont.lfHeight + m_LogFont.lfHeight); 
	::SelectObject(m_hDC, hBrold); 
	::DeleteObject(hBrush); 
}