|
|
Регистрация | << Правила форума >> | 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 resultatrocedure();
А потом после 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 не понимаю. |