flat assembler
Message board for the users of flat assembler.

Index > Windows > another "why this doesn't work" question

Author
Thread Post new topic Reply to topic
daluca



Joined: 05 Nov 2005
Posts: 86
daluca
Hi:
I'm trying to understand the message thing in windows
so i added some code to the template example that comes
with the FASM package,is simple: when the WindowProc is called
by windows (correct me if I'm wrong) the simple procedure
increments a counter,converts its value in a decimal string
and set it as the window title with the SetWindowText function,
so i should see the title of the window increment every time
it receives a message but it doesn't work and I don't know
why, here is the code:

Code:

; Template for program using standard Win32 headers

format PE GUI 4.0

include 'win32ax.inc'

section '.data' data readable writeable

  _title db 'Win32 program template',0
  _class db 'FASMWIN32',0
  ;---added--------------
  buffer db 'xxxxxxxxxx',0
  winH dd 0          ;to keep the window handle
  msg_counter dd 0   ;the counter of the messages
  ;---added--------------
  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

  msg MSG

section '.code' 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

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,192,192,NULL,NULL,[wc.hInstance],NULL
        ;-----added--------------
        mov [winH],eax
        ;------------------------
  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        or      eax,eax
        jz      end_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  end_loop:
        invoke  ExitProcess,[msg.wParam]

proc WindowProc hwnd,wmsg,wparam,lparam
        push    ebx esi edi
        cmp     [wmsg],WM_DESTROY
        je      wmdestroy
        ;-----proc added--------
        inc dword[msg_counter]
        mov eax,[msg_counter]
        mov esi,buffer
        call bin2str
        invoke SetWindowText,[winH],buffer
        ;-----------------------
  defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     finish
  wmdestroy:
        invoke  PostQuitMessage,0
        xor     eax,eax
  finish:
        pop     edi esi ebx
        ret
endp
;---------ADDED---------------------
 bin2str:         ;EAX  number to convert
        push ecx  ;ESI pointer to buffer
        push edi
        mov ecx,1
        mov edi,esi
        add esi,10
;-------div10
.divide:
        push eax
        mov edx,3435973837
        mul edx
        pop eax
        and dl,$f8
        sub eax,edx
        shr edx,2
        sub eax,edx
        shr edx,1
        xchg eax,edx
;-------------------
        or dl,$30
        dec esi
        mov [esi],dl
        inc ecx
        cmp eax,0
        je .salir
        jmp .divide
;-------------------
.salir:
        cld
        rep movsb
        pop edi
        pop ecx
        ret
;--------------------
.end start

    


when I execute the program in XP the window just appears
and immediately disappears.
if I run it in windows ME it says that the program provoke
an error in USER32.DLL

if I remove the line "invoke SetWindowText..."
the program works but obviously I don't see the counter.
and if i cut the ;---proc added--- code and paste it just below
the:
invoke GetMessage,msg,NULL,0,0
or eax,eax
jz end_loop

I can see now the counter but I don't want this
since i read that the GetMessage function doesn't
get all the messages, some are sended directly to
the WindowProc.

thanks in advance.
Post 17 Aug 2006, 04:39
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
That's because SetWindowText sends WM_SETTEXT every time you call it and since your WindowProc always calls SetWindowText you enter in an infinite recursion which is broken inmediatelly by a stack overflow.

A quick solution is to add
Code:
        cmp     [wmsg], WM_SETTEXT
        je      defwndproc     
but you will see that the counter will increase because using SetWindowText causes some messages to be posted on the message queue. Another disadvantage is that you will not count WM_SETTEXT anymore, even if it's not generated by your SetWindowText call.
Post 17 Aug 2006, 05:27
View user's profile Send private message Reply with quote
daluca



Joined: 05 Nov 2005
Posts: 86
daluca
well now i understand the infinite recursion thing
but i add to the code your quick solution and still doesn't work it causes
a error in KERNEL .i use OllyDbg as my just-in-time debuger an only displays:
INT3 command at KERNEL32.DebugBreak

did you actually assembled the source and test it?


so i can't use functions that send messages to my own window?
Post 17 Aug 2006, 06:43
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
I tested this:
Code:
; Template for program using standard Win32 headers

format PE GUI 4.0 

include 'win32ax.inc' 

section '.data' data readable writeable 

  _title db 'Win32 program template',0 
  _class db 'FASMWIN32',0 
  ;---added-------------- 
  buffer db 'xxxxxxxxxx',0 
  winH dd 0          ;to keep the window handle 
  msg_counter dd 0   ;the counter of the messages 
  ;---added-------------- 
  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class 

  msg MSG 

section '.code' 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 

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,192,192,NULL,NULL,[wc.hInstance],NULL 
        ;-----added-------------- 
        mov [winH],eax 
        ;------------------------ 
  msg_loop: 
        invoke  GetMessage,msg,NULL,0,0 
        or      eax,eax 
        jz      end_loop 
        invoke  TranslateMessage,msg 
        invoke  DispatchMessage,msg 
        jmp     msg_loop 

  end_loop: 
        invoke  ExitProcess,[msg.wParam] 

proc WindowProc hwnd,wmsg,wparam,lparam 
        push    ebx esi edi 
        cmp     [wmsg],WM_DESTROY 
        je      wmdestroy
        cmp     [wmsg], WM_SETTEXT
        je      defwndproc
        ;-----proc added-------- 
        inc dword[msg_counter] 
        mov eax,[msg_counter] 
        mov esi,buffer 
        call bin2str 
        invoke SetWindowText,[winH],buffer 
        ;----------------------- 
  defwndproc: 
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] 
        jmp     finish 
  wmdestroy: 
        invoke  PostQuitMessage,0 
        xor     eax,eax 
  finish: 
        pop     edi esi ebx 
        ret 
