Page 1 of 1

handle = GetDefaultIcon(extension$) (windows only)

Posted: Thu Dec 18, 2008 9:53 am
by Joakim Christiansen
As the title says, it returns a handle to the default icon of any filetype. I didn't find such code laying around so I decided to share it, sharing is caring! ;)
Edit: Actually srod's code below is even better.

Code: Select all

Procedure.s RegistryReadKey(hKey,path$,key$="")
  Protected lpData.s{128}, lpcbData = 128, Result${1024}
  If RegOpenKeyEx_(hKey,path$,#Null,#KEY_READ,@hKey) = #ERROR_SUCCESS
    If RegQueryValueEx_(hKey,key$,#Null,#Null,@lpData,@lpcbData) = #ERROR_SUCCESS
      Result$ = PeekS(@lpData,lpcbData)
    EndIf
    RegCloseKey_(hkey)
  EndIf
  ProcedureReturn Result$
EndProcedure
Procedure GetDefaultIcon(extension$)
  Protected program$, icon$, iconPath$, iconNumber, iconHandle
  program$ = RegistryReadKey(#HKEY_CLASSES_ROOT,"."+extension$)
  icon$ = RegistryReadKey(#HKEY_CLASSES_ROOT,program$+"\DefaultIcon")
  icon$ = RemoveString(icon$,#DQUOTE$)
  ;Debug program$+" "+icon$
  If CountString(icon$,",")
    iconPath$   = StringField(icon$,1,",")
    iconNumber  = Val(StringField(icon$,2,","))
  Else
    iconPath$  = icon$
    iconNumber = 0
  EndIf
  iconHandle = ExtractIcon_(0,iconPath$,iconNumber)
  ;ExtractIconEx_(iconPath$,iconNumber,0,@iconHandle,1): iconHandle = PeekL(@iconHandle)
  ProcedureReturn iconHandle ;remember to use DestroyIcon_() to clean up
EndProcedure

OpenWindow(0,0,0,100,50,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)

icon = GetDefaultIcon("txt")
If icon
  StartDrawing(WindowOutput(0))
    DrawImage(icon,5,5)
  StopDrawing()
  DestroyIcon_(icon)
Else
  Debug "No icon found for this filetype."
EndIf

Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow

Posted: Thu Dec 18, 2008 11:05 am
by srod
Hi,

that doesn't work here for pdf files for some reason!!!

Here's the code I normally use :

Code: Select all

Define shInfo.SHFILEINFO

file$ = ".pdf"

If OpenWindow(0, 100, 200, 300, 200, "Icon!")
  If StartDrawing(WindowOutput(0))
    ;Large icon.
      SHGetFileInfo_(file$,#FILE_ATTRIBUTE_NORMAL,@shInfo,SizeOf(SHFILEINFO),#SHGFI_USEFILEATTRIBUTES|#SHGFI_ICON|#SHGFI_LARGEICON|#SHGFI_TYPENAME|#SHGFI_DISPLAYNAME) 
      If shInfo\hIcon
        DrawImage(shInfo\hIcon, 0, 0)
        DestroyIcon_(shInfo\hIcon)
      EndIf
    ;Small icon.
      SHGetFileInfo_(file$,#FILE_ATTRIBUTE_NORMAL,@shInfo,SizeOf(SHFILEINFO),#SHGFI_USEFILEATTRIBUTES|#SHGFI_ICON|#SHGFI_SMALLICON|#SHGFI_TYPENAME|#SHGFI_DISPLAYNAME) 
      If shInfo\hIcon
        DrawImage(shInfo\hIcon, 0, 40)
        DestroyIcon_(shInfo\hIcon)
      EndIf
    StopDrawing()
  EndIf
  Repeat
    EventID = WaitWindowEvent() 
  Until EventID = #PB_Event_CloseWindow
EndIf

Posted: Thu Dec 18, 2008 11:42 am
by Kwai chang caine
that doesn't work here for pdf files for some reason!!!
Hello SROD......it's me :D

Excuse your IDIOTMAN to contradict you, but the PDF works fine here, with the code of JOAKIM :oops:
For one time that something works with me and not for you :lol:

I have W2000, it's perhaps that :roll:

Thanks at you two for this good function 8)

Posted: Thu Dec 18, 2008 11:49 am
by srod
I'm using Vista 32.

For pdf files, JC's code is retrieving, not a default program from which to extract the icon, but the ProgID (COM) "AcroExch.Document".

I think the SHGetFileInfo_() function is definitely the 'fool proof' way of doing this. :wink:

Posted: Thu Dec 18, 2008 12:08 pm
by Joakim Christiansen
srod wrote:I think the SHGetFileInfo_() function is definitely the 'fool proof' way of doing this. :wink:
Yeah, thanks for sharing the code. Seems to retrieve more icons! :)
Btw srod, shouldn't you free up shInfo\hIcon with DestroyIcon_()?

Posted: Thu Dec 18, 2008 12:19 pm
by srod
Joakim Christiansen wrote:
srod wrote:I think the SHGetFileInfo_() function is definitely the 'fool proof' way of doing this. :wink:
Yeah, thanks for sharing the code. Seems to retrieve more icons! :)
Btw srod, shouldn't you free up shInfo\hIcon with DestroyIcon_()?
Yep, you're absolutely right! :)

I've altered the code appropriately. Thanks.

Posted: Thu Dec 18, 2008 12:29 pm
by Joakim Christiansen
Well, now I also made a handy function based on your example, and here is a little example (something to put in the code archive or whatever):

Code: Select all

EnableExplicit

Procedure GetDefaultIcon(extension$,small=#False)
  Protected shInfo.SHFILEINFO
  If small: small = #SHGFI_SMALLICON
  Else: small = #SHGFI_LARGEICON
  EndIf
  SHGetFileInfo_(extension$,#FILE_ATTRIBUTE_NORMAL,@shInfo,SizeOf(SHFILEINFO),#SHGFI_USEFILEATTRIBUTES|#SHGFI_ICON|small|#SHGFI_TYPENAME|#SHGFI_DISPLAYNAME)
  ProcedureReturn shInfo\hIcon ;remember to use DestroyIcon_() to clean up
EndProcedure

Define smallIcon = GetDefaultIcon(".exe",#True)
Define largeIcon = GetDefaultIcon(".exe")

If OpenWindow(0,0,0,180,50,"Default icon example",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  If StartDrawing(WindowOutput(0))
    DrawImage(largeIcon,5,5)
    DrawImage(smallIcon,42,5)
    StopDrawing()
  EndIf
  Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf 

DestroyIcon_(smallIcon)
DestroyIcon_(largeIcon)