Текущий архив: 2006.07.16;
Скачать: CL | DM;
Внизожидание консольным приложением нажатия символьной клавиши Найти похожие ветки
← →
Mr tray (2006-06-30 17:53) [0]Здравствуйте. Я работаю с консольным приложением. Мне нужно, чтоб программа ждала, когда будет нажата какая-либо символьная клавиша. Делаю так:
inphnd:=GetStdHandle(STD_INPUT_HANDLE);
WaitForSingleObjectex(inpHnd,INFINITE,true);
ReadConsole(inpHnd,@c,1,Wr,nil); {c:char; inphnd,wr:cardinal}
Но получается, что WaitForSingleObjectex проскакивает сразу, ничего не ожидая, а ReadConsole срабатывает только по нажатию enter. Короче, получается каша.
Да... И мне нужно, чтоб символ нажатой клавиши не выводился на экран. Читал хелп, там что-то сказано про какой-то SYNHRONIZE для Windows NT, но я чё то не врубился, как это должно быть задействовано. Подскажите решение моей задачи.
← →
Mr tray (2006-06-30 17:58) [1](не SYNHRONIZE, а SYNСHRONIZE)
← →
resuS (2006-06-30 19:54) [2]ууу.. мне тоже интересно... а то с этими консольными приложениями - страх один.
где же наш Шевченко, он должен знать.
← →
Zeqfreed © (2006-06-30 22:13) [3]
program Project1;
{$APPTYPE CONSOLE}
uses
Windows;
type
TCharSet = set of Char;
const
FC_BLACK = 0;
FC_BLUE = 1;
FC_GREEN = 2;
FC_TEAL = 3;
FC_RED = 4;
FC_FUCSIA = 5;
FC_YELLOW = 6;
FC_WHITE = 7;
var
hInput : THandle;
hScreenBuf : Cardinal;
function ConsoleOpen(const Title : String) : Boolean;
begin
Result := AllocConsole();
SetConsoleTitle(PChar(Title));
hInput := GetStdHandle(STD_INPUT_HANDLE);
SetConsoleMode(hInput, ENABLE_PROCESSED_INPUT);
hScreenBuf := CreateConsoleScreenBuffer(GENERIC_READ + GENERIC_WRITE, 0, nil, CONSOLE_TEXTMODE_BUFFER, nil);
SetConsoleActiveScreenBuffer(hScreenBuf);
end;
procedure ConsoleClose();
begin
CloseHandle(hScreenBuf);
CloseHandle(hInput);
FreeConsole();
end;
function ConsoleWaitForInput(const AtX, AtY, InputLen : Integer; const Color : Word; const AllowedChars : TCharSet) : String;
const
BckSpSeq: array[0..2] of Char = (#8,#0,#8);
Err: array[0..5] of Char = "error!";
nErr: array[0..5] of Char = #0#0#0#0#0#0;
var
InputStr : string;
a : Char;
read, written : Cardinal;
c : _coord;
begin
c.X := AtX;
c.Y := AtY;
SetConsoleTextAttribute(hScreenBuf, Color);
SetConsoleCursorPosition(hScreenBuf, c);
repeat
WaitForSingleObjectEx(hInput, INFINITE, True);
ReadConsole(hInput, @a, 1, read, nil);
if (a in AllowedChars) and (InputLen > 0) and (length(InputStr) < InputLen) then begin
InputStr := InputStr + a;
WriteConsole(hScreenBuf, @a, 1, written, nil);
end;
if a = #8 then begin
if Length(InputStr) > 0 then begin
WriteConsole(hScreenBuf, @BckSpSeq, Length(BckSpSeq), written, nil);
InputStr := Copy(InputStr, 1, length(InputStr) - 1);
end;
end;
until (a = #13) and ((#13 in AllowedChars) or (length(InputStr) > 0));
Result := InputStr;
end;
function StringToOEM(const S: AnsiString) : AnsiString;
var
Len: Integer;
begin
Len := Length(S);
SetLength(Result, Len);
if Len > 0 then CharToOEM(PChar(S), PChar(Result));
end;
procedure ConsoleWrite(const AtX, AtY : Integer; const Text : array of String; const Attribs : array of Word);
var
c : _coord;
buf : PChar;
written : Cardinal;
i : Integer;
attr : Word;
begin
c.X := AtX;
c.Y := AtY;
SetConsoleCursorPosition(hScreenBuf, c);
for i := Low(Text) to High(Text) do begin
buf := PChar(StringToOEM(Text[i]));
if i < Length(Attribs) then attr := Attribs[i];
SetConsoleTextAttribute(hScreenBuf, attr);
WriteConsole(hScreenBuf, @(buf[0]), length(buf), written, nil);
end;
end;
var
inp : String;
begin
ConsoleOpen("Hello world");
inp := ConsoleWaitForInput(0, 0, 5, FC_RED, ["a".."z", "A".."Z"]);
ConsoleWrite(0, 1, [inp], [FC_WHITE]);
ConsoleWaitForInput(length(inp), 1, 0, 0, [ #13]);
ConsoleClose();
end.
Вот. Давненько писал, но вроде не очень убогий код :)
← →
Mr tray (2006-07-01 00:05) [4]Zeqfreed © (30.06.06 22:13) [3]
в код вникать не буду, но думаю, что к моей проблеме относятся тут только четверка-пятёрка строчек. всё равно спасибо. я уже сам справился, спасибо.
Страницы: 1 вся ветка
Текущий архив: 2006.07.16;
Скачать: CL | DM;
Память: 0.46 MB
Время: 0.008 c