![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#31
|
|||
|
|||
|
Да в том то и дело что мне не надо тащить в dll переменные из exe , пусть они там и остаются, там и считаются!
Мне в dll надо вызвать функцию из exe. в процедурах описанных в самом exe я могу указать какие угодно параметры а в dll я не хочу их тащить.... |
|
#32
|
||||
|
||||
|
Цитата:
Цитата:
|
|
#33
|
||||
|
||||
|
Вот пример вызова через указатель (на основе твоего примера). Здесь я вызываю процедуру с параметром, но можно и без параметров.
|
|
#34
|
|||
|
|||
|
Я наверно уже надоел, надеюсь задаю последний вопрос как правильно передать указатель в параметрах запущенной ловушки в dll вот код:
Код:
procedure RunStopHook(State : Boolean;nx:pointer) export; stdcall;
begin
if State=true then
begin
SysHook := SetWindowsHookEx(WH_GETMESSAGE,
@SysMsgProc, HInstance, 0);
// здесь nx содержит правильный адрес функции используемой в exe
end
else//
begin
UnhookWindowsHookEx(SysHook);
SysHook := 0;
end;
end;
exports RunStopHook;
function SysMsgProc(code : integer; wParam : word;
lParam : longint) : longint; stdcall;
begin
CallNextHookEx(SysHook, Code, wParam, lParam);
if code = HC_ACTION then
begin
Wnd := TMsg(Pointer(lParam)^).hwnd;
if TMsg(Pointer(lParam)^).message =WM_KEYDOWN then
case (TMsg(Pointer(lParam)^).wParam) of
37: begin
if left1=0 then left1:=GetTickCount();
if (GetTickCount()-left1)>=time then begin left(); end
end;
end;
end;
end;
procedure left();
begin
showmessage(' Nx='+inttostr(Integer(nx^)));
end;
Здесь при запуски ловушки клавиатуры при нажатии клавишы "37" дожны вызваться процедура left(); и внутри выдать сообщение (например) с адресом функции. Я пытался в SysMsgProc вставить в качестве четвертого аргумента nx: pointer выдает ошибку... Прошу поправьте мой код. Последний раз редактировалось helgboy, 07.11.2012 в 21:04. |
|
#35
|
||||
|
||||
|
Попробуй обьяви nx как глобальную переменную для Dll, или попробуй сохранять не указатель, а процедуру.
Код:
var proc:procedure();
begin
...........................................
procedure RunStopHook(State : Boolean;nx:pointer) export; stdcall;
begin
if State=true then
begin
SysHook := SetWindowsHookEx(WH_GETMESSAGE,
@SysMsgProc, HInstance, 0);
if nx<>nil then
@proc:=nx;//запоминаем процедуру (в nx адрес процедуры left()?)
end
else//
begin
UnhookWindowsHookEx(SysHook);
SysHook := 0;
end;
end;
.....................................................................
function SysMsgProc(code : integer; wParam : word;
lParam : longint) : longint; stdcall;
begin
CallNextHookEx(SysHook, Code, wParam, lParam);
if code = HC_ACTION then
begin
Wnd := TMsg(Pointer(lParam)^).hwnd;
if TMsg(Pointer(lParam)^).message =WM_KEYDOWN then
case (TMsg(Pointer(lParam)^).wParam) of
37: begin
if left1=0 then left1:=GetTickCount();
if (GetTickCount()-left1)>=time then
begin
proc(); //вызываем процедуру
end
end;
end;
end;
end;
end; |
|
#36
|
|||
|
|||
|
да нет же , не годится в nx хранится адрес процедуры из exe. nx трогать нельзя.
Мне надо строго при нажатии клавиши 37 запустить функцию left и в ней использовать nx |
|
#37
|
||||
|
||||
|
А кто этот указатель трогает
Чтобы его использовать, его нужно куда-то сохранить, так как через параметр процедуры SysMsgProc его передать нельзя, то я его передаю через Код:
var proc:procedure(); Цитата:
Код:
@proc:=nx; Можешь вместо Код:
var proc:procedure(); Код:
var nx1:pointer; Код:
nx1:=nx; |
|
#38
|
|||
|
|||
|
все я въехал, спасибо
почти получилось.В exe при прорисовки формы присвоил указателю nx адрес нужной мне процедуры : Код:
var .............. procedure perebor(); ........ nx:=@perebor; ......... Далее при нажатии клавиши "37" отрабатывает процедура опять в exe Код:
procedure keyctrl(nx1:pointer)
var i:integer;
procedure rezultat();
begin
@rezultat:=nx1; { вот здесь то и выбивает ошибку [Error] main.pas(14): Left side cannot be assigned to}
end;Почему когда я пишу такой код @rezultat:=nx1; выбивает ошибку ? |
|
#39
|
||||
|
||||
|
обьявляй в разделе var resultat
rocedure(); А потом после begin'а (для проседуры keyctrl) - Код:
@rezultat:=nx1; Код:
procedure keyctrl(nx1:pointer)
var i:integer;
rezultat :procedure() ;
begin
@rezultat:=nx1; { вот так не должно выводить ошибку}
end;ЗЫ интересные эффекты со смайликами. ![]() |
|
#40
|
|||
|
|||
|
Ну чтож почти все получилось. Получил правильный адрес в конечной процедуре keyctrl в exe .
Остался небольшой баг если начальная требуемая процедура perebor(); была объявлена так : Код:
type Tvideodriver = class(TForm) procedure leftClick(Sender: TObject); end; procedure perebor();// адрес этой процедуры передается в dll и обратно var ...... implementation procedure keyctrl(nx1:pointer) var i:integer; rezultat :procedure() ; begin @rezultat:=nx1;// адрес процедуры perebor() end; ...... приверно вот так: Код:
type Tvideodriver = class(TForm) procedure leftClick(Sender: TObject); procedure perebor(Sender: TObject);// адрес этой процедуры передается в dll и обратно end; var ...... implementation procedure keyctrl(nx1:pointer) var i:integer; rezultat :procedure() ; begin @rezultat:=nx1;// адрес процедуры perebor() end; ...... Я правильно понял как говорилось где то выше , что это обойти никак нельзя? |
|
#41
|
|||
|
|||
|
а если присвоить perebor к классу , то тип процедуры изменится
с Код:
Type TProc = Procedure(); Код:
Type TProc = Procedure() of object; ----EXE------ Код:
type Tvideodriver = class(TForm) procedure leftClick(Sender: TObject); procedure perebor(Sender: TObject);// адрес этой процедуры передается в dll и обратно end; ...... procedure keyctrl(nx1:TNotifyEvent); external 'MyDLL.DLL'; implementation procedure Tvideodriver.Button1Click(Sender:TObject); begin keyctrl(perebor); //<<== заметь, без @ и без скобок end; procedure keyctrl(nx1:TNotifyEvent); var rezultat :TNotifyEvent; begin rezultat := nx1; //<<== заметь, без @ и без скобок ... end; |
|
#42
|
|||
|
|||
|
icWasya , спасибо за пример но все не так, вы наверно не читали предыдущие сообщения и многое путаете.
Уточняю должно быть так и только так : -В exe берется поинтер на процедуру perebor() - отправляется в ловушку в dll - в dll при срабатывании процедуры left() открывается процедура keyctrl уже в exe - далее keyctrl запускает изначальную нужную perebor() присваивая адрес на нее. Но тут то и облом... вот тоже самое в коде ----- EXE---- Код:
type Tmain = class(TForm) procedure perebor(Sender: TObject);// адрес этой процедуры передается в dll и обратно end; procedure RunStopHook(State : Boolean;pointperebor:pointer) stdcall; external 'hookkey.dll'; var pointperebor: pointer; ...... implementation procedure keyctrl(x:pointer) var i:integer; rezultat :procedure() ; begin @rezultat:=x;// адрес процедуры perebor() rezultat();// вызов процедуры perebor end; ..... pointperebor:=@Tmain.perebor; ..... begin RunHook(true,pointperebor)// передаем в dll адрес на процедуру perebor end; ...... ------DLL------ Код:
procedure RunStopHook(State : Boolean;pointperebor:pointer) export; stdcall;
begin
if State=true then
begin
// Запускаем ловушку.
SysHook := SetWindowsHookEx(WH_GETMESSAGE,
@SysMsgProc, HInstance, 0);
x:=pointperebor;
left();
end
end;
procedure left(x:pointer);
begin
keyctrl(x);
end;@rezultat:=x;// адрес процедуры perebor() rezultat();// вызов процедуры perebor если perebor присвоен к классу формы. Ошибка "access violation at address" - я так полагаю он пытается запустить процедуру которой уже нет, обойти это никак нельзя? (Приэтом у меня подключен модуль fastsharemem) Последний раз редактировалось helgboy, 08.11.2012 в 17:41. |
|
#43
|
||||
|
||||
|
Во-первых, как ты запускаешь
Цитата:
Во-вторых, если указатель на метод обьекта, то нужно делать как пишет icWasya - типа так: Код:
type Tmain = class(TForm) procedure perebor(Sender: TObject);// адрес этой процедуры передается в dll и обратно end; procedure RunStopHook(State : Boolean;pointperebor:pointer) stdcall; external 'hookkey.dll'; var pointperebor: pointer; pointproc:procedure() of object; ...... implementation procedure keyctrl(x:pointer) var i:integer; rezultat :procedure() of object; begin @rezultat:=x;// адрес процедуры perebor() rezultat();// вызов процедуры perebor end; ..... pointproc:=Tmain.perebor; pointperebor:=@pointproc; ..... begin RunHook(true,pointperebor)// передаем в dll адрес на процедуру perebor end; ...... иначе не получается.Код:
procedure RunStopHook(State : Boolean;pointperebor:pointer) export; stdcall;
begin
if State=true then
begin
// Запускаем ловушку.
SysHook := SetWindowsHookEx(WH_GETMESSAGE,
@SysMsgProc, HInstance, 0);
x:=pointperebor;
left({здесь должен быть какой-то указатель, напр. "Х"});
end
end;
procedure left(x:pointer);
begin
keyctrl(x);
end; |
|
#44
|
|||
|
|||
|
pointproc:=Tmain.perebor; - здесь возникает ошибка
[Error] mainprogram.pas(633): Incompatible types: 'Parameter lists differ' |
|
#45
|
||||
|
||||
|
Цитата:
Код:
var pointperebor: pointer; pointproc:procedure(Sender:TObject) of object;//вот здесь ЗЫ Хотя зачем в perebor этот Sender:TObject не понимаю. ![]() |