Программное нажатие клавиш из лог файла
Пользователи, просматривающие топик: none
|
Зашли как: Guest
|
Имя |
Сообщение |
<< Старые топики Новые топики >> |
|
|
Программное нажатие клавиш из лог файла - 2008-02-09 17:11:20.573333
|
|
|
Dr.KoD
Сообщений: 59
Оценки: 0
Присоединился: 2007-09-29 16:45:59.820000
|
Программа должна записывать в файл или в мемо или в листбокс нажатые клавиши, вообще нужно чтобы отлавливалось только нажатие стрелок вверх, влево, вправо остальные клавиши ненужны ненужны, это все выполняется по нажатию на баттон1, затем нужно чтобы прога считывала записанные клавиши и нажимала в той последовательости, в которой они и вводились. Вот собсно код, который записывает нажатые клавиши в листбокс и в мемо, есть еще несколько вариантов записи в лог файл, но мне кажется, что лучше как то модифицировать этот:unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AppEvnts;
type
TForm1 = class(TForm)
Memo1: TMemo;
ListBox1: TListBox;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure OnAppMessage(var Msg: TMsg; var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
HookHandle : THandle = INVALID_HANDLE_VALUE;
function HookProc(nCode: integer; WParam: Word; LParam: LongInt): Longint; stdcall;
var
EventMsg : PEventMsg;
VirtCode : byte;
ScanCode : dword;
KeyState : TKeyboardState;
Tmp, S : string;
Res : integer;
begin
s := '';
if nCode = HC_ACTION then begin
EventMsg := pointer(LParam);
case EventMsg^.message of
WM_KEYDOWN : begin
VirtCode := EventMsg^.paramL and $FF;
ScanCode := (EventMsg^.paramL and $FF00) shl 8;
SetLength(Tmp, 32);
Res := GetKeyNameText(ScanCode,
@Tmp[1], Length(Tmp));
S := copy(Tmp, 1, Res);
end;
else
end;
Form1.Memo1.Lines.Add(s);
Form1.ListBox1.Items.Add(s);
end;
Result := CallNextHookEx(HookHandle, nCode, wParam, LParam);
end;
function InstallHook : boolean;
begin
if HookHandle = INVALID_HANDLE_VALUE then
HookHandle := SetWindowsHookEx(WH_JOURNALRECORD, @HookProc, hInstance, 0);
Result := HookHandle <> INVALID_HANDLE_VALUE;
end;
function RemoveHook : boolean;
begin
if HookHandle <> INVALID_HANDLE_VALUE then
UnhookWindowsHookEx(HookHandle);
HookHandle := INVALID_HANDLE_VALUE;
Result := true;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
RemoveHook;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := OnAppMessage;
InstallHook;
end;
procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.message = WM_CANCELJOURNAL) and (HookHandle <> INVALID_HANDLE_VALUE) then begin
HookHandle := INVALID_HANDLE_VALUE;
InstallHook;
Handled := true;
end;
end;
end. при том алгоритм нажатия клавиш есть тоже вот он: unit sndkey;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
const
{VK constants missing from windows.pas}
VK_SEMICOLON = 186; {;}
VK_EQUAL = 187; {=}
VK_COMMA = 188; {,}
VK_MINUS = 189; {-}
VK_PERIOD = 190; {.}
VK_SLASH = 191; {/}
VK_BACKQUOTE = 192; {`}
VK_LEFTBRACKET = 219; {[}
VK_BACKSLASH = 220; {\}
VK_RIGHTBRACKET = 221; {]}
VK_QUOTE = 222; {'}
downkey = #0;
upkey = Chr(KEYEVENTF_KEYUP); {#2}
procedure PlayKeys(const keys: String);
function StrToKeys(const s: String): String;
{Alt-F4:
PlayKeys(Chr(vk_menu)+#0+Chr(vk_f4)+#0+Chr(vk_f4)+#2+Chr(vk_menu)+#2)}
{"exit"<return>: PlayKeys(StrToKeys('exit'+chr(vk_return)));}
{"EXIT":
PlayKeys(Chr(vk_shift)+downkey+StrToKeys('exit')+Chr(vk_shift)+upkey));}
{or short form: PlayKeys(Chr(vk_shift)+#0+StrToKeys('exit'));}
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Edit2: TEdit;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
function StrToKeys; {keystroke for alone keys}
var
i: Longint;
c: Char;
begin
for i := 1 to Length(s) do
begin
c := s[i];
if c in ['a'..'z'] then {Upper}
c := Chr(Ord(c) and not $20);
Result := Result + c + downkey
+ c + upkey;
end;
end;
procedure PlayKeys;
const
ExtendedKeys : set of byte =
[ vk_up, vk_down,
vk_left, vk_right,
vk_home, vk_end,
vk_prior, vk_next,
vk_insert, vk_delete];
var
i, ips : Longint;
fb, sb: Byte;
keysdown: String;
procedure keybd (vk, kp : Byte);
begin
if vk in ExtendedKeys then
kp := kp + KEYEVENTF_EXTENDEDKEY;
keybd_event(vk, MapVirtualKey(vk, 0), kp, 0);
end;
begin
keysdown := '';
for i := 1 to Length(keys) div 2 do
begin
fb:= Ord(keys[2*i -1]);
sb:= Ord(keys[2*i]);
if sb = Ord(downkey) then
keysdown := keysdown + Chr(fb)
else
begin
ips := pos(Chr(fb), keysdown);
if ips > 0 then
Delete(keysdown, ips, 1)
else
Continue;
end;
keybd(fb, sb);
end;
{Autocomplete}
for i := 1 to Length(keysdown) do
keybd(Ord(keysdown[i]), Ord(upkey));
end;
procedure SimulateKeystroke(Key: byte; extra: DWORD);
begin
keybd_event(Key, extra, 0, 0);
keybd_event(Key, extra, KEYEVENTF_KEYUP, 0);
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
h: HWND;
begin
h := FindWindow('Окно проги', nil); // ищем окно проги
SendMessage(h, WM_SYSCOMMAND, SC_HOTKEY, h); // активизируем его
PlayKeys(StrToKeys(Edit1.Text )); // нажимаем клавиши
SendMessage(Handle, WM_SYSCOMMAND, SC_HOTKEY, Handle); // возвращаем фокус
end;
end.
А вот как все это чудо заставить работать в одной проге, чет понять немогу. Помогите пожалуйста разобраться.
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-09 18:21:53.346666
|
|
|
Genco
Сообщений: 1662
Оценки: 90
Присоединился: 2007-12-16 23:11:22.003333
|
Эмм…ниасилил вчитываться подробно,но в чем проблема? Вроде как рабочие коды,нужны токо стрелки-так забей на отслеживание остальных клавиш(убрать типо).Пихануть в одну прогу и убрать лишнее? Или типо там где-то косяк в тексте,который ты ищешь?
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-09 19:55:14.810000
|
|
|
Dr.KoD
Сообщений: 59
Оценки: 0
Присоединился: 2007-09-29 16:45:59.820000
|
Да если их объединить работать они будут, но вот как правильно это все безобразие организовать?, вся проблема в том что первый код отлавливает все клавиши, а как зделать фильтр на те клавиши, которые мне нужны незнаю, может вообще др. код использовать лучше и еще первый код выводит название клавиш, т.е. Num 8,4,6, а если так то 2-ой код уже не нажмет стрелку вверх, влево и вправо, наверно нужно зделать чтобы оба кода работали с виртуалными кодами клавиш в hex кодировке, но я чет не разобрался как это можно написать.
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-09 21:13:12.060000
|
|
|
Genco
Сообщений: 1662
Оценки: 90
Присоединился: 2007-12-16 23:11:22.003333
|
А! Ну так: 1)почитай что делают используемые в коде функции.2)Там,в общем, в HookProc(самописная которая) переменная WParam и (+29-й кажется байт Lparam)-код клавиши.Если стрелка-обрабатывай,если нет-передавай дальше.Токо там по-моему nCode надо с чем-то ещё сравнивать в if(<0 чтоль).Сохраняй тоже код клавиши,hex вроде не обязательно.
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-10 13:25:31.213333
|
|
|
Dr.KoD
Сообщений: 59
Оценки: 0
Присоединился: 2007-09-29 16:45:59.820000
|
Так вроде коды клавиш и идут в hex кодировке? if HiWord(GetKeyState(VK_UP)) <> 0 then
//
else
// это что то в этом роде, это я про отлов только нужных клавиш. Ребят неужели никто конкретней не подскажет?, а то уже пипец мозг кипит, все как раз упирается в эти 3 клавиши в какой кодировке записать их, и в какой кодировке считать эти клавиши?
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-10 19:46:58.670000
|
|
|
Genco
Сообщений: 1662
Оценки: 90
Присоединился: 2007-12-16 23:11:22.003333
|
Мля…для "стрелок" там прям константы же есть. VK_UP/VK_DOWN/VK_LEFT/VK_RIGHT. Ну так в HookProc пишешь: if WParam=VK_UP then…(это сам,что уж тебе там надо).Лишний тест выкинь,естессно. Если я таки наврал,Wparam приводишь в другую кодировку и смотришь-пашет или нет.
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-16 16:20:48.503333
|
|
|
Dr.KoD
Сообщений: 59
Оценки: 0
Присоединился: 2007-09-29 16:45:59.820000
|
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TfrmMain = class(TForm)
Memo1: TMemo;
tmKeyStateCheckTimer: TTimer;
Timer1: TTimer;
Timer2: TTimer;
procedure tmKeyStateCheckTimerTimer(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
private
{ Private declarations }
public
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.tmKeyStateCheckTimerTimer(Sender: TObject);
var
i, res : integer;
S : string;
begin
S := '';
for i := 0 to 255 do begin
Res := GetAsyncKeyState(i);
if Res <> 0 then
if i = VK_UP then
if MapVirtualKey(i, 2) > 0 then
S := S + char(MapVirtualKey(i, 2))
else
S := S+inttostr(i);
end;
if length(s) > 0 then
Memo1.Lines.Add('$'+S);
end;
procedure TfrmMain.Timer1Timer(Sender: TObject);
var
i, res : integer;
S : string;
begin
S := '';
for i := 0 to 255 do begin
Res := GetAsyncKeyState(i);
if Res <> 0 then
if i = VK_RIGHT then
if MapVirtualKey(i, 2) > 0 then
S := S + char(MapVirtualKey(i, 2))
else
S := S+inttostr(i);
end;
if length(s) > 0 then
Memo1.Lines.Add('$'+S);
end;
procedure TfrmMain.Timer2Timer(Sender: TObject);
var
i, res : integer;
S : string;
begin
S := '';
for i := 0 to 255 do begin
Res := GetAsyncKeyState(i);
if Res <> 0 then
if i = VK_LEFT then
if MapVirtualKey(i, 2) > 0 then
S := S + char(MapVirtualKey(i, 2))
else
S := S+inttostr(i);
end;
if length(s) > 0 then
Memo1.Lines.Add('$'+S);
end;
end. Вот наконец нашел, то что искал(этот код отлавливает нажатие 3 нужных мне клавиш и записывает их в мемо), но вот проблема осталась, как теперь заставить второй код(см. 1 пост) заставить нажимать клавиши по вирутальным кодам записанным в мемо? Народ ну помогите ктонить:)
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-16 17:43:08.753333
|
|
|
Ясkи
Сообщений: 204
Оценки: 0
Присоединился: 2008-02-12 22:56:17.683333
|
У тебя же есть код, чем помочь то?
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-16 17:56:02.346666
|
|
|
Dr.KoD
Сообщений: 59
Оценки: 0
Присоединился: 2007-09-29 16:45:59.820000
|
Сначало прочти о чем я пишу, а потом отвечай, 2 код(1 пост) нажимает только по символам(а, б, в, a, b, d, и.т.), а мне нужно чтобы он нажимал клавиши по виртуальным кодам!!
|
|
|
RE: Программное нажатие клавиш из лог файла - 2008-02-16 21:25:03.360000
|
|
|
Dr.KoD
Сообщений: 59
Оценки: 0
Присоединился: 2007-09-29 16:45:59.820000
|
Вот кое, что придумал: беру вместо мемо использую листбокс, как мне проверить каждую строку и если в строке стоит допустим $38 то нужно нажать клавишу вверх, с помощью этой процедуры:
procedure SimulateKeystroke(Key: byte; extra: DWORD);
begin
keybd_event(Key, extra, 0, 0);
keybd_event(Key, extra, KEYEVENTF_KEYUP, 0);
end;
//-------------------------------------------------------------------
procedure TfrmMain.Timer3Timer(Sender: TObject);
[b]var
s: string;
begin
s:= ListBox1.Items.Text;
if s='$38' then[/b]
SimulateKeystroke($39,0);
end;
end.
Это я примерно накатал, как правильно написать условие в выделеном коде, что если оно соответствует нужному значению, нажимать клавишу если нет переходить ко второму условию, если и оно не верно то переходим к 3 помогите пожалуйста?
|
|
|
|
|