-
Скачал компонент TCheckGroupBox, наверняка им многие пользуются, но у меня почему-то при работе с ним есть один баг: если Enabled изначально поставить в false, то при запуске приложения компоненты, которые на нем находятся показываются коббудто они доступны, т.е. коббудто Enabled=true, но нажать на них нельзя.. Помогите..
-
> [0] Dmitry_177 (24.07.07 17:36)
Ты явно не сюда залез с этим вопросом....
> TCheckGroupBox, наверняка им многие пользуются
Я им не пользуюсь и нет его у меня, но..
> есть один баг: если Enabled изначально поставить в false, > то при запуске приложения компоненты, которые на нем находятся > показываются коббудто они доступны, т.е. коббудто Enabled=true, > но нажать на них нельзя..
По всей видимости это не баг, а поведение контейнера. Чьи компоненты? Сам "накидал" на него(TCheckGroupBox) компонентов? или его "внутренние"? Если сам, то оно так и должно быть.... т.е. ты дисаблишь контейнер, а не его содержимое, что вследствии и делает такой эфект "енабленности"... Если "внутренние", то тут нужно смотреть сам компонент, но у меня его.... в общем не здесь этот вопрос решаеться... сорри.
-
{RASkov} ну так я могу его выложить и здесь его всем форумом доработать =) Я чего и написал суда сразу..
-
> [2] Dmitry_177 (24.07.07 19:32)
Если это не "противозаконно" (править чужой компонент), то может просто подробнее опишишь ситуацию, а "кидать" сразу компонент целиком не вижу смысла... Хотя бы ответь на вопросы в [1]... и "укажи свое мнение где ошибка", а там разберемся - опять же - если не противозаконно и по правилам форума :).
-
Я уже сам все сделал =))) Из кода автора практически ничего не осталось, почти весь мой код, т.к. компонент маленький, я его выложу, и т.к. я не так уж силен в разработке компонентов, хотел бы чтобы знающие люди проверили бы его на ошибки.. Сам компонент вроде как работает как надо.. 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.
-
> Чьи компоненты?
Обычные стандартные, входящие в состав Delphi
> Сам "накидал" на него(TCheckGroupBox) компонентов? или его > "внутренние"?
У него нету внутренних
-
Блин, мой тоже глючит..=(( Вот в чем состоит сам баг: кладу на форму TCheckGroupBox, на него всякие кнопочки и т.д. выключаю Checked, чтобы все компоненты были неактивны и сам TCheckGroupBox делаю неактивным(Enabled:=false), т.е. чтобы даже Checked был неактивен.. А его (TCheckGroupBox) включает RadioButton, вобщем это задумка формы такая.. Так вот при запуске программы, в OnCreate считываются настройки и если будет так что нужно отметить Checked, т.е. чтобы он был включенным, но сам TCheckGroupBox неактивет, то получается так что все компоненты коббудто активны(коббудто Enabled=true) но нажать на них нельзя..
-
нужно чтобы компоненты были неактивны.. такое ощущение что они не перерисовываются чтоли..
-
сделал с момента запуска трассировку, отчетливо видно что сначала происходит 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; всеравно такая же история.. впринципе оно так и должно быть, а что еще сделать я не знаю... подскажите пожалуйста...
-
> [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); end;
end; но это не ответ на твой вопрос.... А ответ.... посмотри последовательность действий при клике и установки свойств... ладно... я сильно не разглядывал, но попробуй так: procedure TCheckCustomGroupBox.CheckBoxClick(Sender: TObject);
begin
inherited Click;
SetEnabled(FCGBCheckBox.Checked);
if Assigned(FOnCheckBoxClick) then FOnCheckBoxClick(Self);
end; Но... подумай... есть ли смысл в этом компоненте...
-
> procedure TCheckCustomGroupBox.CheckBoxClick(Sender: TObject); > > begin > inherited Click; > SetEnabled(FCGBCheckBox.Checked); > if Assigned(FOnCheckBoxClick) then FOnCheckBoxClick(Self); > > end;
так не пойдет.. при клике по CheckBox-у все становится недействительныи и сам CheckBox тоже, получается что его потом включить нельзя..
-
и это: SetEnabled(FCGBCheckBox.Checked); при запуске мы не может знать что как там будет выставленно в настройках.. флажек может и снят быть..
-
блин, в Dmitry_177 (24.07.07 22:10) [11] фигню спорол.. необращайте внимания..
-
я там имелл ввиду то что при вызове системой SetEnabled(FCGBCheckBox.Checked); там хранится реальное значение Enabled, а FCGBCheckBox.Checked и Enabled отличаются тут по смыслу.. поэтому это недопустимо.. смотрел последовательность действий, как я уже говорил сначала вызывается CheckBoxClick потом SetEnabled.. т.е. при первом вызове CheckBoxClick мы не знаем реального значения Enabled, оно помоему всегда по умолчанию true, вот и там оно будет true, хотя на самом деле false.. и вот как менять эту последовательность я не знаю, на чем я и застрял.. может это можно еще как-то сделать?
-
> может это можно еще как-то сделать?
Еще раз... если я правильно понял, то незачем этот компонент... Вот: Unitunit 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
public
end;
var
Form1: TForm1;
implementation
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 Оно?
-
оно-то может и оно... но у меня уже сама программа почти сделана с этим компонентом... а она большая, и в ней все это изменять сума сойдешь.. много где я его использовал... а глюк этот только сейчас заметил.. проще будет подделать компонент...
-
> [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] и все.... :)
-
> [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; 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]....
-
работает! :)
{RASkov}, большое тебе спасибо! работает как надо :)))
|