flat assembler
Message board for the users of flat assembler.
Index
> Windows > Can't get window to display |
Author |
|
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
|
|||
30 May 2005, 23:41 |
|
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. Thanks again buddy! |
|||
31 May 2005, 01:19 |
|
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' |
|||
31 May 2005, 05:20 |
|
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
|
|||
31 May 2005, 15:29 |
|
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. |
|||
31 May 2005, 17:57 |
|
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. 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 |
|||
31 May 2005, 21:46 |
|
shaolin007 02 Jun 2005, 12:50
Spidark 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? |
|||
02 Jun 2005, 12:50 |
|
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
|
|||
02 Jun 2005, 13:45 |
|
Spidark 02 Jun 2005, 19:51
shaolin007 wrote:
I agree with Coconut, and it would be Nice for someone to fully explain the handle secret ( i know i want to know ), because if you comment out these lines of code Code: ; push 0 ; call [GetModuleHandle] ; mov [hInstance],eax ;------------------------------------------------------; ; FILL WC STRUCTURE ;------------------------------------------------------; ; mov [wc.hInstance],eax I do have a quote from Petzolds Bible. Programming Windows Fifth Edition (C)opyright Charles Petzold wrote:
|
|||
02 Jun 2005, 19:51 |
|
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? |
|||
02 Jun 2005, 20:00 |
|
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
|
|||
02 Jun 2005, 20:05 |
|
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. I can't be satisfied with just the black box. I have to rip the sucker apart and see it's inards. 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' |
|||
02 Jun 2005, 20:29 |
|
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. |
|||
02 Jun 2005, 20:54 |
|
shaolin007 03 Jun 2005, 12:09
Thanks everyone for helping out. Saved me ALOT of time and 'hair pulling'! .
|
|||
03 Jun 2005, 12:09 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.