flat assembler
Message board for the users of flat assembler.

Index > Windows > Can't get window to display

Author
Thread Post new topic Reply to topic
shaolin007



Joined: 03 Sep 2004
Posts: 65
shaolin007 30 May 2005, 21:03
Could someone give a look over my code to see what the problem could be? I'm still learning Windows Programming and still haven't quite got the hang of it yet. Smile Sorry if the code seems a little bloated. Any suggestions would be greatly appreciative! By the way, I tried to keep the code neat for readability reasons.

Code:
format PE GUI 4.0
entry Main

include '%fasminc%\win32a.inc'

section '.code' executable readable writeable

Main:
      ;WINDOW CLASS
      push IDI_APPLICATION
      push 0
      call [LoadIcon]
      mov [wndclass.hIconSm], eax
      push [wndclass.hIconSm]

      mov [wndclass.lpszClassName], _szClassName
      push [wndclass.lpszClassName]

      mov [wndclass.lpszMenuName], 0
      push [wndclass.lpszMenuName]

      push WHITE_BRUSH
      call [GetStockObject]
      mov [wndclass.hbrBackground], eax
      push [wndclass.hbrBackground]

      push IDC_ARROW
      push 0
      call [LoadCursor]
      mov [wndclass.hCursor], eax
      push [wndclass.hCursor]

      push IDI_APPLICATION
      push 0
      call [LoadIcon]
      mov [wndclass.hIcon], eax
      push [wndclass.hIcon]

      mov eax, [_hInstance]
      mov [wndclass.hInstance], eax
      push [wndclass.hInstance]

      mov [wndclass.cbWndExtra], 0
      push [wndclass.cbWndExtra]

      mov [wndclass.cbClsExtra], 0
      push [wndclass.cbClsExtra]

      mov [wndclass.lpfnWndProc], WndProc
      push [wndclass.lpfnWndProc]

      mov eax, CS_HREDRAW
      or eax, CS_VREDRAW
      mov [wndclass.style], eax
      push [wndclass.style]

      mov eax, [wndclass]
      mov [wndclass.cbSize], eax
      push [wndclass.cbSize]
      ;END WINDOW CLASS

      ;REGISTER WINDOW CLASS
      push wndclass
      call [RegisterClass]

      ;CREATE WINDOW
      mov [create.lpCreateParams], 0
      push [create.lpCreateParams]

      mov eax, [_hInstance]
      mov [create.hInstance], eax
      push [create.hInstance]

      mov [create.hMenu], 0
      push [create.hMenu]

      mov [create.hwndParent], 0
      push [create.hwndParent]

      mov [create.cy], CW_USEDEFAULT
      push [create.cy]

      mov [create.cx], CW_USEDEFAULT
      push [create.cy]

      mov [create.y], CW_USEDEFAULT
      push [create.y]

      mov [create.x], CW_USEDEFAULT
      push [create.x]

      mov [create.style], WS_OVERLAPPEDWINDOW
      push [create.style]

      mov eax, _szWndCaption
      mov [create.lpszName], eax
      push [create.lpszName]

      mov eax, _szClassName
      mov [create.lpszClass], eax
      push [create.lpszClass]

      mov [create.dwExStyle], WS_EX_OVERLAPPEDWINDOW
      push [create.dwExStyle]

      call [CreateWindowEx]
      mov [_hwnd], eax

      ;SHOW WINDOW
      push [_iCmdShow]
      push [_hwnd]
      call [ShowWindow]

      ;UPDATE WINDOW
      push [_hwnd]
      call [UpdateWindow]

      ;MESSAGE LOOP
Msg_Loop:
      push 0
      push 0
      push 0
      push wmsg
      call [GetMessage]
      push wmsg
      call [TranslateMessage]
      cmp eax, WM_QUIT
      je Exit_Msg_Loop
      push wmsg
      call [DispatchMessage]
      jmp Msg_Loop

Exit_Msg_Loop:
        push [wmsg.wParam]
        call [ExitProcess]

WndProc:
        mov eax, [wmsg.lParam]
        mov [_lParam], eax
        mov eax, [wmsg.wParam]
        mov [_wParam], eax
        mov eax, [wmsg.message]
        mov [_iMsg], eax
        mov eax, [wmsg.hwnd]
        mov [_hwnd], eax

        cmp [_iMsg], WM_PAINT
        je Paint_Window
        cmp [_iMsg], WM_DESTROY
        je Destroy_Window
        push [_lParam]
        push [_wParam]
        push [_iMsg]
        push [_hwnd]
        call [DefWindowProc]
        jmp WndProc

Paint_Window:
        push ps
        push [_hwnd]
        call [BeginPaint]
        mov [_hdc], eax

        push wrect
        push [_hwnd]
        call GetClientRect

        mov eax, DT_VCENTER
        or eax, DT_CENTER
        or eax, DT_SINGLELINE
        push eax
        push wrect
        push -1
        push _szGreeting
        push [_hdc]
        call [DrawText]

        push ps
        push [_hwnd]
        call [EndPaint]
        mov eax, 0
        ret

Destroy_Window:
        push 0
        call [PostQuitMessage]
        mov eax, 0
        ret

section '.data' data readable writeable

_hInstance              dd ?
_hPrevInstance          dd ?
_iCmdShow               dd ?
_hwnd                   dd ?
_iMsg                   dd ?
_wParam                 dd ?
_lParam                 dd ?
_szClassName            db "My Window",0
_szWndCaption           db "My 1st Window",0
_hdc                    dd ?
_szGreeting             db "Hello this is my 1st window!",0

;STRUCTS
wndclass                WNDCLASSEX
wmsg                    MSG
create                  CREATESTRUCT
ps                      PAINTSTRUCT
wrect                   RECT

section '.idata' import data readable writeable

library   kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL',\
          gdi32, 'GDI32.DLL'
include   '%fasminc%\apia\kernel32.inc'
include   '%fasminc%\apia\user32.inc'
include   '%fasminc%\apia\gdi32.inc'
    
Post 30 May 2005, 21:03
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 30 May 2005, 23:41
add WS_VISIBLE as window style, or do ShowWindow,SW_NORMAL - youre initializing icmdShow as 0... fasm (or any other assembler) doesnt make your command line switches available simply like C++ can, you have to use windows api functions to get switches
Post 30 May 2005, 23:41
View user's profile Send private message Reply with quote
shaolin007



Joined: 03 Sep 2004
Posts: 65
shaolin007 31 May 2005, 01:19
coconut wrote:
add WS_VISIBLE as window style, or do ShowWindow,SW_NORMAL - youre initializing icmdShow as 0... fasm (or any other assembler) doesnt make your command line switches available simply like C++ can, you have to use windows api functions to get switches


Thanks coconut, but it still won't display. Could you check my message loop and window procedure to see if I am doing that portion correctly? I think it might be somewhere there but I'm not sure. Sad Thanks again buddy!
Post 31 May 2005, 01:19
View user's profile Send private message Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 31 May 2005, 05:20
Hello Shaolin007,
You should learn to use the invoke macro, and for that matter the 'if.inc' macros as well. Here is an example with my style of programming:

Code:
;Simple Window
format PE GUI 4.0
entry WinMain

include '%fasminc%\win32a.inc'
include '%fasminc%\macro\if.inc'

section '.code' code readable executable

proc WinMain, hInstance, hPrevInstance, szCmdLine, iCmdShow
     enter

     ;fill in a window's class structure
     mov     [wndclass.style], CS_HREDRAW or CS_VREDRAW
     mov     [wndclass.lpfnWndProc], WndProc
     mov     [wndclass.cbClsExtra], 0
     mov     [wndclass.cbWndExtra], 0
     mov     eax, [hInstance]
     mov     [wndclass.hInstance], eax
     invoke  LoadIcon, NULL, IDI_APPLICATION
     mov     [wndclass.hIcon], eax
     invoke  LoadCursor, NULL, IDC_ARROW
     mov     [wndclass.hCursor], eax
     invoke  GetStockObject, WHITE_BRUSH
     mov     [wndclass.hbrBackground], eax
     mov     [wndclass.lpszMenuName], NULL
     mov     [wndclass.lpszClassName], szAppName

     ;Register the window class with the system
     invoke  RegisterClass, wndclass
     .if     eax, e, NULL
             invoke  MessageBox, NULL, szClassName, szAppName, MB_ICONERROR
             mov     eax,0
             return
     .endif

     ;Create the window
     invoke  CreateWindowEx, NULL, szAppName, szClassName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,\
             CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, [hInstance], NULL
     mov     [hWnd], eax

     ;Show the window to the user
     invoke  ShowWindow, [hWnd], SW_SHOWNORMAL
     invoke  UpdateWindow, [hWnd]

forever_loop:
     ;Window's main message loop
     invoke  GetMessage, msg, NULL, 0, 0

     .if     eax, e, NULL
             jmp     end_loop
     .else
             invoke TranslateMessage, msg
             invoke DispatchMessage, msg
             jmp forever_loop
     .endif

end_loop:
     ;user quit our application, free all resources and close our program
     invoke  ExitProcess,[msg.wParam]
     return
endp

proc WndProc, hwnd, message, wParam, lParam
     enter
     ;called before any real processing for our window takes place
     .if     [message], e, WM_CREATE
             mov     eax,0
             return

     ;allows us to draw in the client area
     .elseif [message], e, WM_PAINT
             invoke  BeginPaint, [hwnd], ps
             mov     [hdc], eax
             invoke  GetClientRect, [hwnd], wrect
             invoke  DrawText, [hdc], szAppName, -1, wrect,\
                     DT_SINGLELINE or DT_CENTER or DT_VCENTER
             invoke  EndPaint, [hwnd], ps
             mov     eax,0
             return

     .elseif [message], e, WM_DESTROY
             invoke  PostQuitMessage, NULL
             mov     eax,0
             return
     .endif

     invoke  DefWindowProc, [hwnd], [message], [wParam], [lParam]
     return
endp

