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

SolidGraph CAD System

Rate me:
Please Sign up or sign in to vote.
4.97/5 (78 votes)
12 Sep 20062 min read 376.1K   29.8K   209  
A SolidGraph CAD system source code.
// COptionTree
//
// License
// -------
// This code is provided "as is" with no expressed or implied warranty.
// 
// You may use this code in a commercial product with or without acknowledgement.
// However you may not sell this code or any modification of this code, this includes 
// commercial libraries and anything else for profit.
//
// I would appreciate a notification of any bugs or bug fixes to help the control grow.
//
// History:
// --------
//	See License.txt for full history information.
//
//
// Copyright (c) 1999-2002 
// ComputerSmarts.net 
// mattrmiller@computersmarts.net

#include "stdafx.h"
#include "OptionTreeRadioButton.h"


// Added Headers
#include "OptionTree.h"

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

/////////////////////////////////////////////////////////////////////////////
// COptionTreeRadioButton

COptionTreeRadioButton::COptionTreeRadioButton()
{
	// Initialize variables
	m_nAllNodes = NULL;
	m_otRadioOption = NULL;
}

COptionTreeRadioButton::~COptionTreeRadioButton()
{
	// Delete all nodes
	Node_DeleteAll();
}


BEGIN_MESSAGE_MAP(COptionTreeRadioButton, CWnd)
	//{{AFX_MSG_MAP(COptionTreeRadioButton)
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	ON_WM_LBUTTONUP()
	ON_WM_MOVE()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// COptionTreeRadioButton message handlers

void COptionTreeRadioButton::Node_Insert(CString strText, BOOL bChecked)
{
	// Declare variables
	OT_RADIO_NODE *NewNode = new OT_RADIO_NODE;

	// Set up the New Node structure
	NewNode->m_bChecked = bChecked;
	NewNode->m_strText = strText;
	NewNode->m_rcHitRect = CRect(0, 0, 0, 0);
	NewNode->m_nNextNode = NULL;

	// Add new node to list
	// -- Do have any other node?
	if (m_nAllNodes == NULL)
	{
		m_nAllNodes = NewNode;
		return;
	}

	// -- Find the end of the list to add the new node to
	OT_RADIO_NODE *curr = m_nAllNodes;
	OT_RADIO_NODE *last = NULL;
	while (curr != NULL)
	{
		// -- -- Save this node
		last = curr;

		// -- -- Follow the link to the next node
		curr = curr->m_nNextNode;
	}

	// -- Link the new nod to the place we found
	last->m_nNextNode = NewNode;
}

void COptionTreeRadioButton::Node_DeleteAll()
{
	// Do have any other results
	if (m_nAllNodes == NULL)
	{
		return;
	}

	
	// Declare variables
	OT_RADIO_NODE *curr = m_nAllNodes;
	OT_RADIO_NODE *last = NULL;
	
	// Check to see if we have only 1
	if (m_nAllNodes->m_nNextNode == NULL)
	{
		// -- Delete m_AllResults (head)
		curr = m_nAllNodes;
		delete curr;
		m_nAllNodes = NULL;

		return;
	}
	

	// Find the end of the list to add the new result to
	while (curr->m_nNextNode != NULL)
	{
		// -- Save this node
		last = curr;

		// -- Follow the link to the next node
		curr = curr->m_nNextNode;
	}

	// Delete this node and set last->m_nNextNode to NULL
	delete curr;
	last->m_nNextNode = NULL;

	// Check to see if we are at second to beginning
	if (m_nAllNodes->m_nNextNode == last)
	{
		// -- Delete last (which is second to head)
		delete last;

		// -- Delete m_AllResults (head)
		curr = m_nAllNodes;
		delete curr;
		m_nAllNodes = NULL;

	}

	// Call this again
	Node_DeleteAll();
}

OT_RADIO_NODE * COptionTreeRadioButton::Node_FindNode(int nIndex)
{
	// Declare variables
	int i = 0;

	// Cycle through all of the nodes
	OT_RADIO_NODE *curr = m_nAllNodes;
	while (curr != NULL)
	{		
		// -- See if this is us
		if (i == nIndex)
		{			
			return curr;
		}

		// -- Follow the link to the next node
		curr = curr->m_nNextNode;

		// -- Increase i
		i++;
	}

	return NULL;
}

OT_RADIO_NODE *COptionTreeRadioButton::Node_FindNode(CString strText)
{
	// Cycle through all of the nodes
	OT_RADIO_NODE *curr = m_nAllNodes;
	while (curr != NULL)
	{		
		// -- See if this is us
		if (curr->m_strText == strText)
		{			
			return curr;
		}

		// -- Follow the link to the next node
		curr = curr->m_nNextNode;
	}

	return NULL;
}

BOOL COptionTreeRadioButton::OnEraseBkgnd(CDC* pDC) 
{
	// Naa, we like flicker free better
	return FALSE;
}

