2006-06-20(Tue)

リストビュー第5回 指定レコードを削除する

小休止 7 8 回

第5回 指定レコードを削除する

ジャックバウアーです。「24」の録画に失敗しました。
残念です。

さて今回はアイテムの削除をやる。
アイテムを削除すると、アイテムの固有32ビット値も歯抜けになるわけで(見えないけど)、削除後にそれの整列もやりたいと思う。
これまでの1~3回4回で加えた分に追加する。

1)メニュー項目の追加
アイテム削除用のメニューを追加。
IDIDM_DelItem にした。


2)アイテム削除
選択行を削除するようにしてみる。
選択行を判別するのは、第4回のアイテム削除と全く同じ処理になる。
ここでは面倒くさいからコピペして書き換える。
実戦ではもっとエクセレントな方法で無駄を省いてくれたまへ。

/*メニュー:アイテム削除*/
Sub MainWnd_IDM_DelItem_MenuClick()
    Dim lvi As LVITEM           'リストビューアイテムの構造体
    Dim j As Long
    Dim AllRecord As Long
    '全行数を取得
    AllRecord = SendMessage( hList, LVM_GETITEMCOUNT, 0, 0 )
    'アイテムが存在しなかった場合は終了
    If AllRecord <= 0 Then Exit Sub
    '選択されたレコードを調べる
    lvi.mask = LVIF_STATE               'アイテム状態について弄るよ
    lvi.stateMask = LVIS_SELECTED       '状態は選択状態のみを対象に操作しますよ
    For j = 0 to AllRecord - 1          '全てのレコードについて調べる(レコード番号は先頭が 0 です)
        lvi.iItem = j                   'インデックス(縦)
        SendMessage( hList, LVM_GETITEM, 0, VarPtr(lvi) As Long )   'アイテム取得
        '選択されているレコードなら削除する
        if lvi.state = LVIS_SELECTED then
            SendMessage( hList, LVM_DELETEITEM, j, 0 )  '削除
            AllRecord = AllRecord - 1   '全行数が1行減る
            j = j - 1                   '削除した1行が詰まるから、もう一回その行を調査
        End If
    Next
    '固有32ビット値を振りなおす
    lvlpRenew()
End Sub

削除の処理は1行だけ。
hListLVM_DELETEITEM を送ればアイテムを削除できる。
wParam削除するインデックス番号lParam0 を指定する。
最後に固有32ビット値を整理するが、この後も良く使う予定なので、lvlpRenew() という別な関数を用意する。

3)アイテムの固有32ビット値の整列
やっていることは単純。
先頭のインデックスから順に、0 1 2 …と連番で固有32ビット値を設定しているだけ。
俺はこれをやっておかないでソートや入れ替えでハマった。

/*固有32ビット値を振りなおす*/
Sub lvlpRenew()
    Dim lvi As LVITEM           'リストビューアイテムの構造体
    Dim i As Long
    Dim AllRecord As Long
    '全行数を取得
    AllRecord = SendMessage( hList, LVM_GETITEMCOUNT, 0, 0 )
    'アイテム分ループ
    lvi.mask = LVIF_PARAM   '固有32ビット値について弄るよ
    While i < AllRecord
        lvi.iItem = i           'i 行目のアイテム
        lvi.lParam = i          '固有32ビット値を i に設定
        SendMessage( hList, LVM_SETITEM, 0, VarPtr(lvi) As Long)    '振りなおす
        i = i + 1
    Wend
End Sub


今回は以上。
実行して適当なレコードを選択後、メニューからアイテム削除を選択するれば、選択レコードが削除されると思う。

じゃ!ハロモニを見て寝る。

以降これまでのソース


'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd

' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。

Dim hList As HWND   'リストビューのハンドル代入用グローバル変数

'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数


Function MainWndProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
    ' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。

    ' イベントプロシージャの呼び出しを行います。

    MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function


'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。


Sub MainWnd_Destroy()
    LV_SAMPLE_DestroyObjects()
    PostQuitMessage(0)
End Sub

/*ウィンドウ作成時*/
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
    'リストビュー初期設定
    hList = GetDlgItem( hMainWnd, ListView1 )    'リストビューのハンドルを取得
    SendMessage( hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
            LVS_EX_GRIDLINES or LVS_EX_FULLROWSELECT or LVS_EX_FLATSB )   'スタイル設定

    'カラム初期設定
    Dim clm As LVCOLUMN 'リストビューカラム構造体
    Dim i As Long
    Dim buf As String
    clm.mask = LVCF_FMT or LVCF_WIDTH or LVCF_TEXT  'マスクの設定(書式と幅と文字を弄るよ)
    clm.fmt = LVCFMT_LEFT           'カラムの書式(左詰でお願いします)
    clm.cx = 100                    'カラムの幅(とりあえず100で)
    For i = 0 to 2
        buf = "カラム" + Str$( i )
        clm.pszText = StrPtr( buf ) 'カラムに表示する文字
        SendMessage( hList, LVM_INSERTCOLUMN, i, VarPtr(clm) As Long) 'カラム作成
    Next
    Dim lvi As LVITEM   'リストビューアイテム構造体
    For i = 0 to 5
        lvi.mask = LVIF_TEXT or LVIF_PARAM  'マスクの設定(アイテムの文字と、固有32ビット値を弄るよ)
        lvi.lParam = i                      '固有32ビット値(とりあえず 0 )
        lvi.iItem = i                       'インデックス(縦方向)の位置
        lvi.iSubItem = 0                    'サブアイテム位置(横方向)、アイテム(先頭)を参照する場合は 0
        buf = "アイテム" + Str$( i )
        lvi.pszText = StrPtr( buf )         'レコード挿入時のアイテムの内容
        SendMessage( hList, LVM_INSERTITEM, 0, VarPtr(lvi) As Long) 'アイテム(つかアイテムの入ったレコード)を挿入
        'サブアイテムを格納してみる
        lvi.mask = LVIF_TEXT                'マスクの設定
        lvi.iSubItem = 1                    'カラム(横方向)位置
        buf = "サブアイテム" + Str$( 5 - i )
        lvi.pszText = StrPtr( buf )         'レコード挿入時の先頭アイテムの内容
        SendMessage( hList, LVM_SETITEM, 0, VarPtr(lvi) As Long)    'アイテムを格納
    Next
