• 在对话框上应用带缩放功能的CScrollView


    一.定义cscrollview派生类和document派生类

     声明:
    DlgView.h:

    //----------------------------------------------------------------------------------

    class CCraftCxPreviewDlg;
    class CDlgDocument : public CDocument
    {
        friend class CCraftCxPreviewDlg;
    protected:
        CDlgDocument();           // protected constructor used by dynamic creation
        DECLARE_DYNCREATE(CDlgDocument)

        // Attributes
    public:

        // Operations
    public:

        // Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CDlgDocument)
    public:
        virtual void Serialize(CArchive& ar);   // overridden for document i/o
    protected:
        virtual BOOL OnNewDocument();
        //}}AFX_VIRTUAL

        // Implementation
    public:
        virtual ~CDlgDocument();
    #ifdef _DEBUG
        virtual void AssertValid() const;
        virtual void Dump(CDumpContext& dc) const;
    #endif

        // Generated message map functions
    protected:
        //{{AFX_MSG(CDlgDocument)
        // NOTE - the ClassWizard will add and remove member functions here.
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    };


    class CCraftCxPreviewDlg;
    /////////////////////////////////////////////////////////////////////////////
    // CDlgView view
    class CDlgView : public CScrollView
    {
        friend class CCraftCxPreviewDlg;
    protected:
        CDlgView();           // protected constructor used by dynamic creation
        DECLARE_DYNCREATE(CDlgView)

        // Attributes
    public:
        
        // Operations
    public:

        // Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CDlgView)
    protected:
        virtual void OnDraw(CDC* pDC);      // overridden to draw this view
        virtual void OnInitialUpdate();     // first time after construct
        //}}AFX_VIRTUAL

        // Implementation
    protected:
        virtual ~CDlgView();
    #ifdef _DEBUG
        virtual void AssertValid() const;
        virtual void Dump(CDumpContext& dc) const;
    #endif

        // Generated message map functions
        //{{AFX_MSG(CDlgView)
        // NOTE - the ClassWizard will add and remove member functions here.
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    public:
        afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
        afx_msg void OnDestroy();

        void OnZoomIn();
        void OnZoomOut();
        
    protected:
        virtual void PostNcDestroy();

    private:
        void InitDC(CDC *pDC);

        float m_zoomScale;
        CSize m_size;    
    };

    定义:

    DlgView.cpp:
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    /////////////////////////////////////////////////////////////////////////////
    // CDlgDocument

    IMPLEMENT_DYNCREATE(CDlgDocument, CDocument)

    CDlgDocument::CDlgDocument()
    {
    }

    BOOL CDlgDocument::OnNewDocument()
    {
        if (!CDocument::OnNewDocument())
            return FALSE;
        return TRUE;
    }

    CDlgDocument::~CDlgDocument()
    {
    }


    BEGIN_MESSAGE_MAP(CDlgDocument, CDocument)
        //{{AFX_MSG_MAP(CDlgDocument)
        // NOTE - the ClassWizard will add and remove mapping macros here.
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CDlgDocument diagnostics

    #ifdef _DEBUG
    void CDlgDocument::AssertValid() const
    {
        CDocument::AssertValid();
    }

    void CDlgDocument::Dump(CDumpContext& dc) const
    {
        CDocument::Dump(dc);
    }
    #endif //_DEBUG

    /////////////////////////////////////////////////////////////////////////////
    // CDlgDocument serialization

    void CDlgDocument::Serialize(CArchive& ar)
    {
        if (ar.IsStoring())
        {
            // TODO: add storing code here
        }
        else
        {
            // TODO: add loading code here
        }
    }



    /////////////////////////////////////////////////////////////////////////////
    // CDlgView

    IMPLEMENT_DYNCREATE(CDlgView, CScrollView)

    CDlgView::CDlgView()
    {
        m_zoomScale = 1.0;
        m_dbHorzScale = 1.0;
        m_dbVertScale = 1.0;
    }

    CDlgView::~CDlgView()
    {
    }


    BEGIN_MESSAGE_MAP(CDlgView, CScrollView)
        //{{AFX_MSG_MAP(CDlgView)
        // NOTE - the ClassWizard will add and remove mapping macros here.
        //}}AFX_MSG_MAP
        ON_WM_MOUSEACTIVATE()
        ON_WM_DESTROY()
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CDlgView drawing

    void CDlgView::OnInitialUpdate()
    {
        CScrollView::OnInitialUpdate();
        CSize sizeTotal;
        sizeTotal.cx = sizeTotal.cy = 30;
        SetScrollSizes(MM_TEXT, sizeTotal);
        m_size =sizeTotal;//成员变量m_size保存视图的原始大小
    }

    void CDlgView::SetPreBitmap(Bitmap *PreBitmap, double dbVert, double dbHorz)
    {
        m_Bitmap = PreBitmap;

        m_dbHorzScale = (dbVert > dbHorz) ? dbVert / dbHorz: 1;
        m_dbVertScale = (dbVert > dbHorz) ? 1 : dbHorz / dbVert;


    }

    void CDlgView::OnDraw(CDC* pDC)
    {
        InitDC(pDC);//设置pDC为新的模式

        int nHeight = m_Bitmap->GetHeight();
        int nWidth = m_Bitmap->GetWidth();

        // 放大位图
        CDC dc;
        dc.CreateCompatibleDC(pDC);
        
        CBitmap bitmap;
        CBitmap* pOldBitmap;
        bitmap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
        pOldBitmap = dc.SelectObject(&bitmap);

        Graphics g(dc.m_hDC);
        g.DrawImage(m_Bitmap, 0, 0);
        
        nWidth *= m_dbHorzScale;
        nHeight *= m_dbVertScale;
        pDC->StretchBlt(0, 0, nWidth, nHeight, &dc, 0, 0, nWidth, nHeight, SRCCOPY);

        dc.SelectObject(pOldBitmap);    

        CRect m_Rect;
        GetClientRect(&m_Rect);
        m_Rect.bottom += 100;
        CSize sizeTotal;

        sizeTotal.cx = nWidth * m_zoomScale;
        sizeTotal.cy = nHeight * m_zoomScale;
        SetScrollSizes(MM_TEXT, sizeTotal);

    }

    int CDlgView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
    {
        return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
    }

    /////////////////////////////////////////////////////////////////////////////
    // CDlgView diagnostics

    #ifdef _DEBUG
    void CDlgView::AssertValid() const
    {
        CScrollView::AssertValid();
    }

    void CDlgView::Dump(CDumpContext& dc) const
    {
        CScrollView::Dump(dc);
    }
    #endif //_DEBUG

    /////////////////////////////////////////////////////////////////////////////
    // CDlgView message handlers
    //////////////////////////////////////////////////////////////////////////

    void CDlgView::OnDestroy()
    {
        CWnd::OnDestroy();
    }

    void CDlgView::PostNcDestroy()
    {
        CWnd::PostNcDestroy();
    }

    void CDlgView::OnZoomIn()
    {
        if (m_zoomScale > 31)
            return;

        CSize size = m_size;
        m_zoomScale++;//成员变量float m_zoom ;放大倍率加1
        size.cx *= m_zoomScale;
        size.cy *= m_zoomScale;
        size.cx += 2;
        size.cy += 2;//可能是计算误差的原因总是看不到最后几个象素
        this->SetScrollSizes(MM_TEXT, size); //设置放大后视图的大小
        this->Invalidate();//重画视图
    }//一个菜单事件进行缩放倍率设置

    void CDlgView::OnZoomOut()
    {
        if (m_zoomScale == 1)
            return;
        
        CSize size = m_size;
        m_zoomScale--;//成员变量float m_zoom ;放大倍率加1
        size.cx *= m_zoomScale;
        size.cy *= m_zoomScale;
        size.cx += 2;
        size.cy += 2;//可能是计算误差的原因总是看不到最后几个象素
        this->SetScrollSizes(MM_TEXT, size); //设置放大后视图的大小
        this->Invalidate();//重画视图
    }//一个菜单事件进行缩放倍率设置


    void CDlgView::InitDC(CDC *pDC)
    {
        
        CSize size(1000,1000);//定义原始图的大小,可以自己随意定
        //但不能太小,数字越大放大的精度就越高
        //举个例子,若数字为1,放大1.5倍,int(1*1.5)=1 等于没放大
        CSize newSize(1000 * m_zoomScale, 1000 * m_zoomScale);//放大后的图大小

        OnPrepareDC(pDC);//pDC设置为绑定逻辑视图
        CPoint point(0,0);//逻辑视图的0点
        pDC->LPtoDP(&point); //转化为设备坐标因为SetViewportOrg的参数需要设备坐标

        pDC->SetMapMode(MM_ANISOTROPIC);// 设置为单位可变模式
        pDC->SetViewportOrg(point);//视口原点为逻辑视图原点
        pDC->SetViewportExt(newSize); //原窗口1000单位 对应到缩放后的单位

        pDC->SetWindowOrg(0,0);
        pDC->SetWindowExt(size);//
    }//对画图dc进行设置


    二.调用

    BOOL CCraftCxPreviewDlg::OnInitDialog()
    {
        CDialog::OnInitDialog();

        CWnd *pWnd = this->GetDlgItem(IDC_STATIC_PRE_BMP);
        CRect RectTargetCtrl;
        pWnd->GetWindowRect(RectTargetCtrl);
        pWnd->DestroyWindow();
        this->ScreenToClient(RectTargetCtrl);

        CCreateContext pContext;
        CWnd* pFrameWnd = this;
        pContext.m_pCurrentDoc = new CDlgDocument;
        pContext.m_pNewViewClass = RUNTIME_CLASS(CDlgView);
        
        m_pZoomView =(CDlgView *) ((CFrameWnd*)pFrameWnd)->CreateView(&pContext);
        ASSERT(m_pZoomView);
        m_pZoomView->m_nMapMode = MM_TEXT;
        m_pZoomView->OnInitialUpdate();
        m_pZoomView->SetPreBitmap(m_pPreBitmap, m_dbDensityVert, m_dbDensityHorz);

        m_pZoomView->ShowWindow(SW_NORMAL);
        m_pZoomView->MoveWindow(RectTargetCtrl);

        return TRUE;  
    }


    void CCraftCxPreviewDlg::OnBnClickedButtonZoomout()
    {
        m_pZoomView->OnZoomOut();
    }

    void CCraftCxPreviewDlg::OnBnClickedButtonZoomin()
    {
        m_pZoomView->OnZoomIn();
    }



  • 相关阅读:
    LUA 协程
    LUA GC 简单测试
    软件重构-笔记
    托管执行过程
    文件夹 加密
    db 文件 查看 打开 工具 db 中文 版 navicat 中文
    qq sid qq sid 是什么 qq sid 怎么用
    windows系统,联系人文件。个性化。
    csdn 音乐 怎么拦截 提交后的程序 csdn 栏目 音乐 csdn 添加 音乐
    CSDN博客栏目设置个性化
  • 原文地址:https://www.cnblogs.com/madlas/p/1383871.html
Copyright © 2020-2023  润新知