![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с компонентами [D5, WinME]
Gari © (2002-09-16 09:08:00)Доброе утро уважаемые господа. У меня вопрос такого порядка: помещаю компонент на форму (собственно созданный, компонент "А"), у которого одно из свойств имеет тип компонента "В". Помещаю на форму компонент "В", устаноавливаю в "А" свойство, ссылающееся на компонент "В". А вот далее вопрос, почему, и как устранить ошибку возникающую при удалении компонента "В" с формы(Ошибка доступ к переменной). Помогите если можете.
Andrey Shakula (2002-09-16 13:51:00) [1]Да незачто. А, я уже тебе примерчик накидал. Просто и красиво.
unit NewComponent;
interface
uses
Classes;
type
TNewComponent = class(TComponent)
private
{ Private declaration }
FComponent: TComponent;
procedure SetComponent(Value: TComponent);
protected
{ Protected declaration }
procedure Notification(AComponent: TComponent; Operation: TOperation);
override;
public
{ Public declaration }
published
{ Published declaration }
property Components: TComponent read FComponent write SetComponent;
end;
procedure Register;
implementation
procedure TNewComponent.SetComponent(Value: TComponent);
begin
if FComponent <> Value then
begin
if Assigned(FComponent) then
Self.RemoveFreeNotification(FComponent);
if Assigned(Value) then
Self.FreeNotification(Value);
FComponent := Value;
end;
end;
procedure TNewComponent.Notification(AComponent: TComponent; Operation: TOperation);
begin
if (Operation = opRemove) and (FComponent = AComponent) then
FComponent := nil;
inherited Notification(AComponent, Operation);
end;
procedure Register;
begin
RegisterComponents("Samples", [TNewComponent]);
end;
end.
Gari (2002-09-16 13:17:00) [2]все работает просто, класс. Это я сам немного ступил. Не там описал процедуру Notification. Огромное спасибо Andrey Shakula. Он мне очень помог. Видно мир не без добрых людей.
Gari (2002-09-16 13:13:00) [3]Исправил. Теперь свойство записать можно, но при удалении возникает таже ошибка. Андрей я перекрыл метод как ты написал (16.09.02 10:40). Подскажи если можешь. За ранее огромное спасибо.
Andrey Shakula (2002-09-16 12:37:00) [4]Sorry. Писал на скорую руку,
Procedure TТвойКомпонентА.SetB(Value: TComponent);
begin
if FB<> Value then
begin
if Assigned(FB) then
Self.RemoveFreeNotification(FB);
if Assigned(Value) then
Self.FreeNotification( Value);
FB := Value;
end;
end;
Но, если на одной форме оба компонента, то должно работать без всяких
if Assigned(FB) then
Self.RemoveFreeNotification(FB);
if Assigned(Value) then
Self.FreeNotification( Value);
нужно только Notification перекрыть.
Если не знаешь, как перекрывать, то пиши ответим.
Gari (2002-09-16 11:19:00) [5]Уважаемый Andrey Shakula, попробовал как вы написали, но увы теперья даже не могу записать свойство. Выдает туже ошибку, что и раньше при удалении (Access violetion at adress ....). Если есть еще мысле поделитесь пожалуйста, работа висит.
Gari (2002-09-16 10:48:00) [6]Огромно спасибо, учту и допишу.
Andrey Shakula (2002-09-16 10:46:00) [7]В догонку:
Писал, писал а главного и не написал.
Procedure TТвойКомпонентА.SetB(Value: TComponent);
begin
if FB<> Value then
begin
if Assigned(FB) then
Self.RemoveFreeNotification(FB);
if Assigned(Value) then
Self.FreeNotification(FB);
FB := Value;
end;
end;
Gari (2002-09-16 10:44:00) [8]За ранее огромное спасибо, попробую так как вы посоветовали.
Andrey Shakula (2002-09-16 10:40:00) [9]Думаю что проблема в этом.
Перекрой Notification.
procedure TТвойКомпонентА.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
case Operation of
opInsert:
begin
end;
opRemove:
begin
if (Self.B = AComponent) then
FB := nil;
end;
end;
end;
При условии что компонент A и B находятся на одной форме или одном дата модуле. Если на разных то установка свойства A.B
должна выглядеть примерно так
Procedure TТвойКомпонентА.SetB(Value: TComponent);
begin
if Assigned(FB) then
Self.RemoveFreeNotification(FB);
if Assigned(Value) then
Self.FreeNotification(FB);
end;
Gari (2002-09-16 10:36:00) [10]Уважаемый Anatoly Podgoretsky, а функция Get написаная Lord-ом Warlock-ом правильная или нет? Если нет то как правиль описать эту функцию. За ранее огромное спасибо.
Anatoly Podgoretsky (2002-09-16 10:30:00) [11]torba (16.09.02 10:25)
То что он написал, это в приципе ошибка, нельзя назначить nil, то что ты привел выше может быть и ошибой и нет, все будет зависить от компонента, например может происходить утечка памяти, пример
FB = xxx
затем
FB = yyy
xxx утеряно, ошибки такого рода потом будешь долго искать.
В варианте, который я предлагаю это может выглядеть так:
if Value = FB then Exit;
FB.Free;
FB: = value;
утечки нет, лишней инициализации нет, не в этом случае конечно, но никакие действия не производятся, если значение FB уже установлено.
Если же конечно FB ординарный тип, то все это можно опустить, но тогда и SetB не нужна.
Gari (2002-09-16 10:09:00) [12]По ходу нашего общения у меня возник еще вопрос. Как написал Lord Warlock, это стандартное определение процедур Get и Set, а вот как написал уважаемый Anatoly Podgoretsky, мне не совсем понятно как это спасет от возникновения ошибки. Если не трудно разясните пожалуйста.
Anatoly Podgoretsky (2002-09-16 09:58:00) [13]А вот так писать не надо, не удастся сделать Unassigned, правильнее писать по другому
function SetB(Value: TComp)
begin
if Value = FB theb Exit;
действия по инициализации или по удалению старого мусора
FB: = value;
end;
Lord Warlock (2002-09-16 09:48:00) [14]Исключительная ситуация вообще не должна возникать, но если очень хочется, то:
function SetB(Value: TComp)
begin
if Assigned(Value) then
FB:= value;
end;
function GetB
begin
result:= nil;
if Assigned(FB) then
result:=FB;
end;
но по моему этого совсем не нужно, да и не пишет никто так
Gari (2002-09-16 09:38:00) [15]После нажатия этих клавишь, сгенерится код (в смысле болванка), а что внутри. Как присваивать значения я знаю,(В функции
function SetB
begin
FB:= value;
end;
function GetB
begin
result:= FB;
end;
кажется так.
А как обработать исключительную ситуацию, или она при таком описании не возникает. Подскажи если знаешь.
Lord Warlock (2002-09-16 09:29:00) [16]Gari (16.09.02 09:24)
Используй вариант 1, а еще лучша напиши так:
property B: TComp read GetB write SetB
и жми Ctrl+Shift+C
Содержание этих процедур предельно простое, но позволяет избежать подобных ошибок. У меня есть компонент с таким свойством, все прекрасно удаляется. Если что не так, посмотри исходники любого компонента с подобным свойством
Gari (2002-09-16 09:24:00) [17]Извеняюсь, в смысле второй вареант. Не через процедуру вызываемую при изменении свойства.
Lord Warlock (2002-09-16 09:22:00) [18]Gari (16.09.02 09:15)
какой конкретно вариант, 1 или 2. Это большая разница
Gari (2002-09-16 09:15:00) [19]Описано через read write
Lord Warlock (2002-09-16 09:14:00) [20]Добрый день.
Как в компоненте А описано свойство В?
FB: TComp
property B: TComp read FB write SetB
или
property B: TComp read FB write FB
?