![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Надо в CallBack API функции передать метод TObject [D7, WinXP]
Still Swamp © (2005-09-14 14:27:00)Надо в CallBack API функции передать метод TObject. Как это сделать. Метод описан в соответствии с требованиями CallBack.
Теперь надо по идее передать указатель на эту процедуру. Как это сделать?
ANB (2005-09-15 10:12:00) [21]Кстати, я как то умудрился запихать метод в качестве CallBack (уже не помню как), но потерял в ней доступ к своему объекту.
Бурундук (2005-09-14 17:15:00) [22]Не так давно наткнулся на такую конструкцию.
(Насколько я разобрался, работает для stdcall-колбэка с
произвольными аргументами).
type
TCallbackThunk = packed record
POPEDX: Byte;
MOVEAX: Byte;
SelfPtr: Pointer;
PUSHEAX: Byte;
PUSHEDX: Byte;
JMP: Byte;
JmpOffset: Integer;
end;
procedure InitCallbackThunk(var Callback: TCallbackThunk; Method: TMethod);
begin
Callback.POPEDX := $5A;
Callback.MOVEAX := $B8;
Callback.SelfPtr := Method.Data;
Callback.PUSHEAX := $50;
Callback.PUSHEDX := $52;
Callback.JMP := $E9;
Callback.JmpOffset := Integer(Method.Code) - Integer(@Callback.JMP) - 5;
end;
var
thunk: TCallBackThunk;
// Время жизни этой структуры должно совпасть с
// временем жизни колбэк-функции. Ведь она и есть тело функции.
// Можно сделать полем объекта, чей метод используется
// в качестве колбэка.
// Для большей надёжности её надо бы было разместить в памяти,
// выделенной с PAGE_EXECUTE_XXX, но что-то я не припомню систем,
// на которых это ограничение реально бы действовало.
procedure TForm1.Button1Click(Sender: TObject);
var m: function(a, b: Integer): Integer of object; stdcall;
begin
m := SomeMethod;
InitCallbackThunk(thunk, TMethod(m));
CallBackTest(@thunk, 8, 9);
end;
Lamer@fools.ua (2005-09-14 17:04:00) [23]>> ANB © (14.09.05 16:53) [22]
Думаю, никто не мешает сделать свой механизм для нужных колбеков по аналогии с MakeObjectInstance().
ANB (2005-09-14 16:53:00) [24]
> Игорь Шевченко © (14.09.05 16:23) [21]
- тогда не поканает :(((
Игорь Шевченко (2005-09-14 16:23:00) [25]ANB © (14.09.05 16:12) [19]
Тут только один момент - эта функция не для любого Callback'а работает. А только для типа TWndMethod
Digitman (2005-09-14 16:23:00) [26]
> Как раз хотел написать компонент для работы с MS SQL через
> DB Lib и застрял на CallBack-ах
вряд ли тебе MakeObjectInstance() подойдет для оной цели - это, мягко говоря, из другой оперы .. это к оконным функциям/сообщениям относится, а не к произвольным колбэкам, коих в Win32 - туча несметная всякоразных ..
ANB (2005-09-14 16:12:00) [27]
> Digitman © (14.09.05 16:05) [18]
- спасибо. Положу в копилку. Как раз хотел написать компонент для работы с MS SQL через DB Lib и застрял на CallBack-ах.
Digitman (2005-09-14 16:05:00) [28]
> Мне бы коротенько
"коротенько" - для "легкого" сопряжения механизма вызова WinAPI-callback-ф-ций c механизмом вызовов соответствующих по логике методов объектов Делфи, предназначенных для обработки Win-сообщений
пусть у тебя имеется некий класс
TMyClass = class(..)
procedure MyHandler(var Message: TMessage);
end;
и ты хочешь , чтобы метод MyHandler некоего объекта MyObject класса TMyClass вызывался всякий раз, когда некоему окну адресовано некое сообщение
с использованием MakeObjectInstance() все это делается оч просто :
SetWindowLong(хэндл_окна_адресата, GWL_WNDPROC, Longint(MakeObjectInstance(MyObject.MyHandler)));
ANB (2005-09-14 15:48:00) [29]
> Digitman © (14.09.05 15:36) [16]
- залез уже. Мне бы коротенько, для чего нужна, а как работает уж разберусь.
Digitman (2005-09-14 15:36:00) [30]
> нет у меня туда доступа
неужели и к тексту classes.pas нет доступа ?!
ANB (2005-09-14 15:32:00) [31]
> Игорь Шевченко © (14.09.05 15:26) [14]
- да нет у меня туда доступа :(((
Игорь Шевченко (2005-09-14 15:26:00) [32]ANB © (14.09.05 15:22) [13]
Самый лучший Help - http://www.google.com
http://community.borland.com/article/0,1410,27295,00.html
ANB (2005-09-14 15:22:00) [33]
> Игорь Шевченко © (14.09.05 15:13) [11]
- а чего она делает ? (Я в хелпере не нашел)
Still Swamp (2005-09-14 15:20:00) [34]
> Передавать в качестве callback ordinal procedure or function
> и уже внутри нее получать ссылку на экземпляр и вызывать
> метод класса.
Ну правильно... :( так как нет параметра приходящего в CallBack - глобальная переменная.
Игорь Шевченко (2005-09-14 15:13:00) [35]Still Swamp (14.09.05 14:39) [2]
MakeObjectInstance не поможет ?
Джо (2005-09-14 15:00:00) [36]
> [8] Still Swamp (14.09.05 14:56)
> не описывать же глобальную переменную
Ну, переменную можно завести в секции implementation.
Reindeer Moss Eater (2005-09-14 14:59:00) [37]Метод класса нужно вызывать имея экземпляр.
А та процедура которой ты передаешь callback ничего же про это не знает.
Надо использовать прокладку.
Передавать в качестве callback ordinal procedure or function и уже внутри нее получать ссылку на экземпляр и вызывать метод класса.
Still Swamp (2005-09-14 14:56:00) [38]не описывать же глобальную переменную
Still Swamp (2005-09-14 14:54:00) [39]а внутри охото с классом работать...
смысл этого забора именно в этом.
Reindeer Moss Eater (2005-09-14 14:46:00) [40]А почему не использовать обычную функцию, а не метод класса?