flat assembler
Message board for the users of flat assembler.

Index > Windows > [SOLVED] GDI

Author
Thread Post new topic Reply to topic
Krecik



Joined: 19 Jul 2012
Posts: 13
Krecik 19 Jul 2012, 14:24
Hello!
I'm the beginning FASM programmer. I read about GDI using, bitmap structures etc. I try to test my skills so I wrote a program. It should display a window with black background by using function SetDIBitsToDevice. And here's a problem because it displays only a normal window.

Below is code that I wrote (it's edited Template from Examples in FASM folder):
Code:
format PE GUI 4.0
entry start

include 'win32w.inc'

section '.text' code readable executable

  start:

        invoke  GetModuleHandle,0
        mov     [wc.hInstance],eax
        invoke  LoadIcon,0,IDI_APPLICATION
        mov     [wc.hIcon],eax
        invoke  LoadCursor,0,IDC_ARROW
        mov     [wc.hCursor],eax
        invoke  RegisterClass,wc
        test    eax,eax
        jz      error

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,800,600,NULL,NULL,[wc.hInstance],NULL
        test    eax,eax
        jz      error
        invoke  GetDC, eax
        mov     [hDC], eax
        or      eax,eax
        jz      error
        invoke  SetDIBitsToDevice, hDC, 0, 0, 800, 600, 0, 0, 0, 600, [bits], [bmi], 0 ; << Here's a problem
        or      eax,eax
        jz      error

  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1
        jb      end_loop
        jne     msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
        invoke  ExitProcess,[msg.wParam]

proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
        cmp     [wmsg],WM_DESTROY
        je      .wmdestroy
  .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .finish
  .wmdestroy:
        invoke  PostQuitMessage,0
        xor     eax,eax
  .finish:
        ret
endp

section '.data' data readable writeable

struct BITMAPINFO
Size dd ?
Width dd ?
Height dd ?
Planes dw ?
BitCount dw ?
Compression dd ?
SizeImage dd ?
XPelsPerMeter dd ?
YPelsPerMeter dd ?
ClrUsed dd ?
ClrImportant dd ?
RGBQuad dd ?
ends

struct BMP
Size dd 600 * 800 dup(?)
ends

  _class TCHAR 'FASMWIN32',0
  _title TCHAR 'GDI32 Test',0
  _error TCHAR 'Error!',0

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class
  bits BMP
  bmi BITMAPINFO 40, 1, 32, 800, 600
  msg MSG
  hDC dd ?



section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          gdi32, 'GDI32.DLL',\
          user32,'USER32.DLL'

  include 'api\kernel32.inc'
  include 'api\gdi32.inc'
  include 'api\user32.inc'    


Can someone tells my where is a problem, please?

Regards,
Krecik.


Last edited by Krecik on 20 Jul 2012, 18:29; edited 3 times in total
Post 19 Jul 2012, 14:24
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1626
Location: Toronto, Canada
AsmGuru62 19 Jul 2012, 17:01
Drawing on a window is allowed in response to WM_PAINT message.
Also, why not just paint a black rectangle instead of calling the BMP designed function?
Post 19 Jul 2012, 17:01
View user's profile Send private message Send e-mail Reply with quote
pabloreda



Joined: 24 Jan 2007
Posts: 116
Location: Argentina
pabloreda 19 Jul 2012, 17:11
try
bmi BITMAPINFO 40, 1, 32, 800, -600

I use this rutines for drawing and work well, i only see this negative number diferent

http://code.google.com/p/reda4/source/browse/trunk/r4asm/r4fasm.asm
Post 19 Jul 2012, 17:11
View user's profile Send private message Visit poster's website Reply with quote
Krecik



Joined: 19 Jul 2012
Posts: 13
Krecik 19 Jul 2012, 18:53
AsmGuru62:
Because I want use bitmaps in next progam.

pabloreda
Negative number doesn't work but I looked at this link and it helped me. Thank you a lot!

Here is woking code:
Code:
; Settings
  Width = 800
  Height = 600
  R = 255
  G = 255
  B = 0
; Code

format PE GUI 4.0
entry start

include 'win32w.inc'

section '.text' code readable executable

  start:

        invoke  GetModuleHandle,0
        mov     [wc.hInstance],eax
        invoke  LoadIcon,0,IDI_APPLICATION
        mov     [wc.hIcon],eax
        invoke  LoadCursor,0,IDC_ARROW
        mov     [wc.hCursor],eax
        invoke  RegisterClass,wc
        test    eax,eax
        jz      error

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,256,192,NULL,NULL,[wc.hInstance],NULL
        mov     [hwnd],eax
        invoke GetDC,[hwnd]
        mov [hDC],eax
        mov [bmi.biSize],sizeof.BITMAPINFOHEADER
        mov [bmi.biWidth],Width
        mov [bmi.biHeight],Height
        mov [bmi.biPlanes],1
        mov [bmi.biBitCount],32
        mov [bmi.biCompression],BI_RGB

  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1
        jb      end_loop
        jne     msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        invoke SetDIBitsToDevice,[hDC],0,0,Width,Height,0,0,0,Height,bits,bmi,0
        jmp     msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
        invoke  ExitProcess,[msg.wParam]

proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
        cmp     [wmsg],WM_DESTROY
        je      .wmdestroy
  .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .finish
  .wmdestroy:
        invoke  PostQuitMessage,0
        xor     eax,eax
  .finish:
        ret
endp

section '.data' data readable writeable

  _class TCHAR 'FASMWIN32',0
  _title TCHAR 'GDI32 Test',0
  _error TCHAR 'Startup failed.',0

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

  msg MSG
  hDC dd 0
  hwnd dd 0
  bmi BITMAPINFOHEADER
  bits db Width*Height dup(0,R,G,B)


section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          gdi32, 'GDI32.DLL',\
          user32,'USER32.DLL'

  include 'api\kernel32.inc'
  include 'api\gdi32.inc'
  include 'api\user32.inc'
    


I changed color for yellow. You can do it yourself in settings (RGB).
Post 19 Jul 2012, 18:53
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1626
Location: Toronto, Canada
AsmGuru62 19 Jul 2012, 20:37
So, you're calling SetDIBitsToDevice every message loop iteration?
Maybe doing it in the WM_PAINT is better?
Post 19 Jul 2012, 20:37
View user's profile Send private message Send e-mail Reply with quote
Krecik



Joined: 19 Jul 2012
Posts: 13
Krecik 20 Jul 2012, 08:27
AsmGuru62:
Right. I just tested it and it's much faster.
Code:
proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam 
        cmp     [wmsg],WM_DESTROY 
        je      .wmdestroy
        cmp     [wmsg],WM_PAINT
        je      .paint
  .defwndproc: 
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] 
        jmp     .finish 
  .wmdestroy: 
        invoke  PostQuitMessage,0 
        xor     eax,eax
  .paint:
        invoke SetDIBitsToDevice,[hDC],0,0,Width,Height,0,0,0,Height,bits,bmi,0
        jmp     .finish
  .finish: 
        ret 
endp      


I have another question: how can I change a single pixel color?

It's an array of bits:
Code:
bits dd Width*Height dup ($FFFFFF) ;Every pixel is white    

And I try change color:
Code:
mov [bits], 0 ;This pixel should be black    

but it doesn't work.
Post 20 Jul 2012, 08:27
View user's profile Send private message Reply with quote
pabloreda



Joined: 24 Jan 2007
Posts: 116
Location: Argentina
pabloreda 20 Jul 2012, 13:36
BITS work like a framebuffer
when call setDIBitsToDebice, copy this to main window.

You need copy the framebuffer after write pixels in BITS

call this in paint not have sense
Post 20 Jul 2012, 13:36
View user's profile Send private message Visit poster's website Reply with quote
Krecik



Joined: 19 Jul 2012
Posts: 13
Krecik 20 Jul 2012, 17:12
pabloreda:
I know about it and I did earlier the same.

Loot at this code:
Code:
; Settings
  Width = 800 
  Height = 600 
  R = 255 
  G = 255
  B = 255
; Code 

format PE GUI 4.0 
entry start 

include 'win32w.inc' 

section '.text' code readable executable 

  start: 

        invoke  GetModuleHandle,0 
        mov     [wc.hInstance],eax 
        invoke  LoadIcon,0,IDI_APPLICATION 
        mov     [wc.hIcon],eax 
        invoke  LoadCursor,0,IDC_ARROW 
        mov     [wc.hCursor],eax 
        invoke  RegisterClass,wc 
        test    eax,eax 
        jz      error 

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,256,192,NULL,NULL,[wc.hInstance],NULL 
        mov     [hwnd],eax 
        invoke GetDC,[hwnd] 
        mov [hDC],eax 
        mov [bmi.biSize],sizeof.BITMAPINFOHEADER 
        mov [bmi.biWidth],Width 
        mov [bmi.biHeight],Height 
        mov [bmi.biPlanes],1
        mov [bmi.biBitCount],24
        mov [bmi.biCompression],BI_RGB


  msg_loop:
        mov [bits], 1
        invoke SetDIBitsToDevice,[hDC],0,0,Width,Height,0,0,0,Height,bits,bmi,0
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1 
        jb      end_loop 
        jne     msg_loop 
        invoke  TranslateMessage,msg 
        invoke  DispatchMessage,msg
        jmp     msg_loop 

  error: 
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK 

  end_loop: 
        invoke  ExitProcess,[msg.wParam] 

proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam 
        cmp     [wmsg],WM_DESTROY 
        je      .wmdestroy
  .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] 
        jmp     .finish 
  .wmdestroy: 
        invoke  PostQuitMessage,0 
        xor     eax,eax
  .finish:
        ret 
endp 

section '.data' data readable writeable 

  _class TCHAR 'FASMWIN32',0 
  _title TCHAR 'GDI32 Test',0 
  _error TCHAR 'Startup failed.',0 

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class 

  msg MSG 
  hDC dd 0 
  hwnd dd 0 
  bmi BITMAPINFOHEADER 
  bits  db Width*Height dup(B, G, R)


section '.idata' import data readable writeable 

  library kernel32,'KERNEL32.DLL',\ 
          gdi32, 'GDI32.DLL',\ 
          user32,'USER32.DLL' 

  include 'api\kernel32.inc' 
  include 'api\gdi32.inc' 
  include 'api\user32.inc'    
Post 20 Jul 2012, 17:12
View user's profile Send private message Reply with quote
pabloreda



Joined: 24 Jan 2007
Posts: 116
Location: Argentina
pabloreda 20 Jul 2012, 17:45
now yes!!

Code:
; Settings
  Width = 800  
  Height = 600  
  R = 255  
  G = 255 
  B = 255 
; Code  

format PE GUI 4.0  
entry start  

include 'win32w.inc'  

section '.text' code readable executable  

  start:  

        invoke  GetModuleHandle,0  
        mov     [wc.hInstance],eax  
        invoke  LoadIcon,0,IDI_APPLICATION  
        mov     [wc.hIcon],eax  
        invoke  LoadCursor,0,IDC_ARROW  
        mov     [wc.hCursor],eax  
        invoke  RegisterClass,wc  
        test    eax,eax  
        jz      error  

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,0,0,800,600,NULL,NULL,[wc.hInstance],NULL
        mov     [hwnd],eax  
        invoke GetDC,[hwnd]  
        mov [hDC],eax  
        mov [bmi.biSize],sizeof.BITMAPINFOHEADER  
        mov [bmi.biWidth],Width  
        mov [bmi.biHeight],-Height
        mov [bmi.biPlanes],1 
        mov [bmi.biBitCount],32
        mov [bmi.biCompression],BI_RGB 

  msg_loop:
        mov [bitsfb], $0

        invoke SetDIBitsToDevice,[hDC],0,0,Width,Height,0,0,0,Height,bitsfb,bmi,0
        invoke  GetMessage,msg,NULL,0,0 
        cmp     eax,1  
        jb      end_loop  
        jne     msg_loop  
        invoke  TranslateMessage,msg  
        invoke  DispatchMessage,msg 
        jmp     msg_loop  

  error:  
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK  

  end_loop:  
        invoke  ExitProcess,[msg.wParam]  

proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam  
        cmp     [wmsg],WM_DESTROY  
        je      .wmdestroy 
  .defwndproc: 
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]  
        jmp     .finish  
  .wmdestroy:  
        invoke  PostQuitMessage,0  
        xor     eax,eax 
  .finish: 
        ret  
endp  

section '.data' data readable writeable  

  _class TCHAR 'FASMWIN32',0  
  _title TCHAR 'GDI32 Test',0  
  _error TCHAR 'Startup failed.',0  

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class  

  msg MSG  
  hDC dd 0  
  hwnd dd 0  
  bmi BITMAPINFOHEADER  
  bitsfb  dd Width*Height dup($ff00)


section '.idata' import data readable writeable  

  library kernel32,'KERNEL32.DLL',\  
          gdi32, 'GDI32.DLL',\  
          user32,'USER32.DLL'  

  include 'api\kernel32.inc'  
  include 'api\gdi32.inc'  
  include 'api\user32.inc'
    
Post 20 Jul 2012, 17:45
View user's profile Send private message Visit poster's website Reply with quote
Krecik



Joined: 19 Jul 2012
Posts: 13
Krecik 20 Jul 2012, 18:28
pabloreda:
I don't understand why it works only with negative height but ok. Thanks. Smile
Post 20 Jul 2012, 18:28
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.