;---------------------------
mov EAX,IDI_APPLICATION
push EAX
xor EAX,EAX
push EAX
call LoadIcon
;---------------------------
push EAX
mov EAX,10;Y
push EAX
mov EAX,1;X
push EAX
push [EBP+@HDC]
call DrawIcon ; <--- here works fine !!!
;---------------------------
mov EAX,0
push EAX ;fuLoad
mov EAX,10h ;y height
push EAX ;cyDesired
mov EAX,10h ;x width
push EAX ;cxDesired
mov EAX,IMAGE_ICON
push EAX ;uType
mov EAX,OIC_WINLOGO
push EAX ;lpszName
xor EAX,EAX
push EAX ;hinst
call LoadImage ; <------ here returns NULL --- WHY ?
;---------------------------
push EAX
mov EAX,200;Y
push EAX
mov EAX,1;X
push EAX
push [EBP+@HDC]
call DrawIcon ; <---- then here is nothing too
cxDesired [in]
The width, in pixels, of the icon or cursor. If this parameter is zero and the fuLoad parameter is LR_DEFAULTSIZE, the function uses the SM_CXICON or SM_CXCURSOR system metric value to set the width. If this parameter is zero and LR_DEFAULTSIZE is not used, the function uses the actual resource width.
;====================================================================
; Displays last Windows system error (assuming there was one), using
; GetLastError(). Formats message and displays it using MessageBox().
;
; Returns last error code.
;====================================================================
ShowLastError PROC
LOCAL buffer[256]:BYTE
CALL GetLastError
MOV EDX, EAX
PUSH EAX
INVOKE FormatMessage, FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, EDX, 0, ADDR buffer, SIZEOF buffer, NULL
INVOKE MessageBox, 0, ADDR buffer, NULL, MB_OK
POP EAX
RET
ShowLastError ENDP
GetLastError after call DrawIcon returns what?
Hi Rockphorr,
you have to use LR_SHARED (0x00008000) for the fuLoad parameter since you try to load a system icon.
Without seeing complete code, I can't tell you what's wrong.Ok! Here it is. See attachment.
mov eax, 7F05 ; <--- resource ID??? but no resource file
That is what I see...
Should be 2 icons in the window, correct?
Shows standard application icon and nothing further. Upon calling LoadImage for the second icon, "ERROR_RESOURCE_DATA_NOT_FOUND" reported by olly
ok I see.. 7F05 == OIC_WINLOGO
But LoadImage doesnt seem to know what that is
I then tried:
mov EAX, IDI_WINLOGO
push EAX ;lpszName
mov EAX, hInstance
push EAX ;hinst
call LoadIcon
with the same result...
Windows 7 32 bit here btw
I would be tempted then to extract the wanted icon to file and create a resource file for it and do it that way. Unless there is something we are both not seeing
mov EAX,IDI_APPLICATION
push EAX
; xor EAX,EAX
push hInstance ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
call LoadIcon
;---------------------------
push EAX
mov EAX,10;Y
push EAX
mov EAX,1;X
push EAX
push hdc
call DrawIcon ;---------------------------
push IDI_APPLICATION
push hInstance
call LoadIcon
;---------------------------
push EAX
push 10 ; Y
push 1 ; X
push hdc
call DrawIcon
;--------------------------- ;---------------------------
invoke LoadIcon, hInstance, IDI_APPLICATION
;---------------------------
invoke DrawIcon, hdc, 1, 10, eax
;---------------------------invoke DrawIcon, hdc, 1, 10, rv(LoadIcon, hInstance, IDI_APPLICATION)Code: [Select]mov EAX,IDI_APPLICATION
push EAX
; xor EAX,EAX
push hInstance ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
call LoadIcon
;---------------------------
push EAX
mov EAX,10;Y
push EAX
mov EAX,1;X
push EAX
push hdc
call DrawIcon
Better:Code: [Select];---------------------------
push IDI_APPLICATION
push hInstance
call LoadIcon
;---------------------------
push EAX
push 10 ; Y
push 1 ; X
push hdc
call DrawIcon
;---------------------------
Even better:Code: [Select];---------------------------
invoke LoadIcon, hInstance, IDI_APPLICATION
;---------------------------
invoke DrawIcon, hdc, 1, 10, eax
;---------------------------
Efficient:Code: [Select]invoke DrawIcon, hdc, 1, 10, rv(LoadIcon, hInstance, IDI_APPLICATION)
And, of course, IDI_APPLICATION is useless if there is no IDI_APPLICATION icon resource.
mov eax, 7F05 ; <--- resource ID??? but no resource file
That is what I see...
Should be 2 icons in the window, correct?
Shows standard application icon and nothing further. Upon calling LoadImage for the second icon, "ERROR_RESOURCE_DATA_NOT_FOUND" reported by olly
invoke DrawIcon, hdc, 100, 100, rv(LoadImage, hInstance, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED)
jj2007 thank you for your help, but it is not a problem. A problem is null handle that LoadImage rerurns.
Indeed. But this line works perfectly:Code: [Select]invoke DrawIcon, hdc, 100, 100, rv(LoadImage, hInstance, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED)
jj2007 thank you for your help, but it is not a problem. A problem is null handle that LoadImage rerurns.
Use this:
invoke DrawIcon, hdc, 100, 100, rv(LoadImage, hInstance, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED)
Hi Rockphorr,
you have to use LR_SHARED (0x00008000) for the fuLoad parameter since you try to load a system icon.
I add it. There is no effect.
See a full asm source below please.
;---------------------------
mov EAX,LR_SHARED or LR_DEFAULTSIZE
push EAX ;fuLoad
mov EAX,0h ;y height - if set to zero LR_DEFAULTSIZE must be set in fuLoad
push EAX ;cyDesired
mov EAX,0h ;x width - if set to zero LR_DEFAULTSIZE must be set in fuLoad
push EAX ;cxDesired
mov EAX,IMAGE_ICON
push EAX ;uType
mov EAX,OIC_WINLOGO
push EAX ;lpszName
xor EAX,EAX ; must be zero if lpszName is a system resource
push EAX ;hinst
call LoadImage
;---------------------------
Hi Rockphorr,
you have to use LR_SHARED (0x00008000) for the fuLoad parameter since you try to load a system icon.
I add it. There is no effect.
See a full asm source below please.
Try this.Code: [Select];---------------------------
mov EAX,LR_SHARED or LR_DEFAULTSIZE
push EAX ;fuLoad
mov EAX,0h ;y height - if set to zero LR_DEFAULTSIZE must be set in fuLoad
push EAX ;cyDesired
mov EAX,0h ;x width - if set to zero LR_DEFAULTSIZE must be set in fuLoad
push EAX ;cxDesired
mov EAX,IMAGE_ICON
push EAX ;uType
mov EAX,OIC_WINLOGO
push EAX ;lpszName
xor EAX,EAX ; must be zero if lpszName is a system resource
push EAX ;hinst
call LoadImage
;---------------------------
You are setting hInstance to 0 - or more accurately you are setting the parameter that requires hInst to 0. Try passing hInst / hInstance instead
or use GetModuleHandle, NULL and pass that value to the hInst / hInstance parameter of the LoadImage
The LoadImage function loads an icon, cursor, or bitmap.
HANDLE LoadImage(
HINSTANCE hinst, // handle of the instance that contains the image
LPCTSTR lpszName, // name or identifier of image
UINT uType, // type of image
int cxDesired, // desired width
int cyDesired, // desired height
UINT fuLoad // load flags
);
Parameters
hinst
Identifies an instance of the module that contains the image to be loaded. To load an OEM image, set this parameter to zero.
IDI_WINLOGO
MAKEINTRESOURCE(32517)Default application icon.
Windows 2000: Windows logo icon.
the second (OIC_WINLOGO or IDI_WINLOGO) returns the error and ultimately fails. That is the problem. NOT WITH IDI_APPLICATION which works with LoadImage as well as with LoadIcon. Hope you understand this better now.
LoadIconA (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadicona)
IDI_APPLICATION
MAKEINTRESOURCE(32512)
Default application icon.
...
IDI_WINLOGO
MAKEINTRESOURCE(32517)
Default application icon.
Windows 2000: Windows logo icon.
the second (OIC_WINLOGO or IDI_WINLOGO) returns the error and ultimately fails. That is the problem. NOT WITH IDI_APPLICATION which works with LoadImage as well as with LoadIcon. Hope you understand this better now.
I perfectly understand this. But unless your OS is Windows 2000, IDI_WINLOGO won't work.QuoteLoadIconA (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadicona)
IDI_APPLICATION
MAKEINTRESOURCE(32512)
Default application icon.
...
IDI_WINLOGO
MAKEINTRESOURCE(32517)
Default application icon.
Windows 2000: Windows logo icon.
I perfectly understand this. But unless your OS is Windows 2000, IDI_WINLOGO won't work. Unless, of course... :tongue:
Aha! You’ve found the missing link. I knew their had to be a (sort of) reasonable explanation to this. :toothy:
invoke DrawIcon, hdc, 10, 1, rv(LoadImage, hInstance, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED)
invoke DrawIcon, hdc, 100, 100, rv(LoadImage, hInstance, IDI_WINLOGO, IMAGE_ICON, 0, 0, LR_SHARED)#include "resource.h"
IDI_APPLICATION ICON "\\Masm32\\MasmBasic\\icons\\Smiley.ico"
IDI_WINLOGO ICON "\\Masm32\\MasmBasic\\icons\\Globe.ico"
01 RT_MANIFEST "\\Masm32\\MasmBasic\\Res\\XpManifest.xml" push EAX
mov EAX,10;Y
push EAX
mov EAX,1;X
push EAX
push hdc
call DrawIconmov eax, 1
push eaxis just an unnecessary "verbose" way of doingpush 1?; Test LoadIcon():
INVOKE LoadIcon, NULL, IDI_WINLOGO
invoke DrawIcon, hdc, 10, 10, rv(LoadIcon, hInstance, IDI_APPLICATION)
invoke DrawIcon, hdc, 50, 10, rv(LoadImage, hInstance, IDI_WINLOGO, IMAGE_ICON, 0, 0, LR_SHARED) invoke LoadIcon, hInst, 123 ; with NULL, you only get the boring grey default icon
mov wc.hIcon,eax
mov wc.hIconSm,eax
*** LoadIcon test.rc not found, will try rsrc.rc ***
*** Assemble, link and run LoadIcon test ***
*** Assemble using UAsm64 ***
Tmp_File.asm(7) : Error A2106: Cannot open file: "\masm32\include\my_masm32rt.inc" [ENOENT]
Tmp_File.asm(14) : Error A2091: Language type must be specified
Tmp_File.asm(67) : Error A2210: Syntax error: WC
Tmp_File.asm(70) : Error A2082: Must be in segment block
Tmp_File.asm(72) : Error A2082: Must be in segment block
Tmp_File.asm(74) : Error A2082: Must be in segment block
Tmp_File.asm(75) : Error A2082: Must be in segment block
Tmp_File.asm(77) : Error A2082: Must be in segment block
Tmp_File.asm(79) : Error A2082: Must be in segment block
Tmp_File.asm(80) : Error A2082: Must be in segment block
Tmp_File.asm(88) : Error A2210: Syntax error: MainWinHandle
Tmp_File.asm(90) : Error A2210: Syntax error: StatusHandle
Tmp_File.asm(91) : Error A2082: Must be in segment block
Tmp_File.asm(93) : Error A2210: Syntax error: S1Handle
Tmp_File.asm(94) : Error A2210: Syntax error: S2Handle
Tmp_File.asm(96) : Error A2210: Syntax error: NullInstIconHandle
Tmp_File.asm(97) : Error A2210: Syntax error: InstIconHandle
Tmp_File.asm(106) : Error A2082: Must be in segment block
Tmp_File.asm(107) : Error A2082: Must be in segment block
Tmp_File.asm(109) : Error A2178: Too many arguments to INVOKE
Tmp_File.asm(110) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(117) : Error A2082: Must be in segment block
Tmp_File.asm(118) : Error A2092: PROC, MACRO or macro loop directive must precede LOCAL
Tmp_File.asm(122) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(123) : Error A2082: Must be in segment block
Tmp_File.asm(126) : Error A2082: Must be in segment block
Tmp_File.asm(127) : Error A2082: Must be in segment block
Tmp_File.asm(128) : Error A2082: Must be in segment block
Tmp_File.asm(129) : Error A2082: Must be in segment block
Tmp_File.asm(132) : Error A2082: Must be in segment block
Tmp_File.asm(133) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(134) : Error A2082: Must be in segment block
Tmp_File.asm(135) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(137) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(138) : Error A2082: Must be in segment block
Tmp_File.asm(139) : Error A2082: Must be in segment block
Tmp_File.asm(140) : Error A2082: Must be in segment block
Tmp_File.asm(141) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(142) : Error A2082: Must be in segment block
Tmp_File.asm(143) : Error A2082: Must be in segment block
Tmp_File.asm(144) : Error A2082: Must be in segment block
Tmp_File.asm(149) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(150) : Error A2082: Must be in segment block
Tmp_File.asm(153) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(154) : Error A2082: Must be in segment block
Tmp_File.asm(155) : Error A2082: Must be in segment block
Tmp_File.asm(157) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(158) : Error A2082: Must be in segment block
Tmp_File.asm(159) : Error A2082: Must be in segment block
Tmp_File.asm(160) : Error A2082: Must be in segment block
Tmp_File.asm(163) : Error A2160: INVOKE requires prototype for procedure
Tmp_File.asm(163) : Fatal error A1113: Too many errors
*** Assembly error ***
Damnit. Sorry 'bout that. I keep forgetting to change my personal include file ("my_masm32rt.inc") to the generic one everyone else here uses. Attachment above fixed.
So JJ, what's with those .asc files in your zips? Is that the source file as used by your editor? Why would we want that file, when we have the .asm file?
No resources needed loading by that program; just uses LoadIcon, NULL, IDI_WINLOGO. Works.
QuoteNo resources needed loading by that program; just uses LoadIcon, NULL, IDI_WINLOGO. Works.
It "works" because Windows gives you that ugly grey default icon that dates back to MS DOS times. Below you can see the difference. Hint: no luck with LoadIcon, NULL...
INVOKE LoadIcon, NULL, IDI_WINLOGO
hIcon1 = LoadIcon(NULL, IDI_WINLOGO);
hIcon2 = LoadImage(NULL, MAKEINTRESOURCE(OIC_WINLOGO), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
Wait, I'm confused. That picture you posted shows exactly the icon I got withCode: [Select]INVOKE LoadIcon, NULL, IDI_WINLOGO
Not the "ugly grey default icon that dates back to MS-DOS times". I loaded no resources. Just the code I gave here.
push hIcon
call GetLastError
pop hIcon;---------------------------
mov EAX,LR_SHARED
push EAX ;fuLoad
mov EAX,32 ;y height
push EAX ;cyDesired
mov EAX,32 ;x width
push EAX ;cxDesired
mov EAX,IMAGE_ICON
push EAX ;uType
;xor EAX,EAX
mov EAX,OIC_WINLOGO
push EAX ;lpszName
xor EAX,EAX
;mov EAX,hInstance
push EAX ;hinst
call LoadImage
;---------------------------
push EAX
mov EAX,100;Y
push EAX
mov EAX,1;X
push EAX
push [EBP+@HDC]
call DrawIcon
;---------------------------
mov EAX,LR_SHARED
push EAX ;fuLoad
mov EAX,32 ;y height
push EAX ;cyDesired
mov EAX,LR_SHARED
push EAX ;fuLoad
mov EAX,32 ;y height
push EAX ;cyDesired
Can you explain, in a few words, the logic of your approach? Why don't you use
push LR_SHARED ; fuLoad
push 32 ; cyDesired
?
INVOKE LoadImage, 0, OIC_WINLOGO, IMAGE_ICON, 32, 32, LR_SHARED
mov EAX,LR_SHARED
push EAX ;fuLoad
mov EAX,32 ;y height
push EAX ;cyDesired
Can you explain, in a few words, the logic of your approach? Why don't you use
push LR_SHARED ; fuLoad
push 32 ; cyDesired
?
Or better yet, as you suggested earlier, just dispense with all this push-push-call crap and use INVOKE as [insert name of deity here] intended:Code: [Select]INVOKE LoadImage, 0, OIC_WINLOGO, IMAGE_ICON, 32, 32, LR_SHARED
It does exactly the same thing as the mess you have and is much more readable, understandable and maintainable.
INVOKE LoadIcon, NULL, IDI_WINLOGO
what I just posted is the old W2K look. The other pics are from newer (Win7 in my case) versions. The difference is obvious.
There are two locations in a standard Windows program where to load icons:
A. in WinMain: mov wc.hIcon, rv(LoadIcon, ...
B. in the WM_PAINT handler: invoke DrawIcon, hdc, 10, 10, rv(LoadIcon, ...
The two locations behave differently. In WinMain, if you load an invalid icon, you get this:
(https://icon-library.com/images/windows-exe-icon/windows-exe-icon-25.jpg)
This is the ugly default icon for executables, and it dates back to the 20th Century - see also below the AltTab screenshot.
If you load an invalid icon in the WM_PAINT handler, you just see nothing.
If you use LoadIcon, hInstance..., Windows checks in this instance, i.e. in the resources of this exe, for a matching ICON.
If you use LoadIcon, NULL..., Windows checks elsewhere, and finds, in most cases, the crappy grey default icon.
I attach a testbed for playing, 48 lines only - the absolute minimum for a Windows program. Pure Masm32 SDK ;-)
I prefer a code style look like inside the debugger.
what I just posted is the old W2K look. The other pics are from newer (Win7 in my case) versions. The difference is obvious.
I have no access to a W2K machine, but I believe you, of course. So instead of the crappy grey icon, you get this colourful icon... but it doesn't change the rule that with LoadIcon, hInstance... you get an icon from the embedded resoures of your own exe, while with LoadIcon, NULL... you get some default icon as a friendly gift from Windows ;-)
BTW, that "crappy" icon isn't gray, it's green. And it is a "new" one, not one that dates back to the 20th century.
mov EAX,LR_SHARED
push EAX ;fuLoad
mov EAX,32 ;y height
push EAX ;cyDesired
Can you explain, in a few words, the logic of your approach? Why don't you use
push LR_SHARED ; fuLoad
push 32 ; cyDesired
?
It is my dos legacy code style.