2008-04-30(Wed)

ActiveBasicで仮想リストビューを作ってみた

なんか久~しぶりに ActiveBasic を弄ったら楽しくなった。
リストビューは公式BBSでソートやら判り易く取り上げられたので、ほったらかしてた。
ということで仮想リストビューを ActiveBasic でやってみた。

参考にさせて頂いたページ
http://www.kumei.ne.jp/c_lang/sdk2/sdk_108.htm
http://members3.jcom.home.ne.jp/progstudio/win_tips4.html


まずプロジェクトを作成して、RADツールでは何もしない。

んで、MainWnd.sbp を編集。
まずは先頭でいろいろ定義する。



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

'デフォルトで定義されない定数や構造体を定義
Const LVSICF_NOINVALIDATEALL  = &H00000001
Const LVSICF_NOSCROLL         = &H00000002

Type LV_ITEM
    mask As DWord
    iItem As DWord
    iSubItem As DWord
    state As DWord
    stateMask As DWord
    pszText As DWordPtr
    cchTextMax As DWord
    iImage As DWord
    lParam As LPARAM
End Type

Type LV_DISPINFO
    hdr As NMHDR
    item As LV_ITEM
End Type

Const VListView1 = 11000        '仮想リストビューのID(適当)
Dim hVList As HWND              '仮想リストビューのハンドル
Const max_count = 50000         '仮想リストビューの最大件数
Dim Data0[max_count] As BytePtr 'テストで格納してみる文字用の配列




次に、ウィンドウ作成時に仮想リストビューを作成する



Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
    '仮想リストビューを設置
    'スタイル値に仮想リストビュー作成フラグ LVS_OWNERDATA を混ぜてやる
    '元々のスタイル値は RADツールで一旦普通の ListView を作り、CallBack.wbp からコピペすると楽
    hVList = CreateWindowEx(&H00000200,"SysListView32","",&H50000009 or LVS_OWNERDATA,10,10,10,10,hMainWnd,VListView1 As HMENU,GetModuleHandle(0),0)
    SendMessage(hVList,WM_SETFONT,hFont_MainWnd As WPARAM,0)
    '仮想リストビューの拡張スタイル設定(罫線引いたり。別段しなくていい。)
    SendMessage( hVList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES or LVS_EX_FULLROWSELECT)
    'カラム初期設定
    Dim clm As LVCOLUMN             '構造体リストビューカラム
    clm.mask = LVCF_FMT or LVCF_WIDTH or LVCF_TEXT
    clm.fmt = LVCFMT_LEFT
    clm.pszText = "0番カラム"       'カラム名
    clm.iSubItem = 0                '作成するカラム番号
    clm.cx = 200 AS Long            '作成するカラム幅
    SendMessage( hVList, LVM_INSERTCOLUMN, 0, VarPtr(clm) As Long) 'カラム作成
    '仮想リストビューに最大件数を教えてやる
    SendMessage( hVList, LVM_SETITEMCOUNT, max_count, LVSICF_NOINVALIDATEALL )
    '格納テストする配列を適当に作成
    Dim i As Long
    Dim buf[255] As Char
    For i = 0 To max_count
        Data0[i] = calloc( 100 )
        wsprintf(buf,"data0:%d",i)
        lstrcpy( Data0[i], VarPtr(buf) )
    Next
End Sub




終了処理のところではテスト用に確保したメモリを解放



Sub MainWnd_Destroy()
    Dim i As Long
    For i = 0 To max_count
        free( Data0[i] )
    Next

    VirtualListViewTest4_DestroyObjects()
    PostQuitMessage(0)
End Sub




リサイズでウィンドウにフィットさせる



Sub MainWnd_Resize(SizeType As Long, cx As Integer, cy As Integer)
    Dim rc As RECT
    GetClientRect(hMainWnd, rc)
    '仮想リストビューをフィット
    MoveWindow( GetDlgItem(hMainWnd, VListView1), 0, 0, rc.right, rc.bottom, 0)
End Sub




肝心の仮想リストビューの内容更新は、WM_NOTIFY で送られてくるのでそっちで処理する



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

    'ウィンドウメッセージを調べる
    Select Case dwMsg
        Case WM_NOTIFY    'ウィンドウメッセージが来た
            Dim pDispInfo As *LV_DISPINFO    'LV_DISPINFO 構造体
            pDispInfo = lParam As *LV_DISPINFO
            'lParam を調べる
            Select Case pDispInfo->hdr.code
                Case LVN_GETDISPINFO         '仮想リストビューが画面更新に必要な情報を要求している
                    'サブアイテムの種類で処理を変える
                    'pDispInfo->item.iItem は更新するアイテムの番号
                    'pDispInfo->item.iSubItem は更新するカラムの番号
                    Select Case pDispInfo->item.iSubItem
                        Case 0:        'カラム0
                            'テキストの場合
                            if pDispInfo->item.mask And LVIF_TEXT Then
                                '表示バッファが足りているかチェックしてから文字列をコピーしている
                                if lstrlen( Data0[pDispInfo->item.iItem] ) < pDispInfo->item.cchTextMax Then
                                    lstrcpy( pDispInfo->item.pszText, Data0[pDispInfo->item.iItem] )
                                Else
                                    lstrcpy( pDispInfo->item.pszText, "バッファ不足" )
                                End If
                            End If
                    End Select
            End Select
    End Select

    ' イベントプロシージャの呼び出しを行います。
    MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function




これで終わり。
実行してみると・・いや~速いね。
役に立ったかな??

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

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

コメント

プロフィール

nakami

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

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