Если можно присвоить, значит и "отсвоить" как-то...

  • Автор темы DblM
  • Дата начала
Статус
Закрыто для дальнейших ответов.
D

DblM

Гость
#1
в проДЖекте есть функция:

procedure TForm1.BitBtn1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
//всякая всячина
end;

создаю кнопку:

... var b:TBitBtn;
begin b:=TBitBtn.Create(form1);
b.OnMouseUp:=BitBtn1MouseUp; //присваиваю ей ту функцию...

а как теперь удалить её? програмно...

пробовал:
там при создании -> i:=b.ComponentIndex;
а где надо -> (Components as TBitBtn).Action.Free;
функция всё равно остаётся...

подмагните кто моГёт)
 

Kmet

Well-Known Member
Java Team
25.05.2006
1 036
8
#2
хм, не уверен, но если по аналогии с Си, то b.OnMouseUp:=nil
 
D

DblM

Гость
#3
это было первое что я попробовал... nil и null... ))
он мне туеву кучу ошибок панавыдавал...
а ща чёто сработал))
наверно компиллер делфи связан с этим форумом и выдаёт ошибки пока на эту тему не будет задан вопрос..))
 
G

garrymax

Гость
#4
Ставить нулевой адрес функции на обработку зарегистрированого события нельзя - потому и ругался.
Если можно убить саму кнопку (умрет и реакция на событие), то проще:
Код:
b.Free;
Если только реакцию мышки (кнопка еще нужна), то проще подставить функцию-заглушку:
Код:
procedure TForm1.NotOnMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin {ничего не делать}end;
......
b.OnMouseUp:=NotOnMouseUp;
Более цивилизованые способы (например ActionList) менее эффективены по размеру кода, а удалить функцию, как машинный код, можно только затиранием самой программы :ph34r:

Да, еще забыл
Код:
b.OnMouseUp:=nil;
если компелятором не проверяется, то по логике не правильный. По крайне мере. в старых версиях у меня такое не работало.
 

Kmet

Well-Known Member
Java Team
25.05.2006
1 036
8
#5
если компелятором не проверяется, то по логике не правильный
Интересно почему? Как раз по логике (скорее по аналогии с Си) nil может быть приведен к любому типу указателя.
 
G

garrymax

Гость
#6
Не путай Сишную ссылку на функцию и что-то вроде hook's - у дельфи свои способы, просто давно об этом читал и до конца не помню, но смысл приблезительно такой (попробую своими словами и сразу извиняй, что коряво):
Форма и остальное (кнопка, это тоже окно) не чисто APIшная и события OnMouseUp и другие, это не отдельный код, который вставляется в функцию окна, а хук, который обрабатывется отдельно. Если этот событие как-бы объявлено, то все равно будет вызов.
Что-то в этом роде.
Кстати, попробуй в Си приписать какой нибуть функции нулевой адрес - что, она сразу перестанет вызываться? Скорее: "Приложение выполнило недопустимую оппера....... - и все такое на счет недопустимой адресации...
По этому и неправильный. Скорее всего компилятор при виде такого присваивания убирает событие.
 
D

DblM

Гость
#7
да всё получилоссь))

а функция была объявлена никому.. а потом уже присвоена кнопке..[после запуска программы] так что nil вполне прокатит...
скорее это не хук а какая-нибудь адресация и всё..)
 
Z

zubr

Гость
#8
Форма и остальное (кнопка, это тоже окно) не чисто APIшная и события OnMouseUp и другие, это не отдельный код, который вставляется в функцию окна, а хук, который обрабатывется отдельно. Если этот событие как-бы объявлено, то все равно будет вызов.
Что-то в этом роде.
Мда... откровение, однако, насчет хука.
В общето OnMouseUp - это сообщение Windows - WM_LBUTTONUP, которое обрабатываются процедурой окна, которое в данном случае является кнопкой. А OnMouseUp - это часть кода (если он есть <>nil), VCL вставляет в процедуру окна.
 

Kmet

Well-Known Member
Java Team
25.05.2006
1 036
8
#9
Кстати, попробуй в Си приписать какой нибуть функции нулевой адрес - что, она сразу перестанет вызываться?
Функции можно присвоить? Покрайней мере не С\С++. Да имя функции может автоматически разыменовываться компиляторомк указателю на первую инструкцию функции, но присвоить функции что либо это вряд ли).

А OnMouseUp - это часть кода (если он есть <>nil), VCL вставляет в процедуру окна
Я коненчно не утверждаю, но почему то не очень себе представлю как имеено ВЦЛ вставяет эту часть кода. Обджект поскаль не поддерживает ни шаблонов ни каго либо другого средства метапрограммирования.


