?? mycombolistctrl.cpp
?? 一個(gè)非常好的WINCE界面
?? CPP
字號(hào):
??
//MyComboListCtrl.cpp
#include "stdafx.h"
#include "MyComboListCtrl.h"
#include "InPlaceCombo.h"
#include "InPlaceEdit.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
/////////////////////////////////////////////////////////////////////////////
// CMyComboListCtrl
CMyComboListCtrl::CMyComboListCtrl()
{
m_iColumnCounts = 0;
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;
}
CMyComboListCtrl::~CMyComboListCtrl()
{
CInPlaceCombo::DeleteInstance();
CInPlaceEdit::DeleteInstance();
}
BEGIN_MESSAGE_MAP(CMyComboListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CMyComboListCtrl)
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()
/////////////////////////////////////////////////////////////////////////////
// CMyComboListCtrl message handlers
CInPlaceCombo* CMyComboListCtrl::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 = (int )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* CMyComboListCtrl::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_strValidChars[iColumnIndex], rstrCurSelection);
return pInPlaceEdit;
}
void CMyComboListCtrl::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 CMyComboListCtrl::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 CMyComboListCtrl::OnLButtonDown(UINT iFlags, CPoint obPoint)
{
// TODO: Add your message handler code here and/or call default
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))
{
return;
}
// Get the current selection before creating the in place combo box
CString strCurSelection = GetItemText(iRowIndex, iColumnIndex);
if (-1 != iRowIndex)
{
UINT flag = LVIS_FOCUSED;
if ((GetItemState(iRowIndex, flag ) & flag) == flag)
{
// Add check for LVS_EDITLABELS
if (GetWindowLong(m_hWnd, GWL_EXSTYLE) & LVS_EDITLABELS)
{
// If combo box is supported
// Create and show the in place combo box
if (IsCombo(iColumnIndex))
{
CStringList obComboItemsList;
GetParent()->SendMessage(WM_SET_ITEMS, (WPARAM)iColumnIndex,
(LPARAM)&obComboItemsList);
CInPlaceCombo* pInPlaceComboBox = ShowInPlaceList(iRowIndex,
iColumnIndex, obComboItemsList, strCurSelection);
ASSERT(pInPlaceComboBox);
// Set the selection to previous selection
pInPlaceComboBox->SelectString(-1, strCurSelection);
}
// If combo box is not read only
// Create and show the in place edit control
else if (!IsReadOnly(iColumnIndex))
{
CInPlaceEdit* pInPlaceEdit = ShowInPlaceEdit(iRowIndex,
iColumnIndex, strCurSelection);
}
}
}
}
}
bool CMyComboListCtrl::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 CMyComboListCtrl::SetComboColumns(int iColumnIndex, bool bSet /*= true*/)
{
// If the Column Index is not present && Set flag is false
// Then do nothing
// If the Column Index is present && Set flag is true
// Then do nothing
POSITION Pos = m_ComboSupportColumnsList.Find(iColumnIndex);
// If the Column Index is not present && Set flag is true
// Then Add to list
if ((NULL == Pos) && bSet)
{
m_ComboSupportColumnsList.AddTail(iColumnIndex);
}
// If the Column Index is present && Set flag is false
// Then Remove from list
if ((NULL != Pos) && !bSet)
{
m_ComboSupportColumnsList.RemoveAt(Pos);
}
}
void CMyComboListCtrl::SetReadOnlyColumns(int iColumnIndex, bool bSet /*= true*/)
{
// If the Column Index is not present && Set flag is false
// Then do nothing
// If the Column Index is present && Set flag is true
// Then do nothing
POSITION Pos = m_ReadOnlyColumnsList.Find(iColumnIndex);
// If the Column Index is not present && Set flag is true
// Then Add to list
if ((NULL == Pos) && bSet)
{
m_ReadOnlyColumnsList.AddTail(iColumnIndex);
}
// If the Column Index is present && Set flag is false
// Then Remove from list
if ((NULL != Pos) && !bSet)
{
m_ReadOnlyColumnsList.RemoveAt(Pos);
}
}
bool CMyComboListCtrl::IsReadOnly(int iColumnIndex)
{
if (m_ReadOnlyColumnsList.Find(iColumnIndex))
{
return true;
}
return false;
}
bool CMyComboListCtrl::IsCombo(int iColumnIndex)
{
if (m_ComboSupportColumnsList.Find(iColumnIndex))
{
return true;
}
return false;
}
void CMyComboListCtrl::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 CMyComboListCtrl::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
// Update the item text with the new text
SetItemText(pDispInfo->item.iItem, pDispInfo->item.iSubItem, pDispInfo->item.pszText);
GetParent()->SendMessage(WM_VALIDATE, GetDlgCtrlID(), (LPARAM)pDispInfo);
*pResult = 0;
}
void CMyComboListCtrl::SetValidEditCtrlCharacters(CString &rstrValidCharacters)
{
m_strValidEditCtrlChars = rstrValidCharacters;
}
void CMyComboListCtrl::SetColumnValidEditCtrlCharacters(CString &rstrValidCharacters,int column)
{
if(column>MAX_LISTCTRL_COLUMNS-1)
return;
if(column == -1)
{
for(int i=0;i<MAX_LISTCTRL_COLUMNS;i++)
{
m_strValidChars[i] = rstrValidCharacters;
}
}
else
m_strValidChars[column] = rstrValidCharacters;
}
void CMyComboListCtrl::EnableHScroll(bool bEnable /*= true*/)
{
if (bEnable)
{
m_dwDropDownCtrlStyle |= WS_HSCROLL;
}
else
{
m_dwDropDownCtrlStyle &= ~WS_HSCROLL;
}
}
void CMyComboListCtrl::EnableVScroll(bool bEnable /*= true*/)
{
if (bEnable)
{
m_dwDropDownCtrlStyle |= WS_VSCROLL;
}
else
{
m_dwDropDownCtrlStyle &= ~WS_VSCROLL;
}
}
void CMyComboListCtrl::ScrollToView(int iColumnIndex, /*int iOffSet, */CRect& robCellRect)
{
// Now scroll if we need to expose the column
CRect rcClient;
GetClientRect(&rcClient);
int iColumnWidth = GetColumnWidth(iColumnIndex);
// Get the column iOffset
int iOffSet = 0;
for (int iIndex_ = 0; iIndex_ < iColumnIndex; iIndex_++)
{
iOffSet += GetColumnWidth(iIndex_);
}
// If x1 of cell rect is < x1 of ctrl rect or
// If x1 of cell rect is > x1 of ctrl rect or **Should not ideally happen**
// If the width of the cell extends beyond x2 of ctrl rect then
// Scroll
CSize obScrollSize(0, 0);
if (((iOffSet + robCellRect.left) < rcClient.left) ||
((iOffSet + robCellRect.left) > rcClient.right))
{
obScrollSize.cx = iOffSet + robCellRect.left;
}
else if ((iOffSet + robCellRect.left + iColumnWidth) > rcClient.right)
{
obScrollSize.cx = iOffSet + robCellRect.left + iColumnWidth - rcClient.right;
}
Scroll(obScrollSize);
robCellRect.left -= obScrollSize.cx;
// Set the width to the column width
robCellRect.left += iOffSet;
robCellRect.right = robCellRect.left + iColumnWidth;
}
void CMyComboListCtrl::OnBeginLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
if (IsReadOnly(pDispInfo->item.iSubItem))
{
*pResult = 1;
return;
}
*pResult = 0;
}
int CMyComboListCtrl::InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat,
int nWidth, int nSubItem)
{
m_iColumnCounts++;
return CListCtrl::InsertColumn(nCol, lpszColumnHeading, nFormat, nWidth, nSubItem);
}
int CMyComboListCtrl::GetColumnCounts()
{
return m_iColumnCounts;
}
void CMyComboListCtrl::DeleteAllColumn()
{
for (int i = 0; i < m_iColumnCounts; i++)
{
DeleteColumn(0);
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -