The MASM Forum

General => The Workshop => Topic started by: ikudesnik on September 03, 2015, 10:48:56 PM

Title: Not satisfied SetTime?
Post by: ikudesnik on September 03, 2015, 10:48:56 PM
.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
.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 ?



.code ; сегмент кода
mytime proc hWnd, uMsg, idEvent, dwTime: DWORD ;hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam: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
invoke KillTimer,NULL, [IDTime]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



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 передаем, как ноль



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



end start ; завершает сегмент кода
   
Title: Re: Not satisfied SetTime?
Post by: avcaballero on September 04, 2015, 12:10:21 AM
Wow, reading Russian is a bit hard, not as Spanish, the most beautiful and easy language in the world, or... yes, English if there's nothing else  :redface:
Title: Re: Not satisfied SetTime?
Post by: rrr314159 on September 04, 2015, 01:36:46 AM
hello ikudesnik,

I'm not satisfied with SetTime either! For a better way to measure time, use RDTSC; see \masm32\macros\timers.asm for an example. Not sure if that's what you're looking for?
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 04, 2015, 02:49:47 AM
- you kill SetTimer, so how should it work?
- SetTimer requires a Windows loop, i.e. a GUI, not a console

.386; 32-bit mode
.model flat, stdcall; compile in exe-file of the API call with the possibility
option casemap: none; lack of distinction between uppercase and lowercase characters

; It provides constant values
include \ 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 \ masm32 \ lib \ winmm.lib
.const
MEMSIZE equ 65535

.data; data segment

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? ;file size
size_file_read dd? , the number of bytes read
ByteWritten dd?

hConsoleInput DWORD? ; variables to hold the handles input and output,
hConsoleOutput DWORD? ; the names of these variables may be different

; 1 byte buffer (with value 0)
1 Buffer byte dup (0); for water Keyboard symbol 1,
; the name of the buffer may be different

NumberOfCharsRead DWORD? ; to record the number of variables actually
NumberOfCharsWritten DWORD? ; input and output symbols,
; the names of these variables may be different

hMemory HANDLE?
pMemory DWORD?


msg1 byte "mission accomplished successfully!" ; string variable

; string variable
msg2 byte "Press Enter, to come out ...", 0; It ends with a zero,
; as it will be transferred
; API-function CharToOem


msg1310 byte 13, 10; line translation
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?

.code; code segment
mytime proc hWnd, uMsg, idEvent, dwTime: DWORD; hWnd: DWORD, uMsg: DWORD, wParam: DWORD, lParam: 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,; open the file to read for diskriptora file
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; get the file size
; 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; function returns a handle to the requested memory block

invoke GlobalLock, hMemory
mov pMemory, eax; returns a pointer to the memory block
; mov esi, eax



invoke ReadFile, hfile_read,; read data from the file
pMemory,; address buffer
file_read_size,; MEMSIZE-1, buffer size, or how many bytes you need to read
ADDR size_file_read,; Address of the variable which is written the actual number of read data
NULL
; CMP EAX, 0
; JE _ERROR_ReadFile

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

invoke SetTimer, NULL, NULL, 1000, ADDR mytime
mov IDTime, eax
invoke KillTimer, NULL, [IDTime]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

invoke WriteFile, hfile_write,
pMemory,; Pointer to the buffer containing the data to be written to a file
size_file_read,; The number of bytes that will be written to a file
ADDR size_file_read,; ADDR ByteWritten,; Pointer to a variable that receives the number of bytes written
NULL
; CMP EAX, 0
; JE _ERROR_WriteFile

invoke CloseHandle, hfile_read
invoke CloseHandle, hfile_write

invoke GlobalUnlock, pMemory
invoke GlobalFree, hMemory

invoke AllocConsole; queries the Windows console

invoke GetStdHandle, STD_INPUT_HANDLE; We get the handle console input
mov hConsoleInput, EAX; write handle variable

invoke GetStdHandle, STD_OUTPUT_HANDLE; We obtain a handle to the console output
mov hConsoleOutput, EAX; write handle variable

invoke WriteConsoleA,; newline console
                      hConsoleOutput,; handle output
                        ADDR msg1310,; address line msg1310
                      SIZEOF msg1310,; line size msg1310
           ADDR NumberOfCharsWritten,; here the function will record the number of characters
                                   0; lpReserved pass as zero

invoke CharToOem, ADDR msg1, ADDR msg1

invoke WriteConsoleA,; write "Hello, World!"
                      hConsoleOutput,
                           ADDR msg1,
                         SIZEOF msg1,
           ADDR NumberOfCharsWritten,
                                   0

invoke WriteConsoleA,; newline
                      hConsoleOutput,
                        ADDR msg1310,
                      SIZEOF msg1310,
           ADDR NumberOfCharsWritten,
                                   0

; invoke CharToOem, ADDR msg2, ADDR msg2; recoding Win1251 -> DOS

invoke WriteConsoleA,; write "Press Enter, to come out ..."
                      hConsoleOutput,
                           ADDR msg2,
                   (SIZEOF msg2) - 1; reduce the size of line msg2 1 (due to zero)
           ADDR NumberOfCharsWritten,
                                   0

invoke ReadConsoleA,; I look forward to the console
                      hConsoleInput,; handle input
                        ADDR Buffer,; buffer address
                                  1, ; enter 1 character
             ADDR NumberOfCharsRead,; here the function will record the number of characters
                                  0; lpReserved pass as zero

invoke ExitProcess, 0; We tell the system that the program is over

end start; completes code segment
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 04, 2015, 04:25:20 AM
even if in Russian, tell us what you want and what is not working   :t
we can use google translate, and get a pretty good idea
Title: Re: Not satisfied SetTime?
Post by: ikudesnik on September 04, 2015, 04:06:47 PM
How to organize a loop: every two seconds to process one character in the console?
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 04, 2015, 04:26:35 PM
you can use Sleep

    mov     ebx,10
    .repeat
        lea     eax,[ebx-1]
        print   str$(eax),32
        INVOKE  Sleep,2000     ;time in mS
        dec     ebx
    .until ZERO?
    print  chr$(13,10)
Title: Re: Not satisfied SetTime?
Post by: ikudesnik on September 04, 2015, 04:52:55 PM
It is necessary to use the API function with timer :(
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 04, 2015, 04:56:51 PM
i guess what you want to do is use SetTimer and KillTimer
generally, we use it to send WM_TIMER messages
but, that's not the only way to use it

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx)

another way to use it is with a callback function
when the time elapses, a PROC is called
notice that the timer function is passed 4 dword arguments

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644907%28v=vs.85%29.aspx (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644907%28v=vs.85%29.aspx)

