# # 作者のぼやき # # はっきり言って私は文章を書くのが嫌いです(きっぱり) # 会員さんがドキュメントが欲しいというから始めた本コーナーも # 30話を突破してしまった。。。 # 密度はともかくとして、なかなか続いているではないですか (^^;; # それなのに!それだというのに!! # 激励のメールが2通しか来ないのはどういう訳だぁ!!!(ガオォォォォ) # 別にいいけどさ・・・フン・・・ # 誰もかまってくれねえさ・・・ヘン・・・ # かわいそうな俺・・・グス・・・ # # 激励のメール待ってますm(_ _)m # |
|
|
|
前回アイテムの削除をしたので、今回はソートでもしようかとおもったのだが、それは止めて(?)スワップに挑戦してみた。 皆さんはスワップをご存知だろうか?(知っている人にしてみれば非常に失礼な言い回しだが) スワップとは、data1とdata2があった時そのデータを交換する事を言います。 つまり、リストコントロール内のデータを交換してみようという試みである。 |
|
|
|
CListBox 等では、DeleteItem(), InsertItem()なる関数が存在したため、何も考えずにスワップできたのだが CListCtrl で同じ事をやろうとすると、データの再代入が起こってしまい非常に見栄えが悪いのである。 スワップしようと思ったとたんにすべてのデータを再描画するので時間がかかってしまう。 これを一瞬の内に行おうというのが今回のねらいである。 |
|
|
|
以下にスワップルーチンのソースコードを示す。
void CRenameDlg::SwapSetItem( LV_ITEM* item_src, LV_ITEM* item_dst, short dt )
{
//データのスワップ
item_src->iItem += dt;
item_dst->iItem -= dt;
//データのセット
m_ListCtrl.SetItem( item_src );
m_ListCtrl.SetItem( item_dst );
//データの初期化
item_src->iItem -= dt;
item_dst->iItem += dt;
}
void foo::SwapSelectedItem( short dt )
{
LV_ITEM item_src;
CString item1_src;
CString item2_src;
CString item3_src;
LV_ITEM item_dst;
CString item1_dst;
CString item2_dst;
CString item3_dst;
int nIdx;
memset( &item_src, 0, sizeof( item_src ) );
item_src.pszText = item1_src.GetBuffer( 512 );
item_src.cchTextMax = 512;
item_src.mask = LVIF_STATE | LVIF_TEXT;
item_src.stateMask = LVIS_SELECTED;
for( nIdx = m_ListCtrl.GetItemCount() - 1; nIdx >= 0; nIdx-- ){
item_src.iItem = nIdx;
m_ListCtrl.GetItem( &item_src );
if( item_src.state == LVIS_SELECTED ){
item1_src.ReleaseBuffer();
item_dst = item_src;
item_dst.iItem = nIdx + dt;
//変更先のアイテム1を取得
item_dst.pszText = item1_dst.GetBuffer( 512 );
m_ListCtrl.GetItem( &item_dst );
item1_dst.ReleaseBuffer();
SwapSetItem( &item_src, &item_dst, dt );
//変更もとのアイテム2を取得
item_src.pszText = item2_src.GetBuffer( 1024 );
item_src.iSubItem = 1;
m_ListCtrl.GetItem( &item_src );
item2_src.ReleaseBuffer();
//変更先のアイテム2を取得
item_dst.pszText = item2_dst.GetBuffer( 1024 );
item_dst.iSubItem = 1;
m_ListCtrl.GetItem( &item_dst );
item2_dst.ReleaseBuffer();
SwapSetItem( &item_src, &item_dst, dt );
//変更もとのアイテム3を取得
item_src.pszText = item3_src.GetBuffer( 20 );
item_src.iSubItem = 2;
m_ListCtrl.GetItem( &item_src );
item3_src.ReleaseBuffer();
//変更先のアイテム3を取得
item_dst.pszText = item3_dst.GetBuffer( 20 );
item_dst.iSubItem = 2;
m_ListCtrl.GetItem( &item_dst );
item3_dst.ReleaseBuffer();
SwapSetItem( &item_src, &item_dst, dt );
//
m_ListCtrl.SetItemState( nIdx, 0, LVIS_FOCUSED );
m_ListCtrl.PostMessage( WM_SETFOCUS, 0, 0 );
break;
}
}
}
void foo::OnUpitem()
{
SwapSelectedItem( -1 );
CheckItemSelected();
}
void foo::OnDownitem()
{
SwapSelectedItem( 1 );
CheckItemSelected();
}
|
|
|
|
最終的な決めて(?)としては「CListCtrl::SetItem()」だったわけであるが、非常に込み入ったソースコードになってしまった。 本来は、カラムが三つである保証が無い為 for ループ等を使うべきなのだが、そうするとサンプルとして非常に見にくくなるのであえて3つに分割してみた。 アイテムのスワップが出来たとすると、リストコントロールに並んだ任意のアイテムを入れ替える事が出来る為、見栄えも違ってくるのではなかろうか?(と考えるのは私だけか?) 次回はカラムを押してアイテムをソートするルーチンを紹介したい。(出来るかどうかは不明) |