handle = GetDefaultIcon(extension$) (windows only)

Share your advanced PureBasic knowledge/code with the community.
User avatar
Joakim Christiansen
Addict
Addict
Posts: 2452
Joined: Wed Dec 22, 2004 4:12 pm
Location: Norway
Contact:

handle = GetDefaultIcon(extension$) (windows only)

Post 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
Last edited by Joakim Christiansen on Thu Dec 18, 2008 12:09 pm, edited 1 time in total.
I like logic, hence I dislike humans but love computers.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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
Last edited by srod on Thu Dec 18, 2008 12:23 pm, edited 2 times in total.
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post 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)
ImageThe happiness is a road...
Not a destination
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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:
I may look like a mule, but I'm not a complete ass.
User avatar
Joakim Christiansen
Addict
Addict
Posts: 2452
Joined: Wed Dec 22, 2004 4:12 pm
Location: Norway
Contact:

Post 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_()?
I like logic, hence I dislike humans but love computers.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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.
I may look like a mule, but I'm not a complete ass.
User avatar
Joakim Christiansen
Addict
Addict
Posts: 2452
Joined: Wed Dec 22, 2004 4:12 pm
Location: Norway
Contact:

Post 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)
I like logic, hence I dislike humans but love computers.
Post Reply