上面是一个小小的例子(我不是来臭屁的,只是大家讨论), 几个特别的地方: procedure TFloatEdit.CreateParams(var Params: TCreateParams); const Alignments: array[Boolean, TAlignment] of DWORD = ((ES_LEFT, ES_RIGHT, ES_CENTER),(ES_RIGHT, ES_LEFT, ES_CENTER));begin inherited CreateParams(Params); with Params do begin Style := Style or Alignments[UseRightToLeftAlignment, FTextAlign]; end; end; 上面这个过程是用来下定义控件风格的,其实在上面代码上可以不需要重载这个过程, 我只是为了好看而已! procedure TFloatEdit.SetTextAlign(Value:TAlignment); begin FTextAlign:=Value; RecreateWnd; end; 上面这个过程改变控件的显示风格,然后重建控件句柄,这是因为DELPHI的VCL的机制(也可以使用API SetClassLong来设置)在改变风格时可以使用ReCreateWnd方法来重建控件句柄,以使用控件的新风格生效!注意这是DELPHI的机制! function TFloatEdit.DoKeyPress(var Message: TWMKey): Boolean; begin Result:=false; Message.Result:=1; if not(Char(Message.CharCode) in ['0'..'9','.'])and not (Message.CharCode in [VK_BACK]) then // if (Message.CharCode<$30)or(Message.CharCode >$39)or (Char(Message.CharCode)<>'.') then begin Message.Result:=0; Result:=true;//函数返回值,别和上面的Message.Result混了 end; end; 上面这个过程说明的问题是: 当消息(TMessage对象的返回值(Result)域为0时表示该消息已经被处理,也就是对后面的过程说:你们都不用处理这条消息了,我已经做了该做了(对于上面的过程说,就是,如果是BACKSAPCE,数字和小数点我就留下用,其它的我不要,Result返回0) 我的代码可能不是最简单的,希望大家指点!
// if (Message.CharCode<$30)or(Message.CharCode >$39)or (Char(Message.CharCode)<>'.') then这一句不要
2、oo的概念要很好
3、先看oo的东西,再看VCL原代码
2:要了解面向对象的机制
3:了解windows的消息
哥哥,你说的好大概哟?
能不能说具体点呢?
http://www2.4tb.net/tghd.asp?name=dgfhz
可以省去一些重复性的操作,将复杂的操作封装成一个组件,
要写好组件关键是理解OOP的思想,同时对WIN API,算法要熟悉。
http://expert.csdn.net/Expert/topic/2294/2294007.xml?temp=.2849542
这是CDSoftwareWj(95927)兄给的答案:
1.《Delphi5 程序员开发指南》 要看会消息处理部分和类部分
2. 看VCL源代码
3. 再看第三方开源组件源代码
4. 都会了你就成达人了 hehe^^
国内有几本书都是扫土的说说不痛不痒的,看了也白看.....
也许你可以借鉴
对你开发软件的需求
对WINDOWS的消息处理能力
最后写出你想要的控件。
Windows, Messages, SysUtils, Classes,StdCtrls,Controls,Forms;type
TFloatEdit = class(TCustomEdit)
private
{ Private declarations }
FPrecision:Integer;
FTextAlign:TAlignment;
//procedure SetPrecision(value:Integer);
procedure SetTextAlign(value:TAlignment);
procedure WMChar(var Message: TWMChar); message WM_CHAR;
protected
{ Protected declarations }
function DoKeyPress(var Message: TWMKey): Boolean;
public
{ Public declarations }
constructor Create(AOwner:TComponent);override;
procedure CreateParams(var Params: TCreateParams); override;
published
{ Published declarations }
property Precision:Integer read FPrecision write FPrecision default 2;
property TextAlign:TAlignment read FTextAlign write SetTextAlign default taRightJustify;
property Anchors;
property AutoSelect;
property AutoSize;
property BorderStyle;
property CharCase;
property Color;
property Constraints;
property DragMode;
property Enabled;
property Font;
property HideSelection;
property MaxLength;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly;
property ShowHint;
property TabOrder;
property TabStop;
property Text;
property Visible;
property OnChange;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
end;
procedure Register;
implementation
uses Tools;
{
VK_NUMPAD0 0 key (numeric keypad)
VK_NUMPAD1 1 key (numeric keypad)
VK_NUMPAD2 2 key (numeric keypad)
VK_NUMPAD3 3 key (numeric keypad)
VK_NUMPAD4 4 key (numeric keypad)
VK_NUMPAD5 5 key (numeric keypad)
VK_NUMPAD6 6 key (numeric keypad)
VK_NUMPAD7 7 key (numeric keypad)
VK_NUMPAD8 8 key (numeric keypad)
VK_NUMPAD9 9 key (numeric keypad)
}
function TFloatEdit.DoKeyPress(var Message: TWMKey): Boolean;
begin
Result:=false;
Message.Result:=1;
if not(Char(Message.CharCode) in ['0'..'9','.'])and not (Message.CharCode in [VK_BACK]) then
// if (Message.CharCode<$30)or(Message.CharCode >$39)or (Char(Message.CharCode)<>'.') then
begin
Message.Result:=0;
Result:=true;
end;
end;
procedure TFloatEdit.WMChar(var Message:TWMKey);
begin
if not DoKeyPress(Message) then inherited;
end;procedure TFloatEdit.CreateParams(var Params: TCreateParams);
const
Alignments: array[Boolean, TAlignment] of DWORD =
((ES_LEFT, ES_RIGHT, ES_CENTER),(ES_RIGHT, ES_LEFT, ES_CENTER));begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or Alignments[UseRightToLeftAlignment, FTextAlign];
end;
end;
procedure TFloatEdit.SetTextAlign(Value:TAlignment);
begin
FTextAlign:=Value;
RecreateWnd;
end;
constructor TFloatEdit.Create(AOwner:TComponent);
begin
inherited Create(AOwner);end;
procedure Register;
begin
RegisterComponents('abc',[TFloatEdit]);
end;end.
几个特别的地方:
procedure TFloatEdit.CreateParams(var Params: TCreateParams);
const
Alignments: array[Boolean, TAlignment] of DWORD =
((ES_LEFT, ES_RIGHT, ES_CENTER),(ES_RIGHT, ES_LEFT, ES_CENTER));begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or Alignments[UseRightToLeftAlignment, FTextAlign];
end;
end;
上面这个过程是用来下定义控件风格的,其实在上面代码上可以不需要重载这个过程,
我只是为了好看而已!
procedure TFloatEdit.SetTextAlign(Value:TAlignment);
begin
FTextAlign:=Value;
RecreateWnd;
end;
上面这个过程改变控件的显示风格,然后重建控件句柄,这是因为DELPHI的VCL的机制(也可以使用API SetClassLong来设置)在改变风格时可以使用ReCreateWnd方法来重建控件句柄,以使用控件的新风格生效!注意这是DELPHI的机制!
function TFloatEdit.DoKeyPress(var Message: TWMKey): Boolean;
begin
Result:=false;
Message.Result:=1;
if not(Char(Message.CharCode) in ['0'..'9','.'])and not (Message.CharCode in [VK_BACK]) then
// if (Message.CharCode<$30)or(Message.CharCode >$39)or (Char(Message.CharCode)<>'.') then
begin
Message.Result:=0;
Result:=true;//函数返回值,别和上面的Message.Result混了
end;
end;
上面这个过程说明的问题是:
当消息(TMessage对象的返回值(Result)域为0时表示该消息已经被处理,也就是对后面的过程说:你们都不用处理这条消息了,我已经做了该做了(对于上面的过程说,就是,如果是BACKSAPCE,数字和小数点我就留下用,其它的我不要,Result返回0)
我的代码可能不是最简单的,希望大家指点!
你这个控件是为了只输入数值吧.
欢迎各位继续踊跃参加,多劳多得,分数多多,大家不要客气呀
国庆到了,大家快乐
是为了数值,本来是想做个浮点数输入框的