section '.data' data readable writeable
     szAppName db "My 1st Window",0
     szClassName db "My Window",0
     align 4

     hWnd dd 0
     hdc dd 0

     msg MSG
     wndclass WNDCLASS
     ps PAINTSTRUCT
     wrect RECT

section '.idata' import data readable writeable

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

include   '%fasminc%\apia\kernel32.inc'
include   '%fasminc%\apia\user32.inc'
include   '%fasminc%\apia\gdi32.inc'
include   '%fasminc%\apia\comdlg32.inc'    
Post 31 May 2005, 05:20
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 31 May 2005, 15:29
check Task Manager, is your program running but not displayed or does it exit immediately? also nothing is wrong with your coding style but have you seen the win32 template in your examples folder? you may find it easier to use the invoke macro instead of push/call - it generates the exact same code
Post 31 May 2005, 15:29
View user's profile Send private message Reply with quote
shaolin007



Joined: 03 Sep 2004
Posts: 65
shaolin007 31 May 2005, 17:57
coconut wrote:
check Task Manager, is your program running but not displayed or does it exit immediately? also nothing is wrong with your coding style but have you seen the win32 template in your examples folder? you may find it easier to use the invoke macro instead of push/call - it generates the exact same code


I did ctrl-atl-delete in WIN2000 and sure enough it is running as My Window.exe, so I assume it works ok but won't display for some reason.

Yea I see the examples of macros but I like to do it the hardway until I get the hang of it. I know that probably sounds silly but I learn better that way actually. When I get this Window up and running correctly, I will change it to macros to narrow down the code.
Post 31 May 2005, 17:57
View user's profile Send private message Reply with quote
Spidark



Joined: 11 May 2005
Posts: 39
Spidark 31 May 2005, 21:46
shaolin007 wrote:
Yea I see the examples of macros but I like to do it the hardway until I get the hang of it. I know that probably sounds silly but I learn better that way actually. When I get this Window up and running correctly, I will change it to macros to narrow down the code.
Hello shaolin007 i'm a newbie myself , still trying to learn assembly and windows programming.
I haven't realy take a deep look at your code , but i do have an working example for you , maybe it could be helpfull to you.
Code:
;-- ----------------------------------------------
; Program Name: hardway.asm
; Version: 1.0
; Purpose: Just an example 
; Author: Spidark (C) 2005
; Date: 31-05-2005
; Created using RadASM IDE with FASM
; This program was tested on Windows XP SP2 
;------------------------------------------------

format PE GUI 4.0
entry start

include "%fasminc%\Win32a.inc"

section '.data' data readable writeable

        hwnd            dd   ?
        hInstance       dd   ?
        hdc             dd   ?
        Wtx             dd   ?
        Wty             dd   ?
        Wwd             dd   ?
        Wht             dd   ?

        _wTitle          db      'Program:[ hardway.asm ]Coded by Spidark 2005',0 ;name of our window
        _wcName          db      'hardwayClass32',0      ;name of our window cla1111
        _errText         db      "Error Detected Program can not run on this machine!",0
        _messCap         db      "Message",0
        _hardCodedText   db      "INVOKELESS CODING IN FASM",0
        
        
        
        msg             MSG
        wc              WNDCLASS
        ps              PAINTSTRUCT
        rect            RECT
        
        
        
section '.code' code readable executable
start:
        push    0        
        call    [GetModuleHandle]
        mov     [hInstance],eax
        
;------------------------------------------------------;
; FILL WC STRUCTURE
;------------------------------------------------------;

        mov     [wc.hInstance],eax
        mov     [wc.style],CS_HREDRAW or CS_VREDRAW
        mov     [wc.lpfnWndProc],WndProc
        mov     [wc.lpszClassName],_wcName
        mov     [wc.hbrBackground],COLOR_WINDOW+1
        
        push    IDI_APPLICATION
        push    NULL
        call    [LoadIcon]                      
        mov     [wc.hIcon],eax                  
        
        push    IDC_ARROW
        push    NULL
        call    [LoadCursor]
        mov     [wc.hCursor],eax
        
        push    wc
        call    [RegisterClass]

        

        mov     [Wwd], 800                      ;Come here for the screen size
        mov     [Wht], 600
        
        push    SM_CXSCREEN
        call    [GetSystemMetrics]
        
        push    eax
        push    [Wwd]
        call    TopXY
        mov     [Wtx], eax
        
        push    SM_CYSCREEN
        call    [GetSystemMetrics]
        
        push    eax
        push    [Wht]
        call    TopXY
        
        mov     [Wty], eax
;-----------------------------------------------------
; CREAT THE MAIN WINDOW
;-----------------------------------------------------
        push    NULL
        push    [hInstance]
        push    NULL
        push    NULL
        push    [Wht]                   ; Window Height
        push    [Wwd]                   ; Window Width
        push    [Wty]                   ; Window Top X Coordinate
        push    [Wtx]                   ; Windows Top Y coordinate
        push    WS_OVERLAPPEDWINDOW and (not ( WS_SIZEBOX or WS_MAXIMIZEBOX)) 
        push    _wTitle                  ; Adress of the Title Name
        push    _wcName                  ; Window Class Name
        push    0                       ; Extended window style
        call    [CreateWindowEx]                ; Call Api
        mov     [hwnd],eax              ; Save The Handle
        
