Click here to Skip to main content
13,255,974 members (50,443 online)
Rate this:
Please Sign up or sign in to vote.
See more:

I have a dialog based application which is used to plot graphs.

And in it, it has a Picture control which I have derived as a Static Class, and I'm using GDI+ to draw.

I've already handle the rubber-banding rectangle in the mouse events.
But how do i zoom in/out using the rubber-band rectangle?
I've found a function called strechblt, but when zooming in, the graphs will be strectched and blurred. Is there anyway that i can redraw what is inside the rubber-band rectangle in the picture control?

All the examples i found were using Cwnd or CScrollView.

This is how i handle my mouse events and how i draw the rect.

void CGraph::OnLButtonDown(UINT nFlags, CPoint point)
	CGraphicPlotter1Dlg *dlg = (CGraphicPlotter1Dlg*) this->GetParent();
	CPoint curPoint;
	mousePt.x = curPoint.x;
	mousePt.y = curPoint.y;
		m_Track = TRUE;
		m_ptStart = point;
		m_ptEnd  = point;
	CStatic::OnLButtonDown(nFlags, point);
void CGraph::OnLButtonUp(UINT nFlags, CPoint point)
	m_Track = FALSE;
	if (GetCapture() == this && rcPic.BottomRight().x >= rcMouse.BottomRight().x 
							 && rcPic.BottomRight().y >= rcMouse.BottomRight().y)
		m_ptEnd = point;
	CStatic::OnLButtonUp(nFlags, point);
void CGraph::OnMouseMove(UINT nFlags, CPoint point)
	if (GetCapture() == this && m_Track == TRUE)
		m_ptEnd = point;
	CStatic::OnMouseMove(nFlags, point);

and in onPaint:
if (m_Track == TRUE)
		CRect r(m_ptStart, m_ptEnd);
		float mouseWidth = r.Width();
		float mouseHeight = r.Height();
		RectF rcGdi(r.TopLeft().x, r.TopLeft().y, mouseWidth, mouseHeight);
		g.DrawRectangle(&mousePen, rcGdi);
Posted 8-Feb-12 17:41pm
SAKryukov 9-Feb-12 1:13am
Not a question.
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

This is not a question. However, if your problem is that you don't like the quality of the picture which you enlarge, I can answer. Can you keep a secret? Listen then: there is no such thing as miracle.


A reply to the follow-up discussion.

They graphics should be vector in this case, never bitmap (pixel) graphics.

You need to have your data model describing the graph logically. The model should have content and also viewing parameters like zoom or pan. You need to render model dynamically depending on the content, zoom, pan, etc.

For this purpose, you need to handle WM_PAINT event of some control, working as the drawing surface. The change in graphic is done via the change of the data model or viewing parameters and calling on of Invalidate functions.

(And please, don't post your comments or questions as a "solution" — will be removed; no one gets e-mail notification. Instead, comment on other posts, use "Improve question".)

Espen Harlinn 9-Feb-12 8:46am
SAKryukov 9-Feb-12 11:52am
Thank you, Espen.
SAKryukov 9-Feb-12 11:53am
OP commented:

ok, let me rephrase my question. I'm using the picture control to draw graphs.
So when i enlarge, i want to be able to get the coordinates. I understand that i have to do some calculations of the picture control and the rubber-band rect and transform into world coordinates or something. But I have no idea how to do so.
SAKryukov 9-Feb-12 11:56am
For drawing graph, you should not use pixel graphics at all. You need to use vector graphics. You should have a data model of you graphs (instead of any bitmaps) and render it depending on current, content, zoom and pan factors, etc.
Rate this: bad
Please Sign up or sign in to vote.

Solution 3

Please observe the following code; it can give you your next ideas :) :
// Trnsformer.h
  class CDrawTransformer
    /// Context to serve
    CDC*  m_pDC;
    /// ID of the original context
    int   m_iOriginalDC;
    /// Mode of the original context
    int   m_iOriginalMode;
    /// Original matrix
    XFORM m_xOriginalForm;
    /// Working matrix
    XFORM m_xWorkingForm;
    CDrawTransformer(CDC* pDC, const CRect& crViewCell, int iZoomPercent);
    void Release();
// Transformer.cpp
CDrawTransformer::CDrawTransformer(CDC* pDC,
                                   const CRect& crViewCell,
                                   int iZoomPercent)
: m_pDC(pDC)
  m_iOriginalDC = SaveDC(m_pDC->m_hDC);
  m_iOriginalMode = SetGraphicsMode(m_pDC->m_hDC, GM_ADVANCED);
  GetWorldTransform(m_pDC->m_hDC, &m_xOriginalForm);
  float fZoomFactor   = (float) iZoomPercent / 100.0f;
  m_xWorkingForm.eM11 = fZoomFactor;
  m_xWorkingForm.eM12 = 0.0f;
  m_xWorkingForm.eM21 = 0.0f;
  m_xWorkingForm.eM22 = fZoomFactor;
  m_xWorkingForm.eDx  = (float) crViewCell.left;
  m_xWorkingForm.eDy  = (float);
  SetWorldTransform(m_pDC->m_hDC, &m_xWorkingForm);
void CDrawTransformer::Release()
  if (m_pDC->GetSafeHdc()) {
    SetWorldTransform(m_pDC->m_hDC, &m_xOriginalForm);
    SetGraphicsMode(m_pDC->m_hDC, m_iOriginalMode);
    RestoreDC(m_pDC->m_hDC, m_iOriginalDC);
    m_pDC = NULL;
// YourDraw.cpp
void CYourWnd::SomeDrawing(CDC* pDC,
                           const CRect& crViewCell,
                           int iZoomPercent)
  // 1. Construct a transformer
  CDrawTransformer cTransformer(pDC, crViewCell, iZoomPercent);
  // 2. Init your GDI+ graphics
  graphics g(pDC, ...);
  // 3. Draw the cell in (0, 0) origin
  GdiPlusDraw(g, crViewCell.Size());
void CYourWnd::GdiPlusDraw(graphics& g, const CSize& sizeCell)
  // Please note: you have to draw the cell in the origin(0, 0) here !

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web04 | 2.8.171114.1 | Last Updated 9 Feb 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100