TreeViewとImageListの関連付けがうまくいかない


ganchan  2009-04-18 16:49:38  No: 101654  IP: 192.*.*.*

OS:Window2000   VisualBasic Ver:6.0
ganchanといいます。昨日問題解決でほっとしていましたが、早速次の問題が出ました。懲りずによろしくお願いします。
TreeViewとImageListを連結しているのですが、SendMessage関数で連結後TreeView1.Nodes.Addを実行すると「イメージリスト コントロールは、使用する前に初期化する必要があります。」と言う
メッセージを表示します。ImageListの作成からTreeViewとの連結までのコードでどこかまずいところがあるのかもしれません。
下に実際のコードを記載しますので、ご指摘をお願いします。
<モジュール>
'-------------------------------------------------------
' 変数
'-------------------------------------------------------
' イメージ リストのハンドル
Public hndImgLst As Long
Public hndTreeView As Long
Public hndListView As Long
'-------------------------------------------------------
' 定数
'-------------------------------------------------------
'ImageList_Create関数のflags項目の定数
Public Const ILC_MASK = &H1         'マスクを使用
Public Const ILC_COLOR = &HFE       'デフォルトの動作、通常はILC_COLOR4
Public Const ILC_COLORDDB = &HFE    'DDBを使用
Public Const ILC_COLOR4 = &H4       '4ビット(16色)DIBセクションを使用
Public Const ILC_COLOR8 = &H8       '8ビット(256色)DIBセクションを使用
Public Const ILC_COLOR16 = &H10     '16ビットDIBセクションを使用
Public Const ILC_COLOR24 = &H18     '24ビットDIBセクションを使用
Public Const ILC_COLOR32 = &H20     '32ビットDIBセクションを使用
'SendMessage関数のwMsg項目の定数
Public Const TV_FIRST = &H1100
Public Const TVM_SETIMAGELIST = (TV_FIRST + 9)
Public Const TVM_GETNEXTITEM = (TV_FIRST + 10)
Public Const TVM_GETITEM = (TV_FIRST + 12)
Public Const TVM_SETITEM = (TV_FIRST + 13)
Public Const TVM_HITTEST = (TV_FIRST + 17)
Public Const TVM_SORTCHILDRENCB = (TV_FIRST + 21)
'SendMessage関数のlParam項目の定数
Public Const TVSIL_NORMAL = 0
Public Const TVSIL_STATE = 2
'-------------------------------------------------------
' 関数
'-------------------------------------------------------
' ImageList_Create関数のDeclare宣言
Public Declare Function ImageList_Create Lib "comctl32.dll" _
  (ByVal cx As Long, ByVal cy As Long, ByVal flags As Long, _
  ByVal cInitial As Long, ByVal cGrow As Long) As Long
' ImageList_ReplaceIcon関数のDeclare宣言
Public Declare Function ImageList_ReplaceIcon Lib "comctl32.dll" _
  (ByVal himl As Long, ByVal i As Long, ByVal hIcon As Long) As Long
' SendMessage関数のDeclare宣言
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
  (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
<サブ関数>
Public Function TreeView_SetImageList(hwnd As Long, himl As Long, iImage As Long) As Long
    TreeView_SetImageList = SendMessage(hwnd, TVM_SETIMAGELIST, ByVal iImage, ByVal himl)
End Function
<フォームロード>
Private Sub Form_Load()
    Dim Icon_Path As String
    Dim Icon_Full As String
    Dim nodX As Node                     'Nodeオブジェクト
    Dim ret As Long
    Dim msgbox_ret As Integer
    Dim msgbox_msg As String
    
    Icon_Path = "C:\Program Files\TacilityLedger\icons\"
    
    hndImgLst = ImageList_Create(16, 16, ILC_MASK Or ILC_COLOR8, 3, 0)
 
    If hndImgLst = 0 Then
        msgbox_msg = "イメージリストのハンドルを取得できません。"
        msgbox_ret = MsgBox(msgbox_msg, 48, "エラーメッセージ")
    Else
        Icon_Full = Icon_Path + "MAINICON.ICO"
        ImageList_AddIcon = ImageList_ReplaceIcon(hndImgLst, -1, LoadPicture(Icon_Full))
        Icon_Full = Icon_Path + "FOLDER.ICO"
        ImageList_AddIcon = ImageList_ReplaceIcon(hndImgLst, -1, LoadPicture(Icon_Full))
        Icon_Full = Icon_Path + "FOLDEROP.ICO"
        ImageList_AddIcon = ImageList_ReplaceIcon(hndImgLst, -1, LoadPicture(Icon_Full))
    End If

    TreeView1.Nodes.Clear
    
    TreeView1.Font.Name = "MS 明朝"
    TreeView1.Font.Size = 8
    TreeView1.Font.Bold = False
    TreeView1.Font.Italic = False
    
    hndTreeView = TreeView1.hwnd
    
    Call TreeView_SetImageList(hndTreeView, hndImgLst, TVSIL_STATE)
    'Call TreeView_SetImageList(hndTreeView, hndImgLst, TVSIL_NORMAL)
  
    TreeView1.Sorted = False
    TreeView1.HideSelection = False
    TreeView1.Indentation = 19
    TreeView1.LabelEdit = tvwManual
  
    Set nodX = TreeView1.Nodes.Add(, tvwFirst, "R", "ルート", 1)
    Set nodX = TreeView1.Nodes.Add("R", tvwChild, "K000001", "ルートの子供その1", 2)
    Set nodX = TreeView1.Nodes.Add("R", tvwChild, "K000002", "ルートの子供その2", 2)
    Set nodX = TreeView1.Nodes.Add("K000001", tvwChild, "K000003", "ルートの子供その1の子供", 2)
    Set nodX = TreeView1.Nodes.Add("K000002", tvwChild, "K000004", "ルートの子供その2の子供", 2)
    
    TreeView1.Nodes(TreeView1.Nodes(1).Index).EnsureVisible
    TreeView1.Nodes(TreeView1.Nodes(2).Index).EnsureVisible
    TreeView1.Nodes(TreeView1.Nodes(3).Index).EnsureVisible
    
End Sub
最後にFormにはTreeViewコントロールとListViewコントロールを貼り付けています
どうかよろしくお願いします。

編集 削除
VBレスキュー(花ちゃん)  2009-04-20 08:12:34  No: 101655  IP: 192.*.*.*

>TreeViewとImageListを連結しているのですが、SendMessage関数で
>連結後TreeView1.Nodes.Addを実行すると「イメージリスト コントロールは、
>使用する前に初期化する必要があります。」と言うメッセージを表示します。
>ImageListの作成からTreeViewとの連結までのコードでどこかまずいところが
>あるのかもしれません。


TreeView1.Nodes.Clear  を実施後、下記のような処理をどこかで実施されていますか?

Set TreeView1.ImageList = ImageList1

編集 削除
K.J.K.  2009-04-20 09:00:49  No: 101656  IP: 192.*.*.*

TreeView コントロールを、API関数を用いて作成した素の ImageList を組み合わせる
のならば、せめてアイコンのインデックスを後付で設定するぐらいにはしとかないと、
と思えますが。

編集 削除
ganchan  2009-04-20 09:41:29  No: 101657  IP: 192.*.*.*

VBレスキュー(花ちゃん)様、K.J.K様、投稿ありがとうございます。
VBレスキュー(花ちゃん)様、Set TreeView1.ImageList = ImageList1 は実行していません。
仮に実行してもオブジェクト名がImageList1でないのでだめだと思います。
K.J.K様、申し訳ないのですが
>せめてアイコンのインデックスを後付で設定
の意味が分からないのです。詳しく教えていただければ幸いです。
よろしくお願いします。

編集 削除
K.J.K.  2009-04-20 11:51:05  No: 101658  IP: 192.*.*.*

まず、本質的に無理がある方法だろう、ということは認識していますよね?
それでもやるならば、せめて、内部の動きをどう偽装するのか、とか、逆に
面倒なところをいかに迂回するのか、とかを考えてみるべきでしょう。

で、新規 Node を Add するときには、アイコンのインデックスを指定せず、
後で TVM_SETITEM などでアイコンのインデックスを指定する、というのが
無難なところでは。

Node オブジェクトから HTREEITEM を得る方法や、その逆は、かなり前に
どこかで書いた覚えがあるので、探せば多分見つかるでしょう。

編集 削除
ganchan  2009-04-21 11:36:35  No: 101659  IP: 192.*.*.*

K.J.Kさん、投稿ありがとうございます。
ImageListの作成からTreeViewとの連結をAPI関数で行っているのでTreeViewへのIcon登録もAPI関数で
行わないといけないと言うことですかね。この後追加、変更、削除も全てAPI関数で行わなければならい事になります。
実施に作りたいのですが、他の仕事がありその余裕がありません。少し時間を置いてすることにしました。
と言っても作るのに時間がかかりますが、一応中断ということにします。
色々ご指導ありがとうございます。今後もよろしくお願いします。

編集 削除