[kaze's test] プログラミングメモ |
→目次 |
CListCtrlのサブアイテム文字列編集
Excelのようにレポート用のCListCtrlをExcelのようにアイテム及びサブアイテムを編集する方法の一つです。

レポート表示用のListCtrlをDialogに貼り付けて、列と行を適当に作成しておきます。ListCtrlのセルをダブルクリックすると、そのセルの上にエディットを出して編集します。編集後に編集結果をセルに書き戻します。
処理の流れは、下記に記述します。
1.ListCtrlをダブルクリックすると、ダブルクリック場所のItemとSubItemのインデックスを求めます。
2.ItemインデックスとSubItemインデックスで、セルの外接する四角形(CRect)を求めます。
3.ListCtrlの子ウィンドウとして、CEditをセルの真上で作成し、セ ルの文字列を当CEditに設定します。
4.CEditのフォーカスを失うイベントハンドルOnKillFocusで、CEditの文字列をセルに逆設定し、CEditのウィンドウを廃棄します。
ソースコード:
下記に列挙しているソースは、CTestDlg、CListCtrlWithEdit、CEditInListCtrlクラスの関係部分だけです。
class CTestDlg : public CDialogEx
{
// 省略
CListCtrlWithEdit m_listctrl;
// 省略
}
BOOL CTestDlg::OnInitDialog()
{
// 省略
CDialogEx::OnInitDialog();
m_listctrl.SetExtendedStyle(m_listctrl.GetExtendedStyle()
| LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
// 省略
}
void CTestDlg::OnNMDblclkListCells(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR);
*pResult = 0;
(pNMItemActivate->iItem < 0 || pNMItemActivate->iSubItem < 1)
return;
m_listctrlCells.BeginEdit(pNMItemActivate->iItem,
pNMItemActivate->iSubItem);
}
class CListCtrlWithEdit : public CListCtrl
{
// 省略
CEditInListCtrl m_Edit;
void BeginEdit(int iItem, int iSubItem);
// 省略
};
#define IDC_EDIT_SUB_ITEM 1234
void CListCtrlWithEdit::BeginEdit(int iItem, int iSubItem)
{
CRect ColumnRect;
if (iSubItem == 0)
GetSubItemRect(iItem, iSubItem, LVIR_LABEL, ColumnRect);
else
GetSubItemRect(iItem, iSubItem, LVIR_BOUNDS, ColumnRect);
ColumnRect.DeflateRect(1,1);
m_Edit.Create(WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT,
ColumnRect, this, IDC_EDIT_SUB_ITEM);
CFont* pFont = GetFont();
m_Edit.SetFont(pFont);
m_Edit.m_row = iItem;
m_Edit.m_col = iSubItem;
m_Edit.SetWindowText(GetItemText(iItem, iSubItem));
m_Edit.SetFocus();
}
class CEditInListCtrl : public CEdit
{
// 省略
int m_row;
int m_col;
afx_msg void OnKillFocus(CWnd* pNewWnd);
// 省略
};
void CEditInListCtrl::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
if (m_row >= 0 && m_col >= 0)
{
CString strText;
GetWindowText(strText);
((CListCtrl*)GetParent())->SetItemText(m_row, m_col, strText);
}
DestroyWindow();
}
|