Конференция "Компоненты" » TCheckGroupBox [D7, WinXP]
 
  • Dmitry_177 (24.07.07 17:36) [0]
    Скачал компонент TCheckGroupBox, наверняка им многие пользуются, но у меня почему-то при работе с ним есть один баг: если Enabled изначально поставить в false, то при запуске приложения компоненты, которые на нем находятся показываются коббудто они доступны, т.е. коббудто Enabled=true, но нажать на них нельзя.. Помогите..
  • {RASkov} © (24.07.07 18:01) [1]
    > [0] Dmitry_177   (24.07.07 17:36)

    Ты явно не сюда залез с этим вопросом....

    > TCheckGroupBox, наверняка им многие пользуются

    Я им не пользуюсь и нет его у меня, но..

    > есть один баг: если Enabled изначально поставить в false,
    > то при запуске приложения компоненты, которые на нем находятся
    > показываются коббудто они доступны, т.е. коббудто Enabled=true,
    > но нажать на них нельзя..

    По всей видимости это не баг, а поведение контейнера.
    Чьи компоненты? Сам "накидал" на него(TCheckGroupBox) компонентов? или его "внутренние"?
    Если сам, то оно так и должно быть.... т.е. ты дисаблишь контейнер, а не его содержимое, что вследствии и делает такой эфект "енабленности"...
    Если "внутренние", то тут нужно смотреть сам компонент, но у меня его.... в общем не здесь этот вопрос решаеться... сорри.
  • Dmitry_177 (24.07.07 19:32) [2]
    {RASkov} ну так я могу его выложить и здесь его всем форумом доработать =) Я чего и написал суда сразу..
  • {RASkov} © (24.07.07 20:07) [3]
    > [2] Dmitry_177   (24.07.07 19:32)

    Если это не "противозаконно" (править чужой компонент), то может просто подробнее опишишь ситуацию, а "кидать" сразу компонент целиком не вижу смысла... Хотя бы ответь на вопросы в [1]... и "укажи свое мнение где ошибка", а там разберемся - опять же - если не противозаконно и по правилам форума :).
  • Dmitry_177 (24.07.07 20:32) [4]
    Я уже сам все сделал =))) Из кода автора практически ничего не осталось, почти весь мой код, т.к. компонент маленький, я его выложу, и т.к. я не так уж силен в разработке компонентов, хотел бы чтобы знающие люди проверили бы его на ошибки.. Сам компонент вроде как работает как надо..

    unit CheckGroupBox;

    interface

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

    type
     TCGBCheckBox = class(TCustomCheckBox)
     published
       property AllowGrayed;
       property Color;
       property Ctl3D;
       property Enabled;
       property ShowHint;
       property State;
       property OnEnter;
       property OnExit;
       property OnKeyDown;
       property OnKeyPress;
       property OnKeyUp;
       property OnMouseDown;
       property OnMouseMove;
       property OnMouseUp;
     end;

     TCheckCustomGroupBox = class(TCustomGroupBox)
     private
       FCGBCheckBox: TCGBCheckBox;
       FOnCheckBoxClick: TNotifyEvent;
       function GetAlignment: TLeftRight;
       procedure SetAlignment(Value: TLeftRight);
       function GetCaption: TCaption;
       procedure SetCaption(Value: TCaption);
       procedure AdjustCheckBounds;
       function GetChecked: boolean;
       procedure SetChecked(Value: boolean);
       procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
     protected
       procedure SetEnabled(Value: Boolean); override;
       procedure CheckBoxClick(Sender: TObject); virtual;
       procedure CreateWnd; override;
     public
       constructor Create(AOwner: TComponent); override;
       destructor Destroy; override;
       property CGBCheckBox: TCGBCheckBox read FCGBCheckBox write FCGBCheckBox;
     published
       property BoxAlignment: TLeftRight read GetAlignment write SetAlignment;
       property Caption: TCaption read GetCaption write SetCaption;
       property Checked: boolean read GetChecked write SetChecked;
       property OnCheckBoxClick: TNotifyEvent read FOnCheckBoxClick write FOnCheckBoxClick;
     end;

     TCheckGroupBox = class(TCheckCustomGroupBox)
     published
       property Align;
       property Anchors;
       property Caption;
       property Color;
       property Ctl3D;
       property DragCursor;
       property DragMode;
       property Enabled;
       property Font;
       property ParentColor;
       property ParentCtl3D;
       property ParentFont;
       property ParentShowHint;
       property PopupMenu;
       property ShowHint;
       property TabOrder;
       property TabStop;
       property Visible;
       property OnClick;
       property OnDblClick;
       property OnDragDrop;
       property OnDragOver;
       property OnEndDrag;
       property OnEnter;
       property OnExit;
       property OnMouseDown;
       property OnMouseMove;
       property OnMouseUp;
       property OnStartDrag;
     end;

    const
     BOXWITH = 19;

    procedure Register;

    implementation

    procedure Register;
    begin
     RegisterComponents('Standard', [TCheckGroupBox]);
    end;

    constructor TCheckCustomGroupBox.Create(AOwner: TComponent);
    begin
     inherited Create(AOwner);
     FCGBCheckBox := TCGBCheckBox.Create(Self);
     with FCGBCheckBox do
       begin
         Parent := Self;
         OnClick := CheckBoxClick;
         Checked := true;
         Left := 6;
         Width := 18;
         inherited Top := 0;
         Caption := '';
       end;
    end;

    destructor TCheckCustomGroupBox.Destroy;
    begin
     FCGBCheckBox.Free;
     inherited Destroy;
    end;

    procedure TCheckCustomGroupBox.CreateWnd;
    begin
     inherited;
     if Caption = '' then
       inherited Text := '';
    end;

    function TCheckCustomGroupBox.GetAlignment: TLeftRight;
    begin
     Result := FCGBCheckBox.Alignment;
    end;

    procedure TCheckCustomGroupBox.SetAlignment(Value: TLeftRight);
    begin
     FCGBCheckBox.Alignment := Value;
    end;

    function TCheckCustomGroupBox.GetCaption: TCaption;
    begin
     Result := FCGBCheckBox.Caption;
    end;

    procedure TCheckCustomGroupBox.SetCaption(Value: TCaption);
    begin
     if (FCGBCheckBox.Left + Canvas.TextWidth(Value) + BOXWITH) < Width then
       begin
         FCGBCheckBox.Caption := Value;
         AdjustCheckBounds;
       end;
    end;

    procedure TCheckCustomGroupBox.SetEnabled(Value: Boolean);
    var
     i: integer;
    begin
     inherited;

     if not Value then
       begin
         for i := 0 to ControlCount - 1 do
           Controls[i].Enabled := false;
       end;

     if Value then
       begin
         for i := 0 to ControlCount - 1 do
           begin
             if Controls[i] is TCGBCheckBox then
               begin
                 Controls[i].Enabled := true;
                 Continue;
               end;
             Controls[i].Enabled := FCGBCheckBox.Checked;
           end;
       end;
    end;

    procedure TCheckCustomGroupBox.CMFontChanged(var Message: TMessage);
    begin
     inherited;
     Canvas.Font := Self.Font;
     FCGBCheckBox.Height := Canvas.TextHeight('ZZ');
     FCGBCheckBox.Top := 0;
     AdjustCheckBounds;
    end;

    procedure TCheckCustomGroupBox.AdjustCheckBounds;
    const
     WordWraps: array[Boolean] of Word = (0, DT_WORDBREAK);
    begin
     FCGBCheckBox.Width := BOXWITH + Canvas.TextWidth(FCGBCheckBox.Caption) + 2;
     FCGBCheckBox.Repaint;
    end;

    function TCheckCustomGroupBox.GetChecked: boolean;
    begin
     Result := FCGBCheckBox.Checked;
    end;

    procedure TCheckCustomGroupBox.SetChecked(Value: boolean);
    begin
     FCGBCheckBox.Checked := Value;
     CheckBoxClick(nil);
    end;

    procedure TCheckCustomGroupBox.CheckBoxClick(Sender: TObject);
    var
     i: integer;
    begin
     inherited Click;
     for i := 0 to ControlCount - 1 do
       begin
         if Controls[i] is TCGBCheckBox then
           Continue;
         Controls[i].Enabled := FCGBCheckBox.Checked;
       end;
     if Assigned(FOnCheckBoxClick) then FOnCheckBoxClick(Self);
    end;

    end.

  • Dmitry_177 (24.07.07 20:33) [5]

    > Чьи компоненты?

    Обычные стандартные, входящие в состав Delphi


    > Сам "накидал" на него(TCheckGroupBox) компонентов? или его
    > "внутренние"?

    У него нету внутренних
  • Dmitry_177 (24.07.07 20:54) [6]
    Блин, мой тоже глючит..=(( Вот в чем состоит сам баг: кладу на форму TCheckGroupBox, на него всякие кнопочки и т.д. выключаю Checked, чтобы все компоненты были неактивны и сам TCheckGroupBox делаю неактивным(Enabled:=false), т.е. чтобы даже Checked был неактивен.. А его (TCheckGroupBox) включает RadioButton, вобщем это задумка формы такая.. Так вот при запуске программы, в OnCreate считываются настройки и если будет так что нужно отметить Checked, т.е. чтобы он был включенным, но сам TCheckGroupBox неактивет, то получается так что все компоненты коббудто активны(коббудто Enabled=true) но нажать на них нельзя..
  • Dmitry_177 (24.07.07 20:56) [7]
    нужно чтобы компоненты были неактивны.. такое ощущение что они не перерисовываются чтоли..
  • Dmitry_177 (24.07.07 21:18) [8]
    сделал с момента запуска трассировку, отчетливо видно что сначала происходит procedure TCheckCustomGroupBox.SetChecked(Value: boolean); т.е. все компоненты "включили", т.к. в OnCreate Checket-у присвается true, а потом идет procedure TCheckCustomGroupBox.SetEnabled(Value: Boolean); который наоборот "выключает" компоненты.. Так вот он почему-то выключить то выключает, а сами они подсвечиваются, что коббудто на них можно нажать.. Я попробовал подправить SetChecked так:
    procedure TCheckCustomGroupBox.SetChecked(Value: boolean);
    begin
    FCGBCheckBox.Checked := Value;
    if Enabled then
     CheckBoxClick(nil);
    end;


    всеравно такая же история.. впринципе оно так и должно быть, а что еще сделать я не знаю... подскажите пожалуйста...
  • {RASkov} © (24.07.07 21:58) [9]
    > [8] Dmitry_177   (24.07.07 21:18)

    Чесное слово.... ужас какойто, я так и не понял, для чего все это... да и еще в виде компонента...
    Не проще ли все это реализовать в программе с уже готовыми(стандартными) компонентами? Так как смысла в "твоем" компоненте не вижу... хотя может и не туда смотрю...(
    Ну а по коду компонента... скажу только, что в методах SetXxxx желательно проверять "старое" значение перед дальнейшем выполнении сего метода, пример:
    procedure TCheckCustomGroupBox.SetChecked(Value: boolean);
    begin
    if FCGBCheckBox.Checked <> Value then begin
      FCGBCheckBox.Checked := Value;
      CheckBoxClick(self); //nil не желательно..
    end;
    end;


    но это не ответ на твой вопрос....
    А ответ.... посмотри последовательность действий при клике и установки свойств... ладно... я сильно не разглядывал, но попробуй так:
    procedure TCheckCustomGroupBox.CheckBoxClick(Sender: TObject);
    begin
    inherited Click;
    SetEnabled(FCGBCheckBox.Checked);
    if Assigned(FOnCheckBoxClick) then FOnCheckBoxClick(Self);
    end;


    Но... подумай... есть ли смысл в этом компоненте...
  • Dmitry_177 (24.07.07 22:07) [10]

    > procedure TCheckCustomGroupBox.CheckBoxClick(Sender: TObject);
    >
    > begin
    > inherited Click;
    > SetEnabled(FCGBCheckBox.Checked);
    > if Assigned(FOnCheckBoxClick) then FOnCheckBoxClick(Self);
    >
    > end;

    так не пойдет.. при клике по CheckBox-у все становится недействительныи и сам CheckBox тоже, получается что его потом включить нельзя..
  • Dmitry_177 (24.07.07 22:10) [11]
    и это: SetEnabled(FCGBCheckBox.Checked); при запуске мы не может знать что как там будет выставленно в настройках.. флажек может и снят быть..
  • Dmitry_177 (24.07.07 22:10) [12]
    блин, в Dmitry_177   (24.07.07 22:10) [11] фигню спорол.. необращайте внимания..
  • Dmitry_177 (24.07.07 22:25) [13]
    я там имелл ввиду то что при вызове системой SetEnabled(FCGBCheckBox.Checked); там хранится реальное значение Enabled, а FCGBCheckBox.Checked и Enabled отличаются тут по смыслу.. поэтому это недопустимо.. смотрел последовательность действий, как я уже говорил сначала вызывается CheckBoxClick потом SetEnabled.. т.е. при первом вызове CheckBoxClick мы не знаем реального значения Enabled, оно помоему всегда по умолчанию true, вот и там оно будет true, хотя на самом деле false.. и вот как менять эту последовательность я не знаю, на чем я и застрял.. может это можно еще как-то сделать?
  • {RASkov} © (24.07.07 22:38) [14]
    > может это можно еще как-то сделать?

    Еще раз... если я правильно понял, то незачем этот компонент...
    Вот:
    Unit
    unit Unit1;
    interface
    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, Grids, StdCtrls;

    type
     TForm1 = class(TForm)
       GroupBox1: TGroupBox;
       CheckBox1: TCheckBox;
       CheckBox2: TCheckBox;
       Edit1: TEdit;
       Button1: TButton;
       procedure CheckBox2Click(Sender: TObject);
       procedure CheckBox1Click(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

    var
     Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.CheckBox2Click(Sender: TObject);
    begin
     GroupBox1.Enabled:=CheckBox2.Checked;
     CheckBox1.Enabled:=GroupBox1.Enabled;
     CheckBox1Click(Sender);
    end;

    procedure TForm1.CheckBox1Click(Sender: TObject);
    var N: Integer;
    begin
     for N := 0 to GroupBox1.ControlCount-1 do
       if GroupBox1.Controls[N]<>CheckBox1 then GroupBox1.Controls[N].Enabled:=CheckBox1.Checked and GroupBox1.Enabled;
    end;

    end.


    DFM:
    object Form1: TForm1
     Left = 192
     Top = 114
     Width = 307
     Height = 206
     Caption = 'Form1'
     Color = clBtnFace
     Font.Charset = DEFAULT_CHARSET
     Font.Color = clWindowText
     Font.Height = -11
     Font.Name = 'MS Sans Serif'
     Font.Style = []
     OldCreateOrder = False
     PixelsPerInch = 96
     TextHeight = 13
     object GroupBox1: TGroupBox
       Left = 8
       Top = 8
       Width = 185
       Height = 105
       Caption = '  '
       TabOrder = 0
       object CheckBox1: TCheckBox
         Left = 13
         Top = -2
         Width = 81
         Height = 17
         Caption = 'CheckBox1'
         Checked = True
         State = cbChecked
         TabOrder = 0
         OnClick = CheckBox1Click
       end
       object Edit1: TEdit
         Left = 16
         Top = 28
         Width = 121
         Height = 21
         TabOrder = 1
         Text = 'Edit1'
       end
       object Button1: TButton
         Left = 32
         Top = 60
         Width = 75
         Height = 25
         Caption = 'Button1'
         TabOrder = 2
       end
     end
     object CheckBox2: TCheckBox
       Left = 16
       Top = 128
       Width = 97
       Height = 17
       Caption = 'CheckBox2'
       Checked = True
       State = cbChecked
       TabOrder = 1
       OnClick = CheckBox2Click
     end
    end


    Оно?
  • Dmitry_177 (24.07.07 22:43) [15]
    оно-то может и оно... но у меня уже сама программа почти сделана с этим компонентом... а она большая, и в ней все это изменять сума сойдешь.. много где я его использовал... а глюк этот только сейчас заметил.. проще будет подделать компонент...
  • {RASkov} © (25.07.07 01:36) [16]
    > [15] Dmitry_177   (24.07.07 22:43)

    Ну и... исходя из [14] следует:
    в твоем компоненте нужно перекрыть метод SetEnabled где:
    procedure TCheckCustomGroupBox.SetEnabled(Value: Boolean);
    begin
     if Enabled<>Value then begin
      inherited;
      FCGBCheckBox.Enabled:=Enabled;
     end;
    end;
    и метод OnClick у ЧекБокса возьми из [14] и все.... :)
  • {RASkov} © (25.07.07 02:03) [17]
    > [16] {RASkov} ©   (25.07.07 01:36)

    Т.е. примерно вот так:
    procedure TCheckCustomGroupBox.SetEnabled(Value: Boolean);
    begin
    if Enabled<>Value then begin
     inherited;
     FCGBCheckBox.Enabled:=Enabled;
     CheckBoxClick(self);
    end;
    end;

    procedure TCheckCustomGroupBox.CheckBoxClick(Sender: TObject);
    var
    i: integer;
    begin
    inherited Click; //незнаю.... вот это вызовет метод Click предка твоего компонента, а не чекбокса в нем
    for i := 0 to ControlCount-1 do
      if Controls[i]<>FCGBCheckBox then Controls[i].Enabled:=FCGBCheckBox.Checked and Enabled;
    if Assigned(FOnCheckBoxClick) then FOnCheckBoxClick(Self);
    end;


    Может где и упустил чего, я это дело не проверял, кроме как [14]....
  • Dmitry_177 (25.07.07 10:41) [18]
    работает! :)

    {RASkov}, большое тебе спасибо! работает как надо :)))
Есть новые Нет новых   [119286   +21][b:0][p:0.006]