为何这个edit控件没有光标在里面? ( 积分: 50 )

  • 主题发起人 主题发起人 awfigsk
  • 开始时间 开始时间
A

awfigsk

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;

interface

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

type
TMyEdit=class(TEdit)
private
FAlignment:TAlignment;
procedure WriteAlignment(Value : TAlignment);
protected
procedure CreateParams(var Params: TCreateParams); Override;
publish
property Alignment:TAlignment read FAlignment write WriteAlignment;
end;
TForm1 = class(TForm)
procedure EditEnter(Sender: TObject);
procedure EditExit(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
myedit:TMyEdit;
Form1:Tform1;

implementation

procedure TMyEdit.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.WriteAlignment(Value : TAlignment);
begin
if Value <> FAlignment then
begin
FAlignment := Value;
RecreateWnd;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
myEdit:=TMyEdit.create(self);
myEdit.parent:=self;
myEdit.width:=100;
myedit.top:=100;
myedit.left:=100;
myedit.onenter:=editenter;
myedit.onexit:=editexit;
myedit.visible:=True;
end;
procedure TForm1.EditEnter(Sender: TObject);
begin
MyEdit.Alignment:=taLeftJustify;
end;

procedure TForm1.EditExit(Sender: TObject);
begin
MyEdit.Alignment:=taRightJustify;
end;

以上代码运行后,myedit这个控件对象为何没有光标在里面?我试着用过showcaret函数也没用.
还请各位大富翁指点,谢谢!
 
试试这个
procedure TForm1.formshow(Sender: TObject);
begin
myedit.setfocus;
end;
 
我试过,在开始时有光标,但是当焦点从myedit这个控件中转到其他控件后,再回来,就没有光标了.
 
procedure TMyEdit.WriteAlignment(Value : TAlignment);
begin
if Value <> FAlignment then
begin
FAlignment := Value;
// RecreateWnd; // 你设计的方法将此注销就可以了。
end;
end;
 
-_-!!!
但这样的话,就不能起到我想要的结果,就是我点击该EDIT后,里面的内容是左对齐,当离开该控件时,里面的内容是右对齐.
就与delphi ide中的Envir..option中Designer页中的Grid size设置框的风格一样.我想做成那样,但是上面的代码可以这样,就是光标没了.

还请各位大富翁指点,谢谢!
 
完美答案,请别忘了加分!
procedure TMyEdit.WriteAlignment(Value: TAlignment);
const
Alignments: array[TAlignment] of WORD = (ES_LEFT, ES_RIGHT, ES_CENTER);
begin
if Value <> FAlignment then
begin
FAlignment := Value;
SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) and not (ES_LEFT or ES_CENTER or ES_RIGHT) or
Alignments[FAlignment]); //设置对齐风格
Invalidate; //让系统实施新的风格
end;
end;

procedure TForm1.EditEnter(Sender: TObject);
begin
MyEdit.Alignment := taLeftJustify;
if MyEdit.AutoSelect then //专业与业余的区别就在这里
PostMessage(MyEdit.Handle, EM_SETSEL, 0, -1)
else
PostMessage(MyEdit.Handle, EM_SETSEL, Length(MyEdit.Text), Length(MyEdit.Text));
end;
 
to kinneng:大侠,真是谢谢!用了你代码的确可以了这样.但有些不明白.
因为开始那些代码有些是TCustomMemo中的代码,我试着搬过来,但是一直不能显示出光标.而用你代码代替recreatewnd语句和在enter方法中加入autoselect就可以了,这是为何?

recreatewnd也是重建一个对象,我试着在createparams中继续使用recreatewnd,在enter中加入autoselect判断,还是显示不了光标,只有用你的代码才能显示出来,真是不明白其中的原理.

能详细指点一下吗?万分感谢!
 
这里用recreatewnd是画蛇添足。
 
这里用recreatewnd是画蛇添足
 
kinneng高手!
 
to awfigsk
ReCreateWnd是先撤销旧控件,然后再创建新控件的过程。

你的问题是在控件的事件响应过程程序里面,执行了ReCreateWnd,结果是撤销了控件,
结果就是失控,这是低级错误。

我的代码直接跨过 Delphi 的封装,用 API 直接设置控件的风格,没有撤销控件。

使用 TCustomMemo 也不能够在它的事件里面执行 ReCreateWnd,我相信在 Memo 的
OnEnter 和 OnExit 里面写 Alignment:= ** 一样会失控。

如果你对 ReCreateWnd 情有独钟,非要它不可,或者你想在 Memo 的 OnEnter 和
OnExit 里面控制 Alignment,那么可以加入一个自订消息处理过程,利用它在控件
外部来设置 Alignment。

uses ***;

const
M_ALIGNMENT = WM_USER + 2774;

type

TForm1 = class(TForm)
***
private
procedure MALIGNMENT(var Message: TMessage); message M_ALIGNMENT;
***

procedure TForm1.MALIGNMENT(var Message: TMessage);
begin
case Message.LParam of
0: MyEdit.Alignment := taLeftJustify;
1: MyEdit.Alignment := taRightJustify
end;
MyEdit.SelectAll;
end;

procedure TForm1.EditEnter(Sender: TObject);
begin
//MyEdit.Alignment := taLeftJustify;
PostMessage(Handle, M_ALIGNMENT, 0, 0);
end;

procedure TForm1.EditExit(Sender: TObject);
begin
//MyEdit.Alignment := taRightJustify;
PostMessage(Handle, M_ALIGNMENT, 0, 1);
end;
 
to kinneng:
晕了,为何用了消息,并且用recreatewnd,光标也会出现呢?
大侠,能再指点一下吗?这其中的原理真让我感到糊涂了。谢谢!
 
我更晕,我不怕难题,也不怕高手,我最怕比我菜的,问题多多,已经写得这么清楚,
别说50分,就算加我一万分,我都不知道怎样继续来答你,这是一个很菜的问题,
你都把代码写到那一步,水平不低了,还不理解吗?
总之一句话,凡是涉及到 ReCreateWnd 这话儿,绝对不能在事件响应过程里面执行!
至于如何做,上面我已经给足了代码,而设置Alignment,根本就不需要,也不应该
用ReCreateWnd,跨过 Delphi 的封装,用 API 直接设置就是了。
 
to kinneng:呵呵,真是很感谢您再次回复!
没接触过recreatewnd方法,这还是第一次接触这个方法!
我再结合您的回贴,仔细看看edit和memo的源代码!
 
当ReCreatewnd将控件destroy了,而这时是在onEnter事件中执行对Alignment属性赋值时调用了recreatewnd,由于控件已被destroy,并且重建了,而事件还是重建前的控件,所以也就出现了kinneng大侠所说的&quot;结果就是失控&quot;。
呵,也不知这样理解正确!先暂且这样吧!
再次谢谢kinneng大侠!
 
后退
顶部