endp 
;---------ADDED--------------------- 
 bin2str:         ;EAX  number to convert 
        push ecx  ;ESI pointer to buffer 
        push edi 
        mov ecx,1 
        mov edi,esi 
        add esi,10 
;-------div10 
.divide: 
        push eax 
        mov edx,3435973837 
        mul edx 
        pop eax 
        and dl,$f8 
        sub eax,edx 
        shr edx,2 
        sub eax,edx 
        shr edx,1 
        xchg eax,edx 
;------------------- 
        or dl,$30 
        dec esi 
        mov [esi],dl 
        inc ecx 
        cmp eax,0 
        je .salir 
        jmp .divide 
;------------------- 
.salir: 
        cld 
        rep movsb 
        pop edi 
        pop ecx 
        ret 
;-------------------- 
.end start     


Works on WinXP SP2
Post 18 Aug 2006, 01:27
View user's profile Send private message Reply with quote
daluca



Joined: 05 Nov 2005
Posts: 86
daluca
thanks..... well I assemble that and it doesn't work in windows ME
and about XP: I will tested later,since i don't have access to it right now.
Post 19 Aug 2006, 05:41
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
To get out any problems I suggest use another window for the counter, that way you call SetWindowText for that window so your main window will not recieve any undesire message anymore

Code:
; Template for program using standard Win32 headers

format PE GUI 4.0  

include 'win32ax.inc'  

section '.data' data readable writeable  

  _title db 'Win32 program template',0  
  _class db 'FASMWIN32',0  
  ;---added--------------  
  buffer db 'xxxxxxxxxx',0  
  winH dd 0          ;to keep the window handle
  winC dd 0
  msg_counter dd 0   ;the counter of the messages  
  ;---added--------------  
  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class  

  msg MSG  

section '.code' 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  

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,192,192,NULL,NULL,[wc.hInstance],NULL  
        ;-----added--------------  
        mov [winH],eax  
        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128+192,128,192,192,NULL,NULL,[wc.hInstance],NULL
        mov [winC], eax
        ;------------------------
  msg_loop:  
        invoke  GetMessage,msg,NULL,0,0  
        or      eax,eax  
        jz      end_loop  
        invoke  TranslateMessage,msg  
        invoke  DispatchMessage,msg  
        jmp     msg_loop  

  end_loop:  
        invoke  ExitProcess,[msg.wParam]  

proc WindowProc hwnd,wmsg,wparam,lparam  
        push    ebx esi edi  
        cmp     [wmsg],WM_DESTROY  
        je      wmdestroy
        mov     eax, [winH]
        cmp     eax, [hwnd]
        jne      defwndproc
        ;-----proc added--------  
        inc dword[msg_counter]  
        mov eax,[msg_counter]  
        mov esi,buffer  
        call bin2str  
        invoke SetWindowText,[winC],buffer
        ;-----------------------  
  defwndproc:  
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]  
        jmp     finish  
  wmdestroy:  
        invoke  PostQuitMessage,0  
        xor     eax,eax  
  finish:  
        pop     edi esi ebx  
        ret  
endp  
;---------ADDED---------------------  
 bin2str:         ;EAX  number to convert  
        push ecx  ;ESI pointer to buffer  
        push edi  
        mov ecx,1  
        mov edi,esi  
        add esi,10  
;-------div10  
.divide:  
        push eax  
        mov edx,3435973837  
        mul edx  
        pop eax  
        and dl,$f8  
        sub eax,edx  
        shr edx,2  
        sub eax,edx  
        shr edx,1  
        xchg eax,edx  
;-------------------  
        or dl,$30  
        dec esi  
        mov [esi],dl  
        inc ecx  
        cmp eax,0  
        je .salir  
        jmp .divide  
;-------------------  
.salir:  
        cld  
        rep movsb  
        pop edi  
        pop ecx  
        ret  
;--------------------  
.end start     
Post 19 Aug 2006, 15:52
View user's profile Send private message Reply with quote
daluca



Joined: 05 Nov 2005
Posts: 86
daluca
yeah: thanks that works just fine. Very Happy

btw: I tested the "other way" (the one that works in your XP sp2 but not in
my ME) and it worked to in XP (no-servicepack), strange.
Post 20 Aug 2006, 05:45
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-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.