Компоненты и VCL

Компоненты и VCL

1. Каковы ограничения на стандартные компоненты Delphi?

Все компоненты, использующие TList для сохранения информации, имеют верхний предел 16368 единиц. Hапример, TTabControl может содержать до 16368 закладок и Delphi Component Palette может содержать до 16368 страниц.

Многие из стандартных компонент Delphi являются надстройкой над стандартными управляющими элементами Windows. Windows 3.1 налагает свои собственные ограничения на эти компоненты. Hапример: TComboBox или TListbox могут содержать до 5440 единиц, а TMemo или TEdit (и соответствующие компоненты) — до 32k текста.

Ресурсы Windows 3.1 ограничивают компонент TNotebook 570 страницами. (Трудно получить более 500 хендлов /handles/ окон в любом приложении Windows). Превышение этих границ вызывает ошибку или послужит причиной странного поведения Windows. 

2. Предел буфера редактирования в 32K для TMemo.

Почему в документации написано, что TMemo может редактировать тексты до 256К, а на деле получается не более 32К?

В документации ошибка. 32К — это ограничение Windows. В Windows все стандартные редакторы используют общий буфер в 32К, компонент TMemo использует другую технику, позволяющую каждому TMemo иметь буфер в 32К. В Windows 95 эта проблема решена.

3. Почему компонент TGauge так медленно работает (медленнее, чем VBX BGauge)?

Компонент TGauge — просто пример, и ничего более. В нем отсутствует даже намек на оптимизацию перерисовок. Если вы посмотрите на код процедуры SetProgress, то увидите

FCurValue := Value;

Refresh;

Это означает, что как только положение изменилось, весь компонент будет перерисован. Тем не менее, есть пути для того, чтобы сделать компонент более быстрым:

1. Не присваивать Progress каждый раз (напр. 3000 раз), т.е. делать обновление менее часто

2. Проверять, действительно ли позиция на экране изменится. Например, в SetProgress сделать следующее:

if Abs(FCurValue-FLastDrawn) >= FDisplayDelta then 

begin

  Refresh;

  FastDrawn := FCurValue;

end;

где FDisplayDelta что-то вроде (FMaxValue-FMinValue) div Width (идеально было-бы учитывать реальный размер экрана.

3. Обновлять только часть индикатора, которая действительно меняется. Процедура Refresh стирает и перерисовывает весь компонент. Можно сделать вызов InvalidateRect (Windows API) и вызвать Update.

4. Если вы сделали как в пункте 3, вы дополнительно можете оптимизировать процедуру перерисовки, чтобы не перерисовывать неизменяющийся участок.