0

I am trying to create a custom checklist component with some added functionalities from Orpheus component(TOvcCheckList) and some UI enhancements. I require some help on creating a CheckList which looks like as in the image,

For achieving this design as of now we didn't design any custom component but we tried by putting a cxGroupBox and on top of group box we have added cxCheckList and implemented the functionality. But now we are requested to create a component so that the need of writing the functionality every where will be reduced.

Tried below source for achieving the design is below. enter image description here

unit DxSelectallGroupBox;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, cxContainer, cxEdit, cxCustomListBox,
  cxCheckListBox, cxGraphics, cxControls, cxLookAndFeels, cxLookAndFeelPainters, cxPC, dxDockPanel, dxDockControl,
  Vcl.StdCtrls, cxGroupBox, cxCheckBox, dxBevel, System.ImageList, Vcl.ImgList,
  Vcl.CheckLst,Imagelistmodule;

type
  TDxSelectallGroupBox = class(TcxCustomGroupBox)
  private
    { Private declarations }
    fGBSelectAll: TcxGroupBox;
    fGBCheckList: TcxGroupBox;
    fCxCheckList: TcxCheckListBox;
    fDxBevel: TdxBevel;
    fCxCheckSelectAll: TcxCheckListBox;
  protected
    { Protected declarations }
  public
    { Public declarations }
     constructor Create(AOwner: TComponent); override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Test Components', [TDxSelectallGroupBox]);
end;

{ TDxChecklistGroupBox }

constructor TDxSelectallGroupBox.Create(AOwner: TComponent);
begin
   inherited;
  SetBounds(Left, Top, 140, 120);
  fGBSelectAll := TcxGroupBox.Create(self);
  fGBSelectAll.Parent := Twincontrol(AOwner);
  fGBSelectAll.SetBounds(10, 10, width, 185);
  fGBSelectAll.Align := alNone;
  fGBSelectAll.Alignment := alTopLeft;

  fCxCheckSelectAll := TcxCheckListBox.Create(Self);
  fCxCheckSelectAll.Parent := fGBSelectAll;

  FdxBevel := Tdxbevel.Create(Self);
  FdxBevel.Parent := fGBSelectAll;

  FgbCheckList := TcxGroupBox.Create(Self);
  FgbCheckList.Parent := fGBSelectAll;

  fCxCheckList := TcxCheckListBox.Create(Self);
  fCxCheckList.Parent := FgbCheckList;

  with fGBSelectAll do begin
    PanelStyle.Active := True;
    ParentBackground := False;
    ParentColor := False;
    Style.BorderColor := 15065047;
    Style.BorderStyle := ebsSingle;
    Style.Color := clWhite;
    Style.LookAndFeel.NativeStyle := False;
    TabOrder := 0;
  end;
    with FdxBevel do begin
      Left := 2;
      Top := 38;
      Width := 181;
      Height := 1;
      Align := alTop;
      AutoSize := True;
      LookAndFeel.NativeStyle := False;
    end ;
    with FgbCheckList do begin
      Left := 2 ;
      Top := 39;
      Align := alClient;
      PanelStyle.Active := True;
      ParentBackground := False;
      Style.BorderStyle := ebsNone;
      Style.LookAndFeel.NativeStyle := False;
      StyleDisabled.LookAndFeel.NativeStyle := False;
      TabOrder := 0;
      Height := 121;
      Width := 181;
    end;
      with fCxCheckList do begin
        Left := 2;
        Top := 2;
        Width := 177;
        Height := 117;
        Margins.Left := 5;
        Margins.Top := 0;
        Margins.Right := 0;
        Margins.Bottom := 0;
        Align := alClient;
        ParentFont := False;
        Style.BorderStyle := cbsNone;
        Style.Color := clWhite;
        Style.Font.Charset := ANSI_CHARSET;
        Style.Font.Color := 7697781;
        Style.Font.Height := -16;
        Style.Font.Name := 'Noto Sans';
        Style.Font.Style := [];
        Style.HotTrack := True;
        Style.LookAndFeel.NativeStyle := False;
        TabOrder := 0;
        additem('One');
        additem('Two');
        additem('Three');
        showchecks:=true;
    end;
    with fCxCheckSelectAll do
    begin
      AlignWithMargins := True;
      Left := 5;
      Top := 5 ;
      Width := 175 ;
      Height := 30 ;
      Align := alTop;
      ParentFont := False ;
      Style.BorderStyle := cbsNone;
      Style.Font.Charset := ANSI_CHARSET;
      Style.Font.Color := 7697781;
      Style.Font.Height := -16 ;
      Style.Font.Name := 'Noto Sans';
      Style.Font.Style := [] ;
      Style.LookAndFeel.NativeStyle := False;
      StyleDisabled.BorderStyle := cbsNone;
      TabOrder := 1 ;
      additem('Select All');
      Showchecks :=True;
    end;


