《VC++深入详解》读书笔记——4.MFC消息映射机制和绘图DC的获取
来源:互联网 发布:多线程编程技术详解 编辑:程序博客网 时间:2024/05/21 17:01
一 . 消息映射机制
1.Windows应用程序消息处理
Windows程序维护有自己的消息队列,保存了队列消息(当然也有非队列消息,它们直接发给窗口),并用过消息循环对消息进行处理。消息循环首先通过GetMessage取得消息并从队列中移走,对于加速键会调用TranslateAccelerator函数,对其进行翻译和处理,如果处理成功就不在调用TranslateMessage。如果不是加速键,就进行消息的转换和派发,让目的窗口的窗口过程来处理消息。示例代码:
while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
2.MFC消息映射
MFC使用同一窗口过程,但MFC消息映射隐藏了消息处理的过程。使用Class Wizard添加一个消息响应函数之后,有两个方面内容被提供用来实现消息映射。
a.消息映射声明和实现
在类的定义(头文件)里,添加声明消息映射的宏DECLARE_MESSAGE_MAP,在类的实现(源文件)里,通过BEGIN_MESSAGE_MAP和END_MESSAGE_MAP()实现消息映射。
b.消息响应函数的声明和实现
当通过ClassWizard添加消息响应函数时就会自动添加函数的声明和实现,代码如下:
声明:
//{{AFX_MSG afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnPaint(); //}}AFX_MSG DECLARE_MESSAGE_MAP()
映射:
BEGIN_MESSAGE_MAP(CTestDialog, CDialog) //{{AFX_MSG_MAP(CTestDialog) ON_WM_TIMER() ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP()
实现:
void CTestDialog::OnPaint() { } void CTestDialog::OnTimer(UINT nIDEvent) { CDialog::OnTimer(nIDEvent); }
通过以上几个消息映射的宏,就可以完成MFC的消息映射,关于MFC的消息映射机制,以下两篇文章做了很详细的论述:
MFC消息映射机制详解
MFC消息派发
3.消息响应的可能方式
a.在基类中针对每种消息做一个虚函数,当子类对消息响应时候,只要在子类中重写这个虚函数即可。缺点:MFC类派生层次很多,如果在基类对每个消息进行虚函数处理,那么从基类派生的每个子类都将背负一个庞大的虚表,这样浪费内存,故MFC没有采取这中方式而采取消息映射方式。
b.消息映射方式:MFC在后台维护了一个句柄和C++对象指针对照表,当收到一个消息后,通过消息结构里资源句柄(查对照表)就可找到与它对应的一个C++对象指针,然后把这个指针传给基类,基类调用WindowProc()函数对消息进行处理,WindowProc()函数中调用OnWndMsg()函数,真正的消息路由及处理是由OnWndMsg()函数完成的。由于WindowProc()和OnWndMsg()都是虚函数,而且是用派生类对象指针调用的,由多态性知最总终调用子类的。在OnWndMsg()函数处理的时候,根据消息种类去查找消息映射,判断所发的消息有没有响应函数,具体方式是先到相应的子类头文件两个AFX_MSG注释宏之间是否有相应的消息响应函数原型的声明;再到子类的源文件中,到BEGIN_MESSAGE_MAP和END_MESSAGE_MAP查找消息映射宏。当然,如果子类中没有对消息进行处理,则消息交由基类处理。
二.绘图DC的获取方式
1 . 使用SDK获取DC句柄(仅针对视类客户区)
HDC hdc;hdc=::GetDc(m_hWnd);//获取DC句柄MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);LineTo(hdc,point.x,point.y);::ReleaseDC(m_hWnd,hdc);//释放DC
2 . 利用MFC的CDC类指针和CWin类成员函数获取DC(仅针对视类客户区)
CDC *pDC=GetDC();pDC->MoveTo(m_ptOrigin);pDC->LineTo(point);ReleaseDC(pDC);
3 . 利用CClientDC对象(CClientDC类从CDC类派生来的,构造时调用GetDC(),析构时调用ReleaseDC(),仅针对视类客户区)
CClientDC dc(this);dc.MoveTo(m_ptOrigin);dc.LineTo(point);
如果获取父类窗口的一个设备句柄,可以调用:
CClientDC dc(GetParrent());
4 . 利用CWindowDC对象(CWindowDC类从CDC类派生来的,该对象可以访问整个窗口区域,包括客户区和非客户区)
CWindowDC dc(this);//dc.MoveTo(m_ptOrigin);dc.LineTo(point);
如果想在整个窗口画线:CWindowDC dc(GetParrent());
如果想在桌面画线:CWindowDC dc(GetDesktopWindow());
三.画笔画刷
利用画笔改变线条颜色和类型:
CPen pen(PS_DOT,1,RGB(0,255,0));//构造画笔对象CClientDC dc(this);CPen *pOldPen=dc.SelectObject(&pen);//将画笔选入DCdc.MoveTo(m_ptOrigin);dc.LineTo(point);dc.SelectObject(pOldPen);//恢复先前的画笔
使用画刷(通常利用画刷去填充矩形区域):
CBrush brush(RGB(255,0,0));//构造画刷对象CClientDC dc(this);dc.FillRect(CRect(m_ptOrigin,point),&brush);
使用位图画刷:
CBitmap bitmap;//构造位图对象(使用前需要初试化)bitmap.LoadBitmap(IDB_BITMAP1);//初试化位图对象CBrush brush(&bitmap);//构造位图画刷CClientDC dc(this);dc.FillRect(CRect(m_ptOrigin,point),&brush);//用指定的位图画刷去填充矩形区域
使用透明画刷:
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//获取透明画刷对象指针CClientDC dc(this);CBrush *pOldBrush=dc.SelectObject(pBrush);//将透明画刷选入DCdc.Rectangle(CRect(m_ptOrigin,point));dc.SelectObject(pOldBrush);//释放透明画刷
在程序中,当构造一个GDI对象后,该对象并不会立即生效,必须选入设备描述表,它才会在以后的绘制操作中生效。一般情况下,在完成绘图操作之后,都要利用SelectObject函数把先前的GDI对象选入设备描述表,以便使其恢复到先前的状态。
- 《VC++深入详解》读书笔记——4.MFC消息映射机制和绘图DC的获取
- MFC消息映射机制和绘图DC的获取
- MFC消息映射机制和绘图DC的获取(转)
- 【转】第三章 MFC消息映射机制和绘图DC的获取
- 孙鑫VC++视频学习笔记之3: MFC消息映射机制和绘图DC
- VC++深入详解(2):MFC消息映射与基本绘图
- VC----MFC消息映射机制详解
- VC----MFC的消息映射机制
- VC----MFC的消息映射机制
- MFC消息映射机制详解
- MFC消息映射机制详解
- MFC消息映射机制详解
- MFC消息映射机制详解
- MFC消息映射机制详解
- MFC绘图 (孙鑫老师 第四讲 MFC消息映射机制和CDC类的使用 参考文章)
- Lesson4 MFC消息映射机制和CDC类的使用 ---孙鑫VC++教程
- Lesson4 MFC消息映射机制和CDC类的使用 ---孙鑫VC++教程
- 孙鑫VC学习笔记:第四讲 MFC消息映射机制和CDC类的使用
- 搭建整合Struts2,Spring,Hibernate的Web开发框架
- 欧拉计划 47
- 开发日记(2017一月)
- 【codeforces 749 D】【set+二分查找+思路清晰】
- Bootstrap源码解读(第七弹:导航条)
- 《VC++深入详解》读书笔记——4.MFC消息映射机制和绘图DC的获取
- java构造与解析json数据
- 快速求出10亿整数中缺失的数。
- 51nod-2条不相交的路径(边双联通分量)
- Linux基础
- 第39篇服务器打日志及Crosswalk Project for iOS
- JS----构造函数与原型prototype 区别
- 一个Git客户端如何从github或者git@osc分别clone项目
- D3D11地形渲染教程教程二之TerrainGrid(地形网格)