Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Shaun E on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

extractAssociatedIcon into an imagelist 1

Status
Not open for further replies.

nickske80

Programmer
Aug 2, 2003
55
BE
hello,

I tought I found the answer here a few weeks ago, but I can 't seem te find it anymore.

I am using the extractassociatedIcon API and I fill up an imagelist for the use of an listview.

I use a picturebox where I draw the icon and I load the picturebox.picture into the imagelist.

This works, but I am hoping that there is a better way to do this. A way without a picturebox. So that the icons ar invisible where they should be and don 't take the background of the picturebox.

Like I said, I tought I found the answer a few weeks ago in this forum, but I can 't seem to find it anymore.

Thanks for replying.
 
It seems that you want to use icons of registered file types in your listview. Thats why you want them to add to your imagelist.

Thread222-523561 demonstrate how to do the same without using an imagelist. It associates the system imagelist used by Windows Explorer to your listview and icons are imported directly into listview from the system imagelist without using a hidden picture box or even an internal imagelist in your application.

Note that the sample code in the above-mentioned thread works only with version 5.0 listview (COMCTL32.OCX). Version 6.0 listview (MSCOMCTL.OCX) does not seem to be happy with this code.
 
So if I use VB 6.0, The code will not work?

I don 't know because I didn 't had time to try out the code.

But thank you very much for your fast reply Hypetia

Is there an other way to do it in VB 6.0?

 
>So if I use VB 6.0, The code will not work?

Sure it will, if you use the listview from Common Controls 5.0 rather than Common Controls 6.0; VB6 comes with copies of both.
 
OK thanks for the replies strongm and Hypetia.
 
OK, so I have tried it.

And it works great. (thanks guys)

But I have a few more questions.

Is there a way to include the icons from folders and drives?
How can you get the big icons?
 
You can get icons from folders and drives as well. For that you need to specify the full path of the folder/drive to the SHGetFileInfo function and omit the flags FILE_ATTRIBUTE_NORMAL and SHGFI_USEFILEATTRIBUTES.

Insert the following lines of code just after the For-Next loop above End Sub statement in Form_Load in the same program presented in thread222-523561. It will add a drive item and a folder item (with their respective icons) to the listview.
___

SendMessage ListView1.hwnd, LVM_SETITEM, 0, lvi
Next

'Here is the C drive.
SHGetFileInfo "C:\", 0, sfi, Len(sfi), SHGFI_SYSICONINDEX Or SHGFI_TYPENAME
ListView1.ListItems.Add(Text:="C:\").SubItems(1) = sfi.szTypeName
lvi.iItem = ListView1.ListItems.Count - 1
lvi.mask = LVIF_IMAGE
lvi.iImage = sfi.iIcon
SendMessage ListView1.hwnd, LVM_SETITEM, 0, lvi
'and here goes the Windows folder.
'(assuming Windows directory = C:\Windows)
SHGetFileInfo "C:\Windows", 0, sfi, Len(sfi), SHGFI_SYSICONINDEX Or SHGFI_TYPENAME
ListView1.ListItems.Add(Text:="Windows").SubItems(1) = sfi.szTypeName
lvi.iItem = ListView1.ListItems.Count - 1
lvi.mask = LVIF_IMAGE
lvi.iImage = sfi.iIcon
SendMessage ListView1.hwnd, LVM_SETITEM, 0, lvi

End Sub
___

As far as large icon view is concerned, I am not successful with the large icon view using the above code. No icons appear in large icon (lvwIcon) view.

I have made a program that uses the same code. That program uses a lot of API stuff and I used APIs to create common controls like listview and statusbar, just for experimentation and to avoid the use of common controls OCX.

The listview created using CreateWindowEx function, worked perfectly with all the views that are supported by this control. But the VB's listview does not display icons in large icon view.

I think the defect does not lie in the code, it is the listview control which has a problem.
VB does not like its listviews to be tampered so extensively using APIs by the client application

I'll try to dig more about it and if I found something I will post it here.

As an alternative, you should also consider the link provided by strongm in the same thread, here I am pasting it again.

 
Thanks Hypetia for the reply.

The code works like a charm.

Te program that I am creating is also a way for me to learn API's.

I am a student and I am learning computer science focused on programming, but I 'm still a newbie at API's. We saw the basis in the courses.

So I would say that I am fairly good in 'normal' programming but with an interest in API's

Is the API way of creating the common controls a good way to learn or a bit to complicated for me?

Nickske
 
Creating and manipulating common controls (and other objects) through Win32 API is too hard and complicated for "pure" VB programmers. But it is a great opportunity to learn how things actually work --- and what a great job VB ActiveX controls are doing for us beneath the surface.
Moreover, with APIs, your program also becomes independent of the OCX files.

However, it is not recommended to make it a regular programming practice because this requires to recreate the wheel everytime in your every program. Why do we carry out the mammoth task if MS has already done it for us?
 
Ok, thanks Hypetia.

But I am still trying to find out how to get the large icons in the listview in case anybody knows.

Oh, by the way, Hypetia.

One star.
You truly deserve it.
 
Thanks,

Did you try the link posted above? The code used in that sample uses a method that makes use of large icons as well.

Or if you are really interested, I can e-mail you my program which uses some hardcore API stuff. As I stated above, the listview created with Win32 API supported all views including large icon view.

This program is a basically a file searching utility that searches for specified files burried in compressed archives like zip rar and cab.

For example, with the help of this utility, you can easily find in which cab the freecell.exe file is located on your Windows 98 CDROM.

But before that, I need views/permission from other members in this forum as e-mailing is not encouraged in this forum...
(faq222-2244 para 12)
 
maybe yet another stupid question from me,

but I am trying to get the icons from exe files.

Most of these exe files have personal icons.

But the routine that you suggest shows de default icon for an exe file.

Do I have to add a flag, or doesn 't this routine supports this function?
 
To extract the "personal" icon from the exe file, you need to call the SHGetFileInfo function just like the way you used to call it for adding drives and folders (the code posted above) i.e., supply the full filename of the exe file and omit the flags FILE_ATTRIBUTE_NORMAL and SHGFI_USEFILEATTRIBUTES. After that, when you modify the list item to set its icon, it will receive the "actual" icon of the executable.

In fact you can use this method for all files and folders, but the original method (that includes the above two flags) is a little bit faster, as it does not check the existance of file on disk but only needs its extension. That is why it fails to retrieve the actual icons of exe files but only their default icons.
 
Thanx for the reply Hypetia,

this works really good.

I think (and hope) that I have covered it all.

Thanx everybody who replied. (so actually only Hypetia and strongm ;-) )

 
One last question (I hope).

The code works really great except when I try to drag and drop the listitems.

I use the following code to fill the dragicon, and it doesn 't seem to work. There appears an ampty icon border (if you know what I mean).

lvwLinks.DragIcon = lvwLinks.HitTest(x, y).CreateDragImage

I can 't seem to get it to work.

thanx for replying.
 
The [tt]CreateDragImage[/tt] method fails because it requires the associated imagelist to create a picture object which does not exist in our case.

I found a solution to this problem. You can create a drag icon if you know the handle of the icon.

In our code we are only querying the imagelist index of the icon using the [tt]SHGFI_SYSICONINDEX[/tt] flag in the [tt]SHGetFileInfo[/tt] function.

However, we can also get the icon handle of that icon if we specify the [tt]SHGFI_ICON[/tt] flag as well when calling this function.

This flag causes the [tt]SHGetFileInfo[/tt] function to fill the [tt].hIcon[/tt] member of the [tt]SHFILEINFO[/tt] structure with the handle of the associated icon. This icon handle can be used later to create the drag image for that icon.

Here I sum up once again. You have to do the following steps.

+ Call the [tt]SHGetFileInfo[/tt] function specifying the [tt]SHGFI_ICON[/tt] flag as well, some thing like this...
[tt]
SHGetFileInfo FileName, 0, sfi, Len(sfi), SHGFI_SYSICONINDEX Or SHGFI_ICON[/tt]
Note that the value of flag [tt]SHGFI_ICON[/tt] is [tt]&H100[/tt].

+ Store the icon handle retrieved in the [tt]hIcon[/tt] member in the Tag property of the ListItem object. (We will use it later for creating the drag icon.)

+ Add this code. This creates a drag icon and initiates the drag operation manually if mouse is dragged over the listview. (assuming DragMode property of the listview is set to 0 - Manual.)
___

[tt]Private Sub ListView1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
If Button = vbLeftButton Then
Dim LI As ListItem
Set LI = ListView1.HitTest(x, y)
If LI Is Nothing Then Exit Sub
'Create the drag icon from the icon handle
'stored in the .Tag property previously
Set ListView1.DragIcon = IconToPicture(LI.Tag, True)
ListView1.Drag 'initiate the drag operation.
End If
End Sub[/tt]
___

And here is the coding of the [tt]IconToPicture[/tt] function. It creates a new picture object from the icon handle supplied to it as the argument, so that it can be used as the drag icon for the listview. (Uses the [tt]OleCreatePictureIndirect[/tt] function.)

Add all of the following code to a separate module for clarity.
___
[tt]
Private Type PictDesc
cbSizeofStruct As Long
picType As Long
hImage As Long
xExt As Long
yExt As Long
End Type
Private Type Guid
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (lpPictDesc As PictDesc, riid As Guid, ByVal fPictureOwnsHandle As Long, ipic As IPicture) As Long
Private Declare Function CopyIcon Lib "user32" (ByVal hIcon As Long) As Long

Public Function IconToPicture(ByVal hIcon As Long, ByVal MakeCopy As Boolean) As IPicture
Dim pd As PictDesc
Dim IPic As Guid

If hIcon = 0 Then Exit Function
If MakeCopy Then hIcon = CopyIcon(hIcon)

With pd
.cbSizeofStruct = Len(pd)
.picType = vbPicTypeIcon
.hImage = hIcon
End With

'Fill in IPicture GUID {7BF80980-BF32-101A-8BBB-00AA00300CAB}
With IPic
.Data1 = &H7BF80980
.Data2 = &HBF32
.Data3 = &H101A
.Data4(0) = &H8B
.Data4(1) = &HBB
.Data4(2) = &H0
.Data4(3) = &HAA
.Data4(4) = &H0
.Data4(5) = &H30
.Data4(6) = &HC
.Data4(7) = &HAB
End With

OleCreatePictureIndirect pd, IPic, True, IconToPicture
End Function[/tt]
___

I have tested all this stuff and found it to be working fine, atleast on my machine.

Hope this makes some sense...
 
thanx Hypetia,

Works like a charm.

I tought that I could find it on my own.
But I would have NEVER found this in my entire life.

so Thank you very much.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top