Как вывести результат из dll (Delphi)

dimon72

Делаю глобальный Хук через dll:

library Hook1;

uses
Windows,
Messages,
SysUtils,
Uhook in 'Uhook.pas';

var
H : THandle;

//ф-ция Hook
function Hook(c0de, wParam, lParam : integer): Lresult; stdcall;
var
w : THandle;
hw, hw2 : hwnd;//дескриптор окна
//
t:TPoint;
buf: array [0..255] of char;
//
begin
if c0de >= 0 then
begin//Если c0de не меньше 0, все в порядке, продолжаем
case wParam of
//Если wParam = WM_RBUTTONUP, т.е. нажата прав.кн. мыши...
WM_RBUTTONUP: begin
//
end;
//Если wParam = WM_LBUTTONUP, т.е. нажата лев.кн. мыши...
WM_LBUTTONUP: begin
GetCursorPos(t);//получить значения экранных координат
GHw:=WindowFromPoint(t);//получить хендл контрола по экранным координатам
GetClassName(GHw,buf,255);//получить название класса контрола по хендлу
hw2:=GetForegroundWindow;//
SetWindowText( hw2,PAnsiChar(FloatToStr(GHw );//вывести хендл контрола в заголовок окна
GetHWnds;//пытаюсь передать во вспомогательную ф-цию найденный хендл, но прога падает!
//
end;
//Если wParam = WM_MBUTTONUP, т.е. нажата средняя кнопка мыши...
WM_MBUTTONUP: begin
//
end;
end;//case
end else
//Если c0de меньше 0
begin
//Вызываем следующую ловушку в цепочке ловушек Windows и выходим из процедуры
result := CallNextHookEx(H, c0de, wParam, lParam);
exit;
end;//if
//Вызываем следующую ловушку в цепочке ловушек Windows
result := CallNextHookEx(H, c0de, wParam, lParam);
End;

//Процедура установки ловушки, если не удалось установить - выводим сообщение об ошибке
procedure Sethook;
begin
H:= SetWindowsHookEx(WH_MOUSE, @Hook, hInstance, 0);
if H = 0 then
MessageBox(0,'Не могу установить Хук!','ERROR',MB_ICONHAND);
end;

//Процедура удаления ловушки
procedure Removehook;
begin
UnhookWindowsHookEx(H);
end;

//Экспорт процедур установки и удаления hook'a
exports
Sethook index 1 name 'sethook',
Removehook index 2 name 'removehook';

end.

Пытаюсь передать найденный Хендл окна через дополнительную функцию, которая описана в дополнительном Unit'е этой же библиотеки:

unit Uhook;

interface

uses Windows, SysUtils;

var
GHw: hwnd;

function GetHWnds: String; stdcall;

exports
GetHWnds name 'GetHWnds';

implementation

//
function GetHWnds: String;
begin
Result:=FloatToStr(GHw);
end;

end.

Вот код вызывающего приложения:

unit UtstHook1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
GHw: HWnd;
GHwStr: String;
procedure sethook; External 'Hook1.dll';
procedure removehook; External 'Hook1.dll';
function GetHWnds: String; external 'Hook1.dll';

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
sethook;
GHwStr:=GetHWnds;
Edit1.Text:=GHwStr;
end;//при трассировке вот здесь падает программа !!

procedure TForm1.Button2Click(Sender: TObject);
begin
removehook;
end;

end.

Когда пытаюсь передать во вспомогательную ф-цию GetHWnds найденный хендл, то прога падает. Что я делаю не так?
Смысл задачи заключается в том, что надо вывести полученный после клика мыши хендл любого окна из dll в вызывающую delphi-программу.

SPARTAK3959

Во-первых FloatToStr нужно заменить на IntToStr.
По статистике 99,99% программистов неправильно ставят глобальные хуки. Нельзя вызывать CallNextHookEx(H,... поскольку переменная H не инициализирована. Строка H:= SetWindowsHookEx(WH_MOUSE, @Hook, hInstance, 0); инициализирует H только в процессе поставившем хук. Но при срабатывании хука, винда подгружает твою dll'ку к чужому процессу и в этой копии твоей dll'ки H не инициализирован! Эта ошибка встерчается настолько часто, что начиная с windows 2000 (могу ошибаться) вместо H можно передавать нуль.
Таким образом, оператор присваивания GHw изменяет эту переменную только в чужом процессе, а в процессе поставившем хук она остается неизменной. Для передачи данных между копиями dll'ки в подобных случаях используют файлы отображаемые в память.

dimon72

Про переменную H понял. Действительно. Даже не думал, что здесь возможен глюк.
А вот с этого места не понятно:
Для передачи данных между копиями dll'ки в подобных случаях используют файлы отображаемые в память.
Мне не между копиями, а из dll в вызывающую программу надо передать переменную.
Так как же мне вывести переменную, содержащую хендл, из dll в вызывающую программу? :crazy:
Можно конкретнее на моём же примере показать как это делать?

dimon72

В общем, я вроде разобрался. Спасибо за задание правильного направления действий. :)
Оставить комментарий
Имя или ник:
Комментарий: