Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.08.04;
Скачать: CL | DM;

Вниз

Как преобразовать адрес процедуры   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.019 c
4-10528
mod
2003-06-03 16:56
2003.08.04
Раскладка клавиатуры


1-10242
-=[SDA]=-
2003-07-21 12:25
2003.08.04
Как узнать какой именно компонент сгенерировал событие!?


3-10133
Rustik
2003-07-11 16:39
2003.08.04
Подскажите как можно в строке выбрать буквы аналоги латинницы


14-10362
zolotov
2003-07-15 21:13
2003.08.04
Как заменить старую версию F1Book более новой?


1-10205
defenseur
2003-07-23 11:14
2003.08.04
Safearray в Delphi