|
-
Jan 5th, 2013, 12:55 PM
#8
Re: LoadImage issue #2
 Originally Posted by NeedHelp!
And we cannot use a resource name or ordinal to retrive the right icon - we have to use the index instead.
nIconIndex [in]
Type: int
. . .
If this value is a negative number and either phiconLarge or phiconSmall is not NULL, the function begins by extracting the icon whose resource identifier is equal to the absolute value of nIconIndex. For example, use -3 to extract the icon whose resource identifier is 3.
 Originally Posted by NeedHelp!
Therefore I wanted to apply LoadImage here too. - But following code is not working:
The following alterations worked for me (not too different from yours, really):
Code:
Private Declare Function FormatMessage Lib "kernel32.dll" Alias "FormatMessageW" (ByVal dwFlags As Long, ByVal lpSource As Long, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As Long, ByVal nSize As Long, Optional ByVal Arguments As Long) As Long
Private Declare Sub SetLastError Lib "kernel32.dll" (ByVal dwErrCode As Long)
Public Function LoadFromLibrary2(ByRef Library As String, _
ByRef ResNameOrOrdinal As Variant, _
Optional ByVal Size As IconSizeEnum = IS_First) As Boolean
'Always pass Strings ByRef, unless intentionally modifying them. Passing ByVal
'makes a copy, slowing down code. Variants are more efficiently passed ByRef too.
'For most other data types (Byte, Integer, Long, Single, etc.), ByVal is always faster.
'Local variables are still allocated whether they were used or not
'Might as well declare them all in one place
Dim hLib As Long, hMod As Long, lpszName As Long, tSize As Size
Call FreeIconMemory 'Destroy the previous Icon, if a new one is loaded
Call SetLastError(0&) 'Reset LastDllError to avoid retrieving previous error code
hLib = LoadLibrary(StrPtr(Library))
MsgBox """" & GetErrorMsg(Err.LastDllError) & """", vbInformation, "hLib = &H" & Hex$(hLib)
Call SetLastError(0&) 'SetLastError used only for debugging; may be removed if desired
hMod = GetModuleHandle(StrPtr(Library)) 'Don't FreeLibrary!
MsgBox """" & GetErrorMsg(Err.LastDllError) & """", vbInformation, "hMod = &H" & Hex$(hMod)
Select Case VarType(ResNameOrOrdinal)
Case vbString: lpszName = StrPtr(ResNameOrOrdinal)
Case vbInteger: lpszName = CLng(ResNameOrOrdinal)
Case Else: FreeLibrary hLib 'Free the module first
Call Err.Raise(5&) 'Invalid procedure call or argument
End Select
tSize = GetSize(Size)
'Some API's don't reset LastDllError upon success
Call SetLastError(0&)
'Do not use LR_SHARED for images that have non-standard sizes,
'that may change after loading, or that are loaded from a file.
m_hIcon = LoadImage(hMod, lpszName, IMAGE_ICON, tSize.cx, tSize.cy, LR_DEFAULTCOLOR)
MsgBox """" & GetErrorMsg(Err.LastDllError) & """", vbInformation, "m_hIcon = &H" & Hex$(m_hIcon)
hLib = FreeLibrary(hLib): Debug.Assert hLib 'If code stops here, the Library wasn't freed
LoadFromLibrary2 = m_hIcon <> 0& 'An inline expression is faster than a function call
End Function
Private Function GetErrorMsg(ByVal ErrNum As Long) As String
Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000&, MAX_BUFFER = &H10000
GetErrorMsg = Space$(MAX_BUFFER - 1&)
GetErrorMsg = Left$(GetErrorMsg, FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, _
0&, ErrNum, 0&, StrPtr(GetErrorMsg), MAX_BUFFER) - 2&)
End Function
Code:
Private Sub Form_Load()
. . .
With New Icon
.LoadFromLibrary2 "shell32.dll", 167, SIZE_Large
.DrawIcon hDC, ScaleX(Width, ScaleMode, vbPixels) - (.Width * 1.5!)
End With
End Sub
 Originally Posted by NeedHelp!
I tried it with GetModuleHandle, like recommended in the MSDN article to LoadImage and with LoadLibrary, in case the module has not been loaded yet.
Both APIs return the same handle, but the first call to one of them (it doesn't matter if GetModuleHandle or LoadLibrary is called first) does also show a dll error: 1402
The LoadImage API then returns 0 and gives the dll error 1813. (I tried it with "shell32.dll" for Library and the value 130 for ResNameOrOrdinal)
Reset the LastDllError (with SetLastError) prior to calling the desired API to make sure the error you're getting was set by it.
 Originally Posted by NeedHelp!
Maybe there is no icon with ordinal 130...
Indeed, there is no such icon resource in shell32.dll.
 Originally Posted by NeedHelp!
How can I check, which icons are in there?
With ResHacker I am just seeing lots of folders under "Icon" with a number as name containing an icon with the name "1033".
Under "Icon Group" I can find some ordinal information, but I still see the above mentiond result, if I use them.
Icon ordinals and names are listed under Icon Group. I believe 1033 is the English (US) language ID. Try Resource Hacker FX instead (unfortunately, the original site isn't available anymore). Scan the exe first on VirusTotal.
Last edited by Bonnie West; Jan 5th, 2013 at 01:16 PM.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|