基本クラスがCListViewの場合に、アイテムを追加するには?

解決


ぺんねーむ  2005-06-03 02:11:52  No: 57674

いつもお世話になっております。

VC++6.0を使用しています。
MFC AppWizard(exe)のSDIで基本クラスをCListViewに選択した場合、
例えばメニューからアイテムを追加したいのですが、どこを変更すれば良いでしょうか?CMFCAddressView::OnInitialUpdate()の中でしょうか?

書籍やWeb上にはCListBoxの説明は多々あるのですが、CListViewを基本クラスとして扱うものは少なく、小生の理解できるサンプルはありませんでした。


ぺんねーむ  2005-06-03 02:13:43  No: 57675

MFCAddressというのはプロジェクト名です。
言葉足らず申し訳在りません。


ぺんねーむ  2005-06-03 03:11:51  No: 57676

下記のようにした場合、実行時にFor infomation on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.とエラーが出てしまいます。何が悪いのでしょうか。

void CMFCAddressView::OnInitialUpdate()
{
  CListView::OnInitialUpdate();
  
  // TODO: GetListCtrl() メンバ関数の呼び出しを通して直接そのリスト コントロールに
  //  アクセスすることによって ListView をアイテムで固定できます。
  m_lv.SetItemState( 1, LVIS_SELECTED , LVIS_SELECTED );
  m_lv.SetFocus();
  UpdateData(FALSE);
}


REE  2005-06-03 04:54:27  No: 57677

メニューからアイテムを追加したいならメニューハンドラに書くのが普通です。


ぺんねーむ  2005-06-03 19:44:15  No: 57678

どうもありがとうございます。

メニューハンドラに書く、というのは
C***View::on***()
の中に書くということですよね?

ここでListBoxなら
CListBox* mylist=(CListBox*)GetDlgItem(IDC_LIST1);
mylist->InsertString(-1, "ABC");
のように書くのだと思いますが、
ListViewの場合、サンプルが無く、何を書いていいのかわからないのです。
ご教示お願いできないでしょうか?


jun  2005-06-04 06:45:11  No: 57679

// listViewはCListView
CListCtrl &ctrl = listView.GetListCtrl();  // CListCtrlを取得して...
ctrl.InsertItem(...);                               // CListCtrlに対してInsert

のような感じでOKかと思います。


RAPT  2005-06-04 22:07:34  No: 57680

自分自身のメンバ関数を呼び出すには、下記のようにします。

void CMFCAddressView::XXXX()
{
    CListCtrl& ctrl = GetListCtrl(); //CMFCAddressView::GetListCtrl()の呼び出し
    ctrl.InsertItem(...);
    ctrl.SetItemState(...);
}


ぺんねーむ  2005-06-06 18:51:54  No: 57681

どうもありがとうございます。


たいにー ぜの  2019-10-29 00:54:16  No: 148350

追記:OnInitialUpdate() は、起動時にID_FILE_NEW=CWinApp::OnFileNew()を経由して
呼び出されます。
そして、「ファイルを開く」lD_FILE_OPEN=CWinApp::OnFileOpen()で、
ファイル選択成功後にも呼び出されます。

「新規作成」と「ファイルを開く」の呼び出しの違いは、
CDocument::GetPathName() が返す値が空文字ならば、「新規作成」。
空文字でなければ、「ファイルを開く」と判断します。

CListViewにはドキュメントクラスへのアクセス関数を持っているので、

CString sPathName = GetDocument()->GetPathName();
とすれば、ファイル名が取得できます。

CWnd::UpdateData(FALSE);は、CWnd::DoDataExchange(CDataExchange*pDX);
を、CDataExchange::m_bSaveAndValidate=FALSE(=読み出しモード)で、呼び出します。
なので、リストビューへ、ヘッダーを書き込んでからアイテム+サブアイテムの順に、
1個1個書き込んでいくループを組んでください。

ソースの例。
<pre>
    CListCtrl& rList = GetListCtrl();
    // 列数を取得し、ヘッダーも含めてすべて削除する。
    int iMaxSubItems = 0;
    CHeaderCtrl* pHead = rList.GetHeaderCtrl();
    if (pHead)
    {
        iMaxSubItems = pHead->GetItemCount();
    }
    BOOL bResult = rList.DeleteAllItems();
    for (int iSubItem = iMaxSubItems -1; bResult && 0 <= iSubItem; iSubItem--)
    {
        bResult = rList.DeleteColumn(iSubItem);
    }
    CString sPathName = GetDocument()->GetPathName();
    if (bResult && !sPathName.IsEmpty())
    {
        // ここからアイテムの追加になります。
        // 例として、5列×100行の情報を ListView へ書き込みます。
        for (iItem = 0; bResult && iItem < 100; iItem++)
        {
            for (iSubItem = 0; bResult && iSubItem < 5; iSubItem++)
            {
                CString sValue;
                if (!iItem)
                {
                    // ヘッダー列の追加
                    sValue.Format(_T("Title%d"), iSubitem + 1);
                    bResult = rList.InsertColumn(iSubItem, LVCFMT_LEFT, 98, sValue);
                }
                if (bResult)
                {
                    // 行追加
                    sValue.Format(_T("Item%d-%d"), iItem + 1, iSubItem + 1);
                    if (!iItem)
                    {
                        // アイテムの追加
                        bResult = iItem == rList.InsertItem(iItem, sValue);
                    }
                    else
                    {
                        // サブアイテムの追加
                        bResult = rList.SetItemText(iItem, iSubItem, sValue);
                    }
                }
            };
        };
    }
</pre>

OnInitialUpdate()へUpdateData(FALSE);の代わりに書き込んでもよいですし、
説明した通り、DoDataExchange()をCListView()の継承クラス上に新たに起こして、
書き込んでも良いですし、、、
意味がわかるなら、OnUpdate()関数を別途新たに起こして書き込んでもよいです。

確か、ビューの切り替えボタンには、何も実装されていないので、
詳細表示ができないと思いますので、
ビューモードの切り替えは、別途調べてください。

つ、疲れた。。。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加