【VC++】SDIにリストコントロールを追加してイベント処理を実装する
<機能>
(1)MFCのSDIアプリケーションにリストコントロール(CListCtrl)を追加する
(2)リストコントロールをCreate(サイズ・WindowStyle指定)する
(3)リストコントロールのフォントを変更してみる(MS UI Gothic使用)
(4)ヘッダ設定(InsertColumn)、データ設定(InsertItem)を行う
(5)イベントを追加する(WindowProc)
・LVN_ITEMCHANGED : リストコントロールに変更があった
・LVN_COLUMNCLICK : リストコントロールのヘッダが左クリックされた
<実行イメージ>
フォントをMS UI Gothicに変更しヘッダ・データをセット
※データは東京都の市区町村別人口
リスト選択により選択行番号と選択行の情報を表示
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
1.MFCアプリケーションでプロジェクトを作成
2.アプリケーションの種類でシングルドキュメントを選択
3.ユーザーインターフェイス機能でくクラシックメニューを使用するを選択
※その他の設定は下図参照
4.高度な機能で不要なチェックを外す
5.プロジェクト構成を確認しソースを追加する
6.クラスウィザードにてCChileViewクラスにOnCreateハンドラーを追加
※OnCreateでリストコントロールを生成しデータを設定する
7.クラスウィザードにてCChileViewクラスにWindowProcハンドラーを追加
※WindowProcでリストコントロールのイベント処理を行う
MainFrm.cpp
//メインフレームのサイズ設定を行う
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE
| WS_SYSMENU;
//cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
//ウィンドウサイズとクライアント領域を一致させる
cs.dwExStyle = WS_EX_CLIENTEDGE;
cs.lpszClass = AfxRegisterWndClass(0);
//作業領域のサイズを取得
//画面全体からシステムのタスクバーやアプリケーションのツールバーが占有する領域を除いた部分
CRect rcSpara;
SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcSpara, NULL);
//ウィンドウサイズの設定
CRect rect(0, 0, 600, 400);
::AdjustWindowRectEx(&rect, cs.style, TRUE, cs.dwExStyle);
//ウィンドウサイズを取得
cs.cx = rect.Width();
cs.cy = rect.Height();
//画面中央に表示
cs.x = rcSpara.left + (rcSpara.Width() - cs.cx) / 2;
cs.y = rcSpara.top + (rcSpara.Height() - cs.cy) / 2;
return TRUE;
}
ChildView.h
//フォント変更するためCFontオブジェクトを追加
class CChildView : public CWnd
{
//省略~~
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
private:
const int D_IDLISTVIEW = 1000;
void InsertListCtrlItems(CListCtrl *pList);
public:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
CFont *m_pFont;
};
ChildView.cpp
CChildView::CChildView()
{
//子ウィンドにフォントをセット
m_pFont = new CFont;
LOGFONT logFont;
logFont.lfHeight = 12;
logFont.lfWidth = 10;
logFont.lfEscapement = 0;
logFont.lfOrientation = 0;
logFont.lfWeight = FW_DONTCARE;
logFont.lfItalic = FALSE;
logFont.lfUnderline = FALSE;
logFont.lfStrikeOut = FALSE;
logFont.lfCharSet = DEFAULT_CHARSET;
logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
logFont.lfQuality = DEFAULT_QUALITY;
logFont.lfPitchAndFamily = FF_DONTCARE;
lstrcpy(logFont.lfFaceName, L"MS UI Gothic");
m_pFont->CreateFontIndirect(&logFont);
}
CChildView::~CChildView()
{
//フォントオブジェクトを破棄
delete m_pFont;
}
/***********************************************************
OnCreate
SDIで子ウィンドウの作成時にリストコントロール(CListCtrl)を生成
***********************************************************/
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
//ウィンドウサイズを取得
CFrameWnd *pFrm = GetParentFrame();
CRect rect;
pFrm->GetClientRect(&rect);
//リストコントロール(レポート形式)を配置
//ウィンドウサイズに対して余白10で配置する
CListCtrl *pListctrl = new CListCtrl();
//List-View Window Stylesはデベロッパーセンターを参照
pListctrl->Create(
WS_VISIBLE | WS_BORDER | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_REPORT | LVS_SINGLESEL,
CRect(10, 10, rect.Width()-20, rect.Height()-20), this, D_IDLISTVIEW);
//拡張スタイルを設定
pListctrl->SetExtendedStyle(pListctrl->GetExtendedStyle() | LVS_EX_FULLROWSELECT);
//リストカラムセッティング
LV_COLUMN lvclm;
ZeroMemory(&lvclm, sizeof(LV_COLUMN));
lvclm.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
//インデックス0の列はは常にLVCFMT_LEFTとなる
//詳細はデベロッパーセンターのRemarks参照
//lvclm.fmt = LVCFMT_CENTER;
lvclm.iSubItem = 0;
lvclm.pszText = L"地域コード";
lvclm.cx = 130;
pListctrl->InsertColumn(0, &lvclm);
lvclm.fmt = LVCFMT_LEFT;
lvclm.iSubItem = 1;
lvclm.pszText = L"市区町村名";
lvclm.cx = 250;
pListctrl->InsertColumn(1, &lvclm);
lvclm.fmt = LVCFMT_RIGHT;
lvclm.iSubItem = 2;
lvclm.pszText = L"人口(人)";
lvclm.cx = 150;
pListctrl->InsertColumn(2, &lvclm);
//アイテムセット
InsertListCtrlItems(pListctrl);
//フォントをセット
GetDlgItem(D_IDLISTVIEW)->SetFont(m_pFont);
return 0;
}
/***********************************************************
InsertListCtrlItems
リストコントロールにデータ(東京都市区町村の人口)をセット
***********************************************************/
void CChildView::InsertListCtrlItems(CListCtrl *pList)
{
TCHAR twk[64];
int idx=0;
LVITEM lvitm;
struct
{
int id;
TCHAR name[128];
int population;
}item[]={
{ 13101,_T("東京都 千代田区"),61218 },{ 13102,_T("東京都 中央区"),156256 },
{ 13103,_T("東京都 港区"),253018 },{ 13104,_T("東京都 新宿区"),343533 },
{ 13105,_T("東京都 文京区"),227141 },{ 13106,_T("東京都 台東区"),202947 },
{ 13107,_T("東京都 墨田区"),264229 },{ 13108,_T("東京都 江東区"),510574 },
{ 13109,_T("東京都 品川区"),397710 },{ 13110,_T("東京都 目黒区"),283005 },
{ 13111,_T("東京都 大田区"),728423 },{ 13112,_T("東京都 世田谷区"),921720 },
{ 13113,_T("東京都 渋谷区"),229670 },{ 13114,_T("東京都 中野区"),335745 },
{ 13115,_T("東京都 杉並区"),575841 },{ 13116,_T("東京都 豊島区"),298050 },
{ 13117,_T("東京都 北区"),348547 },{ 13118,_T("東京都 荒川区"),216273 },
{ 13119,_T("東京都 板橋区"),574058 },{ 13120,_T("東京都 練馬区"),731696 },
{ 13121,_T("東京都 足立区"),677514 },{ 13122,_T("東京都 葛飾区"),450846 },
{ 13123,_T("東京都 江戸川区"),691084 },{ 13201,_T("東京都 八王子市"),577910 },
{ 13202,_T("東京都 立川市"),179390 },{ 13203,_T("東京都 武蔵野市"),146381 },
{ 13204,_T("東京都 三鷹市"),190432 },{ 13205,_T("東京都 青梅市"),135789 },
{ 13206,_T("東京都 府中市"),261829 },{ 13207,_T("東京都 昭島市"),111902 },
{ 13208,_T("東京都 調布市"),235243 },{ 13209,_T("東京都 町田市"),434091 },
{ 13210,_T("東京都 小金井市"),123813 },{ 13211,_T("東京都 小平市"),192874 },
{ 13212,_T("東京都 日野市"),188327 },{ 13213,_T("東京都 東村山市"),150180 },
{ 13214,_T("東京都 国分寺市"),124501 },{ 13215,_T("東京都 国立市"),74610 },
{ 13218,_T("東京都 福生市"),58210 },{ 13219,_T("東京都 狛江市"),82357 },
{ 13220,_T("東京都 東大和市"),84664 },{ 13221,_T("東京都 清瀬市"),75377 },
{ 13222,_T("東京都 東久留米市"),116360 },{ 13223,_T("東京都 武蔵村山市"),71651 },
{ 13224,_T("東京都 多摩市"),147691 },{ 13225,_T("東京都 稲城市"),90225 },
{ 13227,_T("東京都 羽村市"),55225 },{ 13228,_T("東京都 あきる野市"),80373 },
{ 13229,_T("東京都 西東京市"),202201 },{ 13303,_T("東京都 西多摩郡瑞穂町"),33102 },
{ 13305,_T("東京都 西多摩郡日の出町"),17404 },{ 13307,_T("東京都 西多摩郡檜原村"),2096 },
{ 13308,_T("東京都 西多摩郡奥多摩町"),5058 },{ 13361,_T("東京都 大島町"),7580 },
{ 13362,_T("東京都 利島村"),343 },{ 13363,_T("東京都 新島村"),2630 },
{ 13364,_T("東京都 神津島村"),1845 },{ 13381,_T("東京都 三宅島三宅村"),2383 },
{ 13382,_T("東京都 御蔵島村"),343 },{ 13401,_T("東京都 八丈島八丈町"),7330 },
{ 13402,_T("東京都 青ヶ島村"),174 },{ 13421,_T("東京都 小笠原村"),3067 },
0
};
for (INT i = 0;; i++)
{
if (item[i].id == 0) break;
ZeroMemory(&lvitm, sizeof(LVITEM));
lvitm.mask = LVIF_TEXT;
lvitm.iItem = pList->GetItemCount();
lvitm.iSubItem = 0;
ZeroMemory(&twk, sizeof(twk));
wsprintf(twk, _T("%d"), item[i].id);
lvitm.pszText = twk;
idx = ListView_InsertItem(pList->GetSafeHwnd(), &lvitm);
//idx = pList->InsertItem(&lvitm);
if (idx == (-1))
{
AfxMessageBox(L"InsertItem Error!!",MB_ICONSTOP);
return;
}
ZeroMemory(&lvitm, sizeof(LVITEM));
lvitm.mask = LVIF_TEXT;
lvitm.iItem = idx;
lvitm.iSubItem = 1;
lvitm.pszText = item[i].name;
ListView_SetItem(pList->GetSafeHwnd(), &lvitm);
//pList->SetItem(&lvitm);
ZeroMemory(&lvitm, sizeof(LVITEM));
lvitm.mask = LVIF_TEXT;
lvitm.iItem = idx;
lvitm.iSubItem = 2;
ZeroMemory(&twk, sizeof(twk));
wsprintf(twk, _T("%d"), item[i].population);
lvitm.pszText = twk;
ListView_SetItem(pList->GetSafeHwnd(), &lvitm);
//pList->SetItem(&lvitm);
}
}
/***********************************************************
WindowProc
リストコントロールのイベント処理
LVN_ITEMCHANGED : リストコントロールに変更があった
LVN_COLUMNCLICK : リストコントロールのヘッダが左クリックされた
***********************************************************/
LRESULT CChildView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
LV_DISPINFO *lvdisp;
NM_LISTVIEW *pNMLV;
CString cs;
int idx;
switch (message)
{
case WM_NOTIFY:
//リストコントロールからのメッセージのみ処理する
if ((int)wParam == D_IDLISTVIEW) {
lvdisp = (LV_DISPINFO *)lParam;
pNMLV = (NM_LISTVIEW *)lParam;
//リストビューを取得
CListCtrl *pListCtrl = (CListCtrl *)GetDlgItem(D_IDLISTVIEW);
//選択されている行のインデックスを取得
idx = pNMLV->iItem;
switch (lvdisp->hdr.code) {
case LVN_ITEMCHANGED:
//選択行の情報を表示する
if ((pNMLV->uChanged & LVIF_STATE) && (pNMLV->uNewState & LVIS_SELECTED)) {
cs.Format(L"%d行目¥r¥n地域コード [%s]¥r¥n市区町村名 [%s]¥r¥n人口 [%s]",
idx+1,pListCtrl->GetItemText(idx, 0),
pListCtrl->GetItemText(idx, 1),
pListCtrl->GetItemText(idx, 2));
AfxMessageBox(cs,MB_ICONINFORMATION);
}
break;
case LVN_COLUMNCLICK:
//iSubItemを参照してヘッダのクリックされた列を表示する
cs.Format(L"ヘッダ行の%d列目が左クリックされました", pNMLV->iSubItem+1);
AfxMessageBox(cs,MB_ICONINFORMATION);
break;
}
}
break;
default:
;
}
return CWnd::WindowProc(message, wParam, lParam);
}
よろしければポチッと押してください