|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Ноя 16, 2003 21:14:54 У меня проблема с консольным выводом. При использовании WriteConsole иногда, особенно при скором завершении программы, данные предварительно не до конца выводятся. И еще, как реализовать алгоритм в win "нажмите любую клавишу" с помощью api? |
|
|
Дата: Ноя 16, 2003 22:05:16 Стандартный алгоритм: 1.Пишешь на С++ прогу с вызовом нужной функции(#include <conio.h>.... getch()) 2.Компилишь её под Windows (option -W ),посмотри опции. 3.Открываешь .EXE файл HIEW (6.81),там и будет push param2 push param1 ... call NeedProcName (getch()-->API) 4.Пишешь код на ASM. |
|
|
Дата: Ноя 17, 2003 04:22:36 use_32 WriteConsole иногда ... данные ... не до конца выводятся. Что возвращается в lpNumberOfCharsWritten? реализовать алгоритм в win "нажмите любую клавишу" WaitKey proc
LOCAL NumOfEvents:DWORD
LOCAL NumOfEventsRead:DWORD
LOCAL ir:INPUT_RECORD
LOCAL fDone:BOOL
push ebx
mov fDone,FALSE
.while fDone != TRUE
invoke GetNumberOfConsoleInputEvents, hCon, addr NumOfEvents
xor ebx,ebx
.while (ebx < NumOfEvents) && (fDone != TRUE)
invoke ReadConsoleInput, hCon, addr ir, 1, addr NumOfEventsRead
.if (ir.EventType == KEY_EVENT) && (ir.Event.KeyEvent.bKeyDown == TRUE)
move fDone,TRUE
.endif
inc ebx
.endw
.endw
pop ebx
ret
WaitKey endp |
|
|
Дата: Ноя 17, 2003 06:47:57 · Поправил: Grenader q_q "A process can specify a console input buffer handle in one of the wait functions to determine when there is unread console input. When the input buffer is not empty, the state of a console input buffer handle is signaled." WaitKey proc local buffer: dword local NumberOfCharsRead: dword WaitForKey: invoke WaitForSingleObject, hCon, INFINITE invoke ReadConsole, hCon, addr buffer, 1, addr NumberOfCharsRead, NULL cmp NumberOfCharsRead, 0 ; если кликнули мышкой и т.п. je WaitForKey ret WaitKey endp Примерно такой код проще, на мой взгляд. |
|
|
Дата: Ноя 17, 2003 08:34:54 Grenader Примерно говоришь. Ты его пробовал? Для hCon = GetStdHandle(STD_INPUT_HANDLE), WaitForSingleObject сразу возвращает WAIT_OBJECT_0. Консоль должна быть сконфигурирована так, чтобы ReadConsole завершался по любому символу, а не после <Enter> плюс, наверняка ненужно эхо. |
|
|
Дата: Ноя 17, 2003 10:00:03 q_q Для hCon = GetStdHandle(STD_INPUT_HANDLE), WaitForSingleObject сразу возвращает WAIT_OBJECT_0 Ты немного не прав. Мы ждем появления в буфере ЛЮБЫХ событий. И нет никакой гарантии, что к моменту вызова WaitForxxx буфер будет пуст. Если же вызвать FlushConsoleInputBuffer перед WaitForxxx, то все прекрасно работает. Вот пример рабочего кода (только что тестил):
Getch:
push eax
invoke GetConsoleMode, hCon, esp
invoke SetConsoleMode, hCon, ENABLE_PROCESSED_INPUT
invoke FlushConsoleInputBuffer, hCon
invoke WaitForSingleObject, hCon, INFINITE
push eax
mov eax, esp
push edx
mov edx, esp
invoke ReadConsole, hCon, eax, 1, edx, NULL
add esp, 8h
invoke SetConsoleMode, hCon
ret
Можно и в этом случае использовать ReadConsoleInput - но зачем усложнять... |
|
|
Дата: Ноя 17, 2003 11:09:21 Grenader пример рабочего кода (только что тестил) Точно тестил, где второй параметр второго SetConsoleMode? ждем появления в буфере ЛЮБЫХ событий Flush не решает всех возможных проблем. Попробуй забрать фокус у консоли, например, мышкой активизировать другое окно, и WaitForSingleObject вернет управление. use_32 > алгоритм ... "нажмите любую клавишу Попробуй своим кодом поймать не символьную кнопку (eg Esc, Fn). |
|
|
Дата: Ноя 17, 2003 13:41:36 · Поправил: Grenader q_q Точно тестил, где второй параметр второго SetConsoleMode? Этот параметр уже в стеке, см. начало процедуры (push eax) Попробуй своим кодом поймать не символьную кнопку Надо ESC? Легко! :)
WaitKey proc
local ir: INPUT_RECORD
local count: dword
WaitForEvent:
invoke WaitForSingleObject, hCon, INFINITE
invoke GetNumberOfConsoleInputEvents, hCon, addr count
mov edi, [esp]
xor ebx, ebx
ReadInput:
invoke ReadConsoleInput, hCon, ir, 1, addr count
cmp ir.EventType, KEY_EVENT
jne @f
cmp ir.Event.KeyEvent.bKeyDown, 0
sete bl
@@:
dec edi
jnz ReadInput
test ebx, ebx
jz WaitForKey
ret
WaitKey endp
Пришлось конечно юзать ReadConsoleInput - но принцип тот же. |
|
|
Дата: Ноя 18, 2003 04:08:04 Grenader Этот параметр уже в стеке Это я понимаю, почему бы не использовать call ведь invoke хочет два параметра. Легко! ... принцип тот же Куда это подевался Flush? Еще немного подумаешь, избавишься от WaitFor и твой WaitKey практически не отличить от моего. |
|
|
Дата: Ноя 18, 2003 09:32:41 q_q Это я понимаю, почему бы не использовать call ведь invoke хочет два параметра Мой invoke - не требует :) И вобще - я на FASM пишу, а на остальные диалекты транслирую - когда удачно, когда не очень. Но я согласен - надо получше тестить. Еще немного подумаешь, избавишься от WaitFor и твой WaitKey практически не отличить от моего Дело в принципе. Твой код использует цикл, внутри которого постоянно вызвает GetNumberOfConsoleInputEvents - ты не пробовал смотреть на загрузку процессора в этот момент? Это в старые добрые времена ДОС так писать можно было - а сейчас для приостановки потоков используются WaitForxxx. Мой код напрасно процессор не гоняет. Вот, собвственно, и вся разница. Принципиальная. А Flush я взял так, скорее ради примера, что бы показать, что утверждение "Для hCon = GetStdHandle(STD_INPUT_HANDLE), WaitForSingleObject сразу возвращает WAIT_OBJECT_0" немного не верно :) Чей вариант правильнее - думаю, любой программер скажет, даже не задумываясь. PS Я отнюдь не стремлюсь всеми силами показать свою крутость, и непогрешимость. И всегда готов признать, что бываю (как и все) иногда неправ. Так что давай не будем превращать этот топик в выяснение отношений - "кто у кого больше ошибок найдет". Ок? |
|
|
Дата: Ноя 18, 2003 10:07:19 Grenader пробовал смотреть на загрузку процессора С точки зрения теории Wait правильнее. На практике, внутри подобных циклов я использую Sleep(100), что снижает загрузку процессора. В реальной жизни не сталкивался с необходимостью только ждать, обычно необходимо проверять, и если событий нет, то что-либо делать. Ок? q |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.087 |