tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルListItemsコレクションのIcon番号を取得
記事No13657
投稿日: 2009/05/11(Mon) 18:16
投稿者ganchan
ganchanといいます。よろしくお願いします。
OS:Windows2000  Ver 6.0
ListItemコレクションのAddメソッドで登録したImageListコントロールのIcon番号をAPI関数
で取得したいのですが、うまくいきません。
SendMessage関数を使ってやっているのですが、根本的に違っているようです。下にコードを書きます。
    objItem.mask = LVIF_INDENT
    objItem.iItem = lngIndex
    objItem.iSubItem = 0
    lngLength = SendMessage(hWnd, LVM_GETITEM, 0&, objItem)
    imgNo = objItem.iIndent
及び
    objItem.mask = LVIF_IMAGE
    objItem.iItem = lngIndex
    objItem.iSubItem = 0
    lngLength = SendMessage(hWnd, LVM_GETITEM, 0, objItem)
    imgNo = objItem.iImage
です。
objItemはLV_ITEM構造体です。
ImageListコントロールのIcon番号を取得したいのです。どなたか教えてください。
お願いします。

[ツリー表示へ]
タイトルRe: ListItemsコレクションのIcon番号を取得
記事No13658
投稿日: 2009/05/11(Mon) 19:47
投稿者魔界の仮面弁士
> ListItemコレクションのAddメソッド
 ListItemsコレクション、ですよね。

> ListItemコレクションのAddメソッドで登録したImageListコントロールのIcon番号をAPI関数
> で取得したいのですが、うまくいきません。
・ImageList のバージョンは、ver5 / ver6 のいずれを使っているのか。
・Key ではなく、Index でなければならないのか。
・そもそも何故、わざわざ API で取得したいのか。
を説明していただけ無いでしょうか。

コントロールを使っているのであれば、API に頼る必要性が分かりませんし、
API で制御するのであれば、ImageList の生成部分も含めて、すべて API で制御すれば
良いような気がするのですけれども。
http://msdn.microsoft.com/en-us/library/bb761391.aspx

[ツリー表示へ]
タイトルRe^2: ListItemsコレクションのIcon番号を取得
記事No13659
投稿日: 2009/05/12(Tue) 09:19
投稿者ganchan
魔界の仮面弁士さん。投稿ありがとうございます。
> > ListItemコレクションのAddメソッド
>  ListItemsコレクション、ですよね。
はいそうです。
> ・ImageList のバージョンは、ver5 / ver6 のいずれを使っているのか。
ver6 (sp6)
> ・Key ではなく、Index でなければならないのか。
Indexでフォルダアイコンとそれ以外のアプリケーションアイコンを識別したいので
> ・そもそも何故、わざわざ API で取得したいのか。
> を説明していただけ無いでしょうか。
現在ImageListの作成からListView及びTreeViewとの関連付け、各コレクションの登録を
API関数に変更しようと思っています。
今回はistViewのソートの部分を作成中で、ListViewのListItemsコレクションの登録
            Set colL = Me.ListView1.ListItems.Add()
            colL.Key = "K" + Format(i, "#####0")
            colL.Text = gbl_data_titol(i)
            colL.Icon = imgXCnt
            colL.SmallIcon = imgXCnt
で登録後、ListViewのソート実行時にこのimgXCntの番号をAPI関数で取得したいのです。
ご指導よろしくお願いします。

[ツリー表示へ]
タイトルRe^3: ListItemsコレクションのIcon番号を取得
記事No13660
投稿日: 2009/05/12(Tue) 12:51
投稿者魔界の仮面弁士
API コードが上手く動作しないのだとしたら、その宣言部も含めて記述してください。
ByVal/ByRef の違いなど、小さな違いで動作が変わってくる可能性があるわけですし。


