Hi,
I have two bitmap resources in my app, 8001 and 8002. The program has a bitmap that is set to start with the 8001 resource, but how do I change it to 8002 when I want to ? I have searched and was unable to do it using LoadBitmap and the BM_SETIMAGE message.
Thank you and best regards
rafaly
Here is a snippet that works in one of my apps; sm stands for "invoke Sendmessage, "
invoke LoadImage, hInstance, 8001, IMAGE_BITMAP, 0, 0,
LR_DEFAULTCOLOR or LR_SHARED ; Shared: OS will destroy resource
mov hBit1, eax
invoke LoadImage, hInstance, 8002, IMAGE_BITMAP, 0, 0,
LR_DEFAULTCOLOR or LR_SHARED ; Shared: OS will destroy resource
mov hBit2, eax
....
.if Img1
sm hMyButton, BM_SETIMAGE, IMAGE_BITMAP, hBit1
.else
sm hMyButton, BM_SETIMAGE, IMAGE_BITMAP, hBit2
.endif
I'm making this resource enumration prog and i'm having problems with load images when using resource identifiers.
There are bitmaps in shell32.dll with resource identifiers such as 1b91h, but when i do loadbitmap, hShell32,1b91h and insert in the listview control nothing appears.
I've tested it without resource indetifiers and it works. Can some tell me whats wrong?
I'll check later for answers.
Ty, bye and bests from I
If I use a valid resource ID, and I specify the correct resource type, then I can load and display a bitmap or icon, and I assume that cursors will work the same way.
;==============================================================================
; Build as a console app so print will work.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
IDC_STATIC equ 100
;==============================================================================
.data
hwndStatic dd 0
hShell32 dd 0
hImage dd 0
.code
;==============================================================================
DlgProc proc hwndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
SWITCH uMsg
CASE WM_INITDIALOG
invoke GetDlgItem, hwndDlg, IDC_STATIC
mov hwndStatic, eax
print hex$(eax),13,10
invoke LoadLibrary, chr$("shell32.dll")
mov hShell32, eax
print hex$(eax),13,10
;invoke LoadImage, hShell32, 131, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE
invoke LoadBitmap, hShell32, 131
mov hImage, eax
print hex$(eax),13,10
invoke SendMessage, hwndStatic, STM_SETIMAGE, IMAGE_BITMAP, hImage
CASE WM_COMMAND
SWITCH wParam
CASE IDCANCEL
invoke EndDialog, hwndDlg, 0
ENDSW
CASE WM_CLOSE
invoke EndDialog, hwndDlg, 0
ENDSW
return 0
DlgProc endp
;==============================================================================
start:
;==============================================================================
Dialog "Test", \
"MS Sans Serif", 10, \
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
1, \
0,0,200,150, \
1024
DlgStatic 0, SS_BITMAP, 0, 0, 0, 0, IDC_STATIC
invoke GetModuleHandle, NULL
CallModalDialog eax, 0, DlgProc, NULL
invoke ExitProcess, 0
;==============================================================================
end start
Of course that that works but when i enum the Names for a specified resource it resturns identifiers in the order of 80b6h and other large numbers of the sort. When i use for example LoadBitmap,hResrource,80b6h it returns error. I don't know why is this. I shifted lpszName 16 bits right and made sure its an identifier rather than a pointer but things aren't really working out. i'm sending bellow the file so someone can check it out.
it seems to wrok fine if i shift lpszName only 15 bits right instead of 16. Could it be its a signed integer? I guess it should wrok anyway. I'm lost. Can someone plz help out? Help is appreciated. thanks.
ty, bye and bests from I
I tested the enumeration with a small console app, and it appears to work the way it should. On my Windows 2000 system there were too many resources to list all of them in a single column on the console, so I just displayed the first 300 for the cursor, bitmap, or icon types. Using my test dialog, all of the bitmap resources I checked loaded and displayed OK, but only some of the icons would load and I didn't have time to sort this problem out. The code checks for resource IDs > 8000h, and on my system there were only 3 (out of 881).
Edit:
Expanded the resource types and improved the code so it now lists all of the resources with an integer identifier (and ignores the others). I still have no idea why some of the icons will not load (using LoadImage).
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
;-----------------------------------
; These not defined in windows.inc:
;-----------------------------------
RT_MESSAGETABLE equ 11
RT_GROUP_CURSOR equ 12
RT_GROUP_ICON equ 14
RT_VERSION equ 16
RT_DLGINCLUDE equ 17
RT_PLUGPLAY equ 19
RT_VXD equ 20
RT_ANICURSOR equ 21
RT_ANIICON equ 22
RT_HTML equ 23
RT_MANIFEST equ 24
;==============================================================================
;-----------------------------------------------------------
; #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
;-----------------------------------------------------------
IS_INTRESOURCE MACRO _r
mov eax, _r
shr eax, 16
mov eax, 1
jz @F
xor eax, eax
@@:
EXITM <eax>
ENDM
;==============================================================================
.data
hShell32 dd 0
count dd 0
.code
;==============================================================================
EnumResNameProc proc hModule:DWORD,lpszType:DWORD,lpszName:DWORD,lParam:DWORD
.IF IS_INTRESOURCE(lpszType)
inc count
SWITCH lpszType
CASE RT_CURSOR
print "RT_CURSOR ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_BITMAP
print "RT_BITMAP ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_ICON
print "RT_ICON ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_MENU
print "RT_MENU ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_DIALOG
print "RT_DIALOG ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_STRING
print "RT_STRING ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_FONTDIR
print "RT_FONTDIR ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_FONT
print "RT_FONT ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_ACCELERATOR
print "RT_ACCELERATOR ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_RCDATA
print "RT_RCDATA ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_MESSAGETABLE
print "RT_MESSAGETABLE",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_GROUP_CURSOR
print "RT_GROUP_CURSOR",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_GROUP_ICON
print "RT_GROUP_ICON ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_VERSION
print "RT_VERSION ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_DLGINCLUDE
print "RT_DLGINCLUDE ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_PLUGPLAY
print "RT_PLUGPLAY ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_VXD
print "RT_VXD ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_ANICURSOR
print "RT_ANICURSOR ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_ANIICON
print "RT_ANIICON ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_HTML
print "RT_HTML ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
CASE RT_MANIFEST
print "RT_MANIFEST ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
DEFAULT
print "other ",9
.IF IS_INTRESOURCE(lpszName)
print hex$(lpszName),13,10
.ENDIF
ENDSW
mov eax, count
mov ecx, 23
xor edx, edx
div ecx
test edx, edx
jnz @F
inkey "Press any key to continue..."
@@:
.ELSE
;print lpszType,9
.ENDIF
return 1
EnumResNameProc endp
;==============================================================================
EnumResTypeProc proc hModule:DWORD,lpszType:DWORD,lParam:DWORD
invoke EnumResourceNames, hShell32, lpszType, EnumResNameProc, 0
return 1
EnumResTypeProc endp
;==============================================================================
start:
;==============================================================================
invoke LoadLibrary, chr$("shell32.dll")
mov hShell32, eax
invoke EnumResourceTypes, hShell32, EnumResTypeProc, 0
print chr$(13,10,"total resources ")
print str$(count),13,10,13,10
invoke FreeLibrary, hShell32
inkey "Press any key to exit..."
exit
;==============================================================================
end start
The thing is that EnumResNamesProc returns the identifiers with bit 15 of lpszName set. I imagine that this is to be used with IS_INTRESROURCE macro. I've tried to load bitmaps using the returned identifiers but with bit 15 cleared and it works. I don't know why but this doesn't happen with Non-system-defined resources. I don't know what everyone thinks of this but feel free to reply.
ty guys.
Determines whether a value is an integer identifier for a resource.
Syntax
CopyBOOL IS_INTRESOURCE(
WORD wInteger
);
Parameters
wInteger
The integer value to be tested.
Return Value
If the value is a resource identifier, the return value is TRUE. Otherwise, the return value is FALSE.
Remarks
This macro checks whether all bits except the least 16 bits are zero. When true, wInteger is an integer identifier for a resource. Otherwise it is typically a pointer to a string.
;-----------------------------------------------------------
; #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
;-----------------------------------------------------------
IS_INTRESOURCE MACRO _r
xor eax,eax
test _r,8000h ; Check for sign bit
setne al
ENDM
Would this change work for the macro, where it only tests for the bit and uses SETNE to set AL to 0 or 1 respectively?
;-----------------------------------------------------------
; #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
;-----------------------------------------------------------
IS_INTRESOURCE MACRO _r
mov eax, _r
and eax,8000h
shr eax,0Fh ; Shift it across so if the bit is set, al == 1, else al == 0
ENDM
HR,
Ghandi
On my Windows 2000 system for the bitmap resources the code above returns:
RT_BITMAP 00000082
RT_BITMAP 00000083
RT_BITMAP 00000084
RT_BITMAP 00000085
RT_BITMAP 00000086
RT_BITMAP 00000087
RT_BITMAP 00000088
RT_BITMAP 00000089
RT_BITMAP 0000008A
RT_BITMAP 0000008B
RT_BITMAP 0000008C
RT_BITMAP 0000008D
RT_BITMAP 0000008E
RT_BITMAP 0000008F
RT_BITMAP 00000091
RT_BITMAP 00000092
RT_BITMAP 00000093
RT_BITMAP 00000094
RT_BITMAP 00000135
RT_BITMAP 00000136
These are the resource ID values passed in the lpszName parameter of EnumResNameProc, in hex. Every one of them can be passed to LoadImage and displayed in a static control.
Yeah, thanks a lot guys. I'm still a bit concerned with the sign bit since it does nothing. In the beggining i thought it was to be used with IS_INTRESOURCE macro, because when that last bit is shifted CF is set and that could be used in a jump to return eax==TRUE, but because the non-system-defined resources i found don't have that particularity I only know that i know nothing.
Ty and bye
Hey Michael and guys. I've sorted all things more or less and i think i know now that if you were using loadImage or LoadIcon there are great chances that some icons didn't show. You should use for that matter the CreateIconFromResource function. I've tried it and all works fine. I'll post an attachment when things look a bit better. I've changed the program about one hundred times.
See you all later.
invoke FindResource,hResource,addr ResourceName,RT_ICON/RT_GROUP_ICON/RT_CURSOR/RT_GROUP_CURSOR
mov hResFind,eax
invoke LoadResource,hResource,eax
mov hRes,eax
invoke LockResource,eax
mov lpRes,eax
invoke SizeofResource,hResource,hRes
mov ResSize,eax
invoke CreateIconFromResource,lpRes,ResSize,TRUE(ICON)/FALSE(CURSOR),030000h
etc...
bye guys
I noticed that no one answered. It's not like it's a big problem. I guess it'd be more challenging if there was something to solve, so here it goes.
I'm being unable to load RT_GROUP_CURSOR cursors from resource except by LoadImage. I was wondering what i should do to do it via CreateIconFromResource?
I've tried something like this but doesnt work:
....
invoke LockResource,hRes
lea eax,[eax.CURSORDIR].cdEntries
invoke CreateIconFromResource,eax,ResSize,FALSE,30000h
invoke ImageList_AddIcon,hList,eax
...i'll check later to see what someone came up with.
Ty and bye
Oh by the way. If i do this:
invoke LoadResource,hExplorer,hResFind
mov hRes,eax
invoke LockResource,hRes
mov lpRes,eax
invoke SizeofResource,hExplorer,hRes
mov ResSize,eax
invoke CreateIconFromRes,lpRes,ResSize,FALSE,03000h
ImageList_AddIcon,hList,eax
.... it joes shows a black squared cursor.
Thanks again