• VC++技术内幕(三)


    C*View <- Cview <- CWnd <- Cobject

    C*View 两个最重要的基类:CView和CWnd,CWnd提供了C*View的”窗口属性”,CView则提供了它和应用程序框架其他部分间的联系。

    在视窗内绘图:

    OnDraw成员函数:

    是CView类中的虚成员函数,每次视窗被重新绘制时,应用程序都将调用OnDraw。如果用户改变了窗口尺寸,或窗口需要恢复被遮盖部分,则应用程序会直接调用OnDraw;如果程序中某个程序修改了数据,则必须通过调用视图所继承的Invalidate(或者InvalidateRect)成员函数来通知Windows。调用Invalidate后会触发对OnDraw的调用。

    Windows设备环境:

    Windows不允许直接访问硬件,需通过与窗口相关联的”设备环境”跟显示硬件进行通信。MFC库中设备环境由C++的CDC类对象表示,该对象作为参数传给OnDraw函数。通过调用CDC的许多成员函数可完成各种各样的绘图工作。

    OnDraw原型:void OnDraw(CDC* pDC);

    示例:

    void CEx3View::OnDraw(CDC* pDC)

    {

        pDC->TextOut(0,0,"Hello World!");//默认字体,左上角输出

        pDC->SelectStockObject(GRAY_BRUSH);//把GRAY_BRUSH对象选入环境

        pDC->Ellipse(CRect(0,20,100,120));

    //CRect一临时对象作为外接矩形参数传给Ellipse。

    }

    注:SelectStockObject只能把有限的几种对象选入环境,而SelectObject是可以把任意GDI对象选入设备环境。

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

    MS_DOS程序通过调用操作系统功能来获得用户输入,而Windows程序通过操作系统发送的消息处理用户输入。

    MFC库消息映射机制:函数原型、函数体、消息映射中的入口。

    eg:

    函数体:

    void CEx3View::OnLButtonDown(UINT nFlags, CPoint point)

    {

    }

    类头文件中:函数原型

    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

    头文件中还要包含:DECLARE_MESSAGE_MAP()

    afx_msg并没有用途,只是表明该原型是针对消息映射而言。

    消息映射宏,将OnLButtonDown函数同应用程序框架联系起来。(消息映射入口)

    BEGIN_MESSAGE_MAP(CEx3View, CView)

            ON_WM_LBUTTONDOWN()//映射项

    END_MESSAGE_MAP()

    示例:绘一椭圆,鼠标左键单击,如点在椭圆内,椭圆颜色在灰和白间轮换。

    操作都是在C*View中进行:

    添加两成员变量:

    private:

    int m_Color;//颜色

    CRect m_rectEllipse;//椭圆外接矩形

    C*View构造函数中对成员变量初始化:

    C*View ::C*View :m_rectEllipse(0,0,200,200)

    {

        m_nColor = GRAY_BRUSH;

    }

    OnDraw的重写:

    void C*View::OnDraw(CDC* pDC)

    {

        pDC->SelectStockObject(m_nColor);

        pDC->Ellipse(m_rectEllipse);

    }

    通过类向导添加消息控制函数:

    类向导对话框->选择C*View类->Message列表框中选择WM_LBUTTONDOWN;

    编辑OnLButtonDown:

    void CEx3View::OnLButtonDown(UINT nFlags, CPoint point)

    {

        if(m_rectEllipse.PtInRect(point))

        {

           if(m_nColor == GRAY_BRUSH)

           {

               m_nColor = WHITE_BRUSH;

           }else{

               m_nColor = GRAY_BRUSH;

           }

        }

        InvalidateRect(m_rectEllipse);

    //代码中进行了修改,要调用InvalidateRect才会调用OnDraw进行重画。

    }

    注:m_rectEllipse.PtInRect(point)

    判断point是否在椭圆外围矩形m_rectEllipse中。如要更精确判断point是否在椭圆中,代码如下:

    void CEx3View::OnLButtonDown(UINT nFlags, CPoint point)

    {

        CRgn rgn;//定义一对应椭圆的类CRgn对象

        rgn.CreateEllipticRgnIndirect(m_rectEllipse);//获得椭圆区域

        if(rgn.PtInRegion(point))//PtInRegion代替PtInRect

        {

           if(m_nColor == GRAY_BRUSH)

           {

               m_nColor = WHITE_BRUSH;

           }else{

               m_nColor = GRAY_BRUSH;

           }

        }

        InvalidateRect(m_rectEllipse);

    }

  • 相关阅读:
    Centos R安装
    python 排序函数L.sort()和sorted()
    系统评测指标:准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F-Score
    linux exec使用小结
    linux 日志文件
    数据结构中的八大排序算法
    Boyer-Moore(BM)算法,文本查找,字符串匹配问题
    内存为程序分配空间的四种分配方式
    内部碎片、外部碎片
    函数调用过程栈帧变化详解
  • 原文地址:https://www.cnblogs.com/lxshanye/p/3088571.html
Copyright © 2020-2023  润新知