aclockview.cpp
来自「《Visual C/C++图形图像与游戏编程典型实例解析》配套源代码」· C++ 代码 · 共 378 行
CPP
378 行
// AClockView.cpp : CAClockView 类的实现
//
#include "stdafx.h"
#include "AClock.h"
#include "AClockDoc.h"
#include "AClockView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAClockView
IMPLEMENT_DYNCREATE(CAClockView, CView)
BEGIN_MESSAGE_MAP(CAClockView, CView)
ON_COMMAND(ID_130, On130)
ON_WM_TIMER()
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_DESTROY()
END_MESSAGE_MAP()
// CAClockView 构造/销毁
CAClockView::CAClockView()
{
// TODO: 在此处添加构造代码
}
CAClockView::~CAClockView()
{
}
BOOL CAClockView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
// 样式
return CView::PreCreateWindow(cs);
}
// CAClockView 绘制
void CAClockView::OnDraw(CDC* /*pDC*/)
{
CAClockDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: 在此处为本机数据添加绘制代码
}
// CAClockView 诊断
#ifdef _DEBUG
void CAClockView::AssertValid() const
{
CView::AssertValid();
}
void CAClockView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CAClockDoc* CAClockView::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAClockDoc)));
return (CAClockDoc*)m_pDocument;
}
#endif //_DEBUG
// CAClockView 消息处理程序
void CAClockView::On130()
{ //时钟
// TODO: 在此添加命令处理程序代码
int w,h,m;
GetParam(w,h,m);
InitContext(w,h);
SetTimer(0x901,100,0);
PulseEvent(m_hClockEvent);
KillTimer(0x101);
}
void CAClockView::GetParam(int& w,int& h,int& m)
{
RECT rect;
GetClientRect(&rect);
w=rect.right-rect.left;
h=rect.bottom-rect.top;
m=(((w>h)?h:w)-2)/2;
}
DWORD WINAPI DrawClockProc(LPVOID lpParameter)
{
CAClockView* pMainView=(CAClockView*)lpParameter;
DWORD EventID;
int w,h,m;
for(;;)
{
EventID=WaitForSingleObject(pMainView->m_hClockEvent,INFINITE);
if(WAIT_OBJECT_0==EventID)
{
pMainView->GetParam(w,h,m);
pMainView->DrawBackFrame(w,h,m);
}
}
return(0);
}
void CAClockView::InitContext(int w,int h)
{
BITMAPINFOHEADER BmpInfoHdr;
DWORD ThreadID;
CClientDC cdc(this);
ZeroMemory(&BmpInfoHdr,sizeof(BITMAPINFOHEADER));
BmpInfoHdr.biSize=sizeof(BITMAPINFOHEADER);
BmpInfoHdr.biWidth=w;
BmpInfoHdr.biHeight=h;
BmpInfoHdr.biPlanes=1;
BmpInfoHdr.biBitCount=24;
BmpInfoHdr.biCompression=BI_RGB;
BmpInfoHdr.biXPelsPerMeter=11811;
BmpInfoHdr.biYPelsPerMeter=11811;
m_hBmp1=CreateDIBSection(cdc.m_hDC,(BITMAPINFO*)&BmpInfoHdr,
DIB_RGB_COLORS,(void**)&m_pData1,0,0);
FillMemory(m_pData1,w*h*3,0xff);
m_hMemDC=CreateCompatibleDC(cdc.m_hDC);
m_hBmp2=CreateDIBSection(m_hMemDC,(BITMAPINFO*)&BmpInfoHdr,
DIB_RGB_COLORS,(void**)&m_pData2,0,0);
FillMemory(m_pData2,w*h*3,0xff);
m_hClockThread=CreateThread(0,0,DrawClockProc,this,CREATE_SUSPENDED,&ThreadID);
m_hClockEvent=CreateEvent(0,0,0,0);
ResumeThread(m_hClockThread);
// DeleteObject(m_hBmp1);
// DeleteObject(m_hBmp2);
}
void CAClockView::DrawPanel(HDC hDC,int w,int h,int m)
{
Graphics graph(hDC);
Matrix mat1,mat2,mat3;
GraphicsState state;
INT i,j,cw,ch;
REAL ang;
Image img(L"combra.jpg");
cw=img.GetWidth();
ch=img.GetHeight();
mat1.SetElements(1.0f,0.0f,0.0f,1.0f,w/2.0f,h/2.0f);
graph.SetTransform(&mat1);
cw=(cw>h)?2*h/3:cw;
ch=(ch>h)?2*h/3:ch;
graph.DrawImage(&img,-cw/2,-ch/2,cw,ch);
mat1.SetElements(1.0f,0.0f,0.0f,1.0f,w/2.0f,h/2.0f);
mat2.SetElements(cosf(PI/2.0f),-sinf(PI/2.0f),sinf(PI/2.0f),cosf(PI/2.0f),0,0);
mat2.Multiply(&mat1,MatrixOrderAppend);
graph.SetTransform(&mat2);
Pen pen(Color(255,255,0,0),3.0f);
pen.SetStartCap(LineCapSquare);
pen.SetEndCap(LineCapArrowAnchor);
// graph.DrawLine(&pen,-m,0,m,0); //X轴
// graph.DrawLine(&pen,0,-m,0,m); //Y轴
for(i=0;i<360;i+=6)
{
//画表盘
ang=i*PI/180.0f;
state=graph.Save();
mat1.SetElements(1.0f,0.0f,0.0f,1.0f,w/2.0f,h/2.0f);
mat2.SetElements(cosf(PI/2.0f),-sinf(PI/2.0f),sinf(PI/2.0f),cosf(PI/2.0f),0,0);
mat3.SetElements(cosf(ang),sinf(ang),-sinf(ang),cosf(ang),0,0);
mat3.Multiply(&mat2,MatrixOrderAppend);
mat3.Multiply(&mat1,MatrixOrderAppend);
graph.SetTransform(&mat3);
if(0==i%30)
{
pen.SetWidth(6.0f);
pen.SetColor(Color(255,0,255,0));
graph.DrawLine(&pen,m-10,0,m-5,0);
}
else if(0==i%6)
{
pen.SetWidth(3.0f);
pen.SetColor(Color(255,0,0,0));
graph.DrawLine(&pen,m-10,0,m-5,0);
}
graph.Restore(state);
//画数字
mat1.SetElements(1.0f,0.0f,0.0f,1.0f,w/2.0f-10,h/2.0f-12);
graph.SetTransform(&mat1);
SolidBrush brush(Color(255,128,128,64));
FontFamily family(L"Times New Roman");
Font font(&family,24,FontStyleRegular,UnitPixel);
PointF pointF((m-25)*cosf(i*PI/180.0f),(m-25)*sinf(i*PI/180.0f));
TCHAR num[20];
USES_CONVERSION;
if(0==i%30)
{
j=i+90;
j=(j>360)?j%360/30:j/30;
sprintf(num,"%d",j);
graph.DrawString(T2W(num),-1,&font,pointF,&brush);
}
}
}
void CAClockView::DrawPins(HDC hDC,SYSTEMTIME& tm,int w,int h,int m,float c)
{
REAL secAng,minAng,hourAng;
Pen pen(Color(255,0,0,0),c);
pen.SetStartCap(LineCapSquare);
pen.SetEndCap(LineCapArrowAnchor);
secAng=(6.0f*tm.wSecond+6.0f*tm.wMilliseconds/1000.0f)*PI/180.0f;
minAng=(6.0f*tm.wMinute+tm.wSecond/10.0f+tm.wMilliseconds/10000.0f)*PI/180.0f;
hourAng=(30.0f*(tm.wHour%12)+tm.wMinute/2.0f+tm.wSecond/120.0f+tm.wMilliseconds/120000.0f)*PI/180.0f;
pen.SetWidth(c+6.0f);
pen.SetColor(Color(255,255,0,255));
DrawSinglePin(hDC,pen,w,h,hourAng,m-60);
pen.SetWidth(c+2.0f);
pen.SetColor(Color(255,0,0,255));
DrawSinglePin(hDC,pen,w,h,minAng,m-20);
pen.SetWidth(c);
pen.SetColor(Color(255,0,255,0));
DrawSinglePin(hDC,pen,w,h,secAng,m-10);
Matrix mat1;
Graphics graph(hDC);
mat1.SetElements(1.0f,0.0f,0.0f,1.0f,w/2.0f-8,h/2.0f-8);
graph.SetTransform(&mat1);
SolidBrush brush(Color(255,0,0,0));
graph.FillEllipse(&brush,0,0,16,16);
}
void CAClockView::DrawSinglePin(HDC hDC,Pen& pen,int w,int h,float ang,int len)
{
Graphics graph(hDC);
Matrix mat1,mat2,mat3;
GraphicsState state;
state=graph.Save();
mat1.SetElements(1.0f,0.0f,0.0f,1.0f,w/2.0f,h/2.0f);
mat2.SetElements(cosf(PI/2.0f),-sinf(PI/2.0f),sinf(PI/2.0f),cosf(PI/2.0f),0,0);
mat3.SetElements(cosf(ang),sinf(ang),-sinf(ang),cosf(ang),0,0);
mat3.Multiply(&mat2,MatrixOrderAppend);
mat3.Multiply(&mat1,MatrixOrderAppend);
graph.SetTransform(&mat3);
graph.DrawLine(&pen,-20,0,len,0);
graph.Restore(state);
}
void CAClockView::DrawDigital(HDC hDC,SYSTEMTIME& tm,int w,int h,int m)
{
Graphics graph(hDC);
SolidBrush brush(Color(255,0,0,255));
FontFamily family(L"Times New Roman");
Font font(&family,24,FontStyleRegular,UnitPixel);
PointF pt(REAL(m-10),-REAL(m));
TCHAR time[80];
Matrix mat1;
USES_CONVERSION;
mat1.SetElements(1.0f,0.0f,0.0f,1.0f,w/2.0f,h/2.0f);
graph.SetTransform(&mat1);
wsprintf(time,"%02d:%02d:%02d.%01d",tm.wHour,tm.wMinute,tm.wSecond,tm.wMilliseconds/100);
graph.DrawString(T2W(time),-1,&font,pt,&brush);
}
void CAClockView::DrawCurrFrame(int w,int h)
{
CClientDC cdc(this);
Graphics graph(cdc.m_hDC);
Bitmap bmp(m_hBmp1,0);
graph.DrawImage(&bmp,0,0,w,h);
}
void CAClockView::DrawBackFrame(int w,int h,int m)
{
SYSTEMTIME tm;
m_hOldBmp=(HBITMAP)SelectObject(m_hMemDC,m_hBmp2);
FillMemory(m_pData2,w*h*3,0xff);
DrawPanel(m_hMemDC,w,h,m);
GetLocalTime(&tm);
DrawPins(m_hMemDC,tm,w,h,m,3.0f);
DrawDigital(m_hMemDC,tm,w,h,m);
SelectObject(m_hMemDC,m_hOldBmp);
}
void CAClockView::OnTimer(UINT nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(0x901==nIDEvent)
{
int w,h,m;
GetParam(w,h,m);
CopyMemory(m_pData1,m_pData2,w*h*3);
PulseEvent(m_hClockEvent);
DrawCurrFrame(w,h);
}
CView::OnTimer(nIDEvent);
}
int CAClockView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
m_hClockThread=m_hClockEvent=0;
m_pData1=m_pData2=0;
m_hBmp1=m_hBmp2=0;
return 0;
}
void CAClockView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: 在此添加消息处理程序代码
if(m_hBmp1&&m_hBmp2)
{
ClearContext();
InitContext(cx,cy);
SetTimer(0x901,100,0);
}
}
void CAClockView::ClearContext()
{
DWORD ExitCode;
BOOL br;
KillTimer(0x901);
br=GetExitCodeThread(m_hClockThread,&ExitCode);
TerminateThread(m_hClockThread,ExitCode);
CloseHandle(m_hClockEvent);
DeleteObject(m_hBmp1);
DeleteObject(m_hBmp2);
}
void CAClockView::OnDestroy()
{
CView::OnDestroy();
// TODO: 在此添加消息处理程序代码
ClearContext();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?