i can make an example, but not tonight - it's bed time   :P
Title: Re: Not satisfied SetTime?
Post by: ikudesnik on September 04, 2015, 05:12:00 PM
Can I use timesetevent?
Can you give an example of my problem?
Title: Re: Not satisfied SetTime?
Post by: avcaballero on September 04, 2015, 05:29:40 PM
Maybe this may help. Fasm syntax, sorry, don't have masm at hand now. Regards.
Title: Re: Not satisfied SetTime?
Post by: avcaballero on September 04, 2015, 05:31:08 PM
The file. Isn't possible to attach a file on editing a post?
Title: Re: Not satisfied SetTime?
Post by: 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  :(
Title: Re: Not satisfied SetTime?
Post by: ikudesnik on September 04, 2015, 06:15:32 PM
.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
.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 ?



.code ; сегмент кода
mytime proc ;hWnd, uMsg, idEvent, dwTime: DWORD ;hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam: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
    invoke timeKillEvent, IDTime
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 timeSetEvent,20000,0,addr mytime,TIME_ONESHOT,TIME_CALLBACK_FUNCTION ;http://rusapi.narod.ru/timeSetEvent.htm
mov IDTime,eax

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



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 передаем, как ноль



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



end start ; завершает сегмент кода
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 04, 2015, 07:26:15 PM
It is important to understand that SetTimer needs a message loop to work. In general, a console app with no WndProc doesn't have a message loop. But even a simple MessageBox will create one:

include \masm32\include\masm32rt.inc
.code
CbTimer proc hwnd:DWORD, uMsg:DWORD, PMidEvent:DWORD, dwTime:DWORD
  print "*"
  ret
CbTimer endp
start:
   invoke SetTimer, 0, 123, 50, CbTimer
   inkey "hit any key, then Escape"
   .Repeat
    print "#"
invoke Sleep, 100 ; this will NOT allow the timer callback to execute
invoke GetKeyState, VK_ESCAPE
test ah, ah
   .Until Sign?
   MsgBox 0, "Congrats", "SetTimer in console app:", MB_OK
   exit
end start


An alternative is to create a program with WndProc etc but to build it as console app. SetTimer will work just fine, and you can hide the main window if you don't want it.
Title: Re: Not satisfied SetTime?
Post by: rrr314159 on September 04, 2015, 07:37:55 PM
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)
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 04, 2015, 08:07:02 PM
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)
Title: Re: Not satisfied SetTime?
Post by: ikudesnik on September 04, 2015, 09:21:52 PM
The challenge is strictly in the console using api functions.
Settime is not suitable for the console?
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 04, 2015, 10:47:40 PM
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
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 04, 2015, 10:51:07 PM
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. (http://masm32.com/board/index.php?topic=4561.msg48917#msg48917). 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 (http://blogs.msdn.com/b/oldnewthing/archive/2007/12/31/6909007.aspx)). Such as: Access to its message loop denied :(
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 04, 2015, 11:34:31 PM
ok, here is one using the multi-media functions...
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 04, 2015, 11:39:12 PM
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 (https://msdn.microsoft.com/en-us/library/dd757634%28v=vs.85%29.aspx)

oh - it was in the other one   :lol:
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 04, 2015, 11:39:49 PM
Looks convincing - it works even if you insert an inkey into the sleep loop :t
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 05, 2015, 12:14:28 AM
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:
Title: Re: Not satisfied SetTime?
Post by: 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.
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 05, 2015, 01:52:54 AM
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.
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 05, 2015, 01:55:30 AM
i find that, if you set the X, Y, width, and height all to 0, it's hard to see   :biggrin:
Title: Re: Not satisfied SetTime?
Post by: ikudesnik on September 05, 2015, 03:16:51 AM
Give an example please?
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 05, 2015, 03:51:58 AM
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

Title: Re: Not satisfied SetTime?
Post by: ikudesnik on September 05, 2015, 04:15:43 AM
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 ; завершает сегмент кода
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 05, 2015, 10:21:56 AM
приложение окно необходимо использовать SetTimer
Title: Re: Not satisfied SetTime?
Post by: dedndave on September 05, 2015, 10:36:18 AM
Эта программа создает и окно GUI и окно консоли.
Окно графического интерфейса используется для таймера, и окно консоли для отображения используется.
Окно GUI не видно.
Title: Re: Not satisfied SetTime?
Post by: TWell on September 05, 2015, 03:59:13 PM
With another API function and C#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms687003(v=vs.85).aspx
VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
printf("#");
}
int main(void)
{
HANDLE hQueue,hTimer;
if ((hQueue = CreateTimerQueue()) != 0) {
CreateTimerQueueTimer(&hTimer,hQueue,(WAITORTIMERCALLBACK)TimerRoutine,0,1000,1000,0);
while (getchar() != 10);
DeleteTimerQueueTimer(hQueue,hTimer,INVALID_HANDLE_VALUE);
DeleteTimerQueue(hQueue);
}
return 0;
}
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 05, 2015, 05:24:00 PM
Quote from: TWell on September 05, 2015, 03:59:13 PM
With another API function and C#define WIN32_LEAN_AND_MEAN

Works like a charm BUT:
warning #2030: '=' used in a conditional expression:
   if (hQueue = CreateTimerQueue()) {

Is that intentional? When using == it stops working ::)
Title: Re: Not satisfied SetTime?
Post by: TWell on September 05, 2015, 05:39:33 PM
Fixed(hQueue = CreateTimerQueue()) != 0
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 05, 2015, 06:44:27 PM
OK, so you are assigning and testing for errors at the same time.

Here is the assembler version:

include \masm32\include\masm32rt.inc

.code
TimerRoutine proc lParam, TimerOrWaitFired
  print "#"
  ret
TimerRoutine endp

start:
  print "Timer in console:", 13, 10
  invoke CreateTimerQueue
  push eax ; save hTimerQueue
  push eax ; create slot for hTimer
  mov ecx, esp
  invoke CreateTimerQueueTimer, ecx, eax, TimerRoutine, 0, 127, 127, 0
  push eax ; timer-queue timer
  .Repeat
getkey
push eax
print esp
pop eax
  .Until al==VK_ESCAPE
  print "*", 13, 10
  pop eax ; timer-queue timer
  pop ecx ; hTimer
  invoke DeleteTimerQueueTimer, eax, ecx, INVALID_HANDLE_VALUE
  call DeleteTimerQueue ; invoke DeleteTimerQueue, [esp]
  print LastError$()
  invoke Sleep, 2000
  exit
end start
Title: Re: Not satisfied SetTime?
Post by: TWell on September 05, 2015, 07:26:49 PM
Thanks, i forgot thatDeleteTimerQueueTimer(hQueue,hTimer,INVALID_HANDLE_VALUE);
Title: Re: Not satisfied SetTime?
Post by: jj2007 on September 05, 2015, 07:42:12 PM
MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682569%28v=vs.85%29.aspx):
QuoteCompletionEvent [in, optional]

    If this parameter is INVALID_HANDLE_VALUE, the function waits for any running timer callback functions to complete before returning.

    If this parameter is NULL, the function marks the timer for deletion and returns immediately.

Programmers at work in Redmond:
Quote"Ok, let's take -1 for 'complete before returning'"
"No, you can't call it -1, give it a proper name"
"Oh well, -1... let me think ... INVALID_HANDLE_VALUE?"
;)