;------------------------------------------------------
; SHOW THE WINDOW
;------------------------------------------------------
        push    SW_SHOW                 ; How to Show The windows ??
        push    [hwnd]                  ; Window handle
        call    [ShowWindow]            ; Call Api
        

;-------------------------------------------------------
; ENTER LOOPLAND
;--------------------------------------------------------

MSG_LOOP:
        push    NULL
        push    NULL
        push    NULL
        push    msg
        call    [GetMessage]
        or   eax,eax
        jz   END_LOOP
        
        push    msg
        call    [TranslateMessage]
        
        push    msg
        call    [DispatchMessage]
        jmp  MSG_LOOP
END_LOOP:
        push    MB_OK or MB_ICONSTOP
        push    _messCap
        push    _errText
        push    [hwnd]
        call    [MessageBoxEx]
        
        push    0
        call    [ExitProcess]
        

;----------------------------------------------------
; WINDOW CALLBACK FUNCTION WndProc
;----------------------------------------------------
hWnd   equ ebp+8
uMsg   equ ebp+12
wParam equ ebp+16
lParam equ ebp+20       
WndProc:
        push    ebp                                             ; Create a stack frame
        mov     ebp,esp                                         
        push    ebx esi edi                                     ; Save these REGS in WndProc
        cmp     dword [uMsg],WM_PAINT
        je      ON_PAINT
        cmp     dword [uMsg],WM_DESTROY
        je      ON_DESTROY
        cmp     dword [uMsg],WM_NCHITTEST
        je      ON_NCHITTEST
DEFWINPROC:
        push    dword [lParam]
        push    dword [wParam]
        push    dword [uMsg]
        push    dword [hWnd]
        call    [DefWindowProc]
        
        jmp  EXIT
        
ON_PAINT:
        push    ps
        push    dword [hWnd]
        call    [BeginPaint]
        
        
        mov     [hdc],eax
        
        push    rect
        push    dword [hWnd]
        call    [GetClientRect]
        
        
        push    DT_SINGLELINE or DT_CENTER or DT_VCENTER
        push    rect
        xor     eax,eax
        mov     eax,-1                                  ; -1 autocalc Sizeof _hardCodedText
        push    eax
        push    _hardCodedText                                  
        push    [hdc]   
        call    [DrawText]
        
       
        push    ps
        push    dword [hWnd]
        call    [EndPaint]
        
        
        jmp  EXIT
;---------------------------------------------------------------
; MOVE WINDOW AROUND WITH YOUR MOUSE  LEFT MOUSE BUTTON
;---------------------------------------------------------------      
ON_NCHITTEST:

        push    dword [lParam]
        push    dword [wParam]
        push    dword [uMsg]
        push    dword [hWnd]
        call    [DefWindowProc]
        cmp eax,1
        jnz @F
        inc eax
        @@:
        jmp EXIT
ON_DESTROY:
        push    0
        call    [PostQuitMessage]
EXIT:
        pop  ebp
        pop  edi esi ebx
        ret  16
        
;--------------------------------------------------------------------;  
; HELP CALCULATE SCREEN CENTERING
; THIS CODE WAS PASTED FROM FASM FORUM SEARCH AND YOU WIL FIND IT
;---------------------------------------------------------------------;
wDim    equ     ebp+8
sDim    equ     ebp+12
TopXY:
        push    ebp
        mov     ebp,esp
        shr     dword [sDim],1 ; divide screen dimension by 2
        shr     dword [wDim],1 ; divide window dimension by 2
        mov     eax,dword [wDim] ; copy window dimension into eax
        sub     dword [sDim],eax ; sub half win dimension from half screen dimension
        mov     eax,dword [sDim] ; in the masm example they have used "return sDim" so i have added this line to return sDim in eax
        pop     ebp
        ret     8   



section '.idata' import data readable writeable
    library kernel32,'KERNEL32.DLL',\
           user32,    'USER32.DLL',\
           gdi32,     'GDI32.DLL'

  

  include '%fasminc%\apia\kernel32.inc'
  include '%fasminc%\apia\user32.inc'
  include '%fasminc%\apia\gdi32.inc'

        

               
section '.rsrc' resource from 'erer.res' data readable
         
    
Post 31 May 2005, 21:46
View user's profile Send private message Reply with quote
shaolin007



Joined: 03 Sep 2004
Posts: 65
shaolin007 02 Jun 2005, 12:50
Spidark wrote:
shaolin007 wrote:
Yea I see the examples of macros but I like to do it the hardway until I get the hang of it. I know that probably sounds silly but I learn better that way actually. When I get this Window up and running correctly, I will change it to macros to narrow down the code.
Hello shaolin007 i'm a newbie myself , still trying to learn assembly and windows programming.
I haven't realy take a deep look at your code , but i do have an working example for you , maybe it could be helpfull to you.
Code:
;------------------------------------------------
; Program Name: hardway.asm
; Version: 1.0
; Purpose: Just an example 
; Author: Spidark (C) 2005
; Date: 31-05-2005
; Created using RadASM IDE with FASM
; This program was tested on Windows XP SP2 
;------------------------------------------------

