Click here to Skip to main content
15,896,153 members
Articles / Desktop Programming / MFC

Report control - an Outlook 2000 style SuperGrid Report Control

Rate me:
Please Sign up or sign in to vote.
4.90/5 (44 votes)
14 Jun 2001 1.5M   8.7K   152  
An Outlook 98/2000 Style SuperGrid Report Control that tries to overcome some of the weaknesses of other implementations.
////////////////////////////////////////////////////////////////////////////
//	File:		ReportOptionsCtrl.cpp
//	Version:	1.0.0
//
//	Author:		Maarten Hoeben
//	E-mail:		hamster@xs4all.nl
//
//	Implementation of the CReportOptionsCtrl and associated classes.
//
//	This code may be used in compiled form in any way you desire. This
//	file may be redistributed unmodified by any means PROVIDING it is
//	not sold for profit without the authors written consent, and
//	providing that this notice and the authors name and all copyright
//	notices remains intact.
//
//	An email letting me know how you are using it would be nice as well.
//
//	This file is provided "as is" with no expressed or implied warranty.
//	The author accepts no liability for any damage/loss of business that
//	this product may cause.
//
//	The ideas behind this control and its interface are based on the
//  CTreeOptionsCtrl and associated classes by PJ Naughther. The control
//	is derived from CReportCtrl and demonstrates the power of the
//  CReportControl when deriving new behavior.
//
//	Version history
//
//	1.0.0	- Initial release.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ReportOptionsCtrl.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNCREATE(CReportOptionsCtrl, CEdit)

CReportOptionsCtrl::CReportOptionsCtrl()
{
	// Register the window class if it has not already been registered.
	WNDCLASS wndclass;
	HINSTANCE hInst = AfxGetInstanceHandle();

	if(!(::GetClassInfo(hInst, REPORTOPTIONSCTRL_CLASSNAME, &wndclass)))
	{
        wndclass.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
		wndclass.lpfnWndProc = ::DefWindowProc;
		wndclass.cbClsExtra = wndclass.cbWndExtra = 0;
		wndclass.hInstance = hInst;
		wndclass.hIcon = NULL;
		wndclass.hCursor = LoadCursor(hInst, IDC_ARROW);
		wndclass.hbrBackground = (HBRUSH)COLOR_WINDOW;
		wndclass.lpszMenuName = NULL;
		wndclass.lpszClassName = REPORTOPTIONSCTRL_CLASSNAME;

		if (!AfxRegisterClass(&wndclass))
			AfxThrowResourceException();
	}

	m_hControl = NULL;
	m_lpEdit = NULL;
	m_lpCombo = NULL;
}

CReportOptionsCtrl::~CReportOptionsCtrl()
{
}

BEGIN_MESSAGE_MAP(CReportOptionsCtrl, CReportCtrl)
	//{{AFX_MSG_MAP(CReportOptionsCtrl)
	ON_WM_KEYDOWN()
	ON_MESSAGE(WM_USER, OnCloseControl)
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReportOptionsCtrl attributes

BOOL CReportOptionsCtrl::IsGroup(HTREEITEM hItem)
{
	if(HasChildren(hItem))
		return TRUE;

	return FALSE;
}

BOOL CReportOptionsCtrl::IsCheckBox(HTREEITEM hItem)
{
	RVITEM rvi;
	return GetCheck(hItem, &rvi);
}

BOOL CReportOptionsCtrl::IsRadioButton(HTREEITEM hItem)
{
	RVITEM rvi;
	return GetRadio(hItem, &rvi);
}

BOOL CReportOptionsCtrl::IsEditable(HTREEITEM hItem)
{
	INT iItem = GetItemIndex(hItem);
	if(iItem != RVI_INVALID && GetItemData(iItem) != 0)
		return TRUE;

	return FALSE;
}

BOOL CReportOptionsCtrl::IsDisabled(HTREEITEM hItem)
{
	RVITEM rvi;
	if(GetCheck(hItem, &rvi))
		return rvi.iCheck&2 ? TRUE:FALSE;

	if(GetRadio(hItem, &rvi))
		return rvi.iCheck&2 ? TRUE:FALSE;

	return FALSE;
}

