一个滚动视图,我的代码有鼠标滚轮操作(或用快捷键)可以放大或缩小视图,倍率为m_ZoomScale(取值范围1-4), 我在视图上绘有图元,现在想做的如下功能: 假如我当前鼠标指在视图某处, 我想在鼠标滚轮(或快捷键)放大或缩小视图后(其间鼠标指针位置未动), 鼠标以前指向的图元仍在鼠标指针处, 目前想到的方法是设置滚动条的位置,但是不知道如何计算这个值,请高人指点.或者有别的更快捷的方法

解决方案 »

  1.   

    这个我做过。
    你自己得建立绝对坐标系。
    滚轴的Pos要根据绝对坐标系来定。因为视图只能显示其中一部分。然后你视图中有控件的,全部MoveWindow来重新根据绝对坐标系来定坐标。
      

  2.   

    参考
    // ZoomPartView.cpp : implementation of the CZoomPartView class
    //
    //实效编程100例-例19
    #include "stdafx.h"
    #include "ZoomPart.h"#include "ZoomPartDoc.h"
    #include "ZoomPartView.h"
    #include "MainFrm.h"
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CZoomPartViewIMPLEMENT_DYNCREATE(CZoomPartView, CView)BEGIN_MESSAGE_MAP(CZoomPartView, CView)
    //{{AFX_MSG_MAP(CZoomPartView)
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDOWN()
    ON_WM_RBUTTONDOWN()
    //}}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()/////////////////////////////////////////////////////////////////////////////
    // CZoomPartView construction/destructionCZoomPartView::CZoomPartView()
    {
    // TODO: add construction code here
    m_pdcMem = new CDC;
    m_pBitmap = new CBitmap;
    recover = true;
    s = 30; d = 45;
    mana = SRCCOPY;}CZoomPartView::~CZoomPartView()
    {
    delete m_pdcMem;
    delete m_pBitmap;
    }BOOL CZoomPartView::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs return CView::PreCreateWindow(cs);
    }/////////////////////////////////////////////////////////////////////////////
    // CZoomPartView drawingvoid CZoomPartView::OnDraw(CDC* pDC)
    {
    CZoomPartDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here //声明判断是否load位图的静态标志
    static bool load;
    //按原来大小显示位图
    if (!load) {
    BITMAP bm;
    load = !load;
    m_pBitmap->LoadBitmap(IDB_BITMAP1);
    m_pdcMem->CreateCompatibleDC(pDC);
    m_pdcMem->SelectObject(m_pBitmap);
    m_pBitmap->GetObject(sizeof(bm),&bm);
    m_sizeSource.cx = bm.bmWidth;
    m_sizeSource.cy = bm.bmHeight;
    m_sizeDest = m_sizeSource;
    pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,
    m_pdcMem,0,0,m_sizeSource.cx,m_sizeSource.cy,mana);
    }
    else {
    pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,
    m_pdcMem,0,0,m_sizeSource.cx,m_sizeSource.cy,mana);
    }}/////////////////////////////////////////////////////////////////////////////
    // CZoomPartView printingBOOL CZoomPartView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    // default preparation
    return DoPreparePrinting(pInfo);
    }void CZoomPartView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    // TODO: add extra initialization before printing
    }void CZoomPartView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    // TODO: add cleanup after printing
    }/////////////////////////////////////////////////////////////////////////////
    // CZoomPartView diagnostics#ifdef _DEBUG
    void CZoomPartView::AssertValid() const
    {
    CView::AssertValid();
    }void CZoomPartView::Dump(CDumpContext& dc) const
    {
    CView::Dump(dc);
    }CZoomPartDoc* CZoomPartView::GetDocument() // non-debug version is inline
    {
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CZoomPartDoc)));
    return (CZoomPartDoc*)m_pDocument;
    }
    #endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
    // CZoomPartView message handlersvoid CZoomPartView::OnMouseMove(UINT nFlags, CPoint point) 
    {
    //计算要放大的局部矩形的源图像位置和目标位置
    CString cord;
    int dd;
        CRect srect,drect,mrect;
    srect.left = point.x - s;
    srect.top = point.y - s;
    srect.right = point.x + s;
    srect.bottom = point.y + s;

    drect.left = point.x - d;
    drect.top = point.y - d;
    drect.right = point.x + d;
    drect.bottom = point.y + d;

    mrect.left = oldx - d;
    mrect.top = oldy - d;
    mrect.right = oldx + d;
    mrect.bottom = oldy + d;
    dd = 2*d;
    CDC * pDC = GetDC();
    OnPrepareDC(pDC);
    //放大图像
    if (recover)
    {
    pDC->BitBlt(mrect.left,mrect.top,dd,dd,
    m_pdcMem,mrect.left,mrect.top,mana);
    }
    pDC->StretchBlt(drect.left,drect.top,
    drect.Width(),drect.Height(),m_pdcMem,srect.left,
    srect.top,srect.Width(),srect.Height(),SRCCOPY);
    oldx = point.x; oldy = point.y;
    ReleaseDC(pDC);

    recover = true; CView::OnMouseMove(nFlags, point);
    }void CZoomPartView::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    //如果鼠标位置不在位图上,则还原位图大小显示
    CRect rc(0,0,m_sizeSource.cx,m_sizeSource.cy);
    if(!rc.PtInRect(point))
    {
    Invalidate();
    }
    else if (d > 5)//如果放大倍数大于5,就继续减小放大倍数,然后进行放大显示
    {
    CDC * pDC = GetDC();
    pDC->StretchBlt(oldx - d,oldy - d,2*d,
    2*d,m_pdcMem,oldx - d,oldy - d,2*d,2*d,mana);
    d -= 10;
    ReleaseDC(pDC);
    CZoomPartView::OnMouseMove(nFlags, point);

    CView::OnLButtonDown(nFlags, point);
    }void CZoomPartView::OnRButtonDown(UINT nFlags, CPoint point) 
    {
    //如果鼠标位置不在位图上,则还原位图大小显示
    CRect rc(0,0,m_sizeSource.cx,m_sizeSource.cy);
    if(!rc.PtInRect(point))
    {
    Invalidate();
    }
    else if (d <300)//如果放大倍数小于150,就继续增加放大倍数,然后进行放大显示

    d += 10;
    CZoomPartView::OnMouseMove(nFlags, point); 

    CView::OnRButtonDown(nFlags, point);
    }
      

  3.   


    怎么具体?思路我说了
    我当时用鼠标的滚轮来控制放大和缩小的
    每次都要SetScrollSize的,每次改变的大小要重新计算的X,Y(背景总地图的大小)因为背景是总地图的放大的,然后只要其中一部分,用StretchBlt来显示的。