[v2-Beta] - getExtIcon Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

[v2-Beta] - getExtIcon

Post by AHK_user » 24 Oct 2021, 06:26

I am trying to update the getExtIcon function, but seem to get stuck when converting the NumPut and NumGet functions. I used UPtr type as this is the default in V1, or is this incorrect?

v1:

Code: Select all

IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam)
{
    NumPut(NumGet(lParam+4)+1, lParam+4)
    if (lpszName = NumGet(lParam+0))
    {
        NumPut(1, lParam+8)
        return false    ; break
    }
    return true
}
My conversion to V2, but I get the error invalid parameters

Code: Select all

IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam){
    NumPut("UPtr", NumGet(lParam + 4, "UPtr") + 1, lParam + 4)

    if (lpszName = NumGet(lParam + 0, "UPtr")){
        NumPut("UPtr", 1, lParam + 8)
        return false	; break
    }
    return true
}

;V2 full script

Code: Select all

#Requires AutoHotKey v2.0-beta.1
MsgBox(getExtIcon("ahk"))

getExtIcon(Ext){

    from := RegRead("HKEY_CLASSES_ROOT\." Ext)
    DefaultIcon := RegRead("HKEY_CLASSES_ROOT\" from "\DefaultIcon")
    DefaultIcon := StrReplace(DefaultIcon, '"')
    DefaultIcon := StrReplace(DefaultIcon, "%SystemRoot%", A_WinDir)
    DefaultIcon := StrReplace(DefaultIcon, "%ProgramFiles%", A_ProgramFiles)
    DefaultIcon := StrReplace(DefaultIcon, "%windir%", A_WinDir)

    I := StrSplit(DefaultIcon,",")

    Return I[1] " - " IndexOfIconResource( I[1], RegExReplace(I[2], "[^\d]+")  )
}

IndexOfIconResource(Filename, ID){
    hmod := DllCall("GetModuleHandle", "str", Filename)
    ; If the DLL isn't already loaded, load it as a data file.
    loaded := !hmod
        && hmod := DllCall("LoadLibraryEx", "str", Filename, "uint", 0, "uint", 0x2)

    enumproc := CallbackCreate(IndexOfIconResource_EnumIconResources, "F")
    param := Buffer(12, 0), NumPut("UPtr", ID, param, 0)
    ; Enumerate the icon group resources. (RT_GROUP_ICON=14)
    DllCall("EnumResourceNames", "uint", hmod, "uint", 14, "uint", enumproc, "uint", ¶m:=0)
    DllCall("GlobalFree", "uint", enumproc)

    ; If we loaded the DLL, free it now.
    if loaded
        DllCall("FreeLibrary", "uint", hmod)

    return NumGet(param, 8) ? NumGet(param, 4) : 0
}

IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam){
    NumPut("UPtr", NumGet(lParam + 4, "UPtr") + 1, lParam + 4)

    if (lpszName = NumGet(lParam + 0, "UPtr")){
        NumPut("UPtr", 1, lParam + 8)
        return false	; break
    }
    return true
}

;V1 full script

Code: Select all

#Requires AutoHotkey v1.1.33+
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

MsgBox, % getExtIcon("ahk")

getExtIcon(Ext) {
   I1 := I2:= ""
   RegRead, from, HKEY_CLASSES_ROOT, .%Ext%
   MsgBox % from
   RegRead, DefaultIcon, HKEY_CLASSES_ROOT, %from%\DefaultIcon
   StringReplace, DefaultIcon, DefaultIcon, `",,all
   StringReplace, DefaultIcon, DefaultIcon, `%SystemRoot`%, %A_WinDir%,all
   StringReplace, DefaultIcon, DefaultIcon, `%ProgramFiles`%, %A_ProgramFiles%,all
   StringReplace, DefaultIcon, DefaultIcon, `%windir`%, %A_WinDir%,all
   StringSplit, I, DefaultIcon, `,
Return I1 " - " IndexOfIconResource( I1, RegExReplace(I2, "[^\d]+")  )
}

IndexOfIconResource(Filename, ID)
{
    hmod := DllCall("GetModuleHandle", "str", Filename)
    ; If the DLL isn't already loaded, load it as a data file.
    loaded := !hmod
        && hmod := DllCall("LoadLibraryEx", "str", Filename, "uint", 0, "uint", 0x2)
    
    enumproc := RegisterCallback("IndexOfIconResource_EnumIconResources","F")
    VarSetCapacity(param,12,0), NumPut(ID,param,0)
    ; Enumerate the icon group resources. (RT_GROUP_ICON=14)
    DllCall("EnumResourceNames", "uint", hmod, "uint", 14, "uint", enumproc, "uint", ¶m)
    DllCall("GlobalFree", "uint", enumproc)
    
    ; If we loaded the DLL, free it now.
    if loaded
        DllCall("FreeLibrary", "uint", hmod)
    
    return NumGet(param,8) ? NumGet(param,4) : 0
}

IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam)
{
    NumPut(NumGet(lParam+4)+1, lParam+4)
    if (lpszName = NumGet(lParam+0))
    {
        NumPut(1, lParam+8)
        return false    ; break
    }
    return true
}

iseahound
Posts: 1444
Joined: 13 Aug 2016, 21:04
Contact:

Re: [v2-Beta] - getExtIcon

Post by iseahound » 24 Oct 2021, 09:01

Code: Select all

 IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam)
{
    NumPut(“ptr”, NumGet(lParam+4, “ptr”)+1, lParam+4)
    if (lpszName = NumGet(lParam, “ptr”))
    {
        NumPut(“ptr”, 1, lParam+8)
        return false    ; break
    }
    return true
}
Try this but make sure to replace my smart curly quotes with regular tics. iPhone OP

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: [v2-Beta] - getExtIcon

Post by swagfag » 24 Oct 2021, 09:28

what is "the getExtIcon" function? is that a function u wrote that somehow everyone is supposed to be already familiar with or something? is it a function u found? where is the source?

Code: Select all

    DllCall("EnumResourceNames", "uint", hmod, "uint", 14, "uint", enumproc, "uint", ¶m) ; <<<<<<
what is that??

AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: [v2-Beta] - getExtIcon

Post by AHK_user » 24 Oct 2021, 11:08

Changing it to ptr does not solves the error, unfortunately. :(

The function returns the location of the source of the icon, I use it to create a link menu based on a directory with icons, that can be modified by adding or removing files and folders. I will post the whole script if this issue is solved, but posted now just a part of the script to clarify my problem.
(Quicklinks V1)

@swagfag : getExtIcon originated from: https://www.autohotkey.com/board/topic/74066-get-file-type-icon/

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: [v2-Beta] - getExtIcon

Post by swagfag » 24 Oct 2021, 11:29

https://www.autohotkey.com/board/topic/24632-reference-negative-icon-numbers/#entry159967
looks like uve copypasted some badly formatted old forum crap
¶m should have been &param in v1 and just param (no := 0!! its a Buffer you have created that you are populating) in v2

AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: [v2-Beta] - getExtIcon

Post by AHK_user » 10 Nov 2021, 14:43

When filling in Param, I get an error message that it was expected a string and not a buffer.
I tried to use 0 as I found on an old forum post, then I get stuck at the line NumPut("UPtr", NumGet(lParam + 4, "UPtr") + 1, lParam + 4) for invalid parameters. :headwall:

Code: Select all

#Requires AutoHotKey v2.0-beta.1
MsgBox(getExtIcon("ahk"))

getExtIcon(Ext){

    from := RegRead("HKEY_CLASSES_ROOT\." Ext)
    DefaultIcon := RegRead("HKEY_CLASSES_ROOT\" from "\DefaultIcon")
    DefaultIcon := StrReplace(DefaultIcon, '"')
    DefaultIcon := StrReplace(DefaultIcon, "%SystemRoot%", A_WinDir)
    DefaultIcon := StrReplace(DefaultIcon, "%ProgramFiles%", A_ProgramFiles)
    DefaultIcon := StrReplace(DefaultIcon, "%windir%", A_WinDir)

    I := StrSplit(DefaultIcon,",")

    Return I[1] " - " IndexOfIconResource( I[1], RegExReplace(I[2], "[^\d]+")  )
}

IndexOfIconResource(Filename, ID){
    hmod := DllCall("GetModuleHandle", "str", Filename)
    ; If the DLL isn't already loaded, load it as a data file.
    loaded := !hmod
        && hmod := DllCall("LoadLibraryEx", "str", Filename, "uint", 0, "uint", 0x2)

    enumproc := CallbackCreate(IndexOfIconResource_EnumIconResources, "F")
    param := Buffer(12, 0), NumPut("UPtr", ID, param, 0)
    ; Enumerate the icon group resources. (RT_GROUP_ICON=14)
    DllCall("EnumResourceNames", "uint", hmod, "uint", 14, "uint", enumproc, "uint", 0)
    DllCall("GlobalFree", "uint", enumproc)

    ; If we loaded the DLL, free it now.
    if loaded
        DllCall("FreeLibrary", "uint", hmod)

    return NumGet(param, 8) ? NumGet(param, 4) : 0
}

IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam){
    NumPut("UPtr", NumGet(lParam + 4, "UPtr") + 1, lParam + 4)

    if (lpszName = NumGet(lParam + 0, "UPtr")){
        NumPut("UPtr", 1, lParam + 8)
        return false	; break
    }
    return true
}

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: [v2-Beta] - getExtIcon

Post by swagfag » 10 Nov 2021, 14:59

dont look at old forum posts, look at the documentation and figure out what the functions ure calling are supposed to do, how theyre supposed to be used, what arguments they expect and what they return

just changing random shit and hoping it works is pretty pointless
image.png
image.png (68.21 KiB) Viewed 1236 times
does passing 0 as the, quote msdn, "application-defined value passed to the callback function" and then trying to dereference(NumGet) it as though it were a valid pointer to anything make any sense to u??
also fix those dllcall arg types. a UInt is not ptr-sized on x64

just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [v2-Beta] - getExtIcon  Topic is solved

Post by just me » 11 Nov 2021, 11:36

Well, numeric icon IDs are limited to 16 bit values. So the following might do it:

Code: Select all

IndexOfIconResource(Filename, ID) {
   ; If the DLL isn't already loaded, load it as a data file.
   If !DllCall("GetModuleHandle", "Str", Filename, "UPtr")
      HMOD := DllCall("LoadLibraryEx", "Str", Filename, "Ptr", 0, "UInt", 0x02, "UPtr")
   EnumProc := CallbackCreate(IndexOfIconResource_EnumIconResources, "F")
   Param := Buffer(12, 0)
   NumPut("UInt", ID, Param)
   ; Enumerate the icon group resources. (RT_GROUP_ICON=14)
   DllCall("EnumResourceNames", "Ptr", HMOD, "UInt", 14, "Ptr", EnumProc, "Ptr", Param)
   CallbackFree(EnumProc)
   ; If we loaded the DLL, free it now.
   If (HMOD)
      DllCall("FreeLibrary", "Ptr", HMOD)
   Return (NumGet(Param, 8, "UInt")) ? NumGet(Param, 4, "UInt") : 0
}
IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam) {
   NumPut("UInt", NumGet(lParam + 4, "UInt") + 1, lParam + 4)
   If (lpszName = NumGet(lParam, "UInt")){
      NumPut("UInt", 1, lParam + 8)
      Return False ; break
   }
   Return True
}
*without warranty* ;)

AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: [v2-Beta] - getExtIcon

Post by AHK_user » 11 Nov 2021, 16:38

just me wrote:
11 Nov 2021, 11:36
Well, numeric icon IDs are limited to 16 bit values. So the following might do it:

Code: Select all

IndexOfIconResource(Filename, ID) {
   ; If the DLL isn't already loaded, load it as a data file.
   If !DllCall("GetModuleHandle", "Str", Filename, "UPtr")
      HMOD := DllCall("LoadLibraryEx", "Str", Filename, "Ptr", 0, "UInt", 0x02, "UPtr")
   EnumProc := CallbackCreate(IndexOfIconResource_EnumIconResources, "F")
   Param := Buffer(12, 0)
   NumPut("UInt", ID, Param)
   ; Enumerate the icon group resources. (RT_GROUP_ICON=14)
   DllCall("EnumResourceNames", "Ptr", HMOD, "UInt", 14, "Ptr", EnumProc, "Ptr", Param)
   CallbackFree(EnumProc)
   ; If we loaded the DLL, free it now.
   If (HMOD)
      DllCall("FreeLibrary", "Ptr", HMOD)
   Return (NumGet(Param, 8, "UInt")) ? NumGet(Param, 4, "UInt") : 0
}
IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam) {
   NumPut("UInt", NumGet(lParam + 4, "UInt") + 1, lParam + 4)
   If (lpszName = NumGet(lParam, "UInt")){
      NumPut("UInt", 1, lParam + 8)
      Return False ; break
   }
   Return True
}
*without warranty* ;)
:dance:
Thanks a lot for the explanation and solution, @just me and @swagfag, this seems to work perfectly.

My excuses for my limited understanding of the NumGet/NumPut and DllCall functions.

I have posted my implementation of the code to this post QuickLinks.
This creates a linkmenu based on a directory, this is quite user-friendly to modify fast.

Post Reply

Return to “Ask for Help (v2)”