Hi!
Thanks Lexikos, thats quite exactly the way I like it.
I've 2 (finally) Questions:
1.) In the first post, you link to the MSDN-Site, which contains a list of resource types that can be queried. But at the MSDN Site, the Types are Names (like RT_BITMAP), but the script doesn't accept this style. It seems like, you have to pass a Number as equivalent of the Style-Name. But there are no numbers on the MSDN Site. Does I have to guess the numbers, or exists a List of Numbers? Even with google, I found only lists with the Names, not numbers.
2.) Thats a What-If question. What if the RegisterCallback points on the same function as launched from? The callpack function has 4 parameters (which all needed, i guess). Woud it be possible to make a if-question (like if (lParam != "") ) and execute the code from there?
Should be the same, or am I wrong?
Thanks
O-W
EDIT: I tried to pack it into one function, an the RegisterCallback calls the function 7 times (using resource A_AhkPath) with Icon-Type. BUT: There are no Names of the resource.
Code:
MsgBox % "Icon Names:`n" GetResNames(A_AhkPath, 14)
;MsgBox % "Icon Names:`n" GetResourceNames(A_AhkPath, 14, C) "`n`n" C " Icons found"
ExitApp
GetResNames(File, Type, Count="", lParam="") {
If (File = "0") {
NumPut(1 + NumGet(lParam+0), lParam+0)
If (Count >> 16 != 0)
Count := DllCall("MulDiv", Int, Count, Int, 1, Int, 1, Str)
listptr := NumGet(lParam+4), listlen := NumGet(lParam+8)
If listptr {
listptr := DllCall("GlobalReAlloc", UInt, listptr, UInt, listlen+StrLen(Count)+2, UInt, 2)
NumPut(Asc("`n"), listptr + listlen, "char"), listlen += 1
} Else
listptr := DllCall("GlobalAlloc", UInt, 0, UInt, StrLen(Count)+1)
DllCall("RtlMoveMemory", UInt, listptr + listlen, Str, Count, UInt, StrLen(Count)+1)
listlen += StrLen(Count)
NumPut(listptr, lParam+4), NumPut(listlen, lParam+8)
;Msgbox, , , here, 1 ; Simple debug, msgbox appears 7 times
Return, true
}
If (!hmod := DllCall("GetModuleHandle", Str, File))
hmod := DllCall("LoadLibraryEx", Str, File, UInt, 0, UInt, 0x2), loaded := 1
enumproc := RegisterCallback("GetResNames", "F")
VarSetCapacity(param, 12, 0)
DllCall("EnumResourceNames", UInt, hmod, UInt, Type, UInt, enumproc, UInt, ¶m)
DllCall("GlobalFree", UInt, enumproc)
IfEqual, loaded, 1, DllCall("FreeLibrary", UInt, hmod)
If (listptr := NumGet(param,4)) {
list := DllCall("MulDiv", Int, listptr, Int, 1, Int, 1, Str)
DllCall("GlobalFree", UInt, listptr)
}
Count := NumGet(param)
Return, list
}
GetResourceNames(Filename, Type, ByRef Count="") {
; Get a handle to a loaded DLL.
If (!hmod := DllCall("GetModuleHandle", Str, File))
hmod := DllCall("LoadLibraryEx", Str, Filename, UInt, 0, UInt, 0x2)
; Create a callback to be called by EnumResourceNames().
enumproc := RegisterCallback("GetResourceNames_callback", "F")
; Create a structure to pass to the callback.
VarSetCapacity(param, 12, 0)
; Enumerate the resources.
DllCall("EnumResourceNames", UInt, hmod, UInt, Type, UInt, enumproc, UInt, ¶m)
; Free the memory used by the callback.
DllCall("GlobalFree", UInt, enumproc)
; If we loaded the DLL, free it now.
If loaded
DllCall("FreeLibrary", UInt, hmod)
; Retrieve the list of resource names.
If (listptr := NumGet(param,4)) {
list := DllCall("MulDiv", Int, listptr, Int, 1, Int, 1, Str)
DllCall("GlobalFree", UInt, listptr)
} ; Else: No resources or an error occurred. Leave list blank.
; Retrieve the number of resources enumerated.
Count := NumGet(param)
Return, list
}
GetResourceNames_callback(hModule, lpszType, lpszName, lParam) {
; Increment the counter for this enumeration.
NumPut(1 + NumGet(lParam+0), lParam+0)
; lpszName may be an integer identifier or a pointer to a string.
; If it is a pointer to a string, retrieve the string.
If (lpszName >> 16 != 0)
lpszName := DllCall("MulDiv", Int, lpszName, Int, 1, Int, 1,Str)
; Retrieve variables from the structure.
listptr := NumGet(lParam+4), listlen := NumGet(lParam+8)
If listptr {
; Reallocate the list to make room for the name of this resource.
listptr := DllCall("GlobalReAlloc", UInt, listptr, UInt, listlen+StrLen(lpszName)+2, UInt, 2)
; Append delimiter.
NumPut(Asc("`n"), listptr + listlen, "char"), listlen += 1
} Else {
; Allocate memory for the first resource name.
listptr := DllCall("GlobalAlloc", UInt, 0, UInt, StrLen(lpszName)+1)
}
; Append the name of this resource onto the list.
DllCall("RtlMoveMemory", UInt, listptr + listlen, Str, lpszName, UInt, StrLen(lpszName)+1)
listlen += StrLen(lpszName)
; Update the structure.
NumPut(listptr, lParam+4), NumPut(listlen, lParam+8)
; Continue enumeration.
Return, true
}
@lexikos: I modified the functions a little bit. I hope, its ok.