// 很完整的在对话框上绘制矩形的格式
void ScaleSetDlg::OnPaint()
{
CPaintDC dc(this);
CPen penBorder(PS_SOLID,1,RGB(255,255,255));
CPen *ppenOld = dc.SelectObject(&penBorder);
CBrush brPoint(m_color);
CBrush* pbrOld = dc.SelectObject(&brPoint);
dc.Rectangle(180,55,240,85);
dc.SelectObject(ppenOld);
dc.SelectObject(pbrOld);
}
// 很完整的在对话框上 贴图(Bitmap格式)
CBitmap maskbmp,logbmp;
maskbmp.LoadBitmap(IDB_LOGMASK);
logbmp.LoadBitmap(IDB_LOG);
CDC MaskDC,memDC;
MaskDC.CreateCompatibleDC(pDc);
MaskDC.SelectObject(&maskbmp);
memDC.CreateCompatibleDC(pDc);
memDC.SelectObject(&logbmp);
// 不知道为什么要两个同时弄,可能是需要混合原来的颜色
pDc->BitBlt(m_ptMiddle.x - 25 ,ptMiddle.y - nRidius * 0.7,96,96,&MaskDC,0,0,SRCAND);
pDc->BitBlt(m_ptMiddle.x - 25,ptMiddle.y - nRidius * 0.7,96,96,&memDC,0,0,MERGEPAINT);
// 精确的求出 刻度的位置
CPoint CClockScale::ComputerFacePoint(UINT min, int nFaceLength)
{
CPoint ptCalc;
//将分钟转换为角度数 , 这段核心的代码看不懂
double fDegrees = 180+((15+min)%60)*6;
//再转换为弧度数
double fAngle = fDegrees/180;
//计算刻度点位置
ptCalc.x = m_ptMiddle.x + (int)(cos(fAngle*PI)*nFaceLength);
ptCalc.y = m_ptMiddle.y + (int)(sin(fAngle*PI)*nFaceLength);
//返回刻度点位置
return(ptCalc);
}
// 矩形可以随意扩展,很好的函数, 还有可以画一个 3d的矩形,也不错
CRect rectPoint(ptFace.x,ptFace.y,ptFace.x,ptFace.y);
rectPoint.InflateRect(1,1);
pDC->Draw3dRect(&rectPoint,GetSysColor(COLOR_BTNHIGHLIGHT),GetSysColor(COLOR_BTNSHADOW));
// 根据多边形画法,画出三角形 和 圆形
CPoint ptRhombus[4] ;
case TYPE_RHOMBUS:
oldPen = pDC->SelectObject(&penBorder);
ptRhombus[1].x = rectPoint.left + rectPoint.Width()/2;
ptRhombus[1].y = rectPoint.top;
ptRhombus[0].x = rectPoint.left;
ptRhombus[0].y = rectPoint.top + rectPoint.Height()/2;
ptRhombus[3].x = rectPoint.left + rectPoint.Width()/2;
ptRhombus[3].y = rectPoint.bottom;
ptRhombus[2].x = rectPoint.right;
ptRhombus[2].y = rectPoint.top + rectPoint.Height()/2;
pDC->Polygon(ptRhombus,4);
pDC->SelectObject(oldPen);
break;
case TYPE_TRIANGLE:
oldPen = pDC->SelectObject(&penBorder);
ptRhombus[0].x = rectPoint.left;
ptRhombus[0].y = rectPoint.top + rectPoint.Height()/2;
ptRhombus[1].x = rectPoint.left + rectPoint.Width()/2;
ptRhombus[1].y = rectPoint.top;
ptRhombus[2].x = rectPoint.right;
ptRhombus[2].y = rectPoint.top + rectPoint.Height()/2;
pDC->Polygon(ptRhombus,3);
pDC->SelectObject(oldPen);
break;
// 颜色对话框,格式,模板。。
void HandSetDlg::OnHcolor()
{
CColorDialog dlg;
dlg.m_cc.Flags|=CC_RGBINIT ;
// 颜色对话框属性
dlg.m_cc.rgbResult=m_HColor;
// 当前时针边框颜色显示到颜色对话框上
if(IDOK==dlg.DoModal())
{
m_HColor = dlg.m_cc.rgbResult;
// 获取用户选择的颜色
}
}
// 遇到了一个问题,改错误没有直接说明哪里错误,原来是 在类中 只有声明,没有定义
1>C:\Users\Administrator\Desktop\VSCode\DeskClock_Copy\Debug\DeskClock_Copy.exe : fatal error LNK1120: 1 个无法解析的外部命令
// 窗口全屏
WINDOWPLACEMENT m_OldWndPlacement; //用来保存原窗口位置
bool m_bFullScreen;//全屏显示标志
void CDeskClockDlg::OnFull()
{
if(m_bFullScreen)
{
//退出全屏显示, 恢复原窗口显示
ShowWindow(SW_HIDE);
SetWindowPlacement(&m_OldWndPlacement);
m_bFullScreen = false;
}
else
{
GetWindowPlacement(&m_OldWndPlacement);
CRect WindowRect;
GetWindowRect(&WindowRect);
CRect ClientRect;
RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &ClientRect);
ClientToScreen(&ClientRect);
// 获取屏幕的分辨率
int nFullWidth=GetSystemMetrics(SM_CXSCREEN);
int nFullHeight=GetSystemMetrics(SM_CYSCREEN);
//将除控制条外的客户区全屏显示到从(0,0)到(nFullWidth, nFullHeight)区域, 将(0,0)和(nFullWidth,
nFullHeight)两个点外扩充原窗口和除控制条之外的 客户区位置间的差值, 就得到全屏显示的窗口位置
m_FullScreenRect.left=WindowRect.left-ClientRect.left;
m_FullScreenRect.top=WindowRect.top-ClientRect.top;
m_FullScreenRect.right=WindowRect.right-ClientRect.right+nFullWidth;
m_FullScreenRect.bottom=WindowRect.bottom-ClientRect.bottom+nFullHeight;
m_bFullScreen=TRUE; //设置全屏显示标志为 TRUE
//进入全屏显示状态
WINDOWPLACEMENT wndpl;
wndpl.length=sizeof(WINDOWPLACEMENT);
wndpl.flags=0;
wndpl.showCmd=SW_SHOWNORMAL;
wndpl.rcNormalPosition=m_FullScreenRect;
SetWindowPlacement(&wndpl);
}
Invalidate();
}
// 双缓冲步骤
CRect rectClient;
GetClientRect(&rectClient);
CPaintDC dc(this);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
m_ClockScale.DrawScale(&memDC,m_ptMiddle);
dc.StretchBlt(0,0,rectClient.Width(),rectClient.Height(),&memDC,0,0,rectClient.Widt(),rectClient.Height (),SRCCOPY);
本章设计的技术点如下:
1、利用GDI技术绘制图形图像
2、利用双缓冲技术消除闪屏
3、通过蜂鸣器播放音乐
4、利用多线程编程播放音乐
5、通过颜色对话框选择图形色彩
6、利用定时器技术实现时钟时间的实时更新
总结:
大概过了一遍这个例子,开始的时候方法不对,不知道从哪里下手,因为自己想要重新复制一次代码,走了一点弯路,后来才找对门路。
如何看这类型的代码:
a:根据主对话框上面的 绘图(OnPaint)依次顺序往下看实现
b:每个对话框都有相应的类和属性类(普通对话框),其中属性类这个想法特别漂亮,节约了对话框类的大量代码,使代码的层次更加的清晰分明。
c:但是,自己还是走了错路,就是先看了属性类,应该先看对话框类,再看属性类,因为属性类是根据对话框类变化而变化的。 之所以会走这条错路,还是得回到
a中,因为自己是从那里开始看代码,而属性类就包含了 绘画(Draw),所以,就引到了另一条错路。
总的来说,这次的学习是对过去学习的一个小回顾,虽然还有许多小细节没有完成,但这就算是一个小开始吧,后面还有许多以小项目为基础的学习,希望到时候能更加的冷静,淡定,不急躁,多观察,多思考,一心一意,脚踏实地,扎扎实实,直到完全理解了才进入到下一个阶段