Delphi. Вопросы и ответы

Что и как сделать на Delphi. Иногда - с примерами

Полезное
Социалка
Статьи » Delphi. Вопросы и ответы » 

Небольшая хитрость

26.05.2010
18:53

Представь себе такую ситуацию: у тебя есть TabSheet... Или нет. Не так. У тебя есть GroupBox. А на нем, понятное дело, расположены какие-то контролы. И еще несколько GroupBox'ов, так же набитых контролами по самое нехочу. И вот ты в один прекрасный момент в коде пишешь нечто вроде GroupBox1.Enabled := False; и с ужасом обнаруживаешь, что все контролы, лежащие на групбоксе1, задизабленными не выглядят! Как быть?

Разумеется, есть проверенный временем метод: при каждом случае установки доступности групбокса пробежаться в цикле по всем вложенным контролам и поставить им соответствующее значение Enabled. Но мы-то помним, что у нас на форме лежит 27 групбоксов. Писать такую тягомотину для каждого из них - крайне лениво. Поэтому мы пойдем другим путем.

В самом начале кода юнита пишем что-то вроде такого (обрати внимание на выделенное красным):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type TGroupBox = class(StdCtrls.TGroupBox)
  private
    FEnabled: Boolean;
    procedure SetEnabled(const Value: Boolean);
  published
   property Enabled: Boolean read FEnabled write SetEnabled;
end;

Затем - пишем имплементейшн:

procedure TGroupBox.SetEnabled(const Value: Boolean);
var X: Integer;
begin
   FEnabled := Value;
   for X := 0 to Self.ControlCount - 1 do
      Self.Controls[X].Enabled := FEnabled;
   // При желании - доточишь напильником и прикрутишь рекурсию
end;

И теперь все групбоксы на форме при установке им в рунтайме свойства Enabled будут выставлять его и всем вложенным контролам. Весьма удобно. Рекомендую.

Hint. А еще таким образом можно и своих свойств/методов накрутить.

Комментарии

boriss
26.05.2010, 20:11:31
Ответить #1
Ну, на самом деле немножко не так: в данном примере значение самого свойство GroupBox.Enabled, которое унаследовано от StdCtrls.TGroupBox меняться не будет, а вместо него будет изменяться значение поля FEnabled. Таким образом, мы имеем "лишнее" поле FEnabled, которое никоим образом не влияет на значение унаследованного свойства Enabled, что в свою очередь блокирует отправление приложением перекрытому элементу управления TGroupBox и принятия им API-сообщений WM_ENABLE, CM_ENABLEDCHANGED и иже с ними. То есть, если я захочу изменить свойство Enabled элемента управления такого перекрытого класса TGroupBox, с помощью посылки ему API-сообщения WM_ENABLE, то он никак не отреагирует на это.

В общем, более правильно было бы сделать так:

[code]
type
TGroupBox = class (StdCtrls.TGroupBox)
private
protected
function GetEnabled : Boolean; override;
procedure SetEnabled (Value: Boolean); override;

procedure UpdateChilds;

procedure WMEnable (var Message: TWMEnable); message WM_ENABLE;
public
property Enabled : Boolean read GetEnabled write SetEnabled;
end;

// ...

implementation

// ...

{ TGroupBox }

function TGroupBox.GetEnabled: Boolean;
// -------------------------------------------------------------------------------------------------
begin
Result := inherited GetEnabled;
end;

procedure TGroupBox.SetEnabled (Value: Boolean);
// -------------------------------------------------------------------------------------------------
begin
inherited SetEnabled (Value);
end;

procedure TGroupBox.UpdateChilds;
// -------------------------------------------------------------------------------------------------
var
X : Integer;
begin
// а здесь настраиваем состояние дочерних эл-тов управления
for X := 0 to Self.ControlCount - 1 do
Self.Controls[X].Enabled := Enabled;
end;

procedure TGroupBox.WMEnable (var Message: TWMEnable);
// -------------------------------------------------------------------------------------------------
begin
inherited;

UpdateChilds;
end;

[/code]
boriss
26.05.2010, 20:15:15
Ответить #2
и, кстати, в моем вышеприведенном примере объявления свойства Enabled и методы XXXEnabled можно смело убрать. Они там на хер не нужны...
Del
26.05.2010, 20:18:36
Ответить #3
Кому: boriss, #1

И на хера такие пляски?
Единственное - я забыл в коде дописать такое:
[inherited Enabled := FEnabled;]

Вариант, конечно, правильный, но все же - на мой взгляд, излишества...
boriss
26.05.2010, 20:22:17
Ответить #4
И самое главное: хитрость это очень хорошая и полезная, и я ею уже давно с успехом пользуюсь... ;)
boriss
26.05.2010, 20:26:55
Ответить #5
Кому: Del, #3

>И на хера такие пляски?

ну, я думал ты мое мнение спрашиваешь?
а раз оно тебе похер, тогда извини...

>на мой взгляд, излишества...

и в где излишества?
читай внимательнее пост #2 - и правильно и без излишеств
boriss
26.05.2010, 20:29:49
Ответить #6
Кому: Del, #3

а вот приватное поле

> FEnabled: Boolean;

явное излишество...
Del
26.05.2010, 20:33:43
Ответить #7
Кому: boriss, #5

Борис, оно как? По моему методу работать не будет? Мнение - не по хер, нет. Просто я пытаюсь осознать - зачем ты такое количество кода нафигачил?
Del
26.05.2010, 20:37:59
Ответить #8
Кому: boriss, #1

Да, и ББкоды тут не работают :)
boriss
26.05.2010, 20:51:03
Ответить #9
Кому: Del, #7

Да что-ж ты так болезненно-то отнесся к моему замечанию?...

> По моему методу работать не будет?
будет. визуально получится именно то, что и задумывалось...
логически не все правильно, и я это описал

> зачем ты такое количество кода нафигачил?
3 метода, практически абсолютно пустые - это до хера кода?

да и ты вон сам сказал, что часть кода просто забыл вписать... подозреваю, что это не все...

а вот FEnabled -- это точно лишнее, я в своем последнем комменте так и указал...

Кому: Del, #8
да это я по привычке и глубокую надеждою... :)

Оставить коммент

Представьтесь
Введите три 2иф65
Комментарий:
Карта сайта
Новое
Картинки

Ужасы нашего городка

Зверски убитый манекен

Ванкувер, Канада
Все картинки »
Статьи
Bvlgari купить часы от bvlgari купить часы. Купить часы Bvlgari. | Змеиный каньон Lego Racers лего 8896, Лего Мировые гонки 8896 заказать лего Мировые гонки