Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ MFC GDI+
Hi,
 
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();
	this->GetWindowRect(rcPic);
	this->ScreenToClient(rcPic);
	CPoint curPoint;
	GetCursorPos(&curPoint);
	mousePt.x = curPoint.x;
	mousePt.y = curPoint.y;
	if(rcPic.PtInRect(mousePt))
	{
		m_Track = TRUE;
		m_ptStart = point;
		m_ptEnd  = point;
		SetCapture();
	}
	InvalidateRect(rcPic,FALSE);
	CStatic::OnLButtonDown(nFlags, point);
}
 
void CGraph::OnLButtonUp(UINT nFlags, CPoint point)
{
	m_Track = FALSE;
	InvalidateRect(rcPic,FALSE);
	GetClientRect(rcMouse);
	rcMouse.NormalizeRect();
	if (GetCapture() == this && rcPic.BottomRight().x >= rcMouse.BottomRight().x 
							 && rcPic.BottomRight().y >= rcMouse.BottomRight().y)
	{	
		ReleaseCapture();
		m_ptEnd = point;
	}
	ReleaseCapture();
	CStatic::OnLButtonUp(nFlags, point);
}
 
void CGraph::OnMouseMove(UINT nFlags, CPoint point)
{
	if (GetCapture() == this && m_Track == TRUE)
	{ 
		m_ptEnd = point;
	}
	InvalidateRect(rcPic,FALSE);
	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
skfoo1691
Comments
SAKryukov at 9-Feb-12 1:13am
   
Not a question.
--SA
Rate this: bad
good
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.
 
[EDIT]
 
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".)
 
—SA
  Permalink  
v3
Comments
Espen Harlinn at 9-Feb-12 8:46am
   
5'ed!
SAKryukov at 9-Feb-12 11:52am
   
Thank you, Espen.
--SA
SAKryukov at 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 at 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.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Please observe the following code; it can give you your next ideas Smile | :) :
// 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;
 
  public:
    CDrawTransformer(CDC* pDC, const CRect& crViewCell, int iZoomPercent);
    ~CDrawTransformer();
 
    void Release();
  };
 
// Transformer.cpp
CDrawTransformer::CDrawTransformer(CDC* pDC,
                                   const CRect& crViewCell,
                                   int iZoomPercent)
: m_pDC(pDC)
{
  ASSERT(m_pDC->GetSafeHdc());
 
  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) crViewCell.top;
  SetWorldTransform(m_pDC->m_hDC, &m_xWorkingForm);
}
 
CDrawTransformer::~CDrawTransformer()
{
  Release();
}
 
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 !

  //..
}
  Permalink  

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 334
1 Kornfeld Eliyahu Peter 325
2 Maciej Los 239
3 OriginalGriff 188
4 King Fisher 185
0 OriginalGriff 6,303
1 DamithSL 4,764
2 Maciej Los 4,306
3 Kornfeld Eliyahu Peter 3,914
4 Sergey Alexandrovich Kryukov 3,538


Advertise | Privacy | Mobile
Web02 | 2.8.141220.1 | Last Updated 9 Feb 2012
Copyright © CodeProject, 1999-2014
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