![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Передача и вызов процедуры/функции. [D7, Win2k, WinXP]
Nick Denry © (2005-09-21 17:05:00)Есть такая проблема: моей программе передают указатель на процедуру или функцию (из другой программы) и как эту самую функцию, по этому указателю вызвать (своего рода callback).
т.е. надо что-то типа call из asm или можно как-то по-другому?
Игорь Шевченко (2005-09-22 10:42:00) [1]
> ответь все-таки пожалуйста почему?
потому что препод дал задание тебе, а не мне
Германн (2005-09-22 02:38:00) [2]2 GanibalLector © (22.09.05 02:26) [23]
Там было- море, солнце, песок И т.д. и т.п. :)
И, блин, ответы на многие вопросы, которые тут, имхо, слишкомчастые!
Если ты их "прозевал", то увы!
GanibalLector (2005-09-22 02:26:00) [3]2 Германн © (22.09.05 02:07) [22]
>Хорошо, что я успел скачать с сайта ИШ что хотел!
Пардон,конечно...но,что ж там было???
Германн (2005-09-22 02:07:00) [4]Оп-ля!
Хотел было посоветовать автору сабжа обратиться к ИШ приватно, т.е. по email или через его сайт.
Но обнаружил, что из анкеты Игоря - напрочь пропали все ссылки!
Это что? Новая мода? Борьба с вирусописателями?
Хорошо, что я успел скачать с сайта ИШ что хотел!
Nick Denry (2005-09-22 01:14:00) [5]Игорь Шевченко © (22.09.05 00:29) [19]
А препод действительно дал мне, как он сам выразился "задание повышенной сложности".
И описал задачу, которая свелась именно такому решению, и никакого другого, он кстати, не принял.
Я хотел вместо вызова процедуры по типу callback сделать отправку сообщения родительского окну (по типу WM_COMMAND), а он сказал, чтобы был обязательно callback.
Даже если отвечаешь мне последний раз, ответь все-таки пожалуйста почему?
Nick Denry (2005-09-22 01:07:00) [6]Игорь Шевченко © (22.09.05 00:29) [19]
Почему? :(
Из-за того, что это курсовая работа или я чем-то обидел?
И кстати,
@AMyProc := GetProp(HControl, PROP_ATOM);
выдает [Error] Incompatible types: 'Cardinal' and 'Pointer'
на самом деле надо было:
@AMyProc := Ptr(GetProp(HControl, PROP_ATOM));
Eraser © (21.09.05 23:57) [18]
Автор ошибся и указал об этом в [4]
Игорь Шевченко (2005-09-22 00:29:00) [7]
> Дык, это не я, это у препода крыша протекла. Вынь да вылож
> ему (
Я тебе отвечал последний раз.
LMD
Eraser (2005-09-21 23:57:00) [8]
> Игорь Шевченко © (21.09.05 23:23) [15]
> В рамках одного процесса, без разницы, в EXE или в DLL.
Дык автор то просил (из другой программы)...
Nick Denry (2005-09-21 23:42:00) [9]Игорь Шевченко © (21.09.05 23:23) [15]
Спасибо за понятный код :)
Век бы ковырялся с пойнтерами :)
Nick Denry (2005-09-21 23:40:00) [10]Игорь Шевченко © (21.09.05 23:23) [15]
Кулибин.
Дык, это не я, это у препода крыша протекла. Вынь да вылож ему (
Игорь Шевченко (2005-09-21 23:23:00) [11]Nick Denry © (21.09.05 23:18) [14]
Кулибин.
type
TMyProc = procedure (arg: Pojnter);
procedure MyProc (arg: Pointer);
begin
все, что надо
end;
procedure AssociateMyProcWithControl (HControl: HWND);
begin
SetProp(HControl, PROP_ATOM, Handle(@MyProc));
end;
procedure InvokeAssociatedProc (HControl: HWND; Arg: Pointer);
var
AMyProc: TMyProc;
begin
@AMyProc := GetProp(HControl, PROP_ATOM);
if Assigned(AMyProc) then
AMyProc(Arg);
end;
В рамках одного процесса, без разницы, в EXE или в DLL.
Nick Denry (2005-09-21 23:18:00) [12]Eraser © (21.09.05 23:12) [13]
К сожалению у меня задача изобрести велосипед :(
Eraser (2005-09-21 23:12:00) [13]
> Nick Denry ©
Может для твой задачи проще использовать серверы автоматизации COM или NET Remoting или вообще ? Зачем же велосипед изобретать?
Nick Denry (2005-09-21 23:08:00) [14]Zeqfreed © (21.09.05 22:57) [11]
Ну вот, теперь кажется и мне понятно :))
Но не факт, буду пробовать..
Zeqfreed (2005-09-21 22:57:00) [15]А, да. Я так понял тебя интересует именно хранение указателя. Тогда так:
dll:
var
Callback : Pointer;
procedure RegisterCallback(Proc : TCallback);
begin
Callback := @Proc;
end;
procedure UseCallback();
begin
TCallback(Callback );
end;
Nick Denry (2005-09-21 22:54:00) [16]Надеюсь разберешься.
спасибо, постараюсь.
Zeqfreed (2005-09-21 22:50:00) [17]Nick Denry © (21.09.05 22:32) [8]
Файл callback_type.inc:
type
TCallback = procedure();
Файл some.dpr:
library some;
uses
Windows;
{$I callback_type.inc}
var
Callback : TCallback;
procedure RegisterCallback(Proc : TCallback);
begin
Callback := Proc;
end;
procedure UseCallback();
begin
Callback();
end;
exports
RegisterCallback, UseCallback;
begin
end.
Файл prog.dpr:
program prog;
uses
Windows;
{$I callback_type.inc}
procedure RegisterCallback(Proc : TCallback); external 'some.dll' name 'RegisterCallback';
procedure UseCallback(); external 'some.dll' name 'UseCallback';
procedure SomeProc();
begin
MessageBox(0, 'Does it work?', 'Prog', 0);
end;
begin
RegisterCallback(SomeProc);
UseCallback();
end.
Надеюсь разберешься.
Nick Denry (2005-09-21 22:32:00) [18]Zeqfreed © (21.09.05 22:13) [7]
А обратно?
Pointer(DWORD)?
Если список параметров ф-ции не меняется во время выполнения программы, то не понимаю почему решение не подходит.
Наверное я не понял вашего описания. Или неполучится сделать уникальный вызов для каждого контрола.
Если можно, объясните еще раз на пальцах :))
Я тоже пропробую:
Пусть в exe есть процедура:
procedure ProcedureInExe;
begin
ShowMessage('Test');
end;
И соответственно событие, происходящее в DLL в оконной процедуре контрола:
WM_ANYMESSAGE:
begin
end;
Мне надо, что бы для каждого экземпляра контрола (т.е. окна) была установлена индивидуальная ф-ция обработки, -> как я думаю, ее адрес (указатель на нее) можно было бы разместить как Property окна, при поммощи функции SetProp - и извлеч его как GetProp, но
обе ити функци используют DWORD параметры, например:
BOOL SetProp(
HWND hWnd, // handle of window
LPCTSTR lpString, // atom or address of string
HANDLE hData // handle of data
);
Т.е. если, в экзе я могу вызвать код, чтобы поместить туда указатель на процедуру ProcedureInExe;:
Setprop(ControlWnd, PChar('ProcedureInExe'+IntToStr(ControlID))), DWORD(@ProcedureInExe));
то что мне дальше нужно сделать со зхначением, DWORD(@ProcedureInExe), которое я извлеку с помощью функции GetProp?
Т.е. по-идее я должен в Dll
при обработки сообщения WM_ANYMESSAGE сделать следующие деййствия:
...
var
ProcInexePointer : DWORD; // (?POINTER)
WM_ANYMESSAGE:
begin
ProcInexePointer := GetProp(ctrlWnd, PChar('ProcedureInExe'+IntToStr(ControlID))));
а дальше чо-то типа
asm
call ProcInexePointer;
end;
end;
только этот метод почему-то не работает, и как мне в таком случае из DWORD(Pointer) всеже получить обратно Pointer?
или такое можон осуществить еще как-то?
Zeqfreed (2005-09-21 22:13:00) [19]Nick Denry © (21.09.05 21:51) [6]
Если список параметров ф-ции не меняется во время выполнения программы, то не понимаю почему решение не подходит.
> Нверное лучше еще задать подвопрос: как из указателя
> получить DWORD и обратно?
DWORD(SomePointer)?
Nick Denry (2005-09-21 21:51:00) [20]Zeqfreed © (21.09.05 20:23) [5]
Мне не подходит такое решение.
Мне необходимо вызвать поцедуру (даже не функцию),имея на руках только указатель.
Упростим задачу до минимума:
Есть два файла - Exe и Dll.
Как я уже сказал, Dll представляет собой библиотеку с моим контролом.
У каждого экземпляра контрола есть свойиство (Prop), в который мне надо поместить указать на процедуру, содержащуюся в экзешнике, и при наступлении определнного события в контроле из библиотеки вызвать процедуру экзешника.
Нверное лучше еще задать подвопрос: как из указателя получить DWORD и обратно?