BOOL CReportOptionsCtrl::SetCheckBox(HTREEITEM hItem, BOOL bCheck)
{
	RVITEM rvi;
	if(GetCheck(hItem, &rvi) == TRUE)
	{
		rvi.iCheck = (rvi.iCheck&~1);
		rvi.iCheck |= (bCheck ? 1:0);

		rvi.nMask = RVIM_CHECK;
		VERIFY(SetItem(&rvi));
		return TRUE;
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::GetCheckBox(HTREEITEM hItem, BOOL& bCheck)
{
	RVITEM rvi;

	if(GetCheck(hItem, &rvi) == TRUE)
	{
		bCheck = rvi.iCheck&1 ? TRUE:FALSE;
		return TRUE;
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::SetRadioButton(HTREEITEM hParent, INT iIndex)
{
	INT i = 0;
	HTREEITEM hItem = GetNextItem(hParent, RVGN_CHILD);

	while(hItem != NULL && i<iIndex)
	{
		hItem = GetNextItem(hItem, RVGN_NEXT);
		i++;
	}

	i = 0;
	hItem = GetNextItem(hParent, RVGN_CHILD);

	while(hItem != NULL)
	{
		RVITEM rvi;
		if(GetRadio(hItem, &rvi) == TRUE)
		{
			if(i == iIndex)
				rvi.iCheck |= 1;
			else
				rvi.iCheck &= ~1;

			rvi.nMask = RVIM_CHECK;
			VERIFY(SetItem(&rvi));
		}

		hItem = GetNextItem(hItem, RVGN_NEXT);
		i++;
	}

	return TRUE;
}

BOOL CReportOptionsCtrl::SetRadioButton(HTREEITEM hItem)
{
	INT iIndex = -1;
	HTREEITEM hParent = GetNextItem(hItem, RVGN_PARENT);

	ASSERT(hItem != NULL);
	while(hItem != NULL)
	{
		hItem = GetNextItem(hItem, RVGN_PREVIOUS);
		iIndex++;
	}

	return SetRadioButton(hParent, iIndex);
}

BOOL CReportOptionsCtrl::GetRadioButton(HTREEITEM hParent, INT& iIndex, HTREEITEM& hCheckItem)
{
	HTREEITEM hItem = GetNextItem(hParent, RVGN_CHILD);

	iIndex = 0;
	while(hItem != NULL)
	{
		RVITEM rvi;
		if(GetRadio(hItem, &rvi) == TRUE)
		{
			if(rvi.iCheck&1)
				return TRUE;
		}

		hItem = GetNextItem(hItem, RVGN_NEXT);
		iIndex++;
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::GetRadioButton(HTREEITEM hItem, BOOL& bCheck)
{
	RVITEM rvi;
	if(GetRadio(hItem, &rvi) == TRUE)
	{
		bCheck = rvi.iCheck&1 ? TRUE:FALSE;
		return TRUE;
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::SetGroupEnable(HTREEITEM hParent, BOOL bEnable)
{
	HTREEITEM hItem = GetNextItem(hParent, RVGN_CHILD);

	if(hItem == NULL)
		return FALSE;

	while(hItem != NULL)
	{
		SetGroupEnable(hItem, bEnable);
		SetCheckBoxEnable(hItem, bEnable);
		SetRadioButtonEnable(hItem, bEnable);

		hItem = GetNextItem(hItem, RVGN_NEXT);
	}

	return TRUE;
}

BOOL CReportOptionsCtrl::GetGroupEnable(HTREEITEM hParent, BOOL& bEnable)
{
	HTREEITEM hItem = GetNextItem(hParent, RVGN_CHILD);

	if(hItem == NULL)
		return FALSE;

	bEnable = TRUE;

	while(hItem != NULL && bEnable == TRUE)
	{
		GetGroupEnable(hItem, bEnable);
		if(bEnable == FALSE)
			return TRUE;

		GetCheckBoxEnable(hItem, bEnable);
		if(bEnable == FALSE)
			return TRUE;

		GetRadioButtonEnable(hItem, bEnable);
		if(bEnable == FALSE)
			return TRUE;

		hItem = GetNextItem(hItem, bEnable);
	}

	return TRUE;
}

BOOL CReportOptionsCtrl::SetCheckBoxEnable(HTREEITEM hItem, BOOL bEnable)
{
	RVITEM rvi;
	if(GetCheck(hItem, &rvi) == TRUE)
	{
		rvi.iCheck = (rvi.iCheck&~2)|(bEnable ? 0:2);
		rvi.nMask = RVIM_CHECK;
		return SetItem(&rvi);
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::GetCheckBoxEnable(HTREEITEM hItem, BOOL& bEnable)
{
	RVITEM rvi;
	if(GetCheck(hItem, &rvi) == TRUE)
	{
		bEnable = rvi.iCheck&2 ? FALSE:TRUE;
		return TRUE;
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::SetRadioButtonEnable(HTREEITEM hItem, BOOL bEnable)
{
	RVITEM rvi;
	if(GetRadio(hItem, &rvi) == TRUE)
	{
		rvi.iCheck = (rvi.iCheck&~2)|(bEnable ? 0:2);
		rvi.nMask = RVIM_CHECK;
		return SetItem(&rvi);
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::GetRadioButtonEnable(HTREEITEM hItem, BOOL& bEnable)
{
	RVITEM rvi;
	if(GetRadio(hItem, &rvi) == TRUE)
	{
		bEnable = rvi.iCheck&2 ? FALSE:TRUE;
		return TRUE;
	}

	return FALSE;
}

CString CReportOptionsCtrl::GetEditText(HTREEITEM hItem)
{
	ASSERT(IsEditable(hItem) == TRUE);

	INT iItem = GetItemIndex(hItem);
	ASSERT(iItem != RVI_INVALID);

	CString str = GetItemText(iItem, 0);

	INT iOffset = str.Find(_T(": "));
	if(iOffset >= 0)
		str.Delete(0, iOffset+2);
	else
		str.Empty();

	return str;
}

void CReportOptionsCtrl::SetEditText(HTREEITEM hItem, LPCTSTR lpszText)
{
	INT iItem = GetItemIndex(hItem);
	ASSERT(iItem != RVI_INVALID);

	UpdateText(iItem, lpszText);
}

CString CReportOptionsCtrl::GetComboText(HTREEITEM hItem)
{
	return GetEditText(hItem);
}

void CReportOptionsCtrl::SetComboText(HTREEITEM hItem, LPCTSTR lpszText)
{
	SetEditText(hItem, lpszText);
}

/////////////////////////////////////////////////////////////////////////////
// CReportOptionsCtrl operations

HTREEITEM CReportOptionsCtrl::InsertItem(UINT nID, INT iImage, HTREEITEM hParent)
{
	CString str;
	str.LoadString(nID);

	return InsertItem(str, iImage, hParent);
}

HTREEITEM CReportOptionsCtrl::InsertItem(LPCTSTR lpszItem, INT iImage, HTREEITEM hParent)
{
	return CReportCtrl::InsertItem(lpszItem, iImage, -1, -1, hParent);
}

HTREEITEM CReportOptionsCtrl::InsertGroup(UINT nID, INT iImage, HTREEITEM hParent)
{
	CString str;
	str.LoadString(nID);

	return InsertGroup(str, iImage, hParent);
}

HTREEITEM CReportOptionsCtrl::InsertGroup(LPCTSTR lpszItem, INT iImage, HTREEITEM hParent)
{
	return CReportCtrl::InsertItem(lpszItem, iImage, -1, -1, hParent);
}

HTREEITEM CReportOptionsCtrl::InsertCheckBox(UINT nID, HTREEITEM hParent, BOOL bCheck)
{
	CString str;
	str.LoadString(nID);

	return InsertCheckBox(str, hParent, bCheck);
}

HTREEITEM CReportOptionsCtrl::InsertCheckBox(LPCTSTR lpszItem, HTREEITEM hParent, BOOL bCheck)
{
	return CReportCtrl::InsertItem(lpszItem, -1, bCheck ? 1:0, -1, hParent);
}

HTREEITEM CReportOptionsCtrl::InsertRadioButton(UINT nID, HTREEITEM hParent, BOOL bCheck)
{
	CString str;
	str.LoadString(nID);

	return InsertRadioButton(str, hParent, bCheck);
}

HTREEITEM CReportOptionsCtrl::InsertRadioButton(LPCTSTR lpszItem, HTREEITEM hParent, BOOL bCheck)
{
	return CReportCtrl::InsertItem(lpszItem, -1, 4 + (bCheck ? 1:0), -1, hParent);
}

BOOL CReportOptionsCtrl::AddEditBox(HTREEITEM hItem, LPCTSTR lpszText, CRuntimeClass* lpRuntimeClass)
{
	INT iItem = VerifyText(hItem);
	if(iItem != RVI_INVALID && !GetItemData(iItem))
	{
		if(lpRuntimeClass == NULL)
			lpRuntimeClass = RUNTIME_CLASS(CReportOptionsEdit);

		if(SetItemData(iItem, (DWORD)lpRuntimeClass) == TRUE)
		{
			UpdateText(iItem, lpszText);
			return TRUE;
		}
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::AddComboBox(HTREEITEM hItem, LPCTSTR lpszText, CRuntimeClass* lpRuntimeClass)
{
	INT iItem = VerifyText(hItem);
	if(iItem != RVI_INVALID && !GetItemData(iItem))
	{
		if(lpRuntimeClass == NULL)
			lpRuntimeClass = RUNTIME_CLASS(CReportOptionsCombo);

		if(SetItemData(iItem, (DWORD)lpRuntimeClass) == TRUE)
		{
			UpdateText(iItem, lpszText);
			return TRUE;
		}
	}

	return FALSE;
}

void CReportOptionsCtrl::DeleteItem(HTREEITEM hItem)
{
	VERIFY(CReportCtrl::DeleteItem(hItem) == TRUE);
}

void CReportOptionsCtrl::SelectItem(HTREEITEM hItem)
{
	SetSelection(hItem);
}

/////////////////////////////////////////////////////////////////////////////
// CReportOptionsCtrl implementation

BOOL CReportOptionsCtrl::Create()
{
	if(CReportCtrl::Create() == TRUE)
	{
		ASSERT(m_dwStyle&RVS_TREEVIEW);
		ModifyStyle(0, RVS_SINGLESELECT|RVS_NOHEADER|RVS_NOSORT);

		CRect rect;
		GetClientRect(rect);

		RVSUBITEM rvs;
		rvs.lpszText = _T("");
		rvs.iWidth = rect.Width();
		DefineSubItem(0, &rvs);
		ActivateSubItem(0, 0);

		return TRUE;
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::CreateRuntimeClass(HTREEITEM hItem)
{
	INT iItem = GetItemIndex(hItem);
	ASSERT(iItem != RVI_INVALID);

	CFont* pFont = GetFont();
	CRuntimeClass* pRuntimeClass = (CRuntimeClass*)GetItemData(iItem);

	m_strControl = GetEditText(hItem);
	CString strItem = StripText(iItem);

	if(pRuntimeClass->IsDerivedFrom(RUNTIME_CLASS(CReportOptionsEdit)))
	{
		ASSERT(m_lpEdit == NULL);

		VERIFY(m_lpEdit = (CReportOptionsEdit*)pRuntimeClass->CreateObject());
		ASSERT(m_lpEdit->IsKindOf(RUNTIME_CLASS(CReportOptionsEdit)));

		SetItemText(iItem, 0, strItem);

		CRect rect;
		VERIFY(MeasureItem(iItem, 0, rect, TRUE));
		INT iWidth = rect.Width();
		VERIFY(GetItemRect(iItem, 0, rect, RVIR_TEXT));

		rect.left += iWidth - ::GetSystemMetrics(SM_CXEDGE)*2;
		rect.right = rect.left + m_lpEdit->GetWidth();

		m_lpEdit->m_hItem = hItem;

		m_lpEdit->CreateEx(WS_EX_CLIENTEDGE, _T("Edit"), m_strControl, m_lpEdit->GetWindowStyle(), rect, this, REPORTOPTIONSCTRL_CONTROL_ID);
		m_lpEdit->SetFont(pFont);
		m_lpEdit->SetSel(0, -1);
		m_lpEdit->SetFocus();

		m_hControl = hItem;
		return TRUE;
	}

	if(pRuntimeClass->IsDerivedFrom(RUNTIME_CLASS(CReportOptionsCombo)))
	{
		ASSERT(m_lpCombo == NULL);

		VERIFY(m_lpCombo = (CReportOptionsCombo*)pRuntimeClass->CreateObject());
		ASSERT(m_lpCombo->IsKindOf(RUNTIME_CLASS(CReportOptionsCombo)));

		SetItemText(iItem, 0, strItem);

		CRect rect;
		VERIFY(MeasureItem(iItem, 0, rect, TRUE));
		INT iWidth = rect.Width();
		VERIFY(GetItemRect(iItem, 0, rect, RVIR_TEXT));

		rect.left += iWidth - ::GetSystemMetrics(SM_CXEDGE)*2;
		rect.right = rect.left + m_lpCombo->GetWidth();
		rect.bottom += m_lpCombo->GetHeight();

		m_lpCombo->m_hItem = hItem;

		m_lpCombo->Create(m_lpCombo->GetWindowStyle(), rect, this, REPORTOPTIONSCTRL_CONTROL_ID);
		m_lpCombo->SetFont(pFont);
		m_lpCombo->SelectString(-1, m_strControl);
		m_lpCombo->SetFocus();

		m_hControl = hItem;
		return TRUE;
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::DeleteRuntimeClass(BOOL bUpdateFromControl, BOOL bNotify)
{
	if(m_hControl == NULL)
		return FALSE;

	HTREEITEM hParent = GetNextItem(m_hControl, RVGN_PARENT);

	if(m_lpEdit != NULL)
	{
		ASSERT(m_hControl != NULL);

		if(bUpdateFromControl == TRUE)
		{
			m_lpEdit->GetWindowText(m_strControl);
			NotifyParent(ROCN_ITEMCHANGED, hParent, m_hControl, -1);
		}

		m_lpEdit->m_bIgnoreLostFocus = TRUE;
		m_lpEdit->DestroyWindow();
		delete m_lpEdit;
		m_lpEdit = NULL;

		INT iItem = GetItemIndex(m_hControl);
		ASSERT(iItem != RVI_INVALID);

		UpdateText(iItem, m_strControl);

		m_hControl = NULL;
		return TRUE;
	}
	else if(m_lpCombo != NULL)
	{
		ASSERT(m_hControl != NULL);

		if(bUpdateFromControl == TRUE)
		{
			m_lpCombo->GetWindowText(m_strControl);
			NotifyParent(ROCN_ITEMCHANGED, hParent, m_hControl, -1);
		}

		m_lpCombo->m_bIgnoreLostFocus = TRUE;
		m_lpCombo->DestroyWindow();
		delete m_lpCombo;
		m_lpCombo= NULL;

		INT iItem = GetItemIndex(m_hControl);
		ASSERT(iItem != RVI_INVALID);

		UpdateText(iItem, m_strControl);

		m_hControl = NULL;
		return TRUE;
	}

	return FALSE;
}

BOOL CReportOptionsCtrl::GetCheck(HTREEITEM hItem, LPRVITEM lprvi)
{
	VERIFY((lprvi->iItem = GetItemIndex(hItem)) != RVI_INVALID);
	lprvi->iSubItem = 0;

	if(GetItem(lprvi) == TRUE && lprvi->iCheck >= 0 && lprvi->iCheck <= 3)
		return TRUE;

	return FALSE;
}

BOOL CReportOptionsCtrl::GetRadio(HTREEITEM hItem, LPRVITEM lprvi)
{
	VERIFY((lprvi->iItem = GetItemIndex(hItem)) != RVI_INVALID);
	lprvi->iSubItem = 0;

	if(GetItem(lprvi) == TRUE && lprvi->iCheck >= 4 && lprvi->iCheck <= 7)
		return TRUE;

	return FALSE;
}

INT CReportOptionsCtrl::VerifyText(HTREEITEM hItem)
{
	TCHAR sz[REPORTCTRL_MAX_TEXT];

	RVITEM rvi;
	rvi.iItem = GetItemIndex(hItem);
	rvi.iSubItem = 0;
	rvi.lpszText = sz;
	rvi.iTextMax = REPORTCTRL_MAX_TEXT;
	rvi.nMask = RVIM_TEXT;
	if(GetItem(&rvi) == TRUE && rvi.nMask&RVIM_TEXT)
	{
		if(_tcschr(sz, _T(':')) == NULL)
			return rvi.iItem;
	}

	return RVI_INVALID;
}

void CReportOptionsCtrl::UpdateText(INT iItem, LPCTSTR lpszText)
{
	CString str = StripText(iItem);
	str += _T(": ");
	str += lpszText;
	VERIFY(SetItemText(iItem, 0, str));
}

CString CReportOptionsCtrl::StripText(INT iItem)
{
	CString str = GetItemText(iItem, 0);
	INT iOffset = str.Find(_T(": "));
	if(iOffset >= 0)
		str.Delete(iOffset, str.GetLength() - iOffset);

	return str;
}

BOOL CReportOptionsCtrl::Notify(LPNMREPORTVIEW lpnmrv)
{
	switch(lpnmrv->hdr.code)
	{
	case RVN_ITEMCLICK:
		if(lpnmrv->iItem >= RVI_FIRST)
		{
			DeleteRuntimeClass(FALSE, FALSE);

			HTREEITEM hItem = lpnmrv->hItem;
			HTREEITEM hParent = GetNextItem(hItem, RVGN_PARENT);

			if(IsCheckBox(hItem))
			{
				BOOL bCheck;
				if(GetCheckBox(hItem, bCheck) == TRUE)
				{
					ASSERT(hParent != NULL);
					if(IsDisabled(hItem) == FALSE && SetCheckBox(hItem, !bCheck) == TRUE)
						NotifyParent(ROCN_CHECKCHANGED, hParent, hItem, !bCheck);
				}
			}
			else if(IsRadioButton(hItem))
			{
				ASSERT(hParent != NULL);
				if(IsDisabled(hItem) == FALSE && SetRadioButton(hItem) == TRUE)
				{
					INT iIndex;
					GetRadioButton(hParent, iIndex, hItem);
					NotifyParent(ROCN_RADIOCHANGED, hParent, hItem, iIndex);
				}
			}
		}
		break;

	case RVN_ITEMDBCLICK:
		if(lpnmrv->iItem >= RVI_FIRST)
		{
			if(IsEditable(lpnmrv->hItem))
			{
				CreateRuntimeClass(lpnmrv->hItem);
			}
		}
		break;

	case RVN_KEYDOWN:
		break;

	default:
		DeleteRuntimeClass(FALSE, FALSE);
		break;
	}

	return CReportCtrl::Notify(lpnmrv);
}

BOOL CReportOptionsCtrl::NotifyParent(UINT nCode, HTREEITEM hParent, HTREEITEM hChild, INT iIndex)
{
	BOOL bResult = FALSE;

	NMREPORTOPTIONCTRL nmroc;
	nmroc.hdr.hwndFrom = GetSafeHwnd();
	nmroc.hdr.idFrom = GetDlgCtrlID();
	nmroc.hdr.code = nCode;

	nmroc.hParent = hParent;
	nmroc.hChild = hChild;
	nmroc.iIndex = iIndex;

	CWnd* pWnd = GetParent();
	if(pWnd != NULL)
		bResult = pWnd->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmroc);

	return bResult;
}

/////////////////////////////////////////////////////////////////////////////
// CReportOptionsCtrl messages

void CReportOptionsCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if(nChar == VK_SPACE)
	{
		DeleteRuntimeClass(FALSE, FALSE);

		INT iItem = GetItemFromRow(GetCurrentFocus());
		if(iItem >= RVI_FIRST)
		{
			HTREEITEM hItem = GetItemHandle(iItem);
			HTREEITEM hParent = GetNextItem(hItem, RVGN_PARENT);

			if(IsEditable(hItem))
			{
				CreateRuntimeClass(hItem);
			}
			else if(IsCheckBox(hItem))
			{
				BOOL bCheck;
				if(GetCheckBox(hItem, bCheck) == TRUE)
				{
					ASSERT(hParent != NULL);
					if(IsDisabled(hItem) == FALSE && SetCheckBox(hItem, !bCheck) == TRUE)
						NotifyParent(ROCN_CHECKCHANGED, hParent, hItem, !bCheck);
				}
			}
			else if(IsRadioButton(hItem))
			{
				ASSERT(hParent != NULL);
				if(IsDisabled(hItem) == FALSE && SetRadioButton(hItem) == TRUE)
				{
					INT iIndex;
					GetRadioButton(hParent, iIndex, hItem);
					NotifyParent(ROCN_RADIOCHANGED, hParent, hItem, iIndex);
				}
			}
		}
	}
	
	CReportCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}

LRESULT CReportOptionsCtrl::OnCloseControl(WPARAM wParam, LPARAM lParam)
{
	if(m_hControl != NULL)
		DeleteRuntimeClass(wParam == VK_ESCAPE ? FALSE:TRUE, TRUE);

	return 0;
}

void CReportOptionsCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	DeleteRuntimeClass(FALSE, FALSE);

	CReportCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CReportOptionsCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	DeleteRuntimeClass(FALSE, FALSE);
	
	CReportCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}

/////////////////////////////////////////////////////////////////////////////
// CReportOptionsEdit

IMPLEMENT_DYNCREATE(CReportOptionsEdit, CEdit)

CReportOptionsEdit::CReportOptionsEdit()
{
	m_bIgnoreLostFocus = FALSE;
}

CReportOptionsEdit::~CReportOptionsEdit()
{
}


BEGIN_MESSAGE_MAP(CReportOptionsEdit, CEdit)
	//{{AFX_MSG_MAP(CReportOptionsEdit)
	ON_WM_KILLFOCUS()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReportOptionsEdit message handlers

BOOL CReportOptionsEdit::PreTranslateMessage(MSG* pMsg) 
{
	if(pMsg->message == WM_KEYDOWN &&
	   (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
	) {
		CReportOptionsCtrl* pWnd = DYNAMIC_DOWNCAST(CReportOptionsCtrl, GetParent());
		ASSERT(pWnd != NULL);

		pWnd->SendMessage(WM_USER, pMsg->wParam, (LPARAM)m_hWnd);
		return TRUE;
	}

	return CEdit::PreTranslateMessage(pMsg);
}

void CReportOptionsEdit::OnKillFocus(CWnd* pNewWnd) 
{
	if(m_bIgnoreLostFocus == FALSE)
	{
		CReportOptionsCtrl* pWnd = DYNAMIC_DOWNCAST(CReportOptionsCtrl, GetParent());
		ASSERT(pWnd != NULL);

		pWnd->SendMessage(WM_USER, 0, (LPARAM)m_hWnd);
	}

	m_bIgnoreLostFocus = FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// CReportOptionsCombo

IMPLEMENT_DYNCREATE(CReportOptionsCombo, CComboBox)

CReportOptionsCombo::CReportOptionsCombo()
{
	m_bIgnoreLostFocus = FALSE;
}

CReportOptionsCombo::~CReportOptionsCombo()
{
}


BEGIN_MESSAGE_MAP(CReportOptionsCombo, CComboBox)
	//{{AFX_MSG_MAP(CReportOptionsCombo)
	ON_WM_KILLFOCUS()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReportOptionsCombo message handlers

BOOL CReportOptionsCombo::PreTranslateMessage(MSG* pMsg) 
{
	if(pMsg->message == WM_KEYDOWN &&
	   (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
	) {
		CReportOptionsCtrl* pWnd = DYNAMIC_DOWNCAST(CReportOptionsCtrl, GetParent());
		ASSERT(pWnd != NULL);

		pWnd->SendMessage(WM_USER, pMsg->wParam, (LPARAM)m_hWnd);
		return TRUE;
	}
	
	return CComboBox::PreTranslateMessage(pMsg);
}

void CReportOptionsCombo::OnKillFocus(CWnd* pNewWnd) 
{
	if(m_bIgnoreLostFocus == FALSE)
	{
		CReportOptionsCtrl* pWnd = DYNAMIC_DOWNCAST(CReportOptionsCtrl, GetParent());
		ASSERT(pWnd != NULL);

		pWnd->SendMessage(WM_USER, 0, (LPARAM)m_hWnd);
	}

	m_bIgnoreLostFocus = FALSE;
}

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
Web Developer
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions