关于自写EDIT控件遇到的困惑. (高手们啊)(200)

  • 主题发起人 主题发起人 haiip2000
  • 开始时间 开始时间
H

haiip2000

Unregistered / Unconfirmed
GUEST, unregistred user!
关于自写EDIT控件遇到的困惑(SelStart命令出现在Create和Change事件中导致控件不能被使用)自写了一个关于适用于金额输入的EDIT控件。包括¥符号,右对齐,保留两位小数,数字上千以上加逗号分隔等等。需要响应的事件为KeyPress,Keydown,Change三个。控件写出来编译没有错误,也可以正常安装了。却发觉这个控件不能放到窗体中。在控件栏双击该控件则提示“Control '' has no parent window.”我找了一下“Control '' has no parent window.”的出错原因,也没为找到理想解决方案。这些代码在没有做成控件前确定是没问题的,控件的制作方面也没有问题。我有排除法一条一条的尝试排除,最后确定问题代码出现在我写的控件Change事件中,其中一句 ii := Self.SelStart;这句代码为了获取控件的焦点在第几个字符上,以便于进行字符串处理之后重新定位。--------------------------------------------------------------我看了一下 SelStart 是 TCustomEdit = class(TWinControl)中的property SelStart : Integer read GetSelStart write SetSelStart;其代码为:function TCustomEdit.GetSelStart: Integer;begin SendMessage(Handle, EM_GETSEL, Longint(@Result), 0);end;procedure TCustomEdit.SetSelStart(Value: Integer);begin SendMessage(Handle, EM_SETSEL, Value, Value);end;--------------------------------------------------------------我百思不得其解,SelStart这个命令在KeyPress,Keydown都没有问题,但是在Create和Change中就会导致整个控件不能被使用。高手们给解答解答
 
我用的delphi7 控件模板是:{******************************************************************************}{ }{ Email : zhihuali@163.net }{ Email : lizhihua186@msn.com }{ }{ Date : 2001-12-19 }{ }{******************************************************************************}{ }{ 2002-01-19 : 添加 InputStyle , EnterTab 属性 }{ 2002-01-22 : 添加对齐方式 Alignment }{ }{******************************************************************************}unit StyleEdit;interfaceuses Windows, Messages, SysUtils, Classes, Controls, StdCtrls;type TSetInputStyles = (stString,stInteger,stFloat,stMoney);type TStyleEdit = class(TEdit) private FInputStyle : TSetInputStyles; FAlignment : TAlignment; FEnterTab : Boolean; FOnKeyPress : TKeyPressEvent; procedure SetInputStyle(Value : TSetInputStyles); procedure SetAlignment(Value : TAlignment); procedure SetEnterTab(Value : Boolean); { Private declarations } protected procedure KeyPress(var Key: Char); OverRide; procedure CreateParams(var Params: TCreateParams); OverRide; { Protected declarations } public constructor Create(AOwner : TComponent); OverRide; { Public declarations } published property InputStyle : TSetInputStyles Read FInputStyle Write SetInputStyle Default stString; property Alignment : TAlignment Read FAlignment Write SetAlignment Default taLeftJustify; property EnterTab : Boolean Read FEnterTab Write SetEnterTab Default True; property OnKeyPress : TKeyPressEvent read FOnKeyPress write FOnKeyPress; { Published declarations } end;procedure Register;implementation{******************************************************************************}{ 注册控件 }{******************************************************************************}procedure Register;begin RegisterComponents('LzhComponents', [TStyleEdit]);end;{ TStyleEdit }{******************************************************************************}{ 设置控件属性 }{******************************************************************************}constructor TStyleEdit.Create(AOwner: TComponent);begin inherited; Text := '0';end;{******************************************************************************}{ 设置控件左右对齐方式 }{******************************************************************************}procedure TStyleEdit.CreateParams(var Params: TCreateParams);const Alignments: array[TAlignment] of WORD = (ES_LEFT, ES_RIGHT, ES_CENTER);begin inherited CreateParams(Params); Params.Style := Params.Style or Alignments[FAlignment];end;{******************************************************************************}{ 过滤键盘按键信息 }{******************************************************************************}procedure TStyleEdit.KeyPress(var Key: Char);begin inherited KeyPress(Key); if FEnterTab and (Key = #13) then begin PostMessage(Handle, WM_KEYDOWN, VK_TAB, 0); Key := #0; Exit; end; case FInputStyle of stInteger: if not (Key in ['0'..'9', Chr(8)]) then Key := #0; stFloat: begin if not (Key in ['0'..'9', '.', Chr(8)]) then Key := #0; if (Key = '.') and (Pos(Key, Text) > 0) then Key := #0; end; stMoney: begin if not (Key in ['0'..'9', '.', Chr(8)]) then Key := #0; if (Key = '.') and (Pos(Key, Text) > 0) then Key := #0; if (Pos('.', Text) > 0) and (Key <> Chr(8)) and ((Length(Text) - Pos('.', Text)) >= 2) then Key := #0; end; end;end;{******************************************************************************}{ 设置是否用回车代替 TAB 按键 }{******************************************************************************}procedure TStyleEdit.SetEnterTab(Value: Boolean);begin if FEnterTab <> Value then FEnterTab := Value;end;{******************************************************************************}{ 设置控件的 InputStyle 属性 }{******************************************************************************}procedure TStyleEdit.SetInputStyle(Value : TSetInputStyles);begin if Value <> FInputStyle then FInputStyle := Value;end;{******************************************************************************}{ 设置控件的 Alignment 属性 }{******************************************************************************}procedure TStyleEdit.SetAlignment(Value : TAlignment);begin if Value <> FAlignment then begin FAlignment := Value; RecreateWnd; end;end;end.有心人可以尝试一下啊
 
没人来捧场啊。莫非我的做法违反了什么规则?我自己写事件已经都实现了,却做不成控件......
 
代码写的比较整齐。
 
把要在Create实现的放到CreateWnd中procedure TStyleEdit.CreateWnd;begin inherited CreateWnd; ii := SelStart ...end;Change中 if HandleAllocated then ii := SelStart
 
有些代码在设计期是不能用的。出现你所说的情况很正常。我没法测试你的代码。既然你已经找出问题出在SELSTARTA那么你就在设计期间把他屏蔽了。具体方法是:if componentstate=csDesigning ...这样就能解决你的问题。
 
Edit中,Create里面你调用SelStart ,就象 Form Create 里面你Show;一样,都没有建立,如何操作,至于OnChange其实是可以的,加一个判断条件: Var EditCreated : Boolean = False;procedure OnFormActive(); begin EditCreated:=True; end;procedure oneditchange(); begin if not EditCreated then exit; 其他代码! end;
 
控件终于做出来了。谢谢大家。有时间我会发到上边了请大家指正。谢谢
 
后退
顶部