Hi, I have this function to get the thumbnails of files and folders, and it works fine, but in windows 7, it does not work with folders, the function uses "IExtractImage", in window 7 the error is when you call GetUIObjectOf (-2144927486)
Also try to use IShellItemImageFactory but this did not even work on windows 10
The strangest thing is that in a moment he walked but when he reset the project stopped working.
----------EDIT-----------------------------------------
For some strange reason when compiling the project, the IDE starts working, some library is loaded in memory that makes it work but what will be the library?
Never noticed that issue before, but yeah I'm getting the same problem. It returns the interface, but then errors with 80004005 (-2147467259) when calling GetLocation.
In the case of a folder, is there ever a circumstance where the thumbnail will differ from the system image list (which will show custom folder icons)? If you wanted to maximize compatibility you could also just do that on folders.
Otherwise I'd say yeah do a version check and user a newer call like IShellItemImageFactory for Vista+
Note that the behavior of requesting thumbnails from folders is highly variable across OS's. For me on Windows 7, IShellItemImageFactory won't return an image if you specifiy SIIGBF_THUMBNAILONLY for regular folders and folders with custom icons (i.e. all folders except for a very few that have actual thumbnails generated). The design is that if you don't specify an xxxONLY, then it will return the thumbnail first anyway, so it's ok to omit that flag. I just tested this to confirm, and it correctly showed a thumbnailed folder without a flag specified.
PS- Don't use ILFree; always use CoTaskMemFree instead. Sorry if that was my mistake, I used it in a few places before someone corrected me.
Last edited by fafalone; Feb 1st, 2017 at 12:35 AM.
Thanks Fafalone for your suggestions, I think this topic is already solved. Tomorrow I will ask another question in another post about the bmp obtained and convert it into GDI plus Image. I have some problems some images where they are reversed
PS- Don't use ILFree; always use CoTaskMemFree instead. Sorry if that was my mistake, I used it in a few places before someone corrected me.
Sorry, I don't understand, why do you suggest to use CoTaskMemFree instead of ILFree here, when MSDN article is directly saying to use ILFree for ILCreateFromPathW.
Can you, please, clarify it?
EDIT. Ahh, np, found the answer in the notice for ILFree.
Note When using Windows 2000 or later, use CoTaskMemFree rather than ILFree. ITEMIDLIST structures are always allocated with the Component Object Model (COM) task allocator on those platforms.
Last edited by Dragokas; Jan 18th, 2021 at 11:31 AM.
Never noticed that issue before, but yeah I'm getting the same problem. It returns the interface, but then errors with 80004005 (-2147467259) when calling GetLocation.
In the case of a folder, is there ever a circumstance where the thumbnail will differ from the system image list (which will show custom folder icons)? If you wanted to maximize compatibility you could also just do that on folders.
Otherwise I'd say yeah do a version check and user a newer call like IShellItemImageFactory for Vista+
Note that the behavior of requesting thumbnails from folders is highly variable across OS's. For me on Windows 7, IShellItemImageFactory won't return an image if you specifiy SIIGBF_THUMBNAILONLY for regular folders and folders with custom icons (i.e. all folders except for a very few that have actual thumbnails generated). The design is that if you don't specify an xxxONLY, then it will return the thumbnail first anyway, so it's ok to omit that flag. I just tested this to confirm, and it correctly showed a thumbnailed folder without a flag specified.
PS- Don't use ILFree; always use CoTaskMemFree instead. Sorry if that was my mistake, I used it in a few places before someone corrected me.
Hello everyone! My first post here ever :-) I'm an oldie in vb6 programming and I started VB programming back in VB3 in ealy 90th long before I even heard of Type Libs and I-Interfaces ...I ended up with vb6 in 2008 when .Net took much space and I didn't really want to learn a new langugae again since I felt very confortable with VB6 as a "cool" language...however this matter I don´t getting any errors at all when using this interface via GetUIObjectOf.
Everything is nice and smooth since I shall add the hbmp image extracted to the Imagelist (existing or new created). I always got -1 as a result when try to add this hbmp image to the imagelist created or to IImagelist class imported. Same error. Something wrong with the hbmp returned from the extract method? The Extract method differs a bit from Fafalone's TypeLib and the MSDN reference...regarding Fafalone hbmp = IExtractImage.Extract
and MSDN shows pointer IExtractImage::Extract lphbm.
Have Fafalone maybee made a error here in his TypeLib so the hbm-pointer gives wrong value in vb6? in comparison to the MSDN C++ version?
Type libraries allow for rewriting a last [out] argument as the return value instead. I'm not a fan of the technique, precisely because of the confusion it causes by not matching the documentation, but oleexp was forked from olelib and I didn't change existing instances of it so as to not break apps when moving to oleexp. You'll see it in numerous interfaces of oleexp that rewrite things like this, with none of the others having problems. Note the details of the issue: It works on files and folders in some versions of Windows, but fails *on folders* for Windows 7.
For another example look at the common IOleWindow;
By documentation,
Code:
HRESULT GetWindow(
[out] HWND *phwnd
);
But in oleexp rewritten as
Code:
HRESULT GetWindow(
[out, retval] long *phwnd);
So it appears in VB 6 as GetWindow() As Long. This is valid so long as the 'HRESULT' is left in place and the retval attribute is used.
This would break it:
long GetWindow(void);
I've been forced onto Windows 10 since this thread was last active, I should check out how it's behaving now. But your confusion is entirely justified on this point, and that's why I never used this style of rewriting final [out]s as returns (though I still don't want to break everyone's code by changing it).
PS- Off topic but I feel obliged to mention for any old timers looking at VB6 again or just returning to online VB6 communities so might not know, there's now a proper, backwards compatible successor: twinBASIC. It supports x64 compiling, multithreading, defining interfaces in language, and a laundry list of other new language features like overloading and generics, while still being 100% backwards compatible so you don't need to use any of that at first. It's still in beta under development so not quite to 100% yet, but it's very close and runs a lot of existing VB6 apps of significant complexity, including UserControls). We dreamt of something like for so long after MS abandoned VB6 for .NET, and after so many others failed to get off the ground it's finally happening. New releases at https://github.com/twinbasic/twinbasic/releases.
Last edited by fafalone; Oct 8th, 2023 at 10:56 PM.
I did take another look a this problem and I think I have found the issue for the errors reported.
I had the same issue as reported before my modification.
Code:
Public Function ShGetIExtractImage(ByVal pidlFolder As Long, ByRef pIEI As IExtractImage) As Long
Dim hr As Long
Dim pISF As IShellFolder
Dim sBuff As String
Dim pidlRelative As Long
If pidlFolder = 0 Then Exit Function
'The solution is to use the outgoing pidlrelative (in bold and red color) from this API istead of using the ingoing pidlFolder.
hr = SHBindToParent(pidlFolder, IID_IShellFolder, pISF, pidlRelative)
If hr = S_OK Then
hr = pISF.GetUIObjectOf(0, 1, pidlRelative, IID_IExtractImage, 0&, pIEI)
ShGetIExtractImage = hr
Else
ShGetIExtractImage = hr
End If
End Function
Private Sub Command11_Click()
Dim pidlFolder As Long
Dim hBmp As Long
Dim pIEI As IExtractImage
Dim pIRT As IRunnableTask
Dim sBuffer As String
Dim lpSize As SIZE
Dim hr As Long
Dim lpLVBKI As tagLVBKIMAGE
Dim lpRC As RECT
pidlFolder = m_cShell32.GetPIDLFromPath(Text1.Text)
hr = m_cShell32.ShGetIExtractImage(pidlFolder, pIEI)
If hr = S_OK Then
sBuffer = String(MAX_PATH, 0)
GetClientRect g_hWndLV, lpRC
With lpSize
.cx = lpRC.Right - lpRC.Left
.cy = lpRC.Bottom - lpRC.Top
End With
pIEI.GetLocation StrPtr(sBuffer), LenB(sBuffer), 0, lpSize, 32, IEIFLAG_QUALITY Or IEIFLAG_REFRESH Or IEIFLAG_SCREEN
Debug.Print sBuffer
hBmp = pIEI.Extract()
With lpLVBKI
.ulFlags = LVBKIF_SOURCE_HBITMAP Or LVBKIF_STYLE_NORMAL
.hbm = hBmp
End With
SendMessage g_hWndLV, LVM_SETBKIMAGE, 0, ByVal VarPtr(lpLVBKI)
DeleteObject hBmp
Set pIEI = Nothing
CoTaskMemFree pidlFolder
End If
End Sub
In this thread the IShellFolder's BindToObject method is used and not the SHBindToParent API which provides the correct pidl.