Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как передать указатель на структуру из DLL [D6, Win2k]


Alexey Frolov ©   (2002-03-06 11:51:00) 

Я пишу глобальный 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;


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

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



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

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

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

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

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

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


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

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


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

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


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


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


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

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


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

Так и делалось в первом варианте.
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:05:00) [7]

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

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо