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

Вниз

Работа с компонентами   Найти похожие ветки 

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

Наверх




Память: 0.51 MB
Время: 0.014 c
3-85413
Sirus
2002-09-05 09:35
2002.09.26
Почему отчет из TQuickRep принтером HP LaserJet печатается плохо?


1-85609
bedny
2002-09-14 20:02
2002.09.26
sc_data.txt --> TreeWiev


3-85409
UnDISCOvery
2002-09-05 19:27
2002.09.26
Access 2000. Ошибка:


1-85509
Серг
2002-09-17 10:20
2002.09.26
Console App


1-85588
Донской
2002-09-14 15:31
2002.09.26
Установка сервиса