News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Not satisfied SetTime?

Started by ikudesnik, September 03, 2015, 10:48:56 PM

Previous topic - Next topic

rrr314159

Quote from: ikudesnik on September 04, 2015, 06:11:48 PM
I'm probably a fool-I can not understand :icon_eek:

it is necessary to call a function
invoke timeSetEvent,20000,0,addr mytime,TIME_ONESHOT,TIME_CALLBACK_FUNCTION
mov IDTime,eax
invoke timeKillEvent, IDTime

After 20 seconds, the procedure "mytime" should work
but it does not work  :(

- Actually I haven't used these functions, but achieve the same thing within the Window loop. But I think I see two problems,

- you're killing the event as soon as you set it up, long before it fires, that's no good.

- more important you usually want to use a Windows, not console, program to do this. The Windows program stays resident (active) as it processes its message loop, until the user exits, so it will still be there 20 seconds later. But this console program will run in a few milliseconds and exit, and that's the end of it. When the timer event fires, it's not going to go out to disk and reload your program to find your "mytime" proc! instead, the timer event is cancelled when your prog exits. This only works in a Windows prog; or else a console prog with some sort of loop to keep it running for 20 seconds.

- Easiest apprach, just wait until dedndave drags his lazy *** out of bed, and posts an example - that will show you how it works

[edit] wrote this b4 seeing jj2007's previous post, which makes this one more-or-less redundant (except the advice about dedndave is still applicable)
I am NaN ;)

jj2007

Quote from: rrr314159 on September 04, 2015, 07:37:55 PMjust wait until dedndave drags his lazy *** out of bed, and posts an example

It's not just the ***, the whole person is lazy - 7928 posts only 8)

ikudesnik

The challenge is strictly in the console using api functions.
Settime is not suitable for the console?

dedndave

timeSetEvent is the multi-media version of SetTimer

Jochen - i think you can use them in console apps
1) i don't think it needs a message loop to work - if you use a callback
2) console apps do have a message loop, completely hidden from the normal console app
the console window is a GUI app   :biggrin:

we will find out soon, because my lazy ass is up - lol

jj2007

Quote from: dedndave on September 04, 2015, 10:47:40 PMJochen - i think you can use them in console apps
1) i don't think it needs a message loop to work - if you use a callback
2) console apps do have a message loop, completely hidden from the normal console app
the console window is a GUI app   :biggrin:

Try the snippet in reply #14.. Add this line before MsgBox:
print chr$(13,10,"Callback kicks in", 13, 10)