Как мне кажется OnMouseUp, как и любое другое событие в конечном итоге представляет собой указатель на функцию(если более точно указатель на функцию-член), просто в обджект паскале такие указатели определяет достаточно хитро, что вроде type ONMOUSE:procedure (.....) of Object. За синтакс не уверен. И оконная процедура на соответсвующие сообщение, по указателю вызывают функцию отвечающую за обработку события.
 
G

garrymax

Гость
#10
Мда... откровение, однако, насчет хука.
Читай внимательнее: что-то вроде hook's


Да имя функции может автоматически разыменовываться компиляторомк указателю на первую инструкцию функции
Вот ты сам и ответил, только подставь "свое" к остальной части моего выражения. Или нужно было тут талмут писать?


А OnMouseUp - это часть кода (если он есть <>nil), VCL вставляет в процедуру окна.
OnMouseUp - это отдельная функция (ассамблерное CALL и RET) - она и в теле программы на паскале вызывается как процедура - имеет параметры, которые в стек загоняются. Даже по логике, эти параметры будут мешать вкалачиванию кода в функцию окна, а если их описывать, как глобальные переменные, то конечный код был бы тогда ну очень большим.
 

Kmet

Well-Known Member
Java Team
25.05.2006
1 036
8
#11
Для: garrymax

Куда что подставить?!

Сюда что ли?!

Кстати, попробуй в Си приписать какой нибуть функции нулевой адрес - что, она сразу перестанет вызываться?
 
Z

zubr

Гость
#12
Читай внимательнее: что-то вроде hook's
Вроде Володи. Ты хоть знаешь что такое хук. Нахрена окну устанавливать хук на сообщения, когда у него есть своя процедура обработки сообщений. Представь, если каждое окно Windows (кнопки, Editы, Memo и т. п.) будет устанавливать хук - система даже загрузится не сможет.

OnMouseUp - это отдельная функция (ассамблерное CALL и RET) - она и в теле программы на паскале вызывается как процедура - имеет параметры, которые в стек загоняются. Даже по логике, эти параметры будут мешать вкалачиванию кода в функцию окна, а если их описывать, как глобальные переменные, то конечный код был бы тогда ну очень большим.
Опять откровение. Да возьми и открой Controls.pas, да посмотри где вызывается OnMouseUp. В банальном обработчике сообщения WM_LBUTTONUP:
Код:
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;

procedure TControl.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Assigned(FOnMouseUp) then FOnMouseUp(Self, Button, Shift, X, Y);
end;

procedure TControl.DoMouseUp(var Message: TWMMouse; Button: TMouseButton);
begin
if not (csNoStdEvents in ControlStyle) then
with Message do MouseUp(Button, KeysToShiftState(Keys), XPos, YPos);
end;

procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
end;
DoMouseUp(Message, mbLeft);
end;
То что у тебя в голове каша, твои проблемы, но зачем молодежи х**ню впаривать.
 
G

garrymax

Гость
#13
Zubr, заметь - без мата, возможно тебе это тоже будет откровением, но
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
procedure TControl.MouseUp(Button: TMouseButton;
procedure TControl.DoMouseUp(var Message: TWMMouse; Button: TMouseButton);
procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
является описание функций (процедур с возвратом), а не вставляемым кодом. Если не доходит, то возьми любую книгу по структурированному программированию и почитай разницу.
А на счет "вроде Володи": Я уже боюсь упоминать о назначении WndProc - может так статься, что это будет СТРАШНЫМ ОТКРОВЕНИЕМ ДЛЯ ТЕБЯ, но если ты найдешь более подходящее описание подобным ответвлениям, то мне останится снять шляпу перед таким полиглотом. А пока будешь изучать основы Windows API и вообще логику построения программ Windows-приложений на Дельфи, то каша будет в твоих ответах.
Если не достаточно, хотя вопросивший уже закрыл тему, то могу еще много довыдов привести - у меня еще два дня без работы есть.
 
Z

zubr

Гость
#14
Для: garrymax
Это ты 2 дня думал, чтобы опять нести бред.
Цитата(zubr @ 31:07:2006, 20:44 )
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
procedure TControl.MouseUp(Button: TMouseButton;
procedure TControl.DoMouseUp(var Message: TWMMouse; Button: TMouseButton);
procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);

является описание функций (процедур с возвратом), а не вставляемым кодом.
Вообще то выше приведенные процедуры - это процедуры без возврата значения. Учи паскаль.
Я тебе ничего доказывать не буду, имхо это бесполезное занятие.
Все, хватит флеймить. Тема закрыта.
 
Статус
Закрыто для дальнейших ответов.