【VC++】SDIにリストコントロールを追加してイベント処理を実装する

0

    <機能>

    (1)MFCのSDIアプリケーションにリストコントロール(CListCtrl)を追加する

    (2)リストコントロールをCreate(サイズ・WindowStyle指定)する

    (3)リストコントロールのフォントを変更してみる(MS UI Gothic使用)

    (4)ヘッダ設定(InsertColumn)、データ設定(InsertItem)を行う

    (5)イベントを追加する(WindowProc)

      ・LVN_ITEMCHANGED : リストコントロールに変更があった
      ・LVN_COLUMNCLICK : リストコントロールのヘッダが左クリックされた

     

    <実行イメージ>

    フォントをMS UI Gothicに変更しヘッダ・データをセット

    ※データは東京都の市区町村別人口

    VisualStudio,MFC,SDI,CListCtrl,実行イメージ,
     

    リスト選択により選択行番号と選択行の情報を表示

    VisualStudio,MFC,SDI,CListCtrl,LVN_ITEMCHANGED,

    項目行左クリックにより選択カラム番号を表示

    VisualStudio,MFC,SDI,CListCtrl,LVN_COLUMNCLICK,
     

    <動作検証&開発環境>
    Visual Studio Community 2017

     

    <使い方>

    1.MFCアプリケーションでプロジェクトを作成

    2.アプリケーションの種類でシングルドキュメントを選択

    VisualStudio,MFC,SDI,CListCtrl,アプリケーションの種類,
     

    3.ユーザーインターフェイス機能でくクラシックメニューを使用するを選択

    ※その他の設定は下図参照

    VisualStudio,MFC,SDI,CListCtrl,ユーザーインターフェイス機能,
     

    4.高度な機能で不要なチェックを外す

    VisualStudio,MFC,SDI,CListCtrl,高度な機能,
     

    5.プロジェクト構成を確認しソースを追加する

    VisualStudio,MFC,SDI,CListCtrl,ソリューション,プロジェクト構成,
     

    6.クラスウィザードにてCChileViewクラスにOnCreateハンドラーを追加

    ※OnCreateでリストコントロールを生成しデータを設定する

    VisualStudio,MFC,SDI,CListCtrl,クラスウィザード,OnCreate,
     

    7.クラスウィザードにてCChileViewクラスにWindowProcハンドラーを追加

    ※WindowProcでリストコントロールのイベント処理を行う

    VisualStudio,MFC,SDI,CListCtrl,クラスウィザード,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);
    }

     

    よろしければポチッと押してください

    プログラマー ブログランキングへ



    selected entries

    categories

    calendar

    S M T W T F S
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
    << December 2018 >>

    profile

    others

    archives