Click here to Skip to main content
15,867,330 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
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.

C++
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:
C++
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
Comments
Sergey Alexandrovich Kryukov 9-Feb-12 1:13am    
Not a question.
--SA

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
 
Share this answer
 
v3
Comments
Espen Harlinn 9-Feb-12 8:46am    
5'ed!
Sergey Alexandrovich Kryukov 9-Feb-12 11:52am    
Thank you, Espen.
--SA
Sergey Alexandrovich Kryukov 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.
Sergey Alexandrovich Kryukov 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
Please observe the following code; it can give you your next ideas :) :
C#
// 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 !

  //..
}
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900