Hi. I hope I understood well your question. You cannot load an icon from a lnk file as it doesn't contain one, it just contains info about its target. If you want to get the icon for it, you have to resolve the path to its target file and work with that one. Below is something that works here on XP (both Ascii and Unicode). It does it by getting the shortcut's target first. If it's an exe, we can use ExtractIcon(Ex)_ and if not we ask the shell to get the default icon for the file:
Code: Select all
Procedure.s ShortcutTarget(Link.s)
;Inspired by Netmaestro's code
;http://forums.purebasic.com/english/viewtopic.php?p=327478&sid=b6724ae539278cb1e17bf4fcc3076408#p327478
;Modded for Unicode support
CompilerIf #PB_Compiler_Unicode
#CharLen = 2
Protected PSL.IShellLinkW
CompilerElse
#CharLen = 1
Protected PSL.IShellLinkA
CompilerEndIf
If CoInitialize_(0) = #S_OK
If CoCreateInstance_(?CLSID_ShellLink, 0, 1, ?IID_IShellLink, @PSL) = #S_OK
If PSL\QueryInterface(?IID_IPersistFile, @LinkFile.IPersistFile) = #S_OK
If LinkFile\Load(Link, 0) = #S_OK
If PSL\Resolve(0, 1) = #S_OK
CompilerIf #PB_Compiler_Unicode
*Target = AllocateMemory(#MAX_PATH + #CharLen)
If *Target <> 0
PSL\GetPath(*Target, #MAX_PATH, 0, 0)
Result.s = PeekS(*Target)
FreeMemory(*Target)
EndIf
CompilerElse
Result.s = Space(#MAX_PATH + #CharLen)
PSL\GetPath(Result, #MAX_PATH, 0, 0)
CompilerEndIf
EndIf
EndIf
EndIf
PSL\Release()
EndIf
CoUninitialize_()
EndIf
ProcedureReturn Result
EndProcedure
Procedure.i GetExtensionIcon(Ext.s)
SHInfo.SHFILEINFO
If Ext <> ""
SHGetFileInfo_(Ext,#FILE_ATTRIBUTE_NORMAL,@SHInfo,SizeOf(SHFILEINFO),#SHGFI_USEFILEATTRIBUTES|#SHGFI_ICON) ;Also see #SHGFI_SMALLICON
ProcedureReturn SHInfo\hIcon
EndIf
EndProcedure
;---- Put the link path here
MyTarget.s = ShortcutTarget("") ;Don't forget the ".lnk"
If MyTarget <> ""
If OpenWindow(0, 60, 60, 80, 80, MyTarget, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Extension.s = LCase(GetExtensionPart(MyTarget))
If Extension = "exe" Or Extension = "dll" Or Extension = "scr" ;More files can be added? :P
;An exe, extract the icon
MyIcon = ExtractIcon_(GetModuleHandle_(0), MyTarget, 0)
Else
;Any other filetype, get the icon from the system
MyIcon = GetExtensionIcon("."+Extension)
EndIf
If MyIcon <> 0
ImageGadget(0, 25, 25, 48, 48, MyIcon)
Else
Debug "Cannot get the icon"
EndIf
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
CloseWindow(0)
If MyIcon <> 0
DestroyIcon_(MyIcon)
EndIf
EndIf
Else
Debug "Can't get the target, check the link path / forgot to add .lnk?"
EndIf
DataSection
CLSID_ShellLink:
;{00021401-0000-0000-C000-000000000046}
Data.l $00021401
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
IID_IShellLink:
; DEFINE_SHLGUID(IID_IShellLinkA, 0x000214EEL, 0, 0);
; C000-000000000046
CompilerIf #PB_Compiler_Unicode
Data.l $000214F9
CompilerElse
Data.l $000214EE
CompilerEndIf
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
IID_IPersistFile:
;{0000010b-0000-0000-C000-000000000046}
Data.l $0000010b
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
EndDataSection