Lesson4 MFC消息映射机制和CDC类的使用

来源:互联网 发布:虎扑买鞋是什么软件 编辑:程序博客网 时间:2024/04/29 03:13

Lesson4 MFC消息映射机制和CDC类的使用

state:finished

1.在文档-视图结构中,View类总是覆盖在CMainFrm框架窗口之上的.所以框架窗口无法对
  WM_LBUTTONDOWN消息做出响应.

2.在添加WM_LBUTONDOWN后,查看我们的工程的源程序变化
  <1>查看 DrawView.h
-----------------------------------------------------------------------------------
 protected:
 //{{AFX_MSG(CDrawView)    //注释宏
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point); //消息响应函数原型的声明.
 //}}AFX_MSG
-----------------------------------------------------------------------------------
 afx_msg 也是一个宏,指明后面的函数是消息响应函数
  <2>查看 DrawView.cpp
-----------------------------------------------------------------------------------
    BEGIN_MESSAGE_MAP(CDrawView, CView)
 //{{AFX_MSG_MAP(CDrawView)
 ON_WM_LBUTTONDOWN()  //通过这个宏,把消息和我们的消息响应函数
                      //CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
       //关联起来
 //}}AFX_MSG_MAP
 // Standard printing commands
 ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    END_MESSAGE_MAP()
-----------------------------------------------------------------------------------

3.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);
  --------------------------------------------------------------------------------
  //WindowProc(UINT message, WPARAM wParam, LPARAM lParam);是一个虚函数

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

4.实现我们的画线函数
  ---------------------------------------------------------------------------------
   void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
   {
  // TODO: Add your message handler code here and/or call default
  //MessageBox("View Clicled!");
  m_ptOrigin=point;
  CView::OnLButtonDown(nFlags, point);
   }

 void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
 {
  // TODO: Add your message handler code here and/or call default
  HDC hdc;
  hdc=::GetDC(m_hWnd); //每个从CWnd类派生出来的类都有一个内部的数据成员m_hWnd
  MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
  LineTo(hdc,point.x,point.y);
  ::ReleaseDC(m_hWnd,hdc); 
  CView::OnLButtonUp(nFlags, point);
 }

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

  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
  );
  ----------------------------------------------------------------------------------

5.CDC类
  MFC把所有和窗口相关的操作都封装在CWnd类中.同样,MFC把所有和绘图相关的操作也封装在
  CDC类中.
  class CDC :public CObject
  {
   .........................
  };
  使用CDC类完成画线的功能.
  MSDN
  ----------------------------------------------------------------------------------
  CWnd::GetDC
     Retrieves a pointer to a common, class, or private device context for the client
  area depending on the class style specified for the CWnd.

  CDC* GetDC();
  ----------------------------------------------------------------------------------
  DrawView.CPP
  ---------------------------------------------------------------------------------
  void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
  {
 // TODO: Add your message handler code here and/or call default
 CDC *pDC=GetDC();
 pDC->MoveTo(m_ptOrigin);
 pDC->LineTo(point);
 ReleaseDC(pDC);
 CView::OnLButtonUp(nFlags, point);
  }
  ---------------------------------------------------------------------------------
6.使用CClientDC
  CClientDC派生自CDC
  构造CClientDC对象的时候自动调用GetDC,而在析构的时候自动调用ReleaseDC.从而我们不需要
  显示的去调用这两个函数.只需要仅仅构造一个CClientDC对象.
  MSDN
  -----------------------------------------------------------------------------------
  CClientDC::CClientDCSee Also
     Constructs a CClientDC object that accesses the client area of the CWnd pointed
  to by pWnd.

     explicit CClientDC(
        CWnd* pWnd
     );
  -----------------------------------------------------------------------------------
  构造的时候需要一个CWnd*
  DrawView.CPP
  -----------------------------------------------------------------------------------
  void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
  {
 // TODO: Add your message handler code here and/or call default
 //CClientDC dc(this);
    CClientDC dc(GetParent());//获得父窗口(框架窗口的句柄)
 dc.MoveTo(m_ptOrigin);
 dc.LineTo(point);
  }

7.CWindowDC
  class CWindowDC : public CDC
  构造CWindowDC对象时,自动调用GetWindowDC,析构时自动调用ReleaseDC.
  有了CWindowDC对象我们可以访问整个屏幕区域,包括客户区域和非客户区域.
  MSDN
  ----------------------------------------------------------------------------------
  CWindowDC::CWindowDC
     Constructs a CWindowDC object that accesses the entire screen area
  (both client and nonclient) of the CWnd object pointed to by pWnd.
 
     explicit CWindowDC(
        CWnd* pWnd
     );
  -----------------------------------------------------------------------------------
  DrawView.CPP
  -----------------------------------------------------------------------------------
   void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
   {
 // TODO: Add your message handler code here and/or call default
 //CWindowDC dc(this);
    CWindowDC dc(GetParent());//获得父窗口(框架窗口的句柄)
 dc.MoveTo(m_ptOrigin);
 dc.LineTo(point);
   }
  -----------------------------------------------------------------------------------

8.CWnd::GetDesktopWindow 函数
MSDN
-------------------------------------------------------------------------------------
CWnd::GetDesktopWindow
   Returns the Windows desktop window.

   static CWnd* PASCAL GetDesktopWindow( );
-------------------------------------------------------------------------------------
DrawView.CPP
  -----------------------------------------------------------------------------------
   void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
   {
 // TODO: Add your message handler code here and/or call default
 //CWindowDC dc(this);
    CWindowDC dc(GetDesktopWindow());//获得桌面窗口句柄
 dc.MoveTo(m_ptOrigin);
 dc.LineTo(point);
   }
  -----------------------------------------------------------------------------------

9.画出其他颜色的线条

  CPen类
  封装了和画笔相关的操作.
  CPen的构造函数
  MSDN
  -----------------------------------------------------------------------------------
  Constructs a CPen object.

 CPen( );
 CPen(
    int nPenStyle,       //笔的风格 PS_SOLID   Creates a solid pen.
                            //PS_DASH   Creates a dashed pen. Valid only when the
       //pen width is 1 or less, in device units.
                            //PS_DOT   Creates a dotted pen.........
    int nWidth,          //线条的宽度
    COLORREF crColor     //笔的颜色
 );
 CPen(
    int nPenStyle,
    int nWidth,
    const LOGBRUSH* pLogBrush,
    int nStyleCount = 0,
    const DWORD* lpStyle = NULL
 );
  -----------------------------------------------------------------------------------
  RGB宏
  MSDN
  -----------------------------------------------------------------------------------
  COLORREF RGB(
   BYTE byRed,    // red component of color
   BYTE byGreen,  // green component of color
   BYTE byBlue    // blue component of color
 );               //RGB(0,0,0)Black,RGB(255,255,255)White
  -----------------------------------------------------------------------------------
CDC::SelectObject
MSDN
-------------------------------------------------------------------------------------
  CDC::SelectObject
 Selects an object into the device context.

 CPen* SelectObject(
    CPen* pPen
 );
 CBrush* SelectObject(
    CBrush* pBrush
 );
 virtual CFont* SelectObject(
    CFont* pFont
 );
 CBitmap* SelectObject(
    CBitmap* pBitmap
 );
 int SelectObject(
    CRgn* pRgn
 );
 CGdiObject* SelectObject(
    CGdiObject* pObject
 );
------------------------------------------------------------------------------------

DrawView.CPP
  -----------------------------------------------------------------------------------
   void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
   {
 // TODO: Add your message handler code here and/or call default
 
  CPen pen(PS_SOLID,1,RGB(255,0,0)); //创建画笔
  CClientDC dc(this);
  CPen *pOldPen=dc.SelectObject(&pen);//把创建的画笔选进设备描述表
  dc.MoveTo(m_ptOrigin);
  dc.LineTo(point);
  dc.SelectObject(pOldPen); //还原设备描述表
  CView::OnLButtonUp(nFlags, point);
   }
  -----------------------------------------------------------------------------------
10.创建画刷
 CBrush类
 MSDN
 ---------------------------------------------------------------------------------
 CBrush::CBrush
 Constructs a CBrush object.

 CBrush( );
 CBrush(
    COLORREF crColor
 );
 CBrush(
    int nIndex,
    COLORREF crColor
 );
 explicit CBrush(
    CBitmap* pBitmap
 );
 ---------------------------------------------------------------------------------

 DrawView.CPP
  -----------------------------------------------------------------------------------
   void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
   {
 // TODO: Add your message handler code here and/or call default
 
  CBrush brush(RGB(255,0,0)); //创建画刷
  CClientDC dc(this);
  dc.FillRect(CRect(m_ptOrigin,point),&brush);//用制定的画刷,填充矩形区域

  CView::OnLButtonUp(nFlags, point);
   }
  -----------------------------------------------------------------------------------
 
  创建位图的画刷:
  CBitmap类
  MSDN
  -----------------------------------------------------------------------------------
  CBitmap::CBitmap
 Constructs a CBitmap object.

 CBitmap( );  // 需要使用函数对其进行初始化
  Remarks
 The resulting object must be initialized with one of the initialization member
 functions.
-------------------------------------------------------------------------------------
LoadBitmap函数,加载位图
MSDN
-------------------------------------------------------------------------------------
CBitmap::LoadBitmap
 Loads the bitmap resource named by lpszResourceName or identified by the ID number
 in nIDResource from the application's executable file.

 BOOL LoadBitmap(
    LPCTSTR lpszResourceName
 );
 BOOL LoadBitmap(
    UINT nIDResource
 );
-------------------------------------------------------------------------------------
DrawView.CPP
  -----------------------------------------------------------------------------------
   void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
   {
 // TODO: Add your message handler code here and/or call default
 
  CBitmap bitmap;
  bitmap.LoadBitmap(IDB_BITMAP1); //加载位图
  CBrush brush(&bitmap);
  CClientDC dc(this);
  dc.FillRect(CRect(m_ptOrigin,point),&brush);//用制定的画刷,填充矩形区域

  CView::OnLButtonUp(nFlags, point);
   }
  -----------------------------------------------------------------------------------
 
 透明画刷的创建
 CBrush::FromHandle
 MSDN
-------------------------------------------------------------------------------------
CBrush::FromHandle
 Returns a pointer to a CBrush object when given a handle to a Windows HBRUSH object.

 static CBrush* PASCAL FromHandle(
    HBRUSH hBrush                        //这是CBrush类的静态方法
    //在静态的成员函数中,是不能引用非静态的数据成员
    //因为非静态的数据成员,是在类实例化一个对象时才分配内存空间的.
    //静态的数据成员使用之前必须初始化
 );
-------------------------------------------------------------------------------------
 由CBrush::FromHandle可以从一个画刷的句柄,得到指向这个画刷对象的指针.
 DrawView.CPP
  -----------------------------------------------------------------------------------
   void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
   {
 // TODO: Add your message handler code here and/or call default
 
  CClientDC dc(this);
  CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
  CBrush *pOldBrush=dc.SelectObject(pBrush);  
  dc.Rectangle(CRect(m_ptOrigin,point));
  dc.SelectObject(pOldBrush);
  CView::OnLButtonUp(nFlags, point);
   }
  -----------------------------------------------------------------------------------

11.设置绘图模式(CDC::SetROP2)
CDC::SetROP2函数
MSDN
------------------------------------------------------------------------------------
CDC::SetROP2
Sets the current drawing mode.
int SetROP2(
       int nDrawMode
 );
Parameters
nDrawMode
 Specifies the new drawing mode. It can be any of the following values:
 R2_BLACK   Pixel is always black.
 R2_WHITE   Pixel is always white.
 R2_NOP   Pixel remains unchanged.
 R2_NOT   Pixel is the inverse of the screen color.
 R2_COPYPEN   Pixel is the pen color.
 R2_NOTCOPYPEN   Pixel is the inverse of the pen color.

原创粉丝点击