format PE GUI 4.0
entry start

include "%fasminc%\Win32a.inc"

section '.data' data readable writeable

        hwnd            dd   ?
        hInstance       dd   ?
        hdc             dd   ?
        Wtx             dd   ?
        Wty             dd   ?
        Wwd             dd   ?
        Wht             dd   ?

        _wTitle          db      'Program:[ hardway.asm ]Coded by Spidark 2005',0 ;name of our window
        _wcName          db      'hardwayClass32',0      ;name of our window cla1111
        _errText         db      "Error Detected Program can not run on this machine!",0
        _messCap         db      "Message",0
        _hardCodedText   db      "INVOKELESS CODING IN FASM",0
        
        
        
        msg             MSG
        wc              WNDCLASS
        ps              PAINTSTRUCT
        rect            RECT
        
        
        
section '.code' code readable executable
start:
        push    0        
        call    [GetModuleHandle]
        mov     [hInstance],eax
        
;------------------------------------------------------;
; FILL WC STRUCTURE
;------------------------------------------------------;

        mov     [wc.hInstance],eax
        mov     [wc.style],CS_HREDRAW or CS_VREDRAW
        mov     [wc.lpfnWndProc],WndProc
        mov     [wc.lpszClassName],_wcName
        mov     [wc.hbrBackground],COLOR_WINDOW+1
        
        push    IDI_APPLICATION
        push    NULL
        call    [LoadIcon]                      
        mov     [wc.hIcon],eax                  
        
        push    IDC_ARROW
        push    NULL
        call    [LoadCursor]
        mov     [wc.hCursor],eax
        
        push    wc
        call    [RegisterClass]

        

        mov     [Wwd], 800                      ;Come here for the screen size
        mov     [Wht], 600
        
        push    SM_CXSCREEN
        call    [GetSystemMetrics]
        
        push    eax
        push    [Wwd]
        call    TopXY
        mov     [Wtx], eax
        
        push    SM_CYSCREEN
        call    [GetSystemMetrics]
        
        push    eax
        push    [Wht]
        call    TopXY
        
        mov     [Wty], eax
;-----------------------------------------------------
; CREAT THE MAIN WINDOW
;-----------------------------------------------------
        push    NULL
        push    [hInstance]
        push    NULL
        push    NULL
        push    [Wht]                   ; Window Height
        push    [Wwd]                   ; Window Width
        push    [Wty]                   ; Window Top X Coordinate
        push    [Wtx]                   ; Windows Top Y coordinate
        push    WS_OVERLAPPEDWINDOW and (not ( WS_SIZEBOX or WS_MAXIMIZEBOX)) 
        push    _wTitle                  ; Adress of the Title Name
        push    _wcName                  ; Window Class Name
        push    0                       ; Extended window style
        call    [CreateWindowEx]                ; Call Api
        mov     [hwnd],eax              ; Save The Handle
        
;------------------------------------------------------
; SHOW THE WINDOW
;------------------------------------------------------
        push    SW_SHOW                 ; How to Show The windows ??
        push    [hwnd]                  ; Window handle
        call    [ShowWindow]            ; Call Api
        

;-------------------------------------------------------
; ENTER LOOPLAND
;--------------------------------------------------------

MSG_LOOP:
        push    NULL
        push    NULL
        push    NULL
        push    msg
        call    [GetMessage]
        or   eax,eax
        jz   END_LOOP
        
        push    msg
        call    [TranslateMessage]
        
        push    msg
        call    [DispatchMessage]
        jmp  MSG_LOOP
END_LOOP:
        push    MB_OK or MB_ICONSTOP
        push    _messCap
        push    _errText
        push    [hwnd]
        call    [MessageBoxEx]
        
        push    0
        call    [ExitProcess]
        

;----------------------------------------------------
; WINDOW CALLBACK FUNCTION WndProc
;----------------------------------------------------
hWnd   equ ebp+8
uMsg   equ ebp+12
wParam equ ebp+16
lParam equ ebp+20       
WndProc:
        push    ebp                                             ; Create a stack frame
        mov     ebp,esp                                         
        push    ebx esi edi                                     ; Save these REGS in WndProc
        cmp     dword [uMsg],WM_PAINT
        je      ON_PAINT
        cmp     dword [uMsg],WM_DESTROY
        je      ON_DESTROY
        cmp     dword [uMsg],WM_NCHITTEST
        je      ON_NCHITTEST
DEFWINPROC:
        push    dword [lParam]
        push    dword [wParam]
        push    dword [uMsg]
        push    dword [hWnd]
        call    [DefWindowProc]
        
        jmp  EXIT
        
ON_PAINT:
        push    ps
        push    dword [hWnd]
        call    [BeginPaint]
        
        
        mov     [hdc],eax
        
        push    rect
        push    dword [hWnd]
        call    [GetClientRect]
        
        
        push    DT_SINGLELINE or DT_CENTER or DT_VCENTER
        push    rect
        xor     eax,eax
        mov     eax,-1                                  ; -1 autocalc Sizeof _hardCodedText
        push    eax
        push    _hardCodedText                                  
        push    [hdc]   
        call    [DrawText]
        
       
        push    ps
        push    dword [hWnd]
        call    [EndPaint]
        
        
        jmp  EXIT