void COptionTreeRadioButton::OnPaint() 
{
	// Make sure options aren't NULL
	if (m_otRadioOption == NULL)
	{
		return;
	}

	// Declare variables
	CPaintDC dc(this);
	CDC* pDCMem = new CDC;
	CBitmap bpMem;
	CBitmap *bmOld;
	HGDIOBJ hOldBrush;
	int nOldBack;
	CRect rcText, rcRadio, rcClient;
	HGDIOBJ hOld;
	OT_RADIO_NODE *nNode = NULL;
	int nIndex = 0;
	long lLastRadio = 0;
	COLORREF crOld;

	// Get client rectangle
	GetClientRect(rcClient);

	// Create DC
	pDCMem->CreateCompatibleDC(&dc);
	
	// Create bitmap
	bpMem.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());

	// Select bitmap
	bmOld = pDCMem->SelectObject(&bpMem);

	// Set background mode
	nOldBack = pDCMem->SetBkMode(TRANSPARENT);

	// Set text color
	crOld = pDCMem->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));

	// Select font
	hOld = pDCMem->SelectObject(m_otRadioOption->GetNormalFont());

	// Draw control background
	if (m_otRadioOption->IsWindowEnabled() == FALSE)
	{
		hOldBrush = pDCMem->SelectObject(GetSysColorBrush(COLOR_BTNFACE));
	}
	else
	{
		hOldBrush = pDCMem->SelectObject(GetSysColorBrush(COLOR_WINDOW));
	}
	pDCMem->PatBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), PATCOPY);

	// Calculate radio rect
	rcRadio.left = rcClient.left;
	rcRadio.right = rcClient.left + (long) OT_RADIO_SIZE;

	// Go through and draw all nodes
	nNode = Node_FindNode(nIndex);
	while (nNode != NULL)
	{
		// -- Calculate radio rect
		rcRadio.top = lLastRadio + OT_RADIO_VSPACE;
		rcRadio.bottom = rcRadio.top + (long) OT_RADIO_SIZE;

		// -- Calculate text rect
		rcText.top = lLastRadio + OT_RADIO_VSPACE;
		rcText.bottom = rcRadio.top + (long) OT_RADIO_SIZE;
		rcText.left = rcRadio.right + OT_SPACE;
		rcText.right = rcClient.right;

		// -- Save last radio
		lLastRadio = rcRadio.bottom;

		// -- Draw the radio
		if (nNode->m_bChecked == TRUE)
		{
			pDCMem->DrawFrameControl(&rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO | DFCS_CHECKED);
		}
		else
		{
			pDCMem->DrawFrameControl(&rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO);
		}

		// -- Draw text
		pDCMem->DrawText(nNode->m_strText, rcText, DT_SINGLELINE | DT_VCENTER);
		pDCMem->DrawText(nNode->m_strText, rcText, DT_SINGLELINE | DT_VCENTER | DT_CALCRECT);

		// -- Set hit test rect
		nNode->m_rcHitRect.left = rcRadio.left;
		nNode->m_rcHitRect.top = rcRadio.top;
		nNode->m_rcHitRect.bottom = rcRadio.bottom;
		nNode->m_rcHitRect.right = rcText.right;

		// -- Increase index
		nIndex++;

		// -- Get next node
		nNode = Node_FindNode(nIndex);
	}

	// Copy to screen
	dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDCMem, 0, 0, SRCCOPY);

	// Restore GDI ojects
	pDCMem->SelectObject(bmOld);
	pDCMem->SelectObject(hOldBrush);
	pDCMem->SetBkMode(nOldBack);
	pDCMem->SelectObject(hOld);
	pDCMem->SetTextColor(crOld);

	// Delete objects
	if (pDCMem->GetSafeHdc() != NULL)
	{
		pDCMem->DeleteDC();
	}
	delete pDCMem;
	if (bpMem.GetSafeHandle() != NULL)
	{
		bpMem.DeleteObject();
	}

}

void COptionTreeRadioButton::SetRadioOptionsOwner(COptionTree *otOption)
{
	// Save pointer
	m_otRadioOption = otOption;
}

void COptionTreeRadioButton::Node_UnCheckAll()
{
	// Cycle through all of the nodes
	OT_RADIO_NODE *curr = m_nAllNodes;
	while (curr != NULL)
	{
		// -- Un Check
		curr->m_bChecked = FALSE;

		// -- Follow the link to the next node
		curr = curr->m_nNextNode;
	}
}

void COptionTreeRadioButton::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// Run a hit test on all radios
	OT_RADIO_NODE *curr = m_nAllNodes;
	while (curr != NULL)
	{
		// -- See if checked
		if (curr->m_rcHitRect.PtInRect(point) == TRUE)
		{
			// -- -- Uncheck all
			Node_UnCheckAll();

			// -- -- Check this radio
			curr->m_bChecked = TRUE;

			// -- -- Force redaw
			Invalidate();

			// -- -- Update window
			UpdateWindow();

			break;
		}

		// -- Follow the link to the next node
		curr = curr->m_nNextNode;
	}
	
	CWnd::OnLButtonUp(nFlags, point);
}

void COptionTreeRadioButton::OnMove(int x, int y) 
{
	CWnd::OnMove(x, y);
	
	// TODO: Add your message handler code here
	
}

void COptionTreeRadioButton::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	
}

int COptionTreeRadioButton::Node_GetChecked()
{
	// Declare variables
	int i = 0;

	// Cycle through all of the nodes
	OT_RADIO_NODE *curr = m_nAllNodes;
	while (curr != NULL)
	{		
		// -- See if this is us
		if (curr->m_bChecked == TRUE)
		{			
			return i;
		}

		// -- Follow the link to the next node
		curr = curr->m_nNextNode;

		// -- Increase i
		i++;
	}

	return -1;
}

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

Comments and Discussions