ちなみに、LVM_GETITEM の使い方そのものは合っていると思います。
API 宣言等が正しいのだとすれば、画像をインデックス指定している場合において、
hWnd に ListView.hWnd、lngIndex に ListItem.Index を指定することで、
>     objItem.mask = LVIF_IMAGE
>     objItem.iItem = lngIndex
>     objItem.iSubItem = 0
>     lngLength = SendMessage(hWnd, LVM_GETITEM, 0, objItem)
>     imgNo = objItem.iImage
の imgNo に「ListItem.SmallIcon - 1」または「ListItem.Icon - 1」が
入ってくるかと思います。(どちらになるかは、表示モード次第です)


> imgNo = objItem.iIndent
> objItemはLV_ITEM構造体です。
LV_ITEM に iIndent は定義されていなかったはずです。
LVITEM の間違いではありませんか?

ComCtl32.dll v4.70 以降では、(インデント等を指定できるように)拡張された LV_ITEM を
使うように定められていたかと思います。もっとも、現在のヘッダファイルでは、
旧 LV_ITEM を新 LVITEM の別名として処理しているので、LV_ITEM を使った場合にも
iIndent があるかのように見えてしまう可能性はありますけれどね。


> > ・そもそも何故、わざわざ API で取得したいのか。
> > を説明していただけ無いでしょうか。
> 現在ImageListの作成からListView及びTreeViewとの関連付け、各コレクションの登録を
> API関数に変更しようと思っています。

う〜む、それは「何故」ですか、と聞いていたつもりなのですけれども。
繰り返しの逆質問になりますが、API に変更しなければならない事情とは何でしょうか?


また、そもそも ImageList を API で作成するとなれば、その操作・管理方法は、
ActiveX コントロールの場合とは、異なる扱いとなりますよね。

API 管理の LVITEM.iImage / TVITEM.iImage / TVITEM.iSelectedImage はインデックス管理ですし、
VB6 の ListItem.Icon / Node.Image / Node.SelectedImage も、インデックス(またはキー)管理なので
イメージの管理方法や指定方法は酷似していますが、その画像や項目というのは、
Add で登録するわけでは無く、API で登録することになるわけですから、
対応付けは無意味だと思うのですけれども…。

[ツリー表示へ]
タイトルRe^4: ListItemsコレクションのIcon番号を取得
記事No13663
投稿日: 2009/05/12(Tue) 16:09
投稿者ganchan
魔界の仮面弁士さん。投稿ありがとうございます。
> う〜む、それは「何故」ですか、と聞いていたつもりなのですけれども。
> 繰り返しの逆質問になりますが、API に変更しなければならない事情とは何でしょうか?
操作の中でImageListのあるIndex番号のIconを変更しないといけないのが1つの理由です。
APIを使わないで変更する場合は
    ListView1.Icons = Nothing
    ImageList1.ListImages.Remove (1)
    Set imgX = ImageList1.ListImages.Add(1, imgXKey, ipic)                        
    ListView1.Icons = ImageList1
のコードを実行するのですが、NotingによりListViewのTextのIconが解除されるからです。
また、ソートのためにサブクラス化をつっかているのですが、ここの中のコードはAPIでしたい
からです。最後に今後の新しい仕様で対応しやすいと言う点です。
現在、ImageListの作成、Iconの登録まではAPIで作りました。ListViewとImageListとの関連
付けでストップしています。そのコードを下に記載します。
<Module>
' ハンドル
Public hndImgLstLVL As Long     'ListView LargeIcon用
Public hndImgLstLVS As Long     'ListView SmallIcon用
Public hndImgLstTV As Long      'TreeView用
Public hndListView As Long
Public hndTreeView As Long
' インデックス
Public IndxImgLstLVL As Long    'ListView LargeIcon用
Public IndxImgLstLVS As Long    'ListView SmallIcon用
Public IndxImgLstTV As Long     'TreeView用
' カウンタ
Public CntImgLstLVL As Long     'ListView LargeIcon用
Public CntImgLstLVS As Long     'ListView SmallIcon用
Public CntImgLstTV As Long      'TreeView用
' 定数
Public Const LVM_FIRST = &H1000
Public Const LVM_SETIMAGELIST = (LVM_FIRST + 3)  
Public Const LVSIL_NORMAL = 0
Public Const LVSIL_SMALL = 1
Public Const LVSIL_STATE = 2
' 関数
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 ListView_DeleteAllItems(hwnd As Long) As Boolean
    ListView_DeleteAllItems = SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0)
End Function
Public Function ListView_SetImageList(hwnd As Long, himl As Long, _
                                                  iImage As Long) As Long
    ListView_SetImageList = SendMessage(hwnd, LVM_SETIMAGELIST, ByVal iImage, _  
                                                  ByVal himl)
End Function

<Form_load>
    Dim Icon_Full As String
    Dim imgX As ListImage
    Dim imgXCnt As Integer
    Dim imgXKey As String
    Dim colX As ColumnHeader
    Dim colL As ListItem
    Dim nodX As Node
    Dim SHFI As SHFILEINFO
    Dim ipic As IPictureDisp
    Icon_Path = "C:\TacilityLedger\icons\"
    hndImgLstLVL = ImageList_Create(32, 32, ILC_MASK Or ILC_COLOR8, 3, 0)
    If hndImgLstLVL = 0 Then
        msgbox_msg = "イメージリスト(ListView LargeIcon)のハンドルを取得できません。"
        msgbox_ret = MsgBox(msgbox_msg, 48, "エラーメッセージ")
    Else
        Icon_Full = Icon_Path + "MAINICON.ICO"
        IndxImgLstLVL = ImageList_ReplaceIcon(hndImgLstLVL, -1, _
                                                      LoadPictureIcon_Full))
        Icon_Full = Icon_Path + "FOLDER.ICO"
        IndxImgLstLVL = ImageList_ReplaceIcon(hndImgLstLVL, -1, _
                                                      LoadPicture(Icon_Full))
        Icon_Full = Icon_Path + "Iconダミー.SCC"
        Ret = SHGetFileInfo(Icon_Full, FILE_ATTRIBUTES_NORMAL, SHFI, Len(SHFI), _
          SHGFI_USEFILEATTRIBUTES Or SHGFI_ICON Or SHGFI_LARGEICON Or _
          SHGFI_DISPLAYNAME)
        Set ipic = IconToIPicture(SHFI.hIcon)
        IndxImgLstLVL = ImageList_ReplaceIcon(hndImgLstLVL, -1, ipic)
        CntImgLstLVL = ImageList_GetImageCount(hndImgLstLVL)
    End If
    hndImgLstLVS = ImageList_Create(16, 16, ILC_MASK Or ILC_COLOR8, 3, 0)
    If hndImgLstLVS = 0 Then
        msgbox_msg = "イメージリスト(ListView SmallIcon)のハンドルを取得できません。"
        msgbox_ret = MsgBox(msgbox_msg, 48, "エラーメッセージ")
    Else
        Icon_Full = Icon_Path + "MAINICON.ICO"
        IndxImgLstLVS = ImageList_ReplaceIcon(hndImgLstLVS, -1, _
                                                       LoadPicture(Icon_Full))
        Icon_Full = Icon_Path + "FOLDER.ICO"
        IndxImgLstLVS = ImageList_ReplaceIcon(hndImgLstLVS, -1, _
                                                       LoadPicture(Icon_Full))
        Icon_Full = Icon_Path + "Iconダミー.SCC"
        Ret = SHGetFileInfo(Icon_Full, FILE_ATTRIBUTES_NORMAL, SHFI, Len(SHFI), _
                               SHGFI_USEFILEATTRIBUTES Or SHGFI_ICON Or _
                               SHGFI_SMALLICON)
        Set ipic = IconToIPicture(SHFI.hIcon)
        IndxImgLstLVS = ImageList_ReplaceIcon(hndImgLstLVS, -1, ipic)
        CntImgLstLVS = ImageList_GetImageCount(hndImgLstLVS)
    End If
    ListView1.Arrange = lvwAutoTop
   hndListView = ListView1.hwnd
    bRet = ListView_DeleteAllItems(hndListView)
    Ret = ListView_SetImageList(hndListView, 0, LVSIL_NORMAL)
    Ret = ListView_SetImageList(hndListView, 0, LVSIL_SMALL)
    Form1.ListView1.View = lvwReport
    Form1.ListView1.Font.Name = "MS 明朝"
    Form1.ListView1.Font.Size = 9
    Form1.ListView1.Font.Bold = False
    Form1.ListView1.Font.Italic = False
    Ret = ListView_SetImageList(hndListView, hndImgLstLVL, LVSIL_NORMAL)
    Ret = ListView_SetImageList(hndListView, hndImgLstLVS, LVSIL_SMALL)
変数のRetがすべてゼロです。後はうまくいっているようです。
本題と少しずれましたが、よろしくお願いします。

[ツリー表示へ]
タイトルRe: ListItemsコレクションのIcon番号を取得
記事No13668
投稿日: 2009/05/13(Wed) 12:19
投稿者K.J.K.
ImageList を自分で作らず、SHGetFileInfo(Path, Attr, Info, Len(Info), SHGFI_SYSICONINDEX)
や、
SHGetFileInfo(Path, Attr, Info, Len(Info), SHGFI_SYSICONINDEX Or SHGFI_SMALLICON )
の戻り値を使い、ImageList 中の Index は、Info.iIcon で指定すればいいのでは。

# http://hpcgi1.nifty.com/MADIA/VBBBS/wwwlng.cgi?print+200904/09040011.txt
# の続きなのでしょうが、質問する場所を変える意味はあまりないのでは。

[ツリー表示へ]
タイトルRe^2: ListItemsコレクションのIcon番号を取得
記事No13669
投稿日: 2009/05/13(Wed) 13:19
投稿者ganchan
K.J.Kさん。投稿ありがとうございます。
ListView_SetImageList関数の戻り値がゼロで連結していないと判断したのですが、
その下にListView_GetImageList関数を入れ実行すると戻り値がImageListのWhndが返り
正常に連結しているようです。現在確認中です。申し訳ありません。ありがとうございました。

[ツリー表示へ]
タイトルRe: ListItemsコレクションのIcon番号を取得
記事No13670
投稿日: 2009/05/13(Wed) 14:10
投稿者K.J.K.
> K.J.Kさん。投稿ありがとうございます。
> ListView_SetImageList関数の戻り値がゼロで連結していないと判断したのですが、

そういうことではなく、自分で ImageList を作成・Icon の追加を行わなくても
いいのでは、ということです。どうせ SHGetFileInfo を使うのならば、その辺りも
利用してしまうのが基本でしょう。

[ツリー表示へ]
タイトルRe^2: ListItemsコレクションのIcon番号を取得
記事No13671
投稿日: 2009/05/14(Thu) 13:38
投稿者ganchan
K.J.Kさん。投稿ありがとうございます。
> そういうことではなく、自分で ImageList を作成・Icon の追加を行わなくても
> いいのでは、ということです。どうせ SHGetFileInfo を使うのならば、その辺りも
> 利用してしまうのが基本でしょう。
SYSTEMのImageListを活用するということですか。
ListView_InsertItem等を使ってListViewの作成を現在しています。
なかなか難しくて苦労しています。
いま作っているプログラムはAPIでやるべきか、使わないほうがいいのか半信半疑です。
そこで、K.J.Kさんご意見を聞かせていただけませんか。今まで言ってきたのかもしれませんが。
よろしくお願いします。

[ツリー表示へ]
タイトルRe: ListItemsコレクションのIcon番号を取得
記事No13676
投稿日: 2009/05/15(Fri) 09:52
投稿者K.J.K.
> そこで、K.J.Kさんご意見を聞かせていただけませんか。今まで言ってきたのかもしれませんが。

それは貴方が判断すべきことでしょう。こちら側には判断材料がありませんし。

[ツリー表示へ]
タイトルLVITEMでなくLV_ITEMでした
記事No13666
投稿日: 2009/05/12(Tue) 16:46
投稿者ganchan
魔界の仮面弁士さん、ありがとうぞざいます。
Index番号を取得できました。
構造体の名称は中身があっていればなんでもいいと思い込んでいました。
以後注意します。ありがとうぞさいます。

[ツリー表示へ]