;---------------------------------------------------------------
; MOVE WINDOW AROUND WITH YOUR MOUSE  LEFT MOUSE BUTTON
;---------------------------------------------------------------      
ON_NCHITTEST:

        push    dword [lParam]
        push    dword [wParam]
        push    dword [uMsg]
        push    dword [hWnd]
        call    [DefWindowProc]
        cmp eax,1
        jnz @F
        inc eax
        @@:
        jmp EXIT
ON_DESTROY:
        push    0
        call    [PostQuitMessage]
EXIT:
        pop  ebp
        pop  edi esi ebx
        ret  16
        
;--------------------------------------------------------------------;  
; HELP CALCULATE SCREEN CENTERING
; THIS CODE WAS PASTED FROM FASM FORUM SEARCH AND YOU WIL FIND IT
;---------------------------------------------------------------------;
wDim    equ     ebp+8
sDim    equ     ebp+12
TopXY:
        push    ebp
        mov     ebp,esp
        shr     dword [sDim],1 ; divide screen dimension by 2
        shr     dword [wDim],1 ; divide window dimension by 2
        mov     eax,dword [wDim] ; copy window dimension into eax
        sub     dword [sDim],eax ; sub half win dimension from half screen dimension
        mov     eax,dword [sDim] ; in the masm example they have used "return sDim" so i have added this line to return sDim in eax
        pop     ebp
        ret     8   



section '.idata' import data readable writeable
    library kernel32,'KERNEL32.DLL',\
           user32,    'USER32.DLL',\
           gdi32,     'GDI32.DLL'

  

  include '%fasminc%\apia\kernel32.inc'
  include '%fasminc%\apia\user32.inc'
  include '%fasminc%\apia\gdi32.inc'

        

               
section '.rsrc' resource from 'erer.res' data readable
         
    



Thanks man but just a few questions if I may. Why the?

Code:
call [GetModuleHandle]
mov [hInstance], eax
    


Why would you need to do that?
Post 02 Jun 2005, 12:50
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 02 Jun 2005, 13:45
the hinstance is used in the CreateWindow call. its difficult for me to explain what its for, but just rest assured it is necessary. see the msdn for more info: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getmodulehandle.asp
Post 02 Jun 2005, 13:45
View user's profile Send private message Reply with quote
Spidark



Joined: 11 May 2005
Posts: 39
Spidark 02 Jun 2005, 19:51
shaolin007 wrote:


Thanks man but just a few questions if I may. Why the?

Code:
call [GetModuleHandle]
mov [hInstance], eax
    


Why would you need to do that?

I agree with Coconut, and it would be Nice for someone to fully explain the handle secret ( i know i want to know Laughing ), because if you comment out these lines of code
Code:
       ; push    0        
       ; call    [GetModuleHandle]
       ; mov     [hInstance],eax
        
;------------------------------------------------------;
; FILL WC STRUCTURE
;------------------------------------------------------;

       ; mov     [wc.hInstance],eax
     
The Progam stills runs.

I do have a quote from Petzolds Bible.
Programming Windows Fifth Edition (C)opyright Charles Petzold wrote:

A handle is simply a number (usually 32 bits in size) that refers to an object.The handles in Windows are similar to file handles used in conventional C or MS-DOS programming.A program almost always obtains a handle by calling a Windows function.The program uses the handle in other Windows functions to refer to the object.The actual value of the handle is unimportant to your program, but the Windows module that gives your program the handle knows how to use it to reference the object.
Post 02 Jun 2005, 19:51
View user's profile Send private message Reply with quote
shaolin007



Joined: 03 Sep 2004
Posts: 65
shaolin007 02 Jun 2005, 20:00
Instead of calling [GetModuleHandle] Couldn't we get that like this?

Code:

suppose in C

int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, UINT nCmdShow)

Couldn't we access these preliminary parameters through the stack like

mov [hInstance], [ebp+20]
mov [hPrevInstance], [ebp+16]
blah blah and so on...
    


Or does the call actually do just this? Or am I absolutely wrong? Smile
Post 02 Jun 2005, 20:00
View user's profile Send private message Reply with quote
coconut



Joined: 02 Apr 2004
Posts: 326
Location: US
coconut 02 Jun 2005, 20:05
i dont believe you can access them like that, the c runtime library sets that up for you from what i understand. i could be wrong, why dont you give it a try? every win32asm example ive ever seen though always uses GetModuleHandle. perhaps you could make a startup macro that calls the api functions and returns the values to you right at program entry
Post 02 Jun 2005, 20:05
View user's profile Send private message Reply with quote
shaolin007



Joined: 03 Sep 2004
Posts: 65
shaolin007 02 Jun 2005, 20:29
coconut wrote:
i dont believe you can access them like that, the c runtime library sets that up for you from what i understand. i could be wrong, why dont you give it a try? every win32asm example ive ever seen though always uses GetModuleHandle. perhaps you could make a startup macro that calls the api functions and returns the values to you right at program entry


