|
アイテムの挿入が出来たのだから、アイテムの削除ができなきゃいかん!
というわけで、今回は「アイテムの削除」をやります。 私個人の意見としては、「CListCtrlは使いにくい!!」という事である。 従って、今現在 CListCtrlを継承した EListCtrl クラスを作成中である。 どのあたりが「使いにくい」かというと、例えば「現在選択されているアイテムのインデックスを返す関数」が無いのである。 CListBox::GetSel()にあたる関数が無い為、現在どのアイテムが選択されているかを調べたい場合、自前で調べるしかないのである。 |
|
|
|
調べかただが、これまた面倒くさいのである。 まぁ、そろそろ覚悟は出来ていると思うが、またしても「LV_ITEM」を使う事になる。 CListCtrlを実装しようとした場合、「LV_ITEM」とは縁を切れないらしい (^^; 実装する前に概要だが、非常にシンプルである (^^;
とても高等なクラスとは思えない、素敵な仕様になっている。 |
|
|
|
実装は簡単なのだが、簡単だからそクラスの中にパッケージしてほしかったと思う。
void foo::DeleteItem()
{
if( m_LstCtrl.GetSelectedCount() == 0 ){
AfxMessageBox( "No items selected." );
return;
}
// delete all selected items
LV_ITEM item;
int nIdx;
memset( &item, 0, sizeof( item ) );
item.mask = LVIF_STATE;
item.stateMask = LVIS_SELECTED;
//最後から検索!ここがミソ
for( nIdx = m_LstCtrl.GetItemCount(); nIdx >= 0; nIdx-- ){
item.iItem = nIdx;
m_LstCtrl.GetItem( &item );
if( item.state == LVIS_SELECTED )
m_LstCtrl.DeleteItem( nIdx );
}
}
上記のソースコードで選択されているアイテムの削除が可能であるが、for ループの直前のコメントに注目して欲しい。
「最後から検索!ここがミソ」と書いてある。 そのとおり!ここがミソなのである。 (プログラム中級者以上の方は見なくていいです) どうミソかというと、アイテムを削除するとインデックスが入れ替わる為消していくと変になってしまうのです。 従って最後から削除しないとおかしな事になります。 言っている意味分かりますか? 0 test0 1 test1 2 test2 3 test3 4 test4左側がインデックス、右側が名前というようなテーブルを考えた時、test1,test2 だけ削除しようとしましょう。 すると、 0 test0 <- 通過 1 test1 <- 削除となって 0 test0 1 test2 2 test3 3 test4となりますね。 for ループで削除しますから、次の番号は 2 (インデックスで)ですから test3 になってしまいます。 すると・・・test2 は削除できませんでした。 となります。 |
|
|
|
これを回避する為には、最後から削除しなければならないわけです。 分かりましたか? さて、今回はアイテムの削除を学びました(私が) 次回は何をしようかな? |