How to set your bitmap resource to show up during execution?

Started by rafaly, February 22, 2008, 07:24:08 PM

Previous topic - Next topic

rafaly

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

jj2007

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

xandaz

   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

MichaelW

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


eschew obfuscation

xandaz

    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.

xandaz

    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

MichaelW

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

eschew obfuscation

xandaz

    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.
   

Ghandi


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

MichaelW

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.
eschew obfuscation

xandaz

     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

xandaz

   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

xandaz

   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

xandaz

   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