Yea I know, I just have this insatiable desire to know how everything works with everything else. Smile I can't be satisfied with just the black box. I have to rip the sucker apart and see it's inards. Laughing But anyways, I modified my code with the [GetModuleHandle] and did some other changes to my window procedure and I still can't get the window to come up! The process is running when I check it with windows 2k but no dice! Here's my modified code posted below. Maybe you or spidark could see what I'm doing wrong still?

Code:

format PE GUI 4.0
entry Main

include '%fasminc%\win32a.inc'

section '.code' executable readable writeable

Main:
      ;WINDOW CLASS
      push IDI_APPLICATION
      push 0
      call [LoadIcon]
      mov [wndclass.hIconSm], eax

      mov [wndclass.lpszClassName], _szClassName

      mov [wndclass.lpszMenuName], 0

      push WHITE_BRUSH
      call [GetStockObject]
      mov [wndclass.hbrBackground], eax

      push IDC_ARROW
      push 0
      call [LoadCursor]
      mov [wndclass.hCursor], eax

      push IDI_APPLICATION
      push 0
      call [LoadIcon]
      mov [wndclass.hIcon], eax

      push 0
      call [GetModuleHandle]
      mov [_hInstance], eax
      mov [wndclass.hInstance], eax

      mov [wndclass.cbWndExtra], 0

      mov [wndclass.cbClsExtra], 0

      mov [wndclass.lpfnWndProc], WndProc

      mov eax, CS_HREDRAW
      or eax, CS_VREDRAW
      mov [wndclass.style], eax

      mov [wndclass.cbSize], sizeof.WNDCLASS
      ;END WINDOW CLASS

      ;REGISTER WINDOW CLASS
      push wndclass
      call [RegisterClass]

      ;CREATE WINDOW
      mov [create.lpCreateParams], 0
      push [create.lpCreateParams]

      mov eax, [_hInstance]
      mov [create.hInstance], 0
      push [create.hInstance]

      mov [create.hMenu], 0
      push [create.hMenu]

      mov [create.hwndParent], 0
      push [create.hwndParent]

      mov [create.cy], CW_USEDEFAULT
      push [create.cy]

      mov [create.cx], CW_USEDEFAULT
      push [create.cy]

      mov [create.y], CW_USEDEFAULT
      push [create.y]

      mov [create.x], CW_USEDEFAULT
      push [create.x]

      mov [create.style], WS_OVERLAPPEDWINDOW
      push [create.style]

      mov eax, _szWndCaption
      mov [create.lpszName], eax
      push [create.lpszName]

      mov eax, _szClassName
      mov [create.lpszClass], eax
      push [create.lpszClass]

      mov [create.dwExStyle], WS_EX_OVERLAPPEDWINDOW
      push [create.dwExStyle]

      call [CreateWindowEx]
      mov [hwnd], eax

      ;SHOW WINDOW
      push SW_SHOW
      push [hwnd]
      call [ShowWindow]

      ;UPDATE WINDOW
      push [hwnd]
      call [UpdateWindow]

      ;MESSAGE LOOP
Msg_Loop:
      push 0
      push 0
      push 0
      push wmsg
      call [GetMessage]
      push wmsg
      call [TranslateMessage]
      test eax, WM_QUIT
      je Exit_Msg_Loop
      push wmsg
      call [DispatchMessage]
      jmp Msg_Loop

Exit_Msg_Loop:
        push [wmsg.wParam]
        call [ExitProcess]

_hwnd                   equ ebp+20
_iMsg                   equ ebp+16
_wParam                 equ ebp+12
_lParam                 equ ebp+8
WndProc:
        push ebp
        mov ebp, esp
        push ebx esi edi

        cmp dword [_iMsg], WM_PAINT
        je  Paint_Window
        cmp dword [_iMsg], WM_DESTROY
        je  Destroy_Window
Def_Win_Proc:
        push dword [_lParam]
        push dword [_wParam]
        push dword [_iMsg]
        push dword [_hwnd]
        call [DefWindowProc]
        jmp Exit

Paint_Window:
        push ps
        push dword [_hwnd]
        call [BeginPaint]
        mov [_hdc], eax

        push wrect
        push dword [_hwnd]
        call GetClientRect

        mov eax, DT_VCENTER
        or eax, DT_CENTER
        or eax, DT_SINGLELINE
        push eax
        push wrect
        push -1
        push _szGreeting
        push [_hdc]
        call [DrawText]

        push ps
        push dword [_hwnd]
        call [EndPaint]
        jmp Exit

Destroy_Window:
        push 0
        call [PostQuitMessage]
Exit:
        pop ebp
        pop edi esi ebx
        ret 10h
section '.data' data readable writeable
hwnd                    dd ?
_hInstance              dd ?
_szClassName            db "My Window",0
_szWndCaption           db "My 1st Window",0
_hdc                    dd ?
_szGreeting             db "Hello this is my 1st window!",0

