Click here to Skip to main content
15,885,366 members
Articles / Desktop Programming / MFC

GraphFX - A graph framework

Rate me:
Please Sign up or sign in to vote.
3.34/5 (30 votes)
9 Nov 2000 228K   4.5K   104  
A Doc/View framework for displaying graphical data
////////////////////////////////////////////////////////////////////////////////
// Developed by Norm Almond
//
// The software is free to use anywhere...
//
// Please see www.codeproject.com for updates...
//
////////////////////////////////////////////////////////////////////////////////


// GraphViewFX.cpp : implementation of the CGraphViewFX class
//

#include "stdafx.h"
#include "Graph.h"

#include "MainFrm.h"
#include "GraphViewFX.h"

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


/////////////////////////////////////////////////////////////////////////////
// CGraphViewFX

IMPLEMENT_DYNCREATE(CGraphViewFX, CView)

BEGIN_MESSAGE_MAP(CGraphViewFX, CView)
	//{{AFX_MSG_MAP(CGraphViewFX)
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_MOUSEMOVE()
	ON_WM_CONTEXTMENU()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_MOUSEWHEEL()
	ON_WM_VSCROLL()
	ON_WM_KEYUP()
	ON_WM_SETCURSOR()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP

    ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipNeedText)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGraphViewFX construction/destruction

CGraphViewFX::CGraphViewFX()
{	
	m_pItem = NULL;
	m_pSelectedItem = NULL;
	
	LOGFONT lf;
	::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(lf),&lf);
	m_font.CreateFontIndirect(&lf);
	m_fontSmall.CreateFontIndirect(&lf);

	lf.lfWeight = FW_BOLD;
	m_fontSelect.CreateFontIndirect(&lf);
}


CGraphViewFX::~CGraphViewFX()
{
	// Font we self destruct...

}


BOOL CGraphViewFX::PreCreateWindow(CREATESTRUCT& cs)
{
	cs.style |= WS_CLIPCHILDREN;

	return CView::PreCreateWindow(cs);
}

void CGraphViewFX::OnInitialUpdate()
{
	CView::OnInitialUpdate();

	if (m_ToolTip.Create(this, TTS_ALWAYSTIP) && m_ToolTip.AddTool(this))
	{
		m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX);
		m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_AUTOPOP, SHRT_MAX);
		m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_INITIAL, 200);
		m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_RESHOW, 200);
	}	


	m_wndScrollBar.Create(WS_CHILD|SBS_VERT,CRect(0,0,0,0),this,0x0000);

	CRect rc;
	GetClientRect(rc);

	// Fake a size message
	OnSize(0,rc.Width(),rc.Height());
}


/////////////////////////////////////////////////////////////////////////////
// CGraphViewFX diagnostics

/////////////////////////////////////////////////////////////////////////////
// CGraphViewFX message handlers



void CGraphViewFX::OnDraw(CDC* pDC)
{
	CRect rc;
	GetClientRect(rc);

	// Draw Graph
	Draw(rc, pDC, GetList(), GetItemsPerPage());
}

BOOL CGraphViewFX::OnEraseBkgnd(CDC* pDC) 
{
	pDC; // Unused

	return TRUE; // We draw our own background
}


void CGraphViewFX::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);

	
	if (::IsWindow(m_wndScrollBar.m_hWnd))
	{
		

		int nLeft = cx - (RightMargin - 2);
		int nTop = TopLine;
		int nRight = cx;
		int nBottom = (GetItemsPerPage() * BarSize) + TopLine + 2;

		SCROLLINFO si;
		si.cbSize = sizeof(si);
		si.fMask = SIF_RANGE | SIF_PAGE;
		si.nMin = 0;
		si.nMax = GetList()->GetSize() - 1;
		si.nPage = GetItemsPerPage();

		// Position  Scroll Bar
		CRect rect(nLeft, nTop, nRight, nBottom);
		m_wndScrollBar.SetScrollInfo(&si,TRUE);
		m_wndScrollBar.MoveWindow(rect);
		
		if (UINT(si.nMax) < si.nPage)
			m_wndScrollBar.ShowScrollBar(FALSE);
		else
			m_wndScrollBar.ShowScrollBar(TRUE);

	}
}



BOOL CGraphViewFX::OnToolTipNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult)
{
	pResult;	// Unused
	id;			// Unused


	CPoint CursorPos;
	VERIFY(::GetCursorPos(&CursorPos));
	ScreenToClient(&CursorPos);

	CRect ClientRect;
	GetClientRect(ClientRect);

	// Make certain that the cursor is in the client rect, because the
	// mainframe also wants these messages to provide tooltips for the
	// toolbar.
	BOOL bProcessed = FALSE;

	if (ClientRect.PtInRect(CursorPos))
	{
		TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;

		m_pItem = GetList()->HitTest(CursorPos);

		if (m_pItem)
		{
			// Adjust the text by filling in TOOLTIPTEXT
			CString strTip;
			strTip.Format(_T("%s"),m_pItem->GetTipText());
			ASSERT(strTip.GetLength() < sizeof(pTTT->szText));
			::_tcscpy(pTTT->szText, strTip);

			bProcessed = TRUE;

			// Set the text color to same color as you wish...
			//m_ToolTip.SendMessage(TTM_SETTIPTEXTCOLOR, Color, 0L);
		}

		if (!bProcessed)
			pTTT->szText[0] = 0;
		
	}
	return TRUE; // Always return true
}

