/*******************************************************************************
Author : Aravindan Premkumar
Unregistered Copyright 2003 : Aravindan Premkumar
All Rights Reserved
This piece of code does not have any registered copyright and is free to be
used as necessary. The user is free to modify as per the requirements. As a
fellow developer, all that I expect and request for is to be given the
credit for intially developing this reusable code by not removing my name as
the author.
*******************************************************************************/
#include "stdafx.h"
#include "ComboListCtrl.h"
#include "InPlaceCombo.h"
#include "InPlaceEdit.h"
#include "resourceppc.h"
#include "QualityDetailDlg.h"
#include "DyrkDetailDlg.h"
#include "WeightDetailDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//#defines
#define FIRST_COLUMN 0
#define MIN_COLUMN_WIDTH 10
#define MAX_DROP_DOWN_ITEM_COUNT 10
/////////////////////////////////////////////////////////////////////////////
// CComboListCtrl
CComboListCtrl::CComboListCtrl()
{
m_ComboSupportColumnsList.RemoveAll();
m_ReadOnlyColumnsList.RemoveAll();
m_strValidEditCtrlChars.Empty();
m_dwEditCtrlStyle = ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_LEFT | ES_NOHIDESEL;
m_dwDropDownCtrlStyle = WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL;
}
CComboListCtrl::~CComboListCtrl()
{
CInPlaceCombo::DeleteInstance();
CInPlaceEdit::DeleteInstance();
}
BEGIN_MESSAGE_MAP(CComboListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CComboListCtrl)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_LBUTTONDOWN()
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndLabelEdit)
ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginLabelEdit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CComboListCtrl message handlers
CInPlaceCombo* CComboListCtrl::ShowInPlaceList(int iRowIndex, int iColumnIndex, CStringList& rComboItemsList,
CString strCurSelecetion /*= ""*/, int iSel /*= -1*/)
{
// The returned obPointer should not be saved
// Make sure that the item is visible
if (!EnsureVisible(iRowIndex, TRUE))
{
return NULL;
}
// Make sure that iColumnIndex is valid
CHeaderCtrl* pHeader = static_cast<CHeaderCtrl*> (GetDlgItem(FIRST_COLUMN));
int iColumnCount = pHeader->GetItemCount();
if (iColumnIndex >= iColumnCount || GetColumnWidth(iColumnIndex) < MIN_COLUMN_WIDTH)
{
return NULL;
}
// Calculate the rectangle specifications for the combo box
CRect obCellRect(0, 0, 0, 0);
CalculateCellRect(iColumnIndex, iRowIndex, obCellRect);
int iHeight = obCellRect.Height();
int iCount = rComboItemsList.GetCount();
iCount = (iCount < MAX_DROP_DOWN_ITEM_COUNT) ?
iCount + MAX_DROP_DOWN_ITEM_COUNT : (MAX_DROP_DOWN_ITEM_COUNT + 1);
obCellRect.bottom += iHeight * iCount;
// Create the in place combobox
CInPlaceCombo* pInPlaceCombo = CInPlaceCombo::GetInstance();
pInPlaceCombo->ShowComboCtrl(m_dwDropDownCtrlStyle, obCellRect, this, 0, iRowIndex, iColumnIndex, &rComboItemsList,
strCurSelecetion, iSel);
return pInPlaceCombo;
}
CInPlaceEdit* CComboListCtrl::ShowInPlaceEdit(int iRowIndex, int iColumnIndex, CString& rstrCurSelection)
{
// Create an in-place edit control
CInPlaceEdit* pInPlaceEdit = CInPlaceEdit::GetInstance();
CRect obCellRect(0, 0, 0, 0);
CalculateCellRect(iColumnIndex, iRowIndex, obCellRect);
pInPlaceEdit->ShowEditCtrl(m_dwEditCtrlStyle, obCellRect, this, 0,
iRowIndex, iColumnIndex,
m_strValidEditCtrlChars, rstrCurSelection);
return pInPlaceEdit;
}
void CComboListCtrl::OnHScroll(UINT iSBCode, UINT iPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
if (GetFocus() != this)
{
SetFocus();
}
CListCtrl::OnHScroll(iSBCode, iPos, pScrollBar);
}
void CComboListCtrl::OnVScroll(UINT iSBCode, UINT iPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
if (GetFocus() != this)
{
SetFocus();
}
CListCtrl::OnVScroll(iSBCode, iPos, pScrollBar);
}
void CComboListCtrl::OnLButtonDown(UINT iFlags, CPoint obPoint)
{
int iColumnIndex = -1;
int iRowIndex = -1;
// Get the current column and row
if (!HitTestEx(obPoint, &iRowIndex, &iColumnIndex))
{
return;
}
CListCtrl::OnLButtonDown(iFlags, obPoint);
// If column is not read only then
// If the SHIFT or CTRL key is down call the base class
// Check the high bit of GetKeyState to determine whether SHIFT or CTRL key is down
if ((GetKeyState(VK_SHIFT) & 0x80) || (GetKeyState(VK_CONTROL) & 0x80)) //(iColumnIndex==0) ||
{
OnKillFocus(GetParent());
return;
}
// Get the current selection before creating the in place combo box
CString strCurSelection = GetItemText(iRowIndex,iColumnIndex); //iColumnIndex
if (-1 != iRowIndex)
{
UINT flag = LVIS_FOCUSED;
if ((GetItemState(iRowIndex, flag ) & flag) == flag)
{
// Add check for LVS_EDITLABELS
if (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_EDITLABELS)
{
EnableVScroll();
//items要添加的项
//如第三列变成ComboBox
if (iColumnIndex == 3)
{
CStringList obComboItemsList;
obComboItemsList.AddTail("A");
obComboItemsList.AddTail("B");
obComboItemsList.AddTail("C");
CInPlaceCombo* pInPlaceComboBox = ShowInPlaceList(iRowIndex, iColumnIndex, obComboItemsList, strCurSelection);
ASSERT(pInPlaceComboBox);
// Set the selection to previous selection
pInPlaceComboBox->SelectString(-1, strCurSelection);
}
//else if (iColumnIndex == 4)
//CInPlaceEdit* pInPlaceEdit = ShowInPlaceEdit(iRowIndex, iColumnIndex, strCurSelection);
}
}
}
}
bool CComboListCtrl::HitTestEx(CPoint &obPoint, int* pRowIndex, int* pColumnIndex) const
{
if (!pRowIndex || !pColumnIndex)
{
return false;
}
// Get the row index
*pRowIndex = HitTest(obPoint, NULL);
if (pColumnIndex)
{
*pColumnIndex = 0;
}
// Make sure that the ListView is in LVS_REPORT
if ((GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
{
return false;
}
// Get the number of columns
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
int iColumnCount = pHeader->GetItemCount();
// Get bounding rect of item and check whether obPoint falls in it.
CRect obCellRect;
GetItemRect(*pRowIndex, &obCellRect, LVIR_BOUNDS);
if (obCellRect.PtInRect(obPoint))
{
// Now find the column
for (*pColumnIndex = 0; *pColumnIndex < iColumnCount; (*pColumnIndex)++)
{
int iColWidth = GetColumnWidth(*pColumnIndex);
if (obPoint.x >= obCellRect.left && obPoint.x <= (obCellRect.left + iColWidth))
{
return true;
}
obCellRect.left += iColWidth;
}
}
return false;
}
void CComboListCtrl::CalculateCellRect(int iColumnIndex, int iRowIndex, CRect& robCellRect)
{
GetItemRect(iRowIndex, &robCellRect, LVIR_BOUNDS);
CRect rcClient;
GetClientRect(&rcClient);
if (robCellRect.right > rcClient.right)
{
robCellRect.right = rcClient.right;
}
ScrollToView(iColumnIndex, robCellRect);
}
void CComboListCtrl::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*) pNMHDR;
if (pDispInfo->item.iSubItem != 0)
{
CString strEdit = pDispInfo->item.pszText;
SetItemText(pDispInfo->item.iItem, pDispInfo->item.iSubItem, strEdit);
}
*pResult = 0;
}
void CComboListCtrl::SetValidEditCtrlCharacters(CString &rstrValidCharacters)
{
m_strValidEditCtrlChars = rstrValidCharacters;
}
void CComboListCtrl::EnableHScroll(bool bEnable /*= true*/