flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2, 3 Next |
Author |
|
macomics 16 Jul 2022, 11:54
To block the execution of the program, MessageBox starts its own message processing cycle.
SetTimer adds the trigger time to the array/waiting list in chronological order and, with each timer interrupt, the handler checks the first element of this array/list for triggering. If it worked, a message from the timer is added to the message queue. The first message on the timer selects your message processing cycle, and the rest - the message processing cycle of the last MessageBox shown. To prevent such an effect, it is worth stopping the timer for the duration of its function or creating an execution flag (Event/Critical section, etc.) |
|||
![]() |
|
MatQuasar3 27 Nov 2024, 07:04
This is not working, how to use Timer properly in Windows?
No beep. EDIT: Code has been updated following AsmGuru62 advice. Code: format PE GUI 4.0 include 'win32a.inc' IDT_TIMER1=1 section '.text' code readable executable entry $ invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS,16,16,300,300,NULL,NULL,[wc.hInstance],NULL mov [hwnd],eax invoke SetTimer,[hwnd],IDT_TIMER1,3000,NULL or eax,eax jz end_loop 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_CREATE je .wmcreate cmp [wmsg],WM_SIZE je .wmsize cmp [wmsg],WM_PAINT je .wmpaint cmp [wmsg], WM_TIMER je .wmtimer cmp [wmsg],WM_KEYDOWN je .wmkeydown cmp [wmsg],WM_DESTROY je .wmdestroy .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish .wmcreate: xor eax,eax jmp .finish .wmsize: jmp .processed .wmpaint: jmp .processed .wmtimer: cmp [wparam],IDT_TIMER1 jne .processed invoke Beep, 750, 300 ;invoke MessageBeep, MB_OK xor eax,eax jmp .finish .wmkeydown: ;invoke Beep, 750, 300 ;invoke MessageBeep, MB_OK cmp [wparam],VK_ESCAPE jne .defwndproc .wmdestroy: invoke KillTimer,[hwnd],IDT_TIMER1 invoke PostQuitMessage,0 xor eax,eax jmp .finish .processed: mov eax,1 .finish: pop edi esi ebx ret endp section '.data' data readable writeable _title db 'timer',0 _class db 'timer',0 wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,NULL,NULL,_class hwnd dd ? msg MSG section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ GetModuleHandle,'GetModuleHandleA',\ Beep, 'Beep', \ ExitProcess,'ExitProcess' import user,\ RegisterClass,'RegisterClassA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA',\ LoadCursor,'LoadCursorA',\ PostQuitMessage,'PostQuitMessage', \ MessageBeep, 'MessageBeep', \ SetTimer, 'SetTimer', \ KillTimer, 'KillTimer' Last edited by MatQuasar3 on 27 Nov 2024, 16:50; edited 5 times in total |
|||
![]() |
|
MatQuasar3 27 Nov 2024, 11:51
I don't know how to use SetTimer, really..... also not working in console version:
Code: format PE console include 'win32a.inc' section '.text' code readable executable entry $ ;Method #1 - SetTimer, not working ;invoke SetTimer,0,0,3000,TimerProc ;mov [_id],eax ;or eax,eax ;jz .quit .repeat: ;Method #2 - Sleep, working but not ideal ;invoke Sleep,3000 ;invoke Beep,750,300 ;Method #3 - GetTickCount, ideal invoke GetTickCount mov [_new],eax ;SET _new = GetTickCount() mov edx,[_old] sub eax,edx cmp eax, 3000 jb .wait ;IF (GetTickCount - _old < 3000) mov edx,[_new] mov [_old],edx ;SET _old = _new invoke Beep,750,300 .wait: invoke GetKeyState, VK_ESCAPE bt eax, 15 jnc .repeat ;invoke KillTimer, 0, [_id] .quit: invoke ExitProcess,0 proc TimerProc hwnd, uMsg, idEvent, dwTime push ebx esi edi invoke Beep, 750, 300 pop edi esi ebx ret endp section '.data' data readable writeable _id dd ? _new dd ? _old dd ? section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ Beep, 'Beep', \ Sleep, 'Sleep',\ ExitProcess,'ExitProcess',\ GetTickCount, 'GetTickCount' import user,\ MessageBeep, 'MessageBeep', \ SetTimer, 'SetTimer', \ KillTimer, 'KillTimer', \ GetKeyState, 'GetKeyState' Last edited by MatQuasar3 on 29 Nov 2024, 07:51; edited 3 times in total |
|||
![]() |
|
AsmGuru62 27 Nov 2024, 12:54
Please note the "jmp .finish" everywhere.
When any message is processed --- EAX must contain a return value to tell Windows what happened (usually 0, but can be other things). When you look at the label ".finish" --- EAX is never set, so the code returns with whatever was in EAX. Only WM_DESTROY and DefWindowProc responses have correct EAX. |
|||
![]() |
|
MatQuasar3 27 Nov 2024, 13:03
Thanks, AsmGuru62
Now the code jmp to Code: .processed: mov eax,1 except for WM_DESTROY and DefWindowProc. I guess now it is correct. |
|||
![]() |
|
AsmGuru62 27 Nov 2024, 15:15
Well, the Microsoft assigns the return value to every message, like here:
https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-create If you look inside the link --- it says that WM_CREATE proper response is EAX=0. I am going to copy/paste the code you posted and try it in my FASM IDE with proper responses. I will report back. |
|||
![]() |
|
AsmGuru62 27 Nov 2024, 15:16
Ok, you have fixed the code, but does it BEEP now?
|
|||
![]() |
|
MatQuasar3 27 Nov 2024, 16:07
AsmGuru62 wrote: Ok, you have fixed the code, but does it BEEP now? No, it still doesn't beep. The beep only works if I put in WM_KEYDOWN, not work in WM_TIMER. But I will fix the response again tomorrow because you just showed me the link for WM_CREATE. |
|||
![]() |
|
MatQuasar3 27 Nov 2024, 16:13
AsmGuru62 wrote: Well, the Microsoft assigns the return value to every message, like here: Thanks so much! This info is useful. I have modified the code: Code: .wmcreate: xor eax,eax jmp .finish However, the timer still doesn't work, but I am happy to learn about window procedure and window message. |
|||
![]() |
|
MatQuasar3 27 Nov 2024, 19:07
I needed the timer to work for my shooting game (posted in another thread).
Any help to solve this issue is greatly appreciated! |
|||
![]() |
|
sinsi 27 Nov 2024, 19:51
Microsoft SetTimer parameters wrote:
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer |
|||
![]() |
|
AsmGuru62 27 Nov 2024, 19:57
It looks like Timer ID = 1, so does it beep now?
|
|||
![]() |
|
macomics 27 Nov 2024, 20:03
Try
Code: format PE GUI 4.0 include 'win32a.inc' IDT_TIMER1=1 section '.text' code readable executable entry $ invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc invoke CreateWindowEx,0,_class,_title,WS_VISIBLE or WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS,16,16,300,300,NULL,NULL,[wc.hInstance],NULL mov [hwnd],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_CREATE je .wmcreate cmp [wmsg],WM_SIZE je .wmsize ; cmp [wmsg],WM_PAINT ; je .wmpaint cmp [wmsg], WM_TIMER je .wmtimer cmp [wmsg],WM_KEYDOWN je .wmkeydown cmp [wmsg],WM_DESTROY je .wmdestroy .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish .wmcreate: invoke SetTimer,[hwnd],IDT_TIMER1,3000,NULL or eax,eax jz .wmcreate.error xor eax,eax jmp .finish .wmcreate.error: mov eax, -1 jmp .finish .wmsize: jmp .processed .wmpaint: jmp .processed .wmtimer: cmp [wparam],IDT_TIMER1 jne .processed invoke Beep, 750, 300 ;invoke MessageBeep, MB_OK xor eax,eax jmp .finish .wmkeydown: ;invoke Beep, 750, 300 ;invoke MessageBeep, MB_OK cmp [wparam],VK_ESCAPE jne .defwndproc .wmdestroy: invoke KillTimer,[hwnd],IDT_TIMER1 invoke PostQuitMessage,0 xor eax,eax jmp .finish .processed: mov eax,1 .finish: pop edi esi ebx ret endp section '.data' data readable writeable _title db 'timer',0 _class db 'timer',0 wc WNDCLASS CS_HREDRAW or CS_VREDRAW,WindowProc,0,0,NULL,NULL,NULL,COLOR_WINDOWFRAME+1,NULL,_class hwnd dd ? msg MSG section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ GetModuleHandle,'GetModuleHandleA',\ Beep, 'Beep', \ ExitProcess,'ExitProcess' import user,\ RegisterClass,'RegisterClassA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA',\ LoadCursor,'LoadCursorA',\ PostQuitMessage,'PostQuitMessage', \ MessageBeep, 'MessageBeep', \ SetTimer, 'SetTimer', \ KillTimer, 'KillTimer' AsmGuru62 wrote: It looks like Timer ID = 1, so does it beep now? |
|||
![]() |
|
macomics 27 Nov 2024, 20:33
This is how it will work with WM_PAINT, because now the redrawing of the window region will be performed.
Code: format PE GUI 4.0 include 'win32a.inc' IDT_TIMER1=1 section '.text' code readable executable entry $ invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc invoke CreateWindowEx,0,_class,_title,WS_VISIBLE or WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS,16,16,300,300,NULL,NULL,[wc.hInstance],NULL mov [hwnd],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_CREATE je .wmcreate cmp [wmsg],WM_SIZE je .wmsize cmp [wmsg],WM_PAINT je .wmpaint cmp [wmsg], WM_TIMER je .wmtimer cmp [wmsg],WM_KEYDOWN je .wmkeydown cmp [wmsg],WM_DESTROY je .wmdestroy .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish .wmcreate: invoke SetTimer,[hwnd],IDT_TIMER1,3000,NULL or eax,eax jz .wmcreate.error xor eax,eax jmp .finish .wmcreate.error: mov eax, -1 jmp .finish .wmsize: jmp .processed .wmpaint: invoke BeginPaint,[hwnd],ps mov [hdc],eax invoke EndPaint,[hwnd],ps xor eax,eax jmp .finish .wmtimer: cmp [wparam],IDT_TIMER1 jne .processed invoke Beep, 750, 300 ;invoke MessageBeep, MB_OK xor eax,eax jmp .finish .wmkeydown: ;invoke Beep, 750, 300 ;invoke MessageBeep, MB_OK cmp [wparam],VK_ESCAPE jne .defwndproc .wmdestroy: invoke KillTimer,[hwnd],IDT_TIMER1 invoke PostQuitMessage,0 xor eax,eax jmp .finish .processed: mov eax,1 .finish: pop edi esi ebx ret endp section '.data' data readable writeable wc WNDCLASS CS_HREDRAW or CS_VREDRAW,WindowProc,0,0,NULL,NULL,NULL,COLOR_WINDOWFRAME+1,NULL,_class _title db 'timer',0 _class db 'timer',0 align 16 msg MSG ps PAINTSTRUCT hwnd dd ? hdc dd ? section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ GetModuleHandle,'GetModuleHandleA',\ Beep, 'Beep', \ ExitProcess,'ExitProcess' import user,\ BeginPaint,'BeginPaint',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ DispatchMessage,'DispatchMessageA',\ EndPaint,'EndPaint',\ GetMessage,'GetMessageA',\ KillTimer, 'KillTimer',\ LoadCursor,'LoadCursorA',\ MessageBeep, 'MessageBeep', \ PostQuitMessage,'PostQuitMessage', \ RegisterClass,'RegisterClassA',\ SetTimer, 'SetTimer',\ TranslateMessage,'TranslateMessage' |
|||
![]() |
|
MatQuasar3 27 Nov 2024, 21:21
macomics wrote: This is how it will work with WM_PAINT, because now the redrawing of the window region will be performed. Looks like this is the solution to my problem! Thank you, macomics. I will test this piece of code once I wake up tomorrow. There is still room for me to learn in Windows GUI programming. I am impressed by your coding style, sorting the API function names alphabetically. |
|||
![]() |
|
macomics 27 Nov 2024, 22:07
MatQuasar3 wrote: There is still room for me to learn in Windows GUI programming. I am impressed by your coding style, sorting the API function names alphabetically |
|||
![]() |
|
AsmGuru62 27 Nov 2024, 23:21
Well, if all is working --- I am off the hook.
|
|||
![]() |
|
MatQuasar3 28 Nov 2024, 05:39
macomics wrote:
It works, as I have tested now. Of course I notice the changes to window class attributes, and declaration of additional variable and structure for BeginPaint and EndPaint. Is the "align 16" for faster performance? Because with or without it the program still run. Now I know SetTimer is best invoked inside window procedure. Thank you once again! |
|||
![]() |
|
MatQuasar3 28 Nov 2024, 05:41
AsmGuru62 wrote: Well, if all is working --- I am off the hook. Thank you for your guidance on window message. |
|||
![]() |
|
Goto page 1, 2, 3 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.