zoukankan      html  css  js  c++  java
  • MFC笔记——VC++深入详解(第3版)孙鑫

    1、Windows下的程序都是基于消息的,窗口在创建时都会产生一个WM_CREATE消息。其他类可以响应这个消息,添加WM_CREATE消息的处理函数。

    类视图——某个类处鼠标右键,属性——消息(找到WM_CREATE)。或者使用“类向导”。

    2、文档/视类结构,视类窗口始终覆盖在框架类窗口之上,鼠标所有操作都只能由视类窗口捕获。如,CMainFrame中鼠标单击事件无反应,而在CDrawView中就有反应。

     3、消息映射机制

    消息映射表,由头文件的DECLARE_MESSAGE_MAP()、源文件的BEGIN_MESSAGE_MAP与END_MESSAGE_MAP构建而成。BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间,有消息映射宏,一旦有消息产生,程序就调用对应的消息响应函数来处理。

     消息响应函数

     4、画线,推荐方式三

        /* 方式一:SDK
        // 首先获得窗口的设备描述表
        HDC hdc;
        hdc = ::GetDC(m_hWnd); //当前窗口的设备描述表
        //移动到线条的起点
        MoveToEx(hdc, m_ptOrigin.x, m_ptOrigin.y, NULL);
        //画线
        LineTo(hdc, point.x, point.y);
        //释放设备描述表
        ::ReleaseDC(m_hWnd, hdc);
        */
    
        /* 方式二:MFC的CDC类,封装了所有与绘图相关的操作
        CDC* pDC = GetDC();
        pDC->MoveTo(m_ptOrigin);
        pDC->LineTo(point);
        ReleaseDC(pDC);
        */
    
        方式三:MFC的CClientDC类,CDC的进一步封装,省去GetDC与ReleaseDC
        CClientDC dc(this); //客户区范围
        //CClientDC dc(GetParent()); //客户区+工具栏区
        dc.MoveTo(m_ptOrigin);
        dc.LineTo(point);
    
        /* 方式四:MFC的CWindowDC类,也是派生自CDC,可画的范围更大
        CWindowDC dc(this); //客户区范围
        //CWindowDC dc(GetParent()); //客户区+工具栏区
        //CWindowDC dc(GetDesktopWindow()); //所有窗口
        dc.MoveTo(m_ptOrigin);
        dc.LineTo(point);
        */

    5、画笔

        CPen pen(PS_SOLID, 1, RGB(255, 0, 0)); //PS_DASH、PS_DOT宽度≤1,虚线才有效
        CClientDC dc(this);
        CPen* pOldPen = dc.SelectObject(&pen); //选择画笔
        dc.MoveTo(m_ptOrigin);
        dc.LineTo(point);
        //推荐写上以下两行,不然可能造成GDI对象的增加,程序崩溃
        dc.SelectObject(pOldPen); //重置画笔
        pen.DeleteObject(); //释放画笔

    6、画刷,一般用于填充

        CBrush brush(RGB(255, 0, 0));//创建一个红色画刷
        CClientDC dc(this);    //创建并获得设备描述表
        dc.FillRect(CRect(m_ptOrigin, point), &brush);//利用红色画刷填充鼠标拖曳过程中形成的矩形区域
        brush.DeleteObject();

    画刷画矩形,dc中有默认白色画刷。但是新的会覆盖旧的。透明矩形的实现。

        /* 画矩形,dc中有默认白色画刷
        CClientDC dc(this);
        dc.Rectangle(CRect(m_ptOrigin, point)); //绘制矩形,黑边白色填充
        */
    
        // 透明矩形,新的不遮蔽旧的
        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);//恢复先前的画刷
        pBrush->DeleteObject();

    说明,CClientDC操作的都是对象而不是句柄。GetStockObject()获取画刷、画笔、字体的句柄。

     

    将句柄转为对象,用画刷、画笔、字体类提供的FromHandle()函数。

     7、绘制连续线条

    鼠标移动消息WM_MOUSEMOVE,不断更新起始点,不断在起始点与最新点之间画非常短的线段。

    void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
    {
        CClientDC dc(this);        
        CPen pen(PS_SOLID, 1, RGB(255, 0, 0));//创建一个红色的、宽度为1的实线画笔
        CPen *pOldPen = dc.SelectObject(&pen);//把创建的画笔选入设备描述表
    
        if (m_bDraw == TRUE) //鼠标按下开始,抬起结束
        {
            dc.MoveTo(m_ptOrigin);
            dc.LineTo(point);        
            m_ptOrigin = point;//修改线段的起点
        }    
        dc.SelectObject(pOldPen);//恢复设备描述表
        pen.DeleteObject();
    
        CView::OnMouseMove(nFlags, point);
    }

     8、窗口重绘

    当窗口创建时、尺寸发生变化时,都会调用OnDraw()。防止文字等内容在窗口重绘时消失,可以将代码写在OnDraw()中。

  • 相关阅读:
    找水王
    哈利波特图书购买问题
    中序线索化二叉树[C语言实现及注释]
    第一篇随文。
    理解Python函数中的的return
    记录一款实时同步的软件——Lsyncd
    for循环
    while循环
    文件操作
    我的第一个博客
  • 原文地址:https://www.cnblogs.com/xixixing/p/14025705.html
Copyright © 2011-2022 走看看