End Sub

/*リサイズされた*/
Sub MainWnd_Resize(SizeType As Long, cx As Integer, cy As Integer)
    MoveWindow( hList, 0, 0, cx, cy, 1 )    'リストビューの大きさを変更
End Sub

/*メニュー:アイテム取得*/
Sub MainWnd_IDM_GetItem_MenuClick()
    Dim lvi As LVITEM           'リストビューアイテムの構造体
    Dim buf[256] As Byte        'アイテム格納用
    Dim buf2 As String
    Dim i As Long
    Dim j As Long
    Dim AllRecord As Long
    'リストビューの全レコード数を取得
    AllRecord = SendMessage( hList, LVM_GETITEMCOUNT, 0, 0 )
    '選択されたレコードを調べる
    lvi.mask = LVIF_TEXT or LVIF_STATE  '状態とアイテムのテキストについて弄るよ
    lvi.stateMask = LVIS_SELECTED       '状態は選択状態のみを対象に操作しますよ
    For j = 0 to AllRecord -1           '全てのレコードについて調べる(レコード番号は先頭が 0 です)
        lvi.iItem = j                   'インデックス(縦)
        lvi.pszText = VarPtr(buf[0])    '格納するバッファのポインタ
        lvi.cchTextMax = 256            '格納するサイズ(Byte)
        'アイテム情報取得
        For i = 0 to 1
            lvi.iSubItem = i            'サブアイテム(横)
            SendMessage( hList, LVM_GETITEM, 0, VarPtr(lvi) As Long )   'アイテム取得
            buf2 = buf2 + MakeStr( buf As *Byte ) + " "
        Next
        '選択されているレコードなら表示する
        if lvi.state = LVIS_SELECTED then
            '表示
            MessageBox( hMainWnd, buf2, "レコード"+Str$(j), MB_OK )
        End If
        buf2 = ""
    Next
End Sub

/*メニュー:アイテム削除*/
Sub MainWnd_IDM_DelItem_MenuClick()
    Dim lvi As LVITEM           'リストビューアイテムの構造体
    Dim j As Long
    Dim AllRecord As Long
    '全行数を取得
    AllRecord = SendMessage( hList, LVM_GETITEMCOUNT, 0, 0 )
    'アイテムが存在しなかった場合は終了
    If AllRecord <= 0 Then Exit Sub
    '選択されたレコードを調べる
    lvi.mask = LVIF_STATE               'アイテム状態について弄るよ
    lvi.stateMask = LVIS_SELECTED       '状態は選択状態のみを対象に操作しますよ
    For j = 0 to AllRecord - 1          '全てのレコードについて調べる(レコード番号は先頭が 0 です)
        lvi.iItem = j                   'インデックス(縦)
        SendMessage( hList, LVM_GETITEM, 0, VarPtr(lvi) As Long )   'アイテム取得
        '選択されているレコードなら削除する
        if lvi.state = LVIS_SELECTED then
            SendMessage( hList, LVM_DELETEITEM, j, 0 )  '削除
            AllRecord = AllRecord - 1   '全行数が1行減る
            j = j - 1                   '削除した1行が詰まるから、もう一回その行を調査
        End If
    Next
    '固有32ビット値を振りなおす
    lvlpRenew()
End Sub

/*固有32ビット値を振りなおす*/
Sub lvlpRenew()
    Dim lvi As LVITEM           'リストビューアイテムの構造体
    Dim i As Long
    Dim AllRecord As Long
    '全行数を取得
    AllRecord = SendMessage( hList, LVM_GETITEMCOUNT, 0, 0 )
    'アイテム分ループ
    lvi.mask = LVIF_PARAM   '固有32ビット値について弄るよ
    While i < AllRecord
        lvi.iItem = i           'i 行目のアイテム
        lvi.lParam = i          '固有32ビット値を i に設定
        SendMessage( hList, LVM_SETITEM, 0, VarPtr(lvi) As Long)    '振りなおす
        i = i + 1
    Wend
End Sub


コメントの投稿

管理者にだけ表示を許可する

コメント

プロフィール

nakami

Author:nakami
可愛いテンプレートに似合う俺
うそAチームのスミス大佐

NAVI
カテゴリー
最近の記事
リンク
FC2カウンター
ブログ内検索
RSSフィード
sponsored link