But your point 2 is indeed an interesting idea ::)
Unfortunately, there are some special rules for consoles (see Raymond Chen). Such as: Access to its message loop denied :(

dedndave

ok, here is one using the multi-media functions...

dedndave

by the way, i noticed a sentance in the docs....

Quoteoops - wrong document - lol

i guess the timer uses a queue all its' own   :P

https://msdn.microsoft.com/en-us/library/dd757634%28v=vs.85%29.aspx

oh - it was in the other one   :lol:

jj2007

Looks convincing - it works even if you insert an inkey into the sleep loop :t

dedndave

ok - SetTimer does not work without a message loop, as JJ mentioned before
i figured it could use hwndConsole (from GetConsoleWindow) - that does not work

QuoteAn application can process WM_TIMER messages by including a WM_TIMER case statement in the window
procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc
callback function, the default window procedure calls the callback function when it processes WM_TIMER.
Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of
processing WM_TIMER.

sorry about that   :biggrin:

hutch--

What I have normally seen in this type of situation is make a normal UI window and start it off screen, -1000,-1000 used to do the trick. Set your timer in the UI window and trigger whatever you need from there.

jj2007

Quote from: hutch-- on September 05, 2015, 12:22:57 AM
What I have normally seen in this type of situation is make a normal UI window and start it off screen, -1000,-1000 used to do the trick. Set your timer in the UI window and trigger whatever you need from there.

Started as an extra thread, I suppose? The window could be hidden, too.

dedndave

i find that, if you set the X, Y, width, and height all to 0, it's hard to see   :biggrin:

ikudesnik


dedndave

Reply #20 has a working console example using timeSetEvent

attached here is a simple small window program, but i thought you wanted a console app

;create the window

        INVOKE  CreateWindowEx,edi,offset szClassName,offset szAppName,
                WS_OVERLAPPEDWINDOW or WS_VISIBLE or WS_CLIPCHILDREN,
                CW_USEDEFAULT,SW_SHOWNORMAL,MAIN_WIDTH,MAIN_HEIGHT,edi,edi,ebx,edi


if you want it to be invisible, change that line to...

;create the window

        INVOKE  CreateWindowEx,edi,offset szClassName,offset szAppName,
                WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN,
                edi,edi,edi,edi,edi,edi,ebx,edi


ikudesnik

What's wrong, it does not start?
.386 ; 32-битный режим
.model flat, stdcall ; компиляция в exe-файл с возможностью вызова API
option casemap :none ; неразличение прописных и строчных символов



; содержит значения констант
include C:\masm32\include\windows.inc ; STD_INPUT_HANDLE,
; STD_OUTPUT_HANDLE
include \masm32\include\winmm.inc
include <\masm32\include\kernel32.inc>
include <\masm32\include\user32.inc>

includelib <\masm32\lib\kernel32.lib>
includelib <\masm32\lib\user32.lib>
includelib c:\masm32\lib\winmm.lib
MSGSTRUCT STRUC
MSHWND DD ? ;идентификатор окна, получающего сообщение
MSMESSAGE DD ? ;идентификатор сообщения
MSWPARAM DD ? ;дополнительная информация о сообщении
MSLPARAM DD ? ;дополнительная информация о сообщении
MSTIME DD ? ;время посылки сообщения
MSPT DD ? ;положение курсора, во время посылки сообщения
MSGSTRUCT ENDS
.const

MEMSIZE equ 65535

.data ; сегмент данных

hfile_write dd ?
hfile_read dd ?
buff_file db 0

file_read db "file_read.txt",0
file_write db "file_write.txt",0
file_read_size dd ?  ;размер файла
size_file_read dd ?  ;количество считанных байт
ByteWritten dd ?

hConsoleInput DWORD ? ; переменные для хранения хэндлов ввода и вывода,
hConsoleOutput DWORD ? ; названия этих переменных могут быть другими

            ; буфер 1 байт (со значением 0)
Buffer byte 1 dup (0) ; для вода с клавиатуры 1 символа,
; название буфера может быть другим

NumberOfCharsRead DWORD ? ; переменные для записи числа фактически
NumberOfCharsWritten DWORD ? ; введенных и выведенных символов,
; названия этих переменных могут быть другими

hMemory HANDLE ?
pMemory DWORD ?


msg1 byte "Задача выполненна успешно!" ; строковая переменная

; строковая переменная
msg2 byte "Нажмите Enter, чтобы выйти...", 0 ; заканчивается нулем,
; так как она будет передана
; API-функции CharToOem


msg1310 byte 13, 10 ; перевод строки
ERROR_CreateFile byte "ERROR_CreateFile",0
ERROR_GetFileSize byte "ERROR_GetFileSize",0
ERROR_VirtualAlloc byte "ERROR_VirtualAlloc",0
ERROR_ReadFile byte "ERROR_ReadFile",0
ERROR_WriteFile byte "ERROR_WriteFile",0

IDTime dword ?

lpMsg           MSGSTRUCT     <?>

.code ; сегмент кода
mytime proc ;hWnd:DWORD, uMsg:DWORD, idEvent:DWORD, dwTime:DWORD
    pushad
    mov ecx,file_read_size
mov esi,pMemory
loop1:
movzx eax,byte ptr [esi]
mov eax,'f'
mov byte ptr [esi],al
;mov dword ptr [esi],eax
loop2:
inc esi
loop loop1
popad
    ret
mytime endp



start:


invoke CreateFile, ADDR file_write,
GENERIC_WRITE or GENERIC_READ,
  FILE_SHARE_WRITE or FILE_SHARE_READ,
                         NULL,
                CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
                         NULL
;CMP EAX,-1
;JE _ERROR_CreateFile
mov hfile_write, eax

invoke CreateFile, ADDR file_read,                        ;открываем файл для чтения для получения дискриптора файла
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY,
NULL
;CMP EAX,-1
;JE _ERROR_CreateFile
mov hfile_read, eax

invoke GetFileSize, hfile_read, NULL                      ;получаем размер файла
;CMP EAX,0
;JE _ERROR_GetFileSize
mov file_read_size,eax
;mov ecx,eax


invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE
mov  hMemory,eax ;функция возвращает хэндл на запрошенный блок памяти

invoke GlobalLock,hMemory
mov  pMemory,eax ;возвращает указатель на блок памяти
;mov  esi,eax



invoke ReadFile, hfile_read,                          ;считываем данные с файла
pMemory, ;Адрес буфера
file_read_size, ;MEMSIZE-1,  ;Размер буфера или сколько байтов нужно прочитать
ADDR size_file_read,  ; Адрес переменной, в которую записывается реальное количество прочитанных данных
NULL
;CMP EAX,0
;JE  _ERROR_ReadFile



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;установить таймер
invoke  SetTimer, NULL, NULL, 1000, ADDR mytime
mov IDTime,eax
@@Repeat:
    invoke  GetMessage, addr lpMsg, NULL, 0, 0
        cmp      eax,0
        je      @@Exit
        invoke  TranslateMessage, addr lpMsg
        invoke  DispatchMessage, addr lpMsg
        ;cmp lpMsg.message, WM_CHAR
        ;jz  @@Exit
        jmp     @@Repeat


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



invoke WriteFile, hfile_write, 
pMemory, ; Указатель на буфер, содержащий данные, которые будут записаны в файл
size_file_read,     ; Число байтов, которые будут записаны в файл
ADDR size_file_read,;ADDR ByteWritten,   ;Указатель на переменную, которая получает число записанных байтов
NULL
;CMP EAX,0
;JE _ERROR_WriteFile

invoke CloseHandle, hfile_read
invoke CloseHandle, hfile_write

invoke GlobalUnlock,pMemory
invoke GlobalFree,hMemory





invoke AllocConsole ; запрашиваем у Windows консоль

invoke GetStdHandle, STD_INPUT_HANDLE ; получаем хэндл консоли для ввода
mov hConsoleInput, EAX ; записываем хэндл в переменную

invoke GetStdHandle, STD_OUTPUT_HANDLE ; получаем хэндл консоли для вывода
mov hConsoleOutput, EAX ; записываем хэндл в переменную

invoke WriteConsoleA, ; переводим строку в консоли
                      hConsoleOutput, ; хэндл вывода
                        ADDR msg1310, ; адрес строки msg1310
                      SIZEOF msg1310, ; размер строки msg1310
           ADDR NumberOfCharsWritten, ; сюда функция запишет число символов
                                   0 ; lpReserved передаем, как ноль

invoke CharToOem, ADDR msg1, ADDR msg1

invoke WriteConsoleA, ; пишем " Hello, World!"
                      hConsoleOutput,
                           ADDR msg1,
                         SIZEOF msg1,
           ADDR NumberOfCharsWritten,
                                   0



invoke WriteConsoleA, ; переводим строку
                      hConsoleOutput,
                        ADDR msg1310,
                      SIZEOF msg1310,
           ADDR NumberOfCharsWritten,
                                   0



;invoke CharToOem, ADDR msg2, ADDR msg2 ; перекодируем Win1251 -> DOS



invoke WriteConsoleA, ; пишем " Нажмите Enter, чтобы выйти..."
                      hConsoleOutput,
                           ADDR msg2,
                   (SIZEOF msg2) - 1, ; уменьшаем размер строки msg2 на 1 (из-за нуля)
           ADDR NumberOfCharsWritten,
                                   0



invoke ReadConsoleA, ; ожидаем ввода в консоль
                      hConsoleInput, ; хэндл ввода
                        ADDR Buffer, ; адрес буфера
                                  1, ; вводим 1 символ
             ADDR NumberOfCharsRead, ; сюда функция запишет число символов
                                  0 ; lpReserved передаем, как ноль

@@Exit:

invoke timeKillEvent, IDTime
invoke ExitProcess, 0 ; сообщаем системе, что программа окончена



end start ; завершает сегмент кода