【HSP3.x 移植版】『HSPの裏技』リストビューでアイコンを使ってみる

『HSPの裏技』リストビューでアイコンを使ってみる(HSP2.x 版)をHSP3.x バージョンへ書き換えたものです。
http://chokuto.ifdef.jp/urawaza/lv_icon.html

※このサンプルで読み込まれるビットマップファイル iconlist.bmp は上記URLで公開されているものを使用することを仮定しています。

前のが間違ってたので書き直し

『HSPの裏技』リストビューでアイコンを使ってみる(HSP2.x 版)をHSP3.x バージョンへ書き換えたものです。
http://chokuto.ifdef.jp/urawaza/lv_icon.html

※このサンプルで読み込まれるビットマップファイル iconlist.bmp は上記URLで公開されているものを使用することを仮定しています。

前のが間違ってたので書き直し

  • タグ:
  • タグはありません
;【HSP3.x 移植版】
;『HSPの裏技』リストビューでアイコンを使ってみる
; http://chokuto.ifdef.jp/urawaza/lv_icon.html
; ※ファイル iconlist.bmp は上記URLで公開されているものを使用
;
; [参照]『Advanced HSP』ビットマップオブジェクト
; http://chokuto.ifdef.jp/advanced/bitmapobject.html

#module ;###### ビットマップオブジェクト作成モジュール #########

#uselib "gdi32.dll"
#cfunc CreateCompatibleDC "CreateCompatibleDC" int
#cfunc CreateCompatibleBitmap "CreateCompatibleBitmap" int, int, int
#func  SelectObject "SelectObject" int, int
#func  BitBlt "BitBlt" int, int, int, int, int, int, int, int, int
#func  DeleteDC "DeleteDC" int
#func  DeleteObject "DeleteObject" int

#define SRCCOPY     0x00CC0020

; DIBセクションオブジェクト作成
#defcfunc CreateDIB int px, int py, int sx, int sy

    ; DIBセクションオブジェクト作成
    hBitmap = CreateCompatibleBitmap(hdc, sx, sy)

    ; メモリデバイスコンテキスト作成
    hdcMemory = CreateCompatibleDC(hdc)

    ; ビットマップをデバイスコンテキストに選択
    SelectObject hdcMemory, hBitmap
    hOldBitmap = stat

    ; HSPウィンドウからビットマップにイメージをコピー
    BitBlt hdcMemory, 0, 0, sx, sy, hdc, px, py, SRCCOPY

    ; デバイスコンテキストの選択ビットマップを戻す
    SelectObject hdcMemory, hOldBitmap

    ; デバイスコンテキストを削除
    DeleteDC hdcMemory

    ; ビットマップオブジェクト(DIBセクション)のハンドルを返す
    return hBitmap

; DIBオブジェクト削除
#deffunc DeleteDIB int hbmp
    ; ビットマップオブジェクトを削除
    DeleteObject hbmp
    return

#global ;############# モジュール終わり ########################


#module ;########### イメージリスト操作モジュール ##############

#uselib "comctl32.dll"
#cfunc ImageList_Create "ImageList_Create" int,int,int,int,int
#func ImageList_Destroy "ImageList_Destroy" int
#func ImageList_AddMasked "ImageList_AddMasked" int,int,int
#func ImageList_Draw "ImageList_Draw" int,int,int,int,int,int

#define global ILC_COLOR    0x0000
#define global ILC_COLOR4   0x0004
#define global ILC_COLOR8   0x0018
#define global ILC_COLOR16  0x0010
#define global ILC_COLOR24  0x0018
#define global ILC_COLOR32  0x0020
#define global ILC_COLORDDB 0x00FE
#define global ILC_MASK     0x0001

#define ILD_TRANSPARENT 0x0001

; イメージリスト作成
#defcfunc CreateImageList int sx, int sy, int type, int num
    return ImageList_Create(sx, sy, type, num, 0)

; メージリスト破棄
#deffunc DestroyImageList int handle
    ImageList_Destroy handle
    return

; イメージリストに描画中ウィンドウのイメージ追加
#deffunc AddImageListItem int handle, int cx, int cy, int sx, int sy, int maskColor
    ; DIB作成
    hDIB = CreateDIB(cx, cy, sx, sy)

    ; ビットマップをイメージリストに追加
    ImageList_AddMasked handle, hDIB, maskColor
    firstItemIndex = stat

    ; DIB削除
    DeleteDIB hDIB

    return firstItemIndex

; イメージリストのイメージ描画
#deffunc DrawImageListItem int handle, int index, int cx, int cy
    ImageList_Draw handle, index, hdc, cx, cy, ILD_TRANSPARENT
    return

#global ;############# モジュール終わり ########################


#module ;############ リストビュー操作モジュール ###############

#uselib "comctl32.dll"
#func InitCommonControlsEx "InitCommonControlsEx" int

#uselib "user32.dll"
#func SetWindowLong "SetWindowLongA" int,int,int
#cfunc GetWindowLong "GetWindowLongA" int,int

; 各種定数定義
#define ICC_LISTVIEW_CLASSES    4

#define WS_CHILD    0x40000000
#define WS_VISIBLE  0x10000000

#define global LVS_ICON        0x0000
#define global LVS_REPORT      0x0001
#define global LVS_SMALLICON   0x0002
#define global LVS_LIST        0x0003
#define LVS_TYPEMASK    0x0003

#define LVM_SETIMAGELIST    0x1003
#define LVM_SETITEM         0x1006
#define LVM_INSERTITEM      0x1007
#define LVM_DELETEITEM      0x1008
#define LVM_INSERTCOLUMN    0x101B
#define LVM_GETNEXTITEM     0x100C
#define LVM_GETITEMTEXT     0x102D

#define LVCF_FMT        0x0001
#define LVCF_WIDTH      0x0002
#define LVCF_TEXT       0x0004
#define LVCF_SUBITEM    0x0008

#define LVIF_TEXT       0x0001
#define LVIF_IMAGE      0x0002

#define LVNI_SELECTED   0x0002

#define LVSIL_NORMAL    0x0000
#define LVSIL_SMALL     0x0001

#define GWL_STYLE       (-16)

; (外部から参照できるように global 指定)
#define global LVCFMT_LEFT      0x0000
#define global LVCFMT_RIGHT     0x0001
#define global LVCFMT_CENTER    0x0002

; リストビュー作成
#deffunc CreateListView int sx, int sy, int type, int hLargeImgList, int hSmallImgList
    ; コモンコントロールライブラリの初期化
    initinfo = 8, ICC_LISTVIEW_CLASSES
    InitCommonControlsEx varptr(initinfo)

    ; リストビューの作成
    styleFlags = WS_CHILD | WS_VISIBLE | type
    winobj "SysListView32", "", 0, styleFlags, sx, sy
    newObjID = stat

    ; イメージリスト(大きいアイコン)の追加
    if hLargeImgList {
        ; LVM_SETIMAGELIST メッセージ送信
        sendmsg objinfo_hwnd(newObjID), LVM_SETIMAGELIST, LVSIL_NORMAL, hLargeImgList
        logmes "LVM_SETIMAGELIST, LVSIL_NORMAL : " + stat
    }

    ; イメージリスト(小さいアイコン)の追加
    if hSmallImgList {
        ; LVM_SETIMAGELIST メッセージ送信
        sendmsg objinfo_hwnd(newObjID), LVM_SETIMAGELIST, LVSIL_SMALL, hSmallImgList
        logmes "LVM_SETIMAGELIST, LVSIL_SMALL : " + stat
    }

    return newObjID

; リストビューに列を追加
#deffunc InsertListViewColumn int objID, int index, str text, int align, int pixels
    textbuf = text
    ; LVCOLUMN 構造体をセット
    dim lvcolumn, 8
    lvcolumn(0) = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM
    lvcolumn(1) = align
    lvcolumn(2) = pixels
    lvcolumn(3) = varptr(textbuf)
    ; LVM_INSERTCOLUMN メッセージ送信
    sendmsg objinfo_hwnd(objID), LVM_INSERTCOLUMN, index, varptr(lvcolumn)
    return

; リストビューに項目追加
#deffunc InsertListViewItem int objID, int index, str text, int image
    textbuf = text
    ; LVITEM 構造体をセット
    dim lvitem, 13
    lvitem(0) = LVIF_TEXT | LVIF_IMAGE
    lvitem(1) = index
    lvitem(5) = varptr(textbuf)
    lvitem(7) = image
    ; LVM_INSERTITEM メッセージ送信
    sendmsg objinfo_hwnd(objID), LVM_INSERTITEM, 0, varptr(lvitem)
    return

; リストビューの項目またはサブ項目テキスト設定
#deffunc SetListViewItemText int objID, int index, int subitem, str text
    textbuf = text
    ; LVITEM 構造体をセット
    dim lvitem, 13
    lvitem(0) = LVIF_TEXT
    lvitem(1) = index
    lvitem(2) = subitem
    lvitem(5) = varptr(textbuf)
    ; LVM_SETITEM メッセージ送信
    sendmsg objinfo_hwnd(objID), LVM_SETITEM, 0, varptr(lvitem)
    return

; リストビューの項目またはサブ項目テキスト取得
#defcfunc GetListViewItemText int objID, int index, int subitem
    ; LVITEM 構造体をセット
    dim lvitem, 13
    lvitem(2) = subitem
    textbufsize = 256
    ; 取得できるまでバッファサイズを拡張
    repeat
        sdim textbuf, textbufsize
        lvitem(5) = varptr(textbuf)
        lvitem(6) = textbufsize
        ; LVM_GETITEMTEXT メッセージ送信
        sendmsg objinfo_hwnd(objID), LVM_GETITEMTEXT, index, varptr(lvitem)
        if stat < textbufsize - 1 : break
        textbufsize *= 2
    loop
    return textbuf

; リストビューの項目削除
#deffunc DeleteListViewItem int objID, int index
    ; LVM_DELETEITEM メッセージ送信
    sendmsg objinfo_hwnd(objID), LVM_DELETEITEM, index, 0
    return

; リストビューの選択項目のインデックス取得
#defcfunc GetSelectedListViewItem int objID, int startIndex
    ; LVM_GETNEXTITEM メッセージ送信
    sendmsg objinfo_hwnd(objID), LVM_GETNEXTITEM, startIndex, LVNI_SELECTED
    return stat

; リストビューの種別を変更
#deffunc SetListViewType int objID, int type
    ; 現在のウィンドウスタイルを取得
    style = GetWindowLong(objinfo_hwnd(objID), GWL_STYLE)

    ; リストビューの表示形式を変更
    style = (style & (-1 ^ LVS_TYPEMASK)) | type

    ; 新しいウィンドウスタイルを設定
    SetWindowLong objinfo_hwnd(objID), GWL_STYLE, style
    return


#global ;############# モジュール終わり ########################



    ; ビットマップファイルの読み込み
    buffer 2,,, 0           ; フルカラーモード
    picload "iconlist.bmp"

    ; 大きいアイコン(32×32)イメージリスト作成
    hLargeImgList = CreateImageList(32, 32, ILC_COLOR24 | ILC_MASK, 4)
    AddImageListItem hLargeImgList, 0, 0, 32*4, 32, 0xF0CAA6

    ; 小さいアイコン用にイメージを縮小
    pos 0, 0
    gzoom 16*4, 16, 2, 0, 0, 32*4, 32

    ; 小さいアイコン(16×16)イメージリスト作成
    hSmallImgList = CreateImageList(16, 16, ILC_COLOR24 | ILC_MASK, 4)
    AddImageListItem hSmallImgList, 0, 0, 16*4, 16, 0xF0CAA6

    gsel 0

    objsize ginfo_winx, 25
    button gosub "リスト種別変更", *OnChangeListTypeButtonClicked

    ; リストビュー作成
    pos 0, 25
    CreateListView ginfo_winx, ginfo_winy, LVS_ICON, hLargeImgList, hSmallImgList
    listviewID = stat

    ; 列を追加
    InsertListViewColumn listviewID, 0, "名前", LVCFMT_LEFT, 100
    InsertListViewColumn listviewID, 1, "読み", LVCFMT_LEFT, 200

    ; 項目追加・サブ項目設定
    InsertListViewItem listviewID, 0, "在原業平", 0
    SetListViewItemText listviewID, 0, 1, "ありわらのなりひら"

    InsertListViewItem listviewID, 1, "僧正遍昭", 1
    SetListViewItemText listviewID, 1, 1, "そうじょうへんじょう"

    InsertListViewItem listviewID, 2, "喜撰法師", 2
    SetListViewItemText listviewID, 2, 1, "きせんほうし"

    InsertListViewItem listviewID, 3, "大伴黒主", 3
    SetListViewItemText listviewID, 3, 1, "おおとものくろぬし"

    InsertListViewItem listviewID, 4, "文屋康秀", 0
    SetListViewItemText listviewID, 4, 1, "ふんやのやすひで"

    InsertListViewItem listviewID, 5, "小野小町", 1
    SetListViewItemText listviewID, 5, 1, "おののこまち"

    stop

*OnChangeListTypeButtonClicked
    ; リストビューのタイプを変更
    type = (type + 1) \ 4
    SetListViewType listviewID, type
    return