Click here to Skip to main content
15,881,852 members
Articles / Desktop Programming / MFC

The Diffraction Grating Calculator

Rate me:
Please Sign up or sign in to vote.
4.40/5 (5 votes)
30 Oct 2010GPL38 min read 41.3K   678   6  
An MFC Windows program related to Concave Diffraction Gratings using VTK libraries.
// GridCellCombo.cpp: implementation of the CGridCellCombo class.
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "GridCtrl.h"
#include "GridCellCombo.h"

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

IMPLEMENT_DYNCREATE(CGridCellCombo, CGridCell)

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

CGridCellCombo::CGridCellCombo()
:CGridCell(), m_cmbStringList(0)
{
	m_dwStyle = CBS_DROPDOWNLIST;
}

CGridCellCombo::CGridCellCombo(DWORD dwStyle) 
:CGridCell(), m_cmbStringList(0)
{
	Init(dwStyle);
}

CGridCellCombo::~CGridCellCombo()
{
	int nCount = m_cmbStringList.GetObjectCount();
	for(int i = 0; i < nCount; i++)
	{
		delete (CString*) m_cmbStringList.GetObjectByIdx(0);
		m_cmbStringList.DeleteObjectIdx(0);
	}
}

int CGridCellCombo::AddString(CString sText)
{
	CString *psTmp = new CString(sText);
	if(!psTmp)
		throw;

	return m_cmbStringList.AddObject(psTmp);
}

BOOL CGridCellCombo::Edit(int nRow, int nCol, CRect rect, CPoint /* point */, 
							 UINT nID, UINT nChar)
{
	m_bEditing = TRUE;

	// CInPlaceCombo auto-deletes itself
	m_pEditWnd = new CInPlaceCombo(GetGrid(), rect,
		m_dwStyle|DTS_UPDOWN, nID, nRow, nCol, 
		GetTextClr(), GetBackClr(), GetText(), nChar, &m_cmbStringList);

	return TRUE;
}

CWnd* CGridCellCombo::GetEditWnd() const
{
	return m_pEditWnd;
}

void CGridCellCombo::EndEdit()
{
	if (m_pEditWnd) 
		((CInPlaceCombo*)m_pEditWnd)->EndEdit();
}


/////////////////////////////////////////////////////////////////////////////
// CInPlaceDateTime

CInPlaceCombo::CInPlaceCombo(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
								   int nRow, int nColumn, 
								   COLORREF crFore, COLORREF crBack,
								   CString sText,
								   UINT nFirstChar,
								   CObjectList* pList)
{
	int nCount = pList->GetObjectCount();

	CRect cmbRect;
	cmbRect.left = rect.left;
	cmbRect.top = rect.top;
	cmbRect.right = rect.right;
	cmbRect.bottom = rect.top + (min(nCount, 10) + 2) * rect.Height(); 
	
	m_crForeClr     = crFore;
	m_crBackClr     = crBack;
	m_nRow          = nRow;
	m_nCol          = nColumn;
	m_nLastChar     = 0; 
	m_bExitOnArrows = FALSE;
	m_sText        = sText;

	DWORD dwStl = WS_CHILD|WS_VISIBLE|WS_VSCROLL|dwStyle;

	if (!Create(dwStl, cmbRect, pParent, nID)) 
		return;

	SetFont(pParent->GetFont());
	SetFocus();

	CString* psTmp = NULL;
	for(int i = 0; i < nCount; i++)
	{
		psTmp = (CString*) pList->GetObjectByIdx(i);
		if(psTmp)
			AddString(*psTmp);
	}

	SetCurSel(FindStringExact(0, sText));

	switch (nFirstChar) 
	{
		case VK_LBUTTON: 
		case VK_RETURN: return;
		case VK_BACK:   break;
		case VK_DOWN: 
		case VK_UP:   
		case VK_RIGHT:
		case VK_LEFT:  
		case VK_NEXT:  
		case VK_PRIOR: 
		case VK_HOME:  
		case VK_END:    return;
		default:        break;
	}
	SendMessage(WM_CHAR, nFirstChar);
}

CInPlaceCombo::~CInPlaceCombo()
{
}

void CInPlaceCombo::EndEdit()
{
	CString str;
	if (::IsWindow(m_hWnd)) 
		GetWindowText(str);

	// Send Notification to parent
	GV_DISPINFO dispinfo;

	dispinfo.hdr.hwndFrom = GetSafeHwnd();
	dispinfo.hdr.idFrom   = GetDlgCtrlID();
	dispinfo.hdr.code     = GVN_ENDLABELEDIT;

	dispinfo.item.mask    = LVIF_TEXT|LVIF_PARAM;
	dispinfo.item.row     = m_nRow;
	dispinfo.item.col     = m_nCol;
	dispinfo.item.strText = str;
	dispinfo.item.lParam  = (LPARAM) m_nLastChar; 

	CWnd* pOwner = GetOwner();
	if (IsWindow(pOwner->GetSafeHwnd())) {
		pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
	}

	// Close this window (PostNcDestroy will delete this)
	if (::IsWindow(m_hWnd)) {
		PostMessage(WM_CLOSE, 0, 0);
	}
}

void CInPlaceCombo::PostNcDestroy() 
{
	CComboBox::PostNcDestroy();
	delete this;
}

BEGIN_MESSAGE_MAP(CInPlaceCombo, CComboBox)
	//{{AFX_MSG_MAP(CInPlaceDateTime)
	ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelChange)
	ON_WM_KILLFOCUS()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_GETDLGCODE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CInPlaceDateTime message handlers
void CInPlaceCombo::OnSelChange()
{
	EndEdit();
}

void CInPlaceCombo::OnKillFocus(CWnd* pNewWnd) 
{
	CComboBox::OnKillFocus(pNewWnd);

	if (GetSafeHwnd() == pNewWnd->GetSafeHwnd()) {
		return;
	}
	EndEdit();
}

UINT CInPlaceCombo::OnGetDlgCode() 
{
	return DLGC_WANTALLKEYS;
}

void CInPlaceCombo::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if (( nChar == VK_PRIOR || nChar == VK_NEXT ||
		nChar == VK_DOWN  || nChar == VK_UP   ||
		nChar == VK_RIGHT || nChar == VK_LEFT) &&
		(m_bExitOnArrows  || GetKeyState(VK_CONTROL) < 0))
	{
		m_nLastChar = nChar;
		GetParent()->SetFocus();
		return;
	}

	CComboBox::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CInPlaceCombo::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
	{
		m_nLastChar = nChar;
		GetParent()->SetFocus();    // This will destroy this window
		return;
	}

	CComboBox::OnKeyUp(nChar, nRepCnt, nFlags);
}

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, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer (Senior)
Italy Italy
Senior Software Developer in C/C++ and Oracle.
Ex-physicist holding a Ph.D. on x-ray lasers.

Comments and Discussions