ページ 11

リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 11:06
by オカピーα
お久しぶりです。
またもやWIN32 APIプログラミングで挫折中です。

現在リストビューを研究しています。
そこで、リストビューの項目の内容が編集できるものを作りました。
しかし、問題が発生。
一番左の列の項目は編集できるのですが、
右のSubItemの列の項目が編集できないという状況になりました。
WM_NOTIFYメッセージの捕まえ方が悪いのかどうかわかりません。
もしや構造体になんらかの情報が入っているのか?
まったくもって分かりません。
どなたか教えてください。
ソースが漏れてはまずいのでリストビューのところだけ抜粋して載せます。

メインソース

コード:

BOOL CALLBACK MyTimeProc(HWND hDlg,UINT msg,WPARAM wp, LPARAM lp)
{
    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(hDlg, IDC_LISTVIEW);

            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)wp == IDC_LIST1)
            {
                lvinfo = (LV_DISPINFO *)lp;
                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:
		case IDOK:
            EndDialog(hDlg, IDOK);
            break;
		case IDCANCEL:
			EndDialog(hDlg, IDCANCEL);
			break;
        default:
            break;
    }
    return FALSE;
}
リソース

コード:

LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
TIME DIALOG 0, 0, 215, 142
STYLE DS_3DLOOK | DS_CENTER | DS_LOCALEDIT | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "リストビューの研究"
FONT 9, "MS UI Gothic"
BEGIN
    DEFPUSHBUTTON   "OK", IDOK, 97, 118, 50, 14
    PUSHBUTTON      "キャンセル", IDCANCEL, 155, 118, 50, 14
    CONTROL         "", IDC_LISTVIEW, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_EDITLABELS | LVS_REPORT, 14, 13, 173, 98, WS_EX_DLGMODALFRAME
END
リソース製作にはResEditを使っています。
どなたか教えてください。
よろしくお願いします。

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 11:32
by softya(ソフト屋)
まんま猫winな気もしますが再現が大変面倒なのでお答えしにくいです(日頃MFCの人なので)。
ソースコードが添付できない理由は猫winのままって事でしょうか?他の理由なら全コード掲載可能なコンパクト版の作成をお願いします。

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 11:54
by オカピーα
返信ありがとうございます。
このソースは猫WINとインコを掛け合わせた感じです。
転載元は「http://gurigumi.s349.xrea.com/programmi ... w5.html」です
こことまったく同じソースと考えていただいてかまいません。

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 12:04
by softya(ソフト屋)
オカピーα さんが書きました:返信ありがとうございます。
このソースは猫WINとインコを掛け合わせた感じです。
転載元は「http://gurigumi.s349.xrea.com/programmi ... w5.html」です
こことまったく同じソースと考えていただいてかまいません。
えーと、やはりこちらでソースコードを組み立ててほしいと言うことでしょうか?
出来ればその手間を省いて頂けると助かるのですが。
でないと、まとまった時間が取れるまでお待ち頂くことになります。

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 12:26
by オカピーα
新しくプロジェクトを作って書き直しました。
↓をそのままビルドしてくれればおkです。
OS:WindowsXP
コンパイラ:Visual C++ 2008

コード:

#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;
}
リソース

コード:

// Generated by ResEdit 1.5.9
// Copyright (C) 2006-2011
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"




//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
DIALOG_BOX DIALOG 0, 0, 187, 153
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "Ms Shell Dlg"
BEGIN
    CONTROL         "", IDC_LIST1, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_EDITLABELS | LVS_REPORT, 5, 11, 168, 108
END
問題点としては、2列目をクリックしてもフォーカスが与えられません

どなたか教えてください。

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 12:28
by softya(ソフト屋)
resource.hもお願いします。

見つけてきたので貼っておきます。
resource.h

コード:

#define IDC_LIST1 400
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 12:58
by softya(ソフト屋)
とりあえず。この方法では左端しか編集出来ないと言う事だけは確認しました。
代案は検討中です。

【補足】
結論としてWM_NOTIFYで検知せずにダブルクリックを検知してリスト上の何処かを調べた上で、独自のeditで編集、ListView_SetItemTextで書き換えるって感じにしないとダメだと思います。
MFCの例はたくさんあるんですが、Win32APIの例は見つかりませんでした。

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 14:23
by オカピーα
ありがとうございます
その方向で再検討してみます

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 14:33
by トクメイ
ここの内容でなんとかなるのでは?
http://www.h5.dion.ne.jp/~sfsf11/listview/listview.html

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 14:38
by トクメイ
失礼。情報が少なかったので追加します。上記サイトの
(4)1行選択可能にする(LVS_EX_FULLROWSELECT)
の項目が解決の役に立つかと思われます。

Re: リストビューコントロール [WIN32 API]

Posted: 2012年5月26日(土) 14:47
by オカピーα
トクメイ さんが書きました:失礼。情報が少なかったので追加します。上記サイトの
(4)1行選択可能にする(LVS_EX_FULLROWSELECT)
の項目が解決の役に立つかと思われます。
トクメイさんありがとうございます。
せっかくですがその情報はあまり役に立たないと思います。
返信ありがとうございました。