Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
14-85663
Driverrr
2002-08-30 20:33
2002.09.26
Диррективы компилятора


14-85699
EAlexander
2002-08-29 16:13
2002.09.26
Delphi 7 можно скачать с Borland.com


1-85450
Micah'GF
2002-09-15 18:22
2002.09.26
Прога держит винду


1-85522
Андрей Дмитриев
2002-09-13 12:11
2002.09.26
Потоки


1-85446
ed_209
2002-09-14 05:18
2002.09.26
выход из процедуры





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский