半劫小仙男二结局:MFC消息映射机制和CDC类

来源:百度文库 编辑:中财网 时间:2024/05/06 10:21:16

1.      对应用程序(单文档程序)的窗口进行操作的时候,如点击鼠标,拖动鼠标等,所有的窗口消息应该在CView中捕获,而不能在MainFrame进行捕获,因为在文档-视图结构中,CView类总是覆盖在CMainFrm框架窗口之上的。

 

2.      MFC的消息映射机制:

查看MFC的源代码:WINCORE.CPP

---------------------------------------------------------------------------------

  LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

  {

      // OnWndMsg does most of the work, except for DefWindowProc call

      LRESULT lResult = 0;

      if (!OnWndMsg(message, wParam, lParam, &lResult))//真正的消息处理都是由OnWndMsg函数进行处理的

      lResult = DefWindowProc(message, wParam, lParam);

      return lResult;

 }

  ---------------------------------------------------------------------------------

  查看AFX_WIN.h

  ---------------------------------------------------------------------------------

  virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);

  --------------------------------------------------------------------------------

      在MFC中维护了一张消息到窗口的对应表,当接收到一个消息后,通过消息的句柄,找到与其相关联的窗口对象的指针,然后传给CWnd::WindowProc函数,CWnd::WindowProc函数函数交由CWnd::OnWndMsg函数进行处理,判断子类是否有这个消息的响应函数,通过查看子类的头文件看有没有消息响应函数原型的声明,查看源文件,看有没有消息响应函数的定义.如果子类有,那么交由子类处理消息,如果子类没有,消息交由父类进行处理.

 

3.      CDC相关类:

画线程序:

方法1:Win32 GetDC实现

HDC hdc;

      hdc=::GetDC(m_hWnd); //全局函数,所以需要::符号,SDK函数

      MoveToEx(hdc,m_ptStart.x,m_ptStart.y,NULL); //设置操作起点

      LineTo(hdc,point.x,point.y);

::ReleaseDC(m_hWnd,hdc);

     

      方法2:CDC实现,MFC封装了所有的绘图操作在CDC类中

      //只能在CView区域画图

      CDC *pDC=GetDC(); //注意此处的GetDC函数和上面的区别,此处为CWND成员

      pDC->MoveTo(m_ptStart);

      pDC->LineTo(point);

      ReleaseDC(pDC);

 

      方法3:CClientDC实现,只能对客户区域操作

The CClientDC class is derived from CDC and takes care of calling the Windows functions "GetDC" at construction time and "ReleaseDC" at destruction time. This means that the device context associated with a CClientDC object is the client area of a window.

      CClientDC dc(this); //参数为this表示访问的客户区域是CView

CClientDC dc(GetParent()); //参数是GetParent()表示CView的父窗口,即Frame窗口,框架类的客户区域为工具栏(含)以下

      dc.MoveTo(m_ptStart);

      dc.LineTo(point);

     

      方法4:CWindowDC实现,可对客户区和非客户区操作

      CWindowDC dc(this); //对CView区域操作

      CWindowDC dc(GetParent()); //可对整个应用程序区域操作

      CWindowDC dc(GetDesktopWindow()); //可对整个系统操作界面操作

      dc.MoveTo(m_ptStart);

      dc.LineTo(point);

 

注意:对CView之外的绘图区域操作,都是将CView区域模拟成客户区域,即画线动作只能在,CView区域只能,但画线结果可展现在期望区域中

     

      附:MoveTo和LineTo在MSDN中的声明:

BOOL MoveToEx(
      HDC hdc,          // handle to device context
      int X,            // x-coordinate of new current position
      int Y,            // y-coordinate of new current position
      LPPOINT lpPoint   // old current position
  );
  BOOL LineTo(
      HDC hdc,    // device context handle
      int nXEnd,  // x-coordinate of ending point
      int nYEnd   // y-coordinate of ending point
  );

 

4.      CPen:

CPen pen(PS_DASHDOT,1,RGB(255,0,0));

      CClientDC dc(this);

      CPen *pOldPen=dc.SelectObject(&pen); //将新的画笔选到设备描述表中;

      dc.MoveTo(m_ptStart);

      dc.LineTo(point);

dc.SelectObject(pOldPen); //将原先的画笔还原,以防止别地方使用错误的画笔

     

5.      CBrush:

一般用来填充某个封闭区域

a. 颜色画刷:
CBrush brush(RGB(255,0,0));
CClientDC dc(this);
dc.FillRect(CRect(m_ptStart,point),&brush);//因为是有参数可选(&brush),所以不需要选到设备描述表中(SelectStockObject)

 

      b. 位图画刷

       CBitmap bmp;

      bmp.LoadBitmap(IDB_BITMAP1); //参数为已有的位图的资源号,可以创建一张位图

      CBrush brush(&bmp);

      CClientDC dc(this);

      dc.FillRect(CRect(m_ptStart,point),&brush);

c. 透明画刷

      CClientDC dc(this);

       //因为创建矩形时没有提供参数设置画刷类型,所以得考虑将默认的画刷替换掉

//FromHandle函数实现在句柄和指针之间的转化,像CPen也有该函数,另外FromHandle是一个静态方法,静态方法的调用采用::

CBrush *brush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

      CBrush *pOldBrush=dc.SelectObject(brush);

      dc.Rectangle(CRect(m_ptStart,point)); //发现如果两个矩形重叠,则后者会将前者部分区域覆盖,所以需要透明画刷

dc.SelectObject(pOldBrush); //还原

 

6.      设置绘图模式:

CDC::SetROP2,Sets the current drawing mode.