CnPack Forum


 
Subject: 一个极其简单的自画的CheckBox
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6758
Posts 3555
点点分 6758
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2008-4-28 16:22  Profile | Blog | P.M. 
一个极其简单的自画的CheckBox

应York.W的求助,要实现一个非标准的CheckBox,check时为圆形,不check时为方型。但CheckBox组件是继承于WinControl的,本身没有OnPaint也无Paint方法供直接重载,如何画省事呢?

  忽然想到,何必执着于CheckBox?于是从TShape继承了一个组件,哈哈。
  声明:

??TRyCheckBox = class(TShape)
  ??private
  ? ? FChecked: Boolean;
  ? ? FOnChange: TNotifyEvent;
  ??protected
  ? ? procedure DoChanged; virtual;
  ? ? procedure Toggle; virtual;
  ? ? procedure Click; override;
  ??public
  ? ? property OnChange: TNotifyEvent read FOnChange write FOnChange;
  ? ? property Checked: Boolean read FChecked write FChecked;
  ??end;

实现:

{ TRyCheckBox }

  procedure TRyCheckBox.Click;
  begin
  ??Toggle;
  ??inherited;
  end;

  procedure TRyCheckBox.DoChanged;
  begin
  ??if Assigned(FOnChange) then
  ? ? FOnChange(Self);
  end;

  procedure TRyCheckBox.Toggle;
  begin
  ??FChecked := not FChecked;
  ??if FChecked then
  ? ? Shape := stCircle
  ??else
  ? ? Shape := stRectangle;
  ??DoChanged;
  end;

测试代码:

procedure TForm1.FormCreate(Sender: TObject);
  begin
  ??FCheck := TRyCheckBox.Create(Self);
  ??FCheck.Parent := Self;
  ??FCheck.OnChange := CheckClick;
  end;

  procedure TForm1.CheckClick(Sender: TObject);
  begin
  ??if FCheck.Checked then
  ? ? Caption := 'Checked.'
  ??else
  ? ? Caption := 'Unchecked.';
  end;

简单搞定。

  不过缺点也是显而易见的,首先不是WinControl子类,不支持焦点以及空格切换。其次没有灰色状态。不过能满足基本要求也就够了。
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6758
Posts 3555
点点分 6758
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2008-4-28 16:40  Profile | Blog | P.M. 
啊。有个bug,Checked的写方法应该用SetChecked,内部同步Shape状态。
Top
kendling (小冬)
高级版主
Rank: 8Rank: 8
MyvNet


Medal No.1  
UID 703
Digest Posts 5
Credits 978
Posts 580
点点分 978
Reading Access 101
Registered 2005-2-18
Location 广东
Status Offline
Post at 2008-5-9 15:47  Profile | Site | Blog | P.M.  | QQ | Yahoo!
强!!!




小冬
http://MyvNet.com
Top
jjwwang
普通灌水员
Rank: 2



UID 40594
Digest Posts 0
Credits 50
Posts 22
点点分 50
Reading Access 10
Registered 2008-6-22
Status Offline
Post at 2008-6-26 15:06  Profile | Blog | P.M. 
自绘TCheckBox补充 之 继承TCheckBox自绘

无意之中看到这个贴子, 自己试着弄了弄, 一时疏忽大意. 竟绕了个大圈子. 值得高兴的就是最终实现了.

unit Unit1;

interface

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

type
??TForm1 = class(TForm)
? ? BitBtn1: TBitBtn;
? ? CheckBox1: TCheckBox;
? ? Memo1: TMemo;
? ? Edit1: TEdit;
? ? procedure FormCreate(Sender: TObject);
??private
??public
??end;

??TMyCheckBox = class(TCheckBox)
??private
? ? FCanvas: TCanvas;
??protected
? ? procedure CNMeasureItem(var Message: TWMMeasureItem); message CN_MeasureItem;
? ? procedure CNDrawItem(var Message: TWMDrawItem); message CN_DrawItem;
? ? procedure DrawItem(const DrawItemStruct: TDrawItemStruct);
??public
? ? constructor Create(AOwner: TComponent); override;
? ? destructor Destroy; override;
? ? procedure CreateParams(var Params: TCreateParams); override;
??end;

var
??Form1: TForm1;

implementation

{$R *.dfm}
procedure TMyCheckBox.CNDrawItem(var Message: TWMDrawItem);
begin
??DrawItem(Message.DrawItemStruct^);
end;

procedure TMyCheckBox.CNMeasureItem(var Message: TWMMeasureItem);
begin
??with Message.MeasureItemStruct^ do
??begin
? ? itemWidth := Width;
? ? itemHeight := Height;
??end;
end;

constructor TMyCheckBox.Create(AOwner: TComponent);
begin
??inherited Create(AOwner);
??ControlStyle := [csSetCaption, csDoubleClicks];
??Checked := True;
??FCanvas := TCanvas.Create;
??Caption := 'TMyCheckBox';
??Width := 160;
??Height := 20
end;

procedure TMyCheckBox.CreateParams(var Params: TCreateParams);
begin
??inherited CreateParams(Params);
??with Params do
??begin
? ? //这块很关键, 就是这绕了个大圈子. 结果一直拦到CM_DrawItem消息.
? ? Style := Style xor BS_3STATE xor BS_MULTILINE;
? ? Style := Style or BS_OWNERDRAW;
??end;
end;

destructor TMyCheckBox.Destroy;
begin
??FCanvas.Free;
??inherited;
end;

procedure TMyCheckBox.DrawItem(const DrawItemStruct: TDrawItemStruct);
var
??R: TRect;
??DrawR, TextR: TRect;
begin
??FCanvas.Handle := DrawItemStruct.hDC;
??FCanvas.Pen.Width := 2;
??R := ClientRect;

??DrawR.Left := R.Left;
??DrawR.Top := R.Top;
??DrawR.Right := 20;
??DrawR.Bottom := R.Bottom;

??TextR.Left := R.Left + DrawR.Right;
??TextR.Top := R.Top;
??TextR.Right := R.Right;
??TextR.Bottom := R.Bottom;

??if Self.Checked then
? ? FCanvas.Brush.Color := clRed
??else
? ? FCanvas.Brush.Color := clWhite;
??FCanvas.Pen.Color := clBlack;
??FCanvas.Ellipse(DrawR);
??FCanvas.Brush.Style := bsClear;
??FCanvas.Font.Size := 12;
??FCanvas.TextRect(TextR, 22, 2, Caption);
??//DrawText(FCanvas.Handle, PChar(Caption), Length(Caption), TextR, DT_CENTER or DT_VCENTER);
??FCanvas.Handle := 0;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
??with TMyCheckBox.Create(Self) do
??begin
? ? Parent := Self;
? ? Left := 0;
??end;
end;

end.
Top
jjwwang
普通灌水员
Rank: 2



UID 40594
Digest Posts 0
Credits 50
Posts 22
点点分 50
Reading Access 10
Registered 2008-6-22
Status Offline
Post at 2008-6-26 15:08  Profile | Blog | P.M. 
基本上就是这样,但还是有点小问题:
一是画的不好看 二是单击的过快了就....点点看就知道了. 呵.
Top
 




All times are GMT++8, the time now is 2024-4-27 06:50

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.0.0  © 2001-2006 Comsenz Inc.
Processed in 0.007535 second(s), 7 queries , Gzip enabled

Clear Cookies - Contact Us - CnPack Website - Archiver - WAP