MFC消息映射机制的剖析,讲述如何运用ClassWizard,,理解发送给窗口的消息是如何被MFC框架通过窗口句柄映射表和消息映射表来用窗口类的函数进行响应的。
掌握设备描述表及其封装类CDC的使用,CDC是如何与具体的设备发生关联的,融合具体的画图程序进行分析。如何设置封闭图形的填充刷子(位图画刷与透明画刷的使用)
什么是消息映射机制
MFC使用一种消息映射机制来处理消息,在应用程序框架中的表现就是一个消息与消息处理函数一一对应的消息映射表,以及消息处理函数的声明和实现等代码。当窗口接收到消息时,会到消息映射表中查找该消息对应的消息处理函数,然后由消息处理函数进行相应的处理。SDK编程时需要在窗口过程中一一判断消息值进行相应的处理,相比之下MFC的消息映射机制要方便好用的多
在BEGIN_MESSAG_MAP和END_MESSAGE_MAP之间的内容成为消息映射入口项。消息映射除了在CMainFrame的实现文件中添加消息映射表外,在类的定义文件MainFrm.h中还会添加一个宏调用:
DECLARE_MESSAGE_MAP()
一般这个宏调用写在类定义的结尾处
消息映射的实现的方法
不推荐方式:在基类中针对某一种消息做一个虚函数,当子类需要对消息做出响应的时候,只需要重写虚函数就可以,凡是从基类当中派生出来的子类背后都会背负一个虚表,这样对资源是种浪费
MFC实现方式:消息映射,MFC在后台维护了一个句柄和C++对象的指针有一个对照表
当收到一个消息时,通过句柄就能找相对应的指针,通过指针传递给基类,基类会调用一个函数对消息进行处理,这个函数叫WindowProc
然后调用WndMsg,判断消息是否有相对响应函数,从头文件中看是否有消息响应函数的声明,然后在源文件中有没有消息响应映射的宏
在屏幕上画一条线
第二个参数Cpoint表示一个点的类
当鼠标左键点击后坐标点通过参数传递进来
添加成员变量,参数如图
然后在代码中保存起始点
CDrawView::CDrawView() : m_ptOrigin(0) { // TODO: 在此处添加构造代码 m_ptOrigin=0; }
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_ptOrigin=point;//保存 CView::OnLButtonDown(nFlags, point); }
接着添加消息
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 HDC hdc; // 获取一个DC的句柄 hdc=::GetDC(m_hWnd);//如果用全局的函数需要加上两个冒号 获取View类的句柄 MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL); LineTo(hdc,point.x,point.y); //释放dc ::ReleaseDC(m_hWnd,hdc); CView::OnLButtonUp(nFlags, point); }
MoveToEx
功能是将当前绘图位置移动到某个具体的点,同时也可获得之前位置的坐标
MoveToEx(HDC hdc,int X,int Y,LPPOINT lpPoint);
参数:
HDC hdc:传入参数,设备上下文句柄。
int X:传入参数:新位置的X坐标。
int Y:传入参数:新位置的Y坐标。
LPPOINT lpPoint:传出参数:一个指向POINT结构的指针,用来存放上一个点的位置,若此参数为NULL,则不保存上一个点的位置
LineTo
参数:
结果图
利用CDC完成画线功能
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) { //定义指针 CDC *pDC=GetDC(); pDC->MoveTo(m_ptOrigin); pDC->LineTo(point); ReleaseDC(pDC); CView::OnLButtonUp(nFlags, point); }
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) { CClientDC dc(this); dc.MoveTo(m_ptOrigin); dc.LineTo(point); CView::OnLButtonUp(nFlags, point); }
画笔颜色改变
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) { CPen pen(PS_DASH,1,RGB(0,225,0));//创建画笔 CClientDC dc(this); CPen *pOldPen=dc.SelectObject(&pen); dc.MoveTo(m_ptOrigin); dc.LineTo(point); dc.SelectObject(pOldPen); CView::OnLButtonUp(nFlags, point); }
CPen();
CPen( int nPenStyle, int nWidth, COLORREF crColor );
参数:nPenStyle 指定画笔的风格
nWidth 指定画笔的宽度
crColor 包含了画笔的RGB值
创建画刷
出现的问题:
bitmap.LoadBitmap(XXXX);导入的资源无效
展开头文件,打开Resouce.h 复制IDB_BITMAP1
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) { CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1); CBrush brush(&bitmap); CClientDC dc(this); dc.FillRect(CRect(m_ptOrigin,point),&brush); CView::OnLButtonUp(nFlags, point); }