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