void CGraphViewFX::OnMouseMove(UINT nFlags, CPoint point) 
{
	nFlags; // Unused

	CItemArray* pItemList = GetList();

	CItem* pItem = pItemList->HitTest(point);

	if (!pItem || pItem != m_pItem)
	{
		// Use Activate() to hide the tooltip.
		m_ToolTip.Activate(FALSE);		
	}

	if (pItem)
	{
		m_ToolTip.Activate(TRUE);
		m_pItem = pItem;
	}	
}

BOOL CGraphViewFX::PreTranslateMessage(MSG* pMsg) 
{
	if (::IsWindow(m_ToolTip.m_hWnd) && pMsg->hwnd == m_hWnd)
	{
		switch(pMsg->message)
		{
		case WM_LBUTTONDOWN:	
		case WM_MOUSEMOVE:
		case WM_LBUTTONUP:	
		case WM_RBUTTONDOWN:
		case WM_MBUTTONDOWN:	
		case WM_RBUTTONUP:
		case WM_MBUTTONUP:
			m_ToolTip.RelayEvent(pMsg);
			break;
		}
	}
	
	return CView::PreTranslateMessage(pMsg);
}

//
// This computes the number of items visible on the page
//
UINT CGraphViewFX::GetItemsPerPage()
{
	CRect rc;
	GetClientRect(rc);

	int nWidth = rc.Height() - TopLine;
	int nItemsPerPage = (nWidth / BarSize) - 1;

	return nItemsPerPage;

}


//
// This is code to handle selected items
//
void CGraphViewFX::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CItemArray* pItemList = GetList();

	CItem* pItem = pItemList->HitTest(point);

	if (pItem && m_pSelectedItem != pItem)
	{
		if (m_pSelectedItem)
			m_pSelectedItem->Unselect();
		
		m_pSelectedItem  = pItem;
		m_pSelectedItem->Select();
	}

	CView::OnLButtonDown(nFlags, point);
}

//
// Always use to use the thumb wheel
//

BOOL CGraphViewFX::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	if (zDelta > 0)
		SendMessage(WM_VSCROLL,SB_LINEUP,0);

	if (zDelta < 0)
		SendMessage(WM_VSCROLL,SB_LINEDOWN,0);

	
	return CView::OnMouseWheel(nFlags, zDelta, pt);
}


CItemArray* CGraphViewFX::GetList()
{
	return &m_ItemList;
}



void CGraphViewFX::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{

	SCROLLINFO si;
	si.cbSize = sizeof(si);
	si.fMask = SIF_ALL;
	m_wndScrollBar.GetScrollInfo(&si);

	switch (nSBCode)
	{
	case SB_TOP:
		si.nPos = si.nMin;
		break;
	case SB_BOTTOM:
		si.nPos = si.nMax;
		break;
	case SB_LINEDOWN:
		si.nPos += 1;
		break;
	case SB_LINEUP:
		si.nPos -= 1;
		break;
	case SB_PAGEUP:
		si.nPos -= si.nPage;
		break;
	case SB_PAGEDOWN:
		si.nPos += si.nPage;
		break;
	case SB_THUMBTRACK:
		si.nPos = si.nTrackPos;
		break;
	}

	si.fMask = SIF_POS;
	m_wndScrollBar.SetScrollInfo(&si,TRUE);
	Invalidate();

	
	CView::OnVScroll(nSBCode, nPos, pScrollBar);
}

int CGraphViewFX::GetScrollPos()
{
	SCROLLINFO si;
	si.fMask = SIF_ALL;
	m_wndScrollBar.GetScrollInfo(&si);

	return si.nPos;
}

void CGraphViewFX::SetScrollPos(int nPos)
{
	SCROLLINFO si;
	si.cbSize = sizeof(si);
	si.fMask = SIF_ALL;
	m_wndScrollBar.GetScrollInfo(&si);

	si.nPos = nPos;
	si.fMask = SIF_POS;
	m_wndScrollBar.SetScrollInfo(&si,TRUE);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) Software Kinetics
United Kingdom United Kingdom




Software Kinetics
are experts in developing customised and bespoke applications and have expertise in the development of desktop, mobile and internet applications on Windows.


We specialise in:

  • User Interface Design
  • Desktop Development
  • Windows Phone Development
  • Windows Presentation Framework
  • Windows Forms
  • Windows Communication Framework
  • Windows Services
  • Network Applications
  • Database Applications
  • Web Development
  • Web Services
  • Silverlight
  • ASP.net


Visit Software Kinetics

Comments and Discussions