News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

LoadImage

Started by bf2, October 16, 2012, 01:00:37 AM

Previous topic - Next topic

bf2

In my basic Windows program copied from Iczelion, there are two calls to LoadIcon and LoadCursor.

   INVOKE   LoadIcon, NULL, IDI_ASTERISK
   ...
   INVOKE   LoadCursor, NULL, IDC_HAND

I saw on MSDN that these have been replaced by LoadImage.

Questions:
1. I tried to replace these calls with LoadImage in the following way but that didn't seem to work:
   INVOKE   LoadImage, NULL, IDI_ASTERISK, NULL, NULL, NULL, NULL

2. The prototypes of LoadIcon and LoadCursor seem to suggest that the second parameter is a pointer to string (LPCTSTR). How are we then able to pass an integer constant (IDI_ASTERISK)?

Thanks.

dedndave

#1
don't always believe msdn when they say a function has been replaced
the old functions will be around for a long time

there are times to use LoadIcon, LoadCursor and there are times to use LoadImage
use LoadImage if the older method won't work

for example, LoadIcon loads standard sized icons
if you want to load a non-standard size, use LoadImage

i use LoadCursor to load any system cursor or any resource cursor that is standard size
i use LoadImage to get an HBITMAP type handle

LoadIcon and LoadCursor actually return different types of handles than LoadImage

there are a number of functions that allow the use of a constant in place of a lpsz
this works because an address will always be greater than 65535
the constants used are always less than 65536, so the function knows which you are passing

bf2

Thanks. Never knew that about string pointer parameters.

TouEnMasm

Seems that Iczelion is on a good path:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
The IDI_ASTERISK  seem to be a resource ID who replace the lpszName
This could be done because a pointer on data is always > 400 000h
It's the function who made the choice to load a file or to load a resource.
a resource had a number ID < 10 000h (or something like that)
There is a windows MACRO who do that
Quote
IS_INTRESOURCE MACRO valeur
   mov   eax, valeur
   shr   eax, 16         ;/10000h sans reste 400000 >    40 neg
   neg   eax
   sbb   eax, eax
   add   eax, 1
ENDM
Fa is a musical note to play with CL

dedndave

IS_INTRESOURCE MACRO valeur
mov eax, valeur
shr eax, 16 ;/10000h sans reste 400000 > 40 neg
neg eax
sbb eax, eax
add eax, 1
ENDM

yikes !   :shock:

the reason LoadImage did not do what you wanted is probably because of the 3rd parm you were using
INVOKE   LoadImage, NULL, IDI_ASTERISK, NULL, NULL, NULL, NULL
if the 3rd parm is 0, it wants to load a bitmap (IMAGE_BITMAP = 0)

try this code...
INVOKE   LoadImage, NULL, IDI_ASTERISK, IMAGE_ICON, NULL, NULL, LR_SHARED
you can make a little more efficient code like so...
xor     ecx,ecx
INVOKE  LoadImage,ecx,IDI_ASTERISK,IMAGE_ICON,ecx,ecx,LR_SHARED


EDIT: my mistake....
QuoteWhen loading a system icon or cursor, you must use LR_SHARED or the function will fail to load the resource.
modified the code above

TouEnMasm

no shock, this work.test it (vc++ translate /Fa)
Quote
IS_INTRESOURCE MACRO valeur
   mov   eax, valeur
   shr   eax, 16     
   neg   eax
   sbb   eax, eax
   add   eax, 1
ENDM

Fa is a musical note to play with CL

dedndave

just seems like a lot of code for a simple function   :P
of course, they designed it to work with a register, memory, or immediate operand
IS_INTRESOURCE MACRO valeur
    mov     eax,valeur
    push    0
    cmp     eax,10000h
    pop     eax
    adc     al,0
ENDM

qWord

mhh...
test value,0ffff0000h should do it most cases  ;)
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

Quote from: qWord on October 16, 2012, 06:10:20 AM
mhh...
test value,0ffff0000h should do it most cases  ;)

Spielverderber! Warum einfach, wenn's auch kompliziert geht :greensml:

Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)
20 of 20 tests valid, loop overhead is approx. 189/100 cycles
242     cycles for cycles for 100 * IS_INTRESOURCE
125     cycles for cycles for 100 * IsResourceA
72      cycles for cycles for 100 * IsResourceB
50      cycles for cycles for 100 * IsResourceQ

242     cycles for cycles for 100 * IS_INTRESOURCE
125     cycles for cycles for 100 * IsResourceA
69      cycles for cycles for 100 * IsResourceB
50      cycles for cycles for 100 * IsResourceQ

243     cycles for cycles for 100 * IS_INTRESOURCE
126     cycles for cycles for 100 * IsResourceA
72      cycles for cycles for 100 * IsResourceB
50      cycles for cycles for 100 * IsResourceQ

12      bytes for IS_INTRESOURCE
7       bytes for IsResourceA
5       bytes for IsResourceB
7       bytes for IsResourceQ

Test correctness:
Test A: 0+ 65536-
Test B: 0+ 65536-
Test C: 0+ 65536-
Test Q: 0+ 65536-

dedndave

i prefer no code at all - lol
i already know whether or not it's an integer resource   :biggrin:

qWord

Quote from: dedndave on October 16, 2012, 06:28:22 AM
i prefer no code at all - lol
i already know whether or not it's an integer resource   :biggrin:
I'm right there with you :biggrin:
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

well - i kind of thought the informal "rules" were....

1) it has to work with memory, register, or immediate operands
2) it has to return 0 or 1 in EAX, rather than a flag condition

TouEnMasm

Quote
1) it has to work with memory, register, or immediate operands
2) it has to return 0 or 1 in EAX, rather than a flag condition

I aggree with that.Usable and clear code need some µs.
We don"t load a file each milli second and the code is not repeated too often.
Speed is useless here.
Fa is a musical note to play with CL

bf2

Quote from: dedndave on October 16, 2012, 04:33:30 AM

you can make a little more efficient code like so...
xor     ecx,ecx
INVOKE  LoadImage,ecx,IDI_ASTERISK,IMAGE_ICON,ecx,ecx,LR_SHARED


Thanks. That's a really cool technique.