end;

end.

After installing the component I am getting like which looks like below enter image description here

Can anyone helping in correcting my source and put me in right direction? Thank you.

UPDATE

I found the root cause of the error and fixed the Control '' has no parent window. When I install and try to drop the component on form it is giving the error like Access violation at address 1D405F2E in module 'cxLibraryRS25.bpl'. Write of 'address 00000090`

userhi
  • 553
  • 1
  • 7
  • 27
  • Btw, you might want to do some tutorial, like [this oldie](http://etutorials.org/Programming/mastering+delphi+7/Part+II+Delphi+Object-Oriented+Architectures/Chapter+9+Writing+Delphi+Components/Creating+Compound+Components/) on building compound components (AKA [composite controls](https://stackoverflow.com/questions/10902749/is-it-wise-to-create-composite-controls)) – GolezTrol May 02 '19 at 10:02

2 Answers2

1
fGBSelectAll.Parent := Twincontrol(AOwner);

There you're putting fGBSelectAll on the owner of your compound control. That owner is typically the form. So instead of putting the sub-groupbox in the main-groupbox, you're putting it outside of it, straight on the form.

Solution: Use Self, which refers to the instance of the TDxSelectallGroupBox instance itself.

fGBSelectAll.Parent := Self;
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • I tried the same But I am getting error when i drop the component on form Error is `Control '' has no parent window.` Should I have to change all this statements to `self` ' fCxCheckSelectAll := TcxCheckListBox.Create(Self); ' ` fCxCheckSelectAll.Parent := fGBSelectAll; ` ` FdxBevel := Tdxbevel.Create(Self); ` ` FdxBevel.Parent := fGBSelectAll; ` ` FgbCheckList := TcxGroupBox.Create(Self); ` ` FgbCheckList.Parent := fGBSelectAll; ` ` fCxCheckList := TcxCheckListBox.Create(Self); ` ` fCxCheckList.Parent := FgbCheckList;` – userhi May 02 '19 at 11:21
  • I think the others are okay. Regarding the error, it's related to the parent not having handle yet. You could move the settings of the parent, or the whole creation of the controls to another method. This is demonstrated in [this question](https://stackoverflow.com/questions/23316113/control-has-no-parent-window-error) and [this question](https://stackoverflow.com/questions/6403217/how-to-set-a-tcustomcontrols-parent-in-create). Long story short, you could override `Loaded`, `SetParent`, or even `CreateWindowHandle` to set the parent of the sub-components at the right time. – GolezTrol May 02 '19 at 11:22
0

The below code is creating the component as required

unit DxSelectallGroupBox;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, cxContainer, cxEdit, cxCustomListBox,
  cxCheckListBox, cxGraphics, cxControls, cxLookAndFeels, cxLookAndFeelPainters, cxPC, dxDockPanel, dxDockControl,
  Vcl.StdCtrls, cxGroupBox, cxCheckBox, dxBevel, System.ImageList, Vcl.ImgList,
  Vcl.CheckLst, cxListView;

type
  TDxSelectallGroupBox = class(TcxCustomGroupBox)
  private
    { Private declarations }
    fGBSelectAll: TcxGroupBox;
    fGBCheckList: TcxGroupBox;
    fCxCheckList: TcxCheckListBox;
    fDxBevel: TShape;
    fCxCheckSelectAll: TcxCheckBox;
  protected
    { Protected declarations }
  public
    { Public declarations }
     constructor Create(AOwner: TComponent); override;         
  published
    { Published declarations }

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Test Components', [TDxSelectallGroupBox]);
end;

{ TDxChecklistGroupBox }

constructor TDxSelectallGroupBox.Create(AOwner: TComponent);
begin
  inherited;
  Parent := TWinControl(AOwner);
  SetBounds(Left, Top, 140, 120);
  Height := 200;
  Width := 200;
  fGBSelectAll := TcxGroupBox.Create(self);
  fGBSelectAll.Parent := self;
  fGBSelectAll.SetBounds(1, 1, width, 199);
  fGBSelectAll.Align := alNone;
  fGBSelectAll.Alignment := alTopLeft;

  fCxCheckSelectAll := TcxCheckBox.Create(Self);
  fCxCheckSelectAll.Parent := fGBSelectAll;

  FdxBevel := TShape.Create(Self);
  FdxBevel.Parent := fGBSelectAll;

  FgbCheckList := TcxGroupBox.Create(Self);
  FgbCheckList.Parent := fGBSelectAll;

  fCxCheckList := TcxCheckListBox.Create(Self);
  fCxCheckList.Parent := FgbCheckList;

  Style.BorderColor := 15065047;
  Style.BorderStyle := ebsSingle;
  Style.Color := clWhite;
  Style.LookAndFeel.NativeStyle := False;

  with fGBSelectAll do begin
    PanelStyle.Active := True;
    ParentBackground := False;
    ParentColor := False;
    Style.BorderColor := 15065047;
    Style.BorderStyle := ebsSingle;
    Style.Color := clWhite;
    Style.LookAndFeel.NativeStyle := False;
    TabOrder := 0;
    Width := 199;
  end;
    with FdxBevel do begin
      Left := 0;
      Top := 38;
      Width :=300;
      Height := 1;
      Align := alTop;
      Pen.Color := 15065047;
    end ;
    with FgbCheckList do begin
      Left := 2 ;
      Top := 39;
      Align := alClient;
      PanelStyle.Active := True;
      ParentBackground := False;
      Style.BorderStyle := ebsNone;
      Style.LookAndFeel.NativeStyle := False;
      StyleDisabled.LookAndFeel.NativeStyle := False;
      TabOrder := 0;
      Height := 200;
      Width := 200;
    end;
      with fCxCheckList do begin
        Left := 2;
        Top := 2;
        Width := 200;
        Height := 117;
        Margins.Left := 5;
        Margins.Top := 0;
        Margins.Right := 0;
        Margins.Bottom := 0;
        Align := alClient;
        ParentFont := False;
        Style.BorderStyle := cbsNone;
        Style.Color := clWhite;
        Style.Font.Charset := ANSI_CHARSET;
        Style.Font.Color := 7697781;
        Style.Font.Height := -16;
        Style.Font.Name := 'Noto Sans';
        Style.Font.Style := [];
        Style.HotTrack := True;
        Style.LookAndFeel.NativeStyle := False;
        StyleFocused.BorderStyle := cbsNone;
        StyleHot.BorderStyle := cbsNone;
        TabOrder := 0;
        additem('One');
        additem('Two');
        additem('Three');
        showchecks:=true;
    end;
    with fCxCheckSelectAll do
    begin
      AlignWithMargins := True;
      Left := 5;
      Top := 5 ;
      Width := 200 ;
      Height := 30 ;
      Align := alTop;
      ParentFont := False ;
      Style.BorderStyle := ebsSingle;
      Style.BorderColor := 15065047;
      Style.Font.Charset := ANSI_CHARSET;
      Style.Font.Color := 7697781;
      Style.Font.Height := -16 ;
      Style.Font.Name := 'Noto Sans';
      Style.Font.Style := [] ;
      Style.LookAndFeel.NativeStyle := False;
      StyleDisabled.BorderStyle := ebsSingle;
      StyleHot.BorderStyle := ebsSingle;
      TabOrder := 1 ;
      Caption := 'Select All';
    end;
end;
userhi
  • 553
  • 1
  • 7
  • 27