Форум: "Основная";
Текущий архив: 2003.08.04;
Скачать: [xml.tar.bz2];
ВнизКак преобразовать адрес процедуры Найти похожие ветки
← →
Still Swamp (2003-07-21 10:09) [0]Есть процедура MyProc. Как преобразовать адрес процедуры в значение Cardinal?
Что такое MakeObjectInstance? В хелпе нету.
← →
Skier (2003-07-21 10:21) [1]>Still Swamp (21.07.03 10:09)
> Как преобразовать адрес процедуры в значение Cardinal?
IntToStr(...)
> Что такое MakeObjectInstance?
Достаточно просто перевести с английского...
← →
Ihor Osov'yak (2003-07-21 10:25) [2]1. Cardinal(@MyProc)
2. MakeObjectInstance - получает метод обьекта и "регистрирует" его в списке InstFreeList. Это нужно для того, чтобы метод можно было "использовать" в качестве оконной процедуры. Подробности - исходники VCL.
← →
Skier (2003-07-21 10:26) [3]Ё ! IntToStr(...) совершенно не в ту сторону. Sorry.
← →
Still Swamp (2003-07-21 10:30) [4]По поводу перевода - лихой ответ. Допустим СделатьОбъектТребованием много мне даст?
Обязательно ли MakeObhectInstance выполнять, если мне требуется подменить этой процедурой стандартный обработчик сообщений для окна?
← →
Still Swamp (2003-07-21 10:34) [5]Ну эээ в общем да. :)
Cardinal(@MyProc) тоже не идет. Компилятор говорит, что ему охота параметры MyProc получить.
← →
Skier (2003-07-21 10:34) [6]>Still Swamp (21.07.03 10:30)
> Допустим СделатьОбъектТребованием много мне даст?
???
> Обязательно ли MakeObhectInstance выполнять, если мне требуется
> подменить этой процедурой стандартный обработчик сообщений
> для окна?
Причём тут MakeObhectInstance ?
← →
Skier (2003-07-21 10:35) [7]>Still Swamp (21.07.03 10:34)
Cardinal(@TYourClass.YourProc)
← →
Still Swamp (2003-07-21 10:37) [8]Можно более расширенный вопрос?
Как направить обаботчик событий для окошка на свою процедуру?
← →
Skier (2003-07-21 10:43) [9]
> Как направить обаботчик событий для окошка на свою процедуру?
Ну...скажем перекрыть обработчик "стандартного" или написать обработчик своего сообщения
Например :
//объявление
uses Messages;
const
UM_YOUR_MESSAGE = WM_USER + 1;
YourMessageHandler(var Message : TMessage); message UM_YOUR_MESSAGE;
//реализация
TYourClass.YourMessageHandler(var Message : TMessage);
begin
//bla-bla-bla
end;
← →
Still Swamp (2003-07-21 10:45) [10]не - мне нужно переловить сообщения для окошка, обработать их, и отправить обратно окошку, которому они предназначались.
← →
Skier (2003-07-21 10:46) [11]>Still Swamp (21.07.03 10:45)
И что ?
← →
Skier (2003-07-21 10:48) [12]>Still Swamp (21.07.03 10:45)
Перекрой WndProc и будет тебе счастье...
← →
Still Swamp (2003-07-21 10:59) [13]WndProc - это если у тебя хотя бы TControl есть, а у меня к сожалению только Handle.
← →
Skier (2003-07-21 11:00) [14]>Still Swamp (21.07.03 10:59)
Как так ?
← →
Still Swamp (2003-07-21 11:02) [15]из предыдущего совета и из исходников выискал вот это:
SetWindowLong(Handle, GWL_WNDPROC, Longint(MakeObjectInstance(Method)));
Однако, поставить себе на службу не могу.
← →
Ihor Osov'yak (2003-07-21 11:11) [16]2 Skier © (21.07.03 10:35)
Естественно.. Для методов. Но для процедур - да. Спрашивалось о процедуре.
Уточнение Still Swamp (21.07.03 10:34) уже потом было..
2 Still Swamp (21.07.03 11:02)
в чем проблема то?
← →
Skier (2003-07-21 11:13) [17]>Ihor Osov"yak © (21.07.03 11:11)
Странно...Я разве что против сказал ?
>Still Swamp
"Бриллиантов всё ещё не видно"
← →
Ihor Osov'yak (2003-07-21 11:20) [18]2 Skier © (21.07.03 11:13)
Извини. Я немного контекст разговора неверно отследил. Все нормально..
Зы. Ждемс брилиантовс..
← →
Anatoly Podgoretsky (2003-07-21 11:42) [19]А по вопросу нужно только преобразование адрес, то есть он есть.
Cardinal(Адрес) но преобразовывать адрес в кардинал как то неверно, поскольку Cardinal это generic тип (размер меняется) и не факт, точнее точно не факт, что размер Cardinal = адрес
← →
Ihor Osov'yak (2003-07-21 11:57) [20]2 Anatoly Podgoretsky © (21.07.03 11:42)
Вопрос был то о кардилан.
И хелпе черным по белому написано, что cardinal - сейчас это unsigned 32-bit..
Но.. Возможно вернее всего работа с поинтерамы. Но проблема то в том, что всякие SetWindowLong ожидают то integer, вернее LongInt.. Да и поинтер наверно не всегда 32 битным будет..
Зы. Я, в общем то, в такий случаях пишу dword.
← →
Толик (2003-07-21 12:00) [21]MakeObjectInstance нужна для того, чтобы в качестве оконной процедуры вида
function (hWnd, Msg: longword; wParam, lParam: longint): longint; stdcall;
выполнялась ф-я член класса видаprocedure(var Message: TMessage) of object
Делает это она довольно просто (см. Classes.pas) - подсовывает окну указатель на StdWndProc, а уже StdWndProc вызывает нужную ф-ю член класса.
P.S.
На самом деле эта ф-я полна багов. Достаточно посмотреть хотя бы на то, что MakeObjectInstance вызывает VirtualAlloc, а вот FreeObjectInstance эту память освобождать не собирается ну и т.д. Поэтому лучше написать некий свой аналог...
← →
Anatoly Podgoretsky (2003-07-21 12:03) [22]Ihor Osov"yak © (21.07.03 11:57)
Насчет указателей и их размеров и размера Cardinal - это просто змаечание/дополнение к вопросу. А суть и ответ это Cardinal(Адрес)
← →
PVOzerski (2003-07-21 12:05) [23]>generic тип (размер меняется)
пока 64-разрядного Delphi нет, IMHO, cardinal будет всегда то же, что LongWord. Хотя можно конвертить и в LongWord:
x:=longword(@proc);
Метод класса впихнуть обработчиком окна нельзя из-за несоответствия списка параметров (а всякий метод имеет еще скрытый от программиста параметр - ссылку на self). Но никто не мешает обращаться к классу из неинкасулированной функции, которая и может стать обработчиком сообщений окна, будучи приделанной через SetWindowLong. Неплохо, кстати, не потерять исходный обработчик - см. GetWindowLong, CallWindowProc. А можно даже "привязать" конкретный экземпяр класса к конкретному окошку, запихнув его через тот же SetWindowLong по смещению GWL_USERDATA и потом обращаясь через GetWindowLong.
← →
Still Swamp (2003-07-21 14:35) [24]Вобщем и целом сделал. Наковырял из Windows. Это работает.
TMyClass=Class
protected
FHandle:HWND;
FNewWndProc:TFarProc;
FOldWndProc:TFarProc;
constructor Create(Handle:HWND);
procedure ClientWndProc(var Message: TMessage);
end;
constrictor TMyClass.Create;
begin
Inherited Create;
FHandle:=Handle;
FNewWndProc := MakeObjectInstance(ClientWndProc);
FOldWndProc := Pointer(GetWindowLong(FHandle, GWL_WNDPROC));
SetWindowLong(FHandle, GWL_WNDPROC, Longint(FNewWndProc));
end;
procedure TMyClass.ClientWndProc(var Message: TMessage);
begin
//обработчик
with Message do Result:=CallWindowProc(FOldWndProc, FHandle, Msg, wParam, lParam);
end;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.08.04;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.008 c