;STRUCTS
wndclass                WNDCLASSEX
wmsg                    MSG
create                  CREATESTRUCT
ps                      PAINTSTRUCT
wrect                   RECT

section '.idata' import data readable writeable

library   kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL',\
          gdi32, 'GDI32.DLL'
include   '%fasminc%\apia\kernel32.inc'
include   '%fasminc%\apia\user32.inc'
include   '%fasminc%\apia\gdi32.inc'
    
Post 02 Jun 2005, 20:29
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 02 Jun 2005, 20:54
I have corrected many mistakes, so I'm just posting the working version (may look a bit ugly, just some patching done over your code), hope this is enough to help you:
Code:
format PE GUI 4.0
entry Main

include 'win32a.inc'

section '.code' executable readable writeable

Main:
      ;WINDOW CLASS
      push IDI_APPLICATION
      push 0
      call [LoadIcon]
      mov [wndclass.hIconSm], eax

      mov [wndclass.lpszClassName], _szClassName

      mov [wndclass.lpszMenuName], 0

      push WHITE_BRUSH
      call [GetStockObject]
      mov [wndclass.hbrBackground], eax

      push IDC_ARROW
      push 0
      call [LoadCursor]
      mov [wndclass.hCursor], eax

      push IDI_APPLICATION
      push 0
      call [LoadIcon]
      mov [wndclass.hIcon], eax

      push 0
      call [GetModuleHandle]
      mov [_hInstance], eax
      mov [wndclass.hInstance], eax

      mov [wndclass.cbWndExtra], 0

      mov [wndclass.cbClsExtra], 0

      mov [wndclass.lpfnWndProc], WndProc

      mov eax, CS_HREDRAW
      or eax, CS_VREDRAW
      mov [wndclass.style], eax

      mov [wndclass.cbSize], sizeof.WNDCLASSEX

      ;REGISTER WINDOW CLASS
      push wndclass
      call [RegisterClassEx]

      ;CREATE WINDOW
      push 0
      push [_hInstance]
      push 0
      push 0
      push CW_USEDEFAULT
      push CW_USEDEFAULT
      push CW_USEDEFAULT
      push CW_USEDEFAULT
      push WS_OVERLAPPEDWINDOW
      push _szWndCaption
      push _szClassName
      push WS_EX_OVERLAPPEDWINDOW
      call [CreateWindowEx]
      mov [hwnd], eax

      ;SHOW WINDOW
      push SW_SHOW
      push [hwnd]
      call [ShowWindow]

      ;UPDATE WINDOW
      push [hwnd]
      call [UpdateWindow]

      ;MESSAGE LOOP
Msg_Loop:
      push 0
      push 0
      push 0
      push wmsg
      call [GetMessage]
      or   eax,eax
      jz Exit_Msg_Loop
      push wmsg
      call [TranslateMessage]
      push wmsg
      call [DispatchMessage]
      jmp Msg_Loop

Exit_Msg_Loop:
        push [wmsg.wParam]
        call [ExitProcess]

_hwnd                   equ ebp+8
_iMsg                   equ ebp+0Ch
_wParam                 equ ebp+10h
_lParam                 equ ebp+14h
WndProc:
        push ebp
        mov ebp, esp
        push ebx esi edi
        cmp dword [_iMsg], WM_PAINT
        je  Paint_Window
        cmp dword [_iMsg], WM_DESTROY
        je  Destroy_Window
Def_Win_Proc:
        push dword [_lParam]
        push dword [_wParam]
        push dword [_iMsg]
        push dword [_hwnd]
        call [DefWindowProc]
        jmp Exit

Paint_Window:
        push ps
        push dword [_hwnd]
        call [BeginPaint]
        mov [_hdc], eax

        push wrect
        push dword [_hwnd]
        call [GetClientRect]

        mov eax, DT_VCENTER
        or eax, DT_CENTER
        or eax, DT_SINGLELINE
        push eax
        push wrect
        push -1
        push _szGreeting
        push [_hdc]
        call [DrawText]

        push ps
        push dword [_hwnd]
        call [EndPaint]
        jmp Exit

Destroy_Window:
        push 0
        call [PostQuitMessage]
Exit:
        pop edi esi ebx
        pop ebp
        ret 10h

section '.data' data readable writeable
hwnd                    dd ?
_hInstance              dd ?
_szClassName            db "My Window",0
_szWndCaption           db "My 1st Window",0
_hdc                    dd ?
_szGreeting             db "Hello this is my 1st window!",0

;STRUCTS
wndclass                WNDCLASSEX
wmsg                    MSG
ps                      PAINTSTRUCT
wrect                   RECT

section '.idata' import data readable writeable

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


PS. The %fasminc% references are removed because I currently use the INCLUDE variable, if you prefer old style FASMINC, put them back.
Post 02 Jun 2005, 20:54
View user's profile Send private message Visit poster's website Reply with quote
shaolin007



Joined: 03 Sep 2004
Posts: 65
shaolin007 03 Jun 2005, 12:09
Thanks everyone for helping out. Saved me ALOT of time and 'hair pulling'! Smile .
Post 03 Jun 2005, 12:09
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.