Форум: "Основная";
Текущий архив: 2003.09.29;
Скачать: [xml.tar.bz2];
ВнизВопрос об удивительном глюке пропертей компонентов VCL Найти похожие ветки
← →
Starkom (2003-09-17 15:01) [0]Есть такая странная ситуация:
type PInteger = ^Integer;
...
var pi:PInteger;
but:TBitBtn;
bev:TBevel;
begin
pi:=@bev.Left;
pi^:=StrToInt("1");
bev.Parent.Refresh;
pi:=@but.Left;
pi^:=StrToInt("1");
ShowMessage(IntToStr(but.Left));
but.Parent.Refresh;
end;
Глюк заключается в том, что для Бевела все нормально работает. Для БитБаттона же ШоуМесседж выдает 1! Но визуально это никак не отображается! При том, что, если добавим строчку but.Top:=1; вместо шоумесседжа, то все нормально отображается - то есть и топ становится 1, и лефт=1!!!
Помогите разобраться!!! Копался в исходниках VCL - так и не нашел отгадки.
← →
Palladin (2003-09-17 15:05) [1]заяц это не только ценный мех но и...
адрес property может указывать не только на отвечающую за него переменную, но (что в этом случае и имеет место) на процедуру write для него...
так что ты записываешь 1 в первый байт начала тела процедуры...
← →
Starkom (2003-09-17 15:12) [2]Хмм.
property Left: Integer read FLeft write SetLeft; - это у TControl
Ни для TBevel-TGraphicControl, ни для TBitBtn-TButton-TButtonControl-TWinControl SetLeft не переопределен, то есть метод вызывается и для Бевела, и для БитБаттона один и тот же. Вся загвоздка в том, почему же для Бевела тогда это работает, если все так и есть, как Вы сказали?
← →
Verg (2003-09-17 15:15) [3]
> Помогите разобраться!!! Копался в исходниках VCL - так и
> не нашел отгадки.
Как не нашел?
а
property Left: Integer read FLeft write SetLeft;
где
procedure SetLeft(Value: Integer);
Ну допустим, в данном случае @Left вернет адрес поля FLeft
экземпляра класса. Ну а когда ты пишешь в этот адрес значение, с какой такой радости будет вызван SetLeft?
← →
Palladin (2003-09-17 15:17) [4]хем... надо поковырять исходники... по идее и при вызове берется read а в данном случае это поле...
а зачем столь извращенная вещь понадобилась?
← →
Starkom (2003-09-17 15:42) [5]В-общем, вся проблема в том, что Бевел - это Контрол, а БитБаттон - это ВинКонтрол. У них разные СетБаундсы, которые вызываются из СетЛефтов. И bev.Parent.Refresh; работает, потому что у ТКонтрола Инвалидейт, вызываемый из Рефреша делает почти то же самое, что и СетБаундс. У ВинКонтрола же все иначе :((
← →
Starkom (2003-09-17 15:54) [6]Придется юзать SetPropValue, а так не хочется :((
← →
me (2003-09-17 16:02) [7]А причём здесь вообще SetLeft?
конструкция
pi:=@bev.Left
даст тебе адрес FLeft, а если чтение происходит через метод -
то вообще ошибку компиляции.
Я вообще сколнен считать возможность взять адрес св-ва
недосмотром разработчиков.
Дело скорее всего в том, что компилятор в такой конструкции
сразу заменяет св-во на FXXX или SetXXX.
Пользоваться этой дырой ИМХО - весьма и весьма дурной тон.
← →
Starkom (2003-09-17 16:06) [8]2 me: EXACTLY!!! При попытке подсунуть оператору @ св-во, получаемое через Get-метод, компилятор выдает ошибку. А насчет недосмотра - разработчики дают инструмент, кто-то его использует с умом, кто-то без (например, я :) ). Никто же не ругает разработчиков огнестрельного оружия, за то, что кто-то его использует не так, как это задумывали сами разработчики.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.09.29;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.01 c