Форум: "Основная";
Текущий архив: 2002.09.26;
Скачать: [xml.tar.bz2];
ВнизРабота с компонентами Найти похожие ветки
← →
Gari (2002-09-16 09:08) [0]Доброе утро уважаемые господа. У меня вопрос такого порядка: помещаю компонент на форму (собственно созданный, компонент "А"), у которого одно из свойств имеет тип компонента "В". Помещаю на форму компонент "В", устаноавливаю в "А" свойство, ссылающееся на компонент "В". А вот далее вопрос, почему, и как устранить ошибку возникающую при удалении компонента "В" с формы(Ошибка доступ к переменной). Помогите если можете.
← →
Lord Warlock (2002-09-16 09:14) [1]Добрый день.
Как в компоненте А описано свойство В?
FB: TComp
property B: TComp read FB write SetB
или
property B: TComp read FB write FB
?
← →
Gari (2002-09-16 09:15) [2]Описано через read write
← →
Lord Warlock (2002-09-16 09:22) [3]Gari (16.09.02 09:15)
какой конкретно вариант, 1 или 2. Это большая разница
← →
Gari (2002-09-16 09:24) [4]Извеняюсь, в смысле второй вареант. Не через процедуру вызываемую при изменении свойства.
← →
Lord Warlock (2002-09-16 09:29) [5]Gari (16.09.02 09:24)
Используй вариант 1, а еще лучша напиши так:
property B: TComp read GetB write SetB
и жми Ctrl+Shift+C
Содержание этих процедур предельно простое, но позволяет избежать подобных ошибок. У меня есть компонент с таким свойством, все прекрасно удаляется. Если что не так, посмотри исходники любого компонента с подобным свойством
← →
Gari (2002-09-16 09:38) [6]После нажатия этих клавишь, сгенерится код (в смысле болванка), а что внутри. Как присваивать значения я знаю,(В функции
function SetB
begin
FB:= value;
end;
function GetB
begin
result:= FB;
end;
кажется так.
А как обработать исключительную ситуацию, или она при таком описании не возникает. Подскажи если знаешь.
← →
Lord Warlock (2002-09-16 09:48) [7]Исключительная ситуация вообще не должна возникать, но если очень хочется, то:
function SetB(Value: TComp)
begin
if Assigned(Value) then
FB:= value;
end;
function GetB
begin
result:= nil;
if Assigned(FB) then
result:=FB;
end;
но по моему этого совсем не нужно, да и не пишет никто так
← →
Anatoly Podgoretsky (2002-09-16 09:58) [8]А вот так писать не надо, не удастся сделать Unassigned, правильнее писать по другому
function SetB(Value: TComp)
begin
if Value = FB theb Exit;
действия по инициализации или по удалению старого мусора
FB: = value;
end;
← →
Gari (2002-09-16 10:09) [9]По ходу нашего общения у меня возник еще вопрос. Как написал Lord Warlock, это стандартное определение процедур Get и Set, а вот как написал уважаемый Anatoly Podgoretsky, мне не совсем понятно как это спасет от возникновения ошибки. Если не трудно разясните пожалуйста.
← →
Anatoly Podgoretsky (2002-09-16 10:30) [10]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:36) [11]Уважаемый Anatoly Podgoretsky, а функция Get написаная Lord-ом Warlock-ом правильная или нет? Если нет то как правиль описать эту функцию. За ранее огромное спасибо.
← →
Andrey Shakula (2002-09-16 10:40) [12]Думаю что проблема в этом.
Перекрой 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:44) [13]За ранее огромное спасибо, попробую так как вы посоветовали.
← →
Andrey Shakula (2002-09-16 10:46) [14]В догонку:
Писал, писал а главного и не написал.
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:48) [15]Огромно спасибо, учту и допишу.
← →
Gari (2002-09-16 11:19) [16]Уважаемый Andrey Shakula, попробовал как вы написали, но увы теперья даже не могу записать свойство. Выдает туже ошибку, что и раньше при удалении (Access violetion at adress ....). Если есть еще мысле поделитесь пожалуйста, работа висит.
← →
Andrey Shakula (2002-09-16 12:37) [17]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 13:13) [18]Исправил. Теперь свойство записать можно, но при удалении возникает таже ошибка. Андрей я перекрыл метод как ты написал (16.09.02 10:40). Подскажи если можешь. За ранее огромное спасибо.
← →
Gari (2002-09-16 13:17) [19]все работает просто, класс. Это я сам немного ступил. Не там описал процедуру Notification. Огромное спасибо Andrey Shakula. Он мне очень помог. Видно мир не без добрых людей.
← →
Andrey Shakula (2002-09-16 13:51) [20]Да незачто. А, я уже тебе примерчик накидал. Просто и красиво.
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.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.09.26;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.008 c