Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.21;
Скачать: [xml.tar.bz2];




Вниз

Как передать указатель на структуру из DLL 


Alexey Frolov   (2002-03-06 11:51) [0]

Я пишу глобальный HOOK на мышь. В главной программе надо отслеживать все ее перемешения.
Проблема в следующем: когда мышь находится над "cвоей" формой-все работает. Когда мышь выходит за пределы формы начинабтся проблемы.
Я попробовал 3 варианта передачи указателя на структуру tagMOUSEHOOKSTRUCT в сообщении.
1. tagMOUSEHOOKSTRUCT размещается вместе с глобальной информацией
В таком варианте комп отвисает

Type
PShareInf = ^TShareInf;
PMouseStruct = ^tagMOUSEHOOKSTRUCT;
TShareInf = Record
AppWndHandle: HWND;
KeyboardHookHandle: HHOOK;
MouseHookHandle: HHOOK;
hm:THandle;
KeyboardMsgId:integer;
MouseMsgId:integer;
pStruct:PMouseStruct;
cData:tagMOUSEHOOKSTRUCT;
End;

Function MouseHook(Code: Integer; ParamW: WPARAM; ParamL: LPARAM): LRESULT;stdcall;
Begin
If Code IN [HC_ACTION, HC_NOREMOVE] Then
Begin
/////////////////////////////////////////////////////////////////
ShareInf^.pStruct:=Pointer(ParamL);
ShareInf^.cData.pt.X:=ShareInf^.pStruct^.pt.X;
ShareInf^.cData.pt.Y:=ShareInf^.pStruct^.pt.Y;
/////////////////////////////////////////////////////////////////
SendMessage(ShareInf^.AppWndHandle,ShareInf^.MouseMsgId,integer(@ShareInf^.cData), Code);
End;
Result := CallNextHookEx(ShareInf^.KeyboardHookHandle, Code, ParamW, ParamL)
End;

2. Во 2 и 3 вариантах выдаются ошибки "Access violation"

Type
PShareInf = ^TShareInf;
PMouseStruct = ^tagMOUSEHOOKSTRUCT;
TShareInf = Record
AppWndHandle: HWND;
KeyboardHookHandle: HHOOK;
MouseHookHandle: HHOOK;
hm:THandle;
KeyboardMsgId:integer;
MouseMsgId:integer;
End;

Function MouseHook(Code: Integer; ParamW: WPARAM; ParamL: LPARAM): LRESULT;stdcall;
var
pStruct:PMouseStruct;
cData:tagMOUSEHOOKSTRUCT;
Begin
If Code IN [HC_ACTION, HC_NOREMOVE] Then
Begin
pStruct:=Pointer(ParamL);
cData.pt.X:=pStruct^.pt.X;
cData.pt.Y:=pStruct^.pt.Y;
SendMessage(ShareInf^.AppWndHandle, ShareInf^.MouseMsgId, integer(@cData), Code);
End;
Result := CallNextHookEx(ShareInf^.KeyboardHookHandle, Code, ParamW, ParamL)
End;

3.
Type
PShareInf = ^TShareInf;
PMouseStruct = ^tagMOUSEHOOKSTRUCT;
TShareInf = Record
AppWndHandle: HWND;
KeyboardHookHandle: HHOOK;
MouseHookHandle: HHOOK;
hm:THandle;
KeyboardMsgId:integer;
MouseMsgId:integer;
End;

Function MouseHook(Code: Integer; ParamW: WPARAM; ParamL: LPARAM): LRESULT;stdcall;
var
pStruct:PMouseStruct;
cData:tagMOUSEHOOKSTRUCT;
Begin
If Code IN [HC_ACTION, HC_NOREMOVE] Then
Begin
SendMessage(ShareInf^.AppWndHandle, ShareInf^.MouseMsgId, ParamL, Code);
End;
Result := CallNextHookEx(ShareInf^.KeyboardHookHandle, Code, ParamW, ParamL)
End;


Обработчик сообщения во всех случаях одинаков:
Procedure TMainForm.WM_MouseMessage(var Message: TMessage);
var
cData:tagMOUSEHOOKSTRUCT;
pStruct:PMouseStruct;
Begin
pStruct:=Pointer(Message.WParam);
cData.pt.X:=pStruct^.pt.X;
cData.pt.Y:=pStruct^.pt.Y;
Memo2.Lines.Clear();
Memo2.Lines.Add("Mouse Event");
Memo2.Lines.Add("X:="+IntToStr(cData.pt.X)+" Y:="+IntToStr(cData.pt.y));
End;



Виктор Щербаков   (2002-03-06 12:05) [1]

Я конечно весь постинг не прочитал (влом).
Но сразу замечание: указатели имеет смысл передавать, если передатчик (hook dll) и приемник (твоя программа) находятся в одном адресном пространстве. В случае глобального хука - это не верно (вернее верно только для 1-го процесса).

Вывод: передавать структуру целиком, например через FileMapping.



Alexey Frolov   (2002-03-06 12:15) [2]

Так и делалось в первом варианте.
ShareInf размещается через FileMapping:

Procedure DLLEntryPoint(dwReason: DWORD); stdcall;
Begin
Case dwReason Of
DLL_PROCESS_ATTACH:
Begin
MapHandle:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TShareInf), GlobMapID);
ShareInf:=MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TShareInf));
End;
DLL_PROCESS_DETACH:
Begin
UnMapViewOfFile(ShareInf);
CloseHandle(MapHandle);
End
End;
End;



Виктор Щербаков   (2002-03-06 12:21) [3]


> Так и делалось в первом варианте.
> ShareInf размещается через FileMapping:


> Обработчик сообщения во всех случаях одинаков:

Вот в этом и проблема. Обработчик сообщения так же должен был работать с FileMapping.



Alexey Frolov   (2002-03-06 12:46) [4]

А как это сделать?



Fellomena   (2002-03-06 13:25) [5]

Делается это в твоём приложении точно так же как ты это в dll делал, главное и в dll и в главной проге использовать одно и то же имя для файлового отображения.
См. SDK по теме - всё просто.



Dimedrol   (2002-03-06 13:33) [6]

Я в своем большом проекте делаю так :

Беру указатель на мою структуру и

MF.PubIntMsg(M_REFRESHBONE,integer(MF.GetActiveBone));

Посылаю зарегистрированный MESSAGE с конвертнутым указателем,
потом принимаю его и вперед ! ;-)

Если заинтересовало, - спишемся по мылу, расскажу поподробнее...
могу код кинуть....



Alexey Frolov   (2002-03-06 13:45) [7]

Подсказка с FileMapping сработала. Большое всем спасибо. Тему можно считать закрытой.





Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.21;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.74 MB
Время: 0.017 c
7-67024           Rosco                 2001-12-14 12:07  2002.03.21  
Как запустить свою программу как сервис


1-66857           PlaZZma               2002-03-05 12:22  2002.03.21  
Как ловить жмаканья клавиш?


3-66799           perov                 2002-02-20 10:33  2002.03.21  
связывание таблиц


1-66844           Techno                2002-03-05 11:27  2002.03.21  
Настройка принтера


14-66980          Yuri Btr              2002-02-07 10:39  2002.03.21  
Знатоки Clipperа!!!