flat assembler
Message board for the users of flat assembler.

Index > Windows > [Bitmap]How to display a bitmap file?

Author
Thread Post new topic Reply to topic
LiuGuoHua(Chinese)



Joined: 26 Sep 2003
Posts: 25
LiuGuoHua(Chinese) 24 Jan 2004, 12:52
I know how to display a bitmap picture resource .
but how to display a bitmap file on my window?
Thx!~
Post 24 Jan 2004, 12:52
View user's profile Send private message Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1150
Location: Russian Federation
comrade 24 Jan 2004, 18:36
Use LoadImage instead of LoadBitmap

_________________
comrade (comrade64@live.com; http://comrade.ownz.com/)
Post 24 Jan 2004, 18:36
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
Vortex



Joined: 17 Jun 2003
Posts: 318
Vortex 24 Jan 2004, 20:17
Hi LiuGuoHua,

For a real example, have a look at Iczelion's assembly tutorial #25 :

http://spiff.tripnet.se/~iczelion/tut25.html

_________________
Code it... That's all...
Post 24 Jan 2004, 20:17
View user's profile Send private message Visit poster's website Reply with quote
vbVeryBeginner



Joined: 15 Aug 2004
Posts: 884
Location: \\world\asia\malaysia
vbVeryBeginner 28 Sep 2004, 08:04
hi,
i spend some hours to make it load bitmap, but still fail, anyone have any idea, where went wrong? i check with res hacker and i am sure the bitmap is already binded to the application, but somehow, it just fail to load using the LoadBitmap function, cmp eax,NULL will je us to a messagebox

this is the fasm code i wrote for iczelion tutorial 25
Code:
format PE GUI 4.0
entry start

include '%fasminc%\win32a.inc'

section '.data' data readable writeable
        wndH            dd ?                    ;handle for window
        insH            dd ?                    ;handle for instance
        wndClsName      db 'TUT_25',0
        wndTitle        db 'Tutorial 25',0

        wndCls  WNDCLASS
        wndMsg  MSG
        
        bmp1H           dd ?                    ;handle for BMP file
        bmp1Ps          PAINTSTRUCT
        bmp1Rect        RECT
        dcH             dd ?
        dcMemH          dd ?
        
        
section '.code' code readable executable
   start:
        invoke  GetModuleHandle,
                mov  [insH],eax
                mov  [wndCls.hInstance],eax
                mov  [wndCls.style],CS_HREDRAW + CS_VREDRAW
                mov  [wndCls.lpfnWndProc],window_procedure
                mov  [wndCls.lpszClassName],wndClsName
                mov  [wndCls.hbrBackground],COLOR_WINDOW+1
        invoke  LoadIcon,NULL,IDI_APPLICATION
                mov  [wndCls.hIcon],eax
        invoke  LoadCursor,NULL,IDC_ARROW
                mov  [wndCls.hCursor],eax
        invoke  RegisterClass,wndCls

        invoke  CreateWindowEx,\
                WS_EX_CLIENTEDGE,\
                wndClsName,\
                wndTitle,\
                WS_OVERLAPPEDWINDOW + WS_VISIBLE,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                NULL,\
                NULL,\
                [insH],\
                NULL
                mov  [wndH],eax

   ;+---------------------------+
   ;| entering the message loop |
   ;+---------------------------+
   window_message_loop_start:
        invoke  GetMessage,wndMsg,NULL,0,0
                or    eax,eax
                je    window_message_loop_end
        invoke  TranslateMessage,wndMsg
        invoke  DispatchMessage,wndMsg
                jmp     window_message_loop_start

   window_message_loop_end:
        invoke  ExitProcess,0

   ;+----------------------+
   ;| the window procedure |
   ;+----------------------+
   proc window_procedure,hWnd,uMsg,wParam,lParam
                push ebx esi edi
                cmp  [uMsg],WM_CREATE
                je   wmCREATE
                cmp  [uMsg],WM_PAINT
                je   wmPAINT
                cmp  [uMsg],WM_DESTROY
                je   wmDESTROY
        

        wmDEFAULT:
                invoke  DefWindowProc,[hWnd],[uMsg],[wParam],[lParam]
                        jmp  wmBYE

        wmCREATE:
                invoke  LoadBitmap,[insH],300
                        mov  [bmp1H],eax
                        cmp  eax,NULL
                        je   @f
                        jmp  wmBYE
                @@:
                invoke  MessageBox,NULL,wndClsName,wndClsName,MB_OK
                        jmp  wmBYE

        wmPAINT:
                invoke  BeginPaint,[hWnd],bmp1Ps
                        mov  [dcH],eax
                invoke  CreateCompatibleDC,[dcH]
                        mov  [dcMemH],eax
                invoke  SelectObject,[dcMemH],[bmp1H]
                invoke  GetClientRect,[hWnd],bmp1Rect
                invoke  BitBlt,[dcH],0,0,[bmp1Rect.right],[bmp1Rect.bottom],[dcMemH],0,0,SRCCOPY
                invoke  DeleteDC,[dcMemH]
                invoke  EndPaint,[hWnd],bmp1Ps
                        jmp  wmBYE

        wmDESTROY:
                invoke  DeleteObject,[bmp1H]
                invoke  PostQuitMessage,0

        wmBYE:
                pop edi esi ebx
                return
   endp

section '.idata' import data readable
    library     KERNEL32, 'KERNEL32.DLL',\
                USER32,   'USER32.DLL',\
                GDI32,    'GDI32.DLL'
    
    import      KERNEL32,\
                GetModuleHandle,        'GetModuleHandleA',\
                FindResource,           'FindResourceA',\
                LoadResource,           'LoadResource',\
                LockResource,           'LockResource',\
                ExitProcess,            'ExitProcess'
    import      USER32,\
                RegisterClass,          'RegisterClassA',\
                CreateWindowEx,         'CreateWindowExA',\
                DefWindowProc,          'DefWindowProcA',\
                LoadCursor,             'LoadCursorA',\
                LoadIcon,               'LoadIconA',\
                LoadBitmap,             'LoadBitmapA',\
                LoadMenu,               'LoadMenuA',\
                BeginPaint,             'BeginPaint',\
                EndPaint,               'EndPaint',\
                GetClientRect,          'GetClientRect',\
                MessageBox,             'MessageBoxA',\
                SendMessage,            'SendMessageA',\
                GetMessage,             'GetMessageA',\
                DestroyWindow,          'DestroyWindow',\
                TranslateMessage,       'TranslateMessage',\
                DispatchMessage,        'DispatchMessageA',\
                PostQuitMessage,        'PostQuitMessage'
    import      GDI32,\
                CreateCompatibleDC,     'CreateCompatibleDC',\
                SelectObject,           'SelectObject',\
                BitBlt,                 'BitBlt',\
                DeleteDC,               'DeleteDC',\
                DeleteObject,           'DeleteObject'

section '.rsrc' data readable resource from 'tut_25.res'
;tut_25.rc
;300 BITMAP "tweety78.bmp"

;section '.rsrc' resource data readable
;       directory       RT_BITMAP, appBmp
;       
;       resource        appBmp,\
;                       300,LANG_NEUTRAL,bmp1
;       
;       bitmap          bmp1, "tweety78.bmp"
    


this is the iczelion tutorial 25 coded in MASM
Code:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
IDB_MAIN   equ 1

.data
ClassName db "SimpleWin32ASMBitmapClass",0
AppName  db "Win32ASM Simple Bitmap Example",0

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hBitmap dd ?

.code
start:
        invoke GetModuleHandle, NULL
        mov    hInstance,eax
        invoke GetCommandLine
        mov    CommandLine,eax
        invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
        invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
        LOCAL wc:WNDCLASSEX
        LOCAL msg:MSG
        LOCAL hwnd:HWND
        mov   wc.cbSize,SIZEOF WNDCLASSEX
        mov   wc.style, CS_HREDRAW or CS_VREDRAW
        mov   wc.lpfnWndProc, OFFSET WndProc
        mov   wc.cbClsExtra,NULL
        mov   wc.cbWndExtra,NULL
        push  hInstance
        pop   wc.hInstance
        mov   wc.hbrBackground,COLOR_WINDOW+1
        mov   wc.lpszMenuName,NULL
        mov   wc.lpszClassName,OFFSET ClassName
        invoke LoadIcon,NULL,IDI_APPLICATION
        mov   wc.hIcon,eax
        mov   wc.hIconSm,eax
        invoke LoadCursor,NULL,IDC_ARROW
        mov   wc.hCursor,eax
        invoke RegisterClassEx, addr wc
        INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL
        mov   hwnd,eax
        invoke ShowWindow, hwnd,SW_SHOWNORMAL
        invoke UpdateWindow, hwnd
        .while TRUE
                invoke GetMessage, ADDR msg,NULL,0,0
                .break .if (!eax)
                invoke TranslateMessage, ADDR msg
                invoke DispatchMessage, ADDR msg
        .endw
        mov     eax,msg.wParam
        ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
   LOCAL ps:PAINTSTRUCT
   LOCAL hdc:HDC
   LOCAL hMemDC:HDC
   LOCAL rect:RECT
   .if uMsg==WM_CREATE
      invoke LoadBitmap,hInstance,IDB_MAIN
      mov hBitmap,eax
   .elseif uMsg==WM_PAINT
      invoke BeginPaint,hWnd,addr ps
      mov hdc,eax
      invoke CreateCompatibleDC,hdc
      mov hMemDC,eax
      invoke SelectObject,hMemDC,hBitmap
      invoke GetClientRect,hWnd,addr rect
      invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY
      invoke DeleteDC,hMemDC
      invoke EndPaint,hWnd,addr ps
        .elseif uMsg==WM_DESTROY
      invoke DeleteObject,hBitmap
                invoke PostQuitMessage,NULL
        .ELSE
                invoke DefWindowProc,hWnd,uMsg,wParam,lParam            
                ret
        .ENDIF
        xor eax,eax
        ret
WndProc endp
end start

    


sincerely,
vbVeryBeginner d(??)b
Post 28 Sep 2004, 08:04
View user's profile Send private message Visit poster's website Reply with quote
Vortex



Joined: 17 Jun 2003
Posts: 318
Vortex 28 Sep 2004, 18:02
Hi vbVeryBeginner,

First of all, it looks like that you forgot to put the parameter of GetModuleHandle, have a look at you source code:
Code:
invoke  GetModuleHandle,
    


It should be :
Code:
invoke  GetModuleHandle,0
    


Second, what's the meaning of 300?
Code:
invoke  LoadBitmap,[insH],300
    


It should be:
Code:
invoke  LoadBitmap,[insH],1
    


The original resource script:
Code:
#define IDB_MAIN 1
IDB_MAIN BITMAP "tweety78.bmp"
    


After correcting the source file, your code runs fine.

_________________
Code it... That's all...
Post 28 Sep 2004, 18:02
View user's profile Send private message Visit poster's website Reply with quote
vbVeryBeginner



Joined: 15 Aug 2004
Posts: 884
Location: \\world\asia\malaysia
vbVeryBeginner 28 Sep 2004, 20:20
Quote:

First of all, it looks like that you forgot to put the parameter of
GetModuleHandle, have a look at you source code:


oh man, this silly mistake cost me some hours Sad


Last edited by vbVeryBeginner on 28 Sep 2004, 20:33; edited 1 time in total
Post 28 Sep 2004, 20:20
View user's profile Send private message Visit poster's website Reply with quote
vbVeryBeginner



Joined: 15 Aug 2004
Posts: 884
Location: \\world\asia\malaysia
vbVeryBeginner 28 Sep 2004, 20:32
so,
Code:
invoke       GetModuleHandle,
    

why this could be assembled without error? coz fasm should show error of lacking param instead of assemble it.
Post 28 Sep 2004, 20:32
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 28 Sep 2004, 21:24
use WIN32AXP.INC to perform parameter checking.
Post 28 Sep 2004, 21:24
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 28 Sep 2004, 23:01
vbVeryBeginner wrote:
why this could be assembled without error? coz fasm should show error of lacking param instead of assemble it.


Parameter checking often can stop you from using some good technicques, possible only in assembly language. For example it is very frequent case:

We want to create some object to make several operations with it and then to destroy it. Typical case - brush or pen. So, where to save the handle, until we need it for passing as argument to the procedure that will destroy the object (DeleteObject for example)?

We can use some of the persistent registers - esi, edi, ebx. Or some local variable. But why to waste registers or to create one-time-using local variables?
Simply, we can use the technique I call "early parameter passing":

Code:
; ebx - handle to the device context
; esi - pointer to the rectangle we want to draw
invoke CreateSolidBrush, $123456 ; some strange color.
push  eax  ; prepare arguments for DeleteObject
invoke FillRect, ebx, esi, eax   ; we just lost eax (brush handle)

; Here is the trick - we call DeleteObject without argument, 
; because the handle of the object is already pushed in the stack 
invoke DeleteObject
    


Another, more complex example:
Code:
invoke  CreatePen, PS_SOLID, 0, $123456
invoke  SelectObject, [.hdc], eax ; we lost the handle. 
;SelectObject returns the previous pen handle.
push eax
invoke  CreateSolidBrush, $654321
invoke  SelectObject, [.hdc], eax
push eax 

; Draw operations.
invoke  MoveToEx...........
invoke  LineTo....... 
invoke  Rectangle....... etc.

; Cleanup
invoke  SelectObject, [.hdc]  ; the handle of the previous brush is in the stack
invoke  DeleteObject, eax  ; we destroy the brush.
invoke  SelectObject, [.hdc]  ; the handle of the previous pen is in the stack
invoke  DeleteObject, eax ; we destroy the pen
    


Regards.
Post 28 Sep 2004, 23:01
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
vbVeryBeginner



Joined: 15 Aug 2004
Posts: 884
Location: \\world\asia\malaysia
vbVeryBeginner 29 Sep 2004, 09:49
Code:
; Here is the trick - we call DeleteObject without argument,  
; because the handle of the object is already pushed in the stack  
invoke DeleteObject 
    

yup, it is a nice trick Smile thanks
Post 29 Sep 2004, 09:49
View user's profile Send private message Visit poster's website Reply with quote
i-don



Joined: 18 Jul 2003
Posts: 66
i-don 30 Sep 2004, 17:47
Like LiuGuoHua, I would like to know how to open, load and display a bitmap file at run-time. Most of the post above described about using resource bitmap. I hope anyone has idea to help us know.

Thank in advance. Wink

i-don.
Post 30 Sep 2004, 17:47
View user's profile Send private message Reply with quote
Vortex



Joined: 17 Jun 2003
Posts: 318
Vortex 30 Sep 2004, 18:54
Hi i-don,

Have a look at this thread:

Displaying bitmaps from memory

_________________
Code it... That's all...
Post 30 Sep 2004, 18:54
View user's profile Send private message Visit poster's website Reply with quote
i-don



Joined: 18 Jul 2003
Posts: 66
i-don 02 Oct 2004, 02:54
Hi Vortex,

Thanks it helps very much. Very Happy

ps - We should have a pinned thread that listing some working examples from each forum. It will save some energy to ask subjects that already has an answer.

i-don.
Post 02 Oct 2004, 02:54
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.