リストビューの項目を編集する

リストビュー

リストビューの項目を編集できるようにします。編集ができるのは、一番左側の項目だけにします。
項目を左クリックすることで、項目が編集できるようになります。

リストビュー1 - インコのWindowsSDK で作成したソースを修正します。

流れ

WM_NOTIFY

1.WM_NOTIFYメッセージを捕まえます。

2.この時のwParamの値を調べてツリービューのIDと同じかどうか調べて同じなら、 lParamの値をLV_DISPINFO構造体のポインタに代入します。

typedef struct tag LV_DISPINFO {
  NMHDR hdr;     // NMHDR構造体
  LVITEM item; 
} LV_DISPINFO;

3.TV_DISPINFO構造体のメンバであるNMHDR構造体のcodeメンバが、LVN_BEGINLABELEDITならば、編集が開始されたと、判断します。このとき、ListView_GetEditControl()で、表示されたエデットコントロールのハンドルを取得します。

HWND ListView_GetEditControl(
    HWND hwnd
);

SendMessage(hWndControl, LVM_GETEDITCONTROL, 0, 0)と同等。

4.TV_DISPINFO構造体のメンバであるNMHDR構造体のcodeメンバが、LVN_ENDLABELEDITメッセージならば編集が終わったと判断し、 GetWindowText()でエディトコントロールに入力された文字列をバッファ(ここではbuf)にセット。

5.ListView_SetItemText()で、リストビューの文字をセット。

VOID ListView_SetItemText(
    HWND hwnd,       // リストビューのハンドル
    int i,           // リストの項目のインデックス
    int iSubItem,    // リストの項目のサブアイテム(サブアイテムでないときは、0)
    LPCTSTR pszText  // セットする文字列
);

SendMessage(hWndControl, LVM_SETITEMTEXT, 0, 0)と同等。

リソース

ウインドウスタイルにLVS_EDITLABELSを追加。

ソースコードの入力

ソースコードは下記のように入れてください。

test.cpp
#include <windows.h>
#include <commctrl.h>
#include "resource.h"

#pragma comment(lib, "comctl32.lib")

LPTSTR strItem0[] = { TEXT("TILTE1"), TEXT("TILTE2") };
int CX[] = { 80, 160 };
LPTSTR strItem1[] =
         { TEXT("LIST11"), TEXT("LIST12") };
LPTSTR strItem2[] =
         { TEXT("LIST21"), TEXT("LIST22") };

// このコード モジュールに含まれる関数の宣言を転送します:
BOOL CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
          PSTR lpCmdLine, int nCmdShow )
{
    DialogBox(hInstance, TEXT("DIALOG_BOX"), NULL, DialogProc);
    return 0;
}

BOOL CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LVCOLUMN lvcol;
    LVITEM item;
    UINT i;
    static HWND hList;
    LV_DISPINFO *lvinfo;
    TCHAR buf[64];
    static HWND hEdit;
    switch (msg)
    {
        case WM_INITDIALOG:
            InitCommonControls();
            hList = GetDlgItem(hWnd, IDC_LIST1);

            lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
            lvcol.fmt = LVCFMT_LEFT;
            for(i = 0; i < 2; i++)
            {
                lvcol.cx = CX[i];             // 表示位置
                lvcol.pszText = strItem0[i];  // 見出し
                lvcol.iSubItem = i;           // サブアイテムの番号
                ListView_InsertColumn(hList, i, &lvcol);
            }

            item.mask = LVIF_TEXT;
            for(i = 0; i < 2; i++)
            {
                item.pszText = strItem1[i];   // テキスト
                item.iItem = i;               // 番号
                item.iSubItem = 0;            // サブアイテムの番号
                ListView_InsertItem(hList, &item);
                item.pszText = strItem2[i];   // テキスト
                item.iItem = i;               // 番号
                item.iSubItem = 1;            // サブアイテムの番号
                ListView_SetItem(hList, &item);
            }

            break;
        case WM_NOTIFY:
            if ((int)wParam == IDC_LIST1)
            {
                lvinfo = (LV_DISPINFO *)lParam;
                switch (lvinfo->hdr.code)
                {
                    case LVN_BEGINLABELEDIT:
                        hEdit = ListView_GetEditControl(hList);
                        break;
                    case LVN_ENDLABELEDIT:
                        GetWindowText(hEdit, buf, sizeof(buf));
                        ListView_SetItemText(hList, lvinfo->item.iItem, 0, buf);
                        break;
                }
            }
            break;
        case WM_CLOSE:
            EndDialog(hWnd, IDOK);
            break;
        default:
            break;
    }
    return FALSE;
}

上記の太線で示している箇所のみ追加です。

resource.h (変更なし)
#define IDC_LIST1 400
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif

test.rc
#include <windows.h>
#include <commctrl.h>
#include "resource.h"

/////////////////////////////////////////////////////////////////////////////
//
// ダイアログ
//

DIALOG_BOX DIALOG 0, 0, 170, 62
FONT 9, "MS UI Gothic"
CAPTION "ダイアログ"
BEGIN
     CONTROL         "", IDC_LIST1,
                    WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_ICON | LVS_EDITLABELS,
                    2, 2, 166, 58
END

Reseditで作成した場合は、これとは異なるソースコードになります。 上記の太線で示している箇所のみ追加です。