Search code examples
winapiassemblygraphicsgdifasm

How to draw a colored line in FASM with WinAPI?


I am currently trying to learn how to use FASM and I've been trying to make an application that draws colored lines using only WinAPI and GDI, but I can't figure out how to do that. I found this template for drawing lines, but they are always black.

format PE GUI 4.0

include 'win32wx.inc'

.data

_class TCHAR 'FASMWIN32',0
_title TCHAR 'Win32 program template',0
_error TCHAR 'Startup failed.',0

wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BACKGROUND,NULL,_class

msg MSG

hdc dd ?
paintstruct PAINTSTRUCT

.code

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 CreateSolidBrush, 0xFFFFFF  
    mov [wc.hbrBackground], eax
    invoke  RegisterClass,wc
    test    eax,eax
    jz  error

    invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,128,128,256,192,NULL,NULL,[wc.hInstance],NULL
    test    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
    cmp [wmsg], WM_PAINT
    je .wmpaint

.defwndproc:
    invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
    jmp .finish

.wmdestroy:
    invoke  PostQuitMessage,0
    xor eax,eax
    jmp .finish

.wmpaint:
    invoke BeginPaint, [hwnd], paintstruct 
    mov [hdc], eax  
    invoke MoveToEx, [hdc], 10, 15, 0  
    invoke LineTo, [hdc], 200, 100  
    invoke EndPaint, [hwnd], paintstruct  

.finish:
    ret
endp

.end start

This doesn't seem to work either, unless I am trying to put "hBrush HBRUSH" in the wrong place (doesn't work in '.data', 'illegal instruction'; "HBRUSH hBrush" doesn't work as well).

hBrush HBRUSH
invoke CreateSolidBrush, 0xFFFFFF
invoke SelectObject [hdc], hBrush

Can someone please give me an example of drawing colored lines with WinAPI and GDI?


Solution

  • My mistake was that I was trying to use brushes instead of pens to draw lines. If someone has the same question, the code is:

        invoke CreatePen,PS_SOLID, 1, 0x000000 ; PS_SOLID is the pen style and 0x000000 is the color
        invoke SelectObject, [hdc], eax
        invoke MoveToEx, [hdc], 0, 32, 0
        invoke LineTo, [hdc], 256, 32   
    

    Full example:

    format PE GUI 4.0
    
    include 'win32wx.inc'
    
    .data
    
    _class TCHAR 'FASMWIN32',0
    _title TCHAR 'Win32 program template',0
    _error TCHAR 'Startup failed.',0
    
    wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BACKGROUND,NULL,_class
    
    msg MSG
    
    hdc dd ?
    paintstruct PAINTSTRUCT
    
    .code
    
    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 CreateSolidBrush, 0xA0A0A0
        mov [wc.hbrBackground], eax
        invoke  RegisterClass,wc
        test    eax,eax
        jz  error
        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,128,128,256,192,NULL,NULL,[wc.hInstance],NULL
        test    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
        cmp [wmsg], WM_PAINT
        je .wmpaint
    
    .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp .finish
    
    .wmdestroy:
        invoke  PostQuitMessage,0
        xor eax,eax
        jmp .finish
    
    .wmpaint:
        invoke BeginPaint, [hwnd], paintstruct
        mov [hdc], eax
        invoke CreatePen,PS_SOLID, 1, 0x000000
        invoke SelectObject, [hdc], eax
        invoke MoveToEx, [hdc], 0, 32, 0
        invoke LineTo, [hdc], 256, 32
        invoke EndPaint, [hwnd], paintstruct  
    
    .finish:
        ret
    endp
    
    .end start