////////////////////////////////////////////////////////////////////////////////
// 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);
}