如何在TEdit中加Button(50分)

  • 主题发起人 主题发起人 x_ws
  • 开始时间 开始时间
X

x_ws

Unregistered / Unconfirmed
GUEST, unregistred user!
请问在TEdit中加Button有哪些方法.
我在CreateParams中加了aButton := TButton.Create(Self)
但是当我双击TEdit时,Button会出现反白.
我想是因为aButton.Parent := TEdit的原因.
 
重绘的区域还是它原来的,很画白了,你可以设置另一种COLOR试试,是否是这个问题
 
button的父不可以是edit的吧??你其实只要固定好那个button的位置,使它在edit上应该
就可以的
 
Constructor TTestEdit.Create(AOwer:TComponent);
Begin
inherited Create(AOwer);
FButton:=TButton.Create(Self);
Fbutton.visible:=true;
Fbutton.parent:=self;
fbutton.height:=....
// 下面插入button相对与edit的位置,通过设置位置属性,应该可以的
 
如果是写控件的话,就继承TPanel,然活在TPanel上放TEDit和TButton.
 
看看D5开发人员指南,上面有这个例子
 
同意bluerain!
 
我就是安葬zhou707兄那样写的.
但是当我输入一些字母,然后双击后全选时,会有白色把Button给遮住.
不过点击Button后又恢复原样.
 
1.你不要从TEdit继承,否则你必须处理Edit重绘消息,很麻烦
2.可以按照D5开发人员指南上所讲的来作
 
你在CREATE里面创建就行了,
 
为什么非要用TEDIT?
用TPANEL立即搞定。
 
>> 你不要从TEdit继承,否则你必须处理Edit重绘消息,很麻烦
>> 但是当我输入一些字母,然后双击后全选时,会有白色把Button给遮住.
可以向 TEdit 发送 EM_SETRECT 消息来设定 Edit 区域。
 
procedure myedit.SetEditRect;
var
Loc: TRect;
begin
SetRect(Loc, 0, 0, ClientWidth - Btn.Width - 2, ClientHeight + 1);
SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
end; // SetEditRect}

procedure myedit.SetBounds(Left, Top, Width, Height : Integer);
begin
case Parent <> nil of
True :
begin
inherited SetBounds(Left, Top, Width, Height);
with Btn do
begin
Left := Self.Width - Btn.Width - 4;
Height := Self.Height - 4;
end;
SetEditRect;//!!!!
end;
False : inherited SetBounds(Left, Top, Width, Height);
end;
end; // SetBounds}

 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, DBGrids, StdCtrls,Mask, DB, Themes;

type
Tpjp = class(TCustomEdit)
private
ButtonWidth:Integer;
FPressed: Boolean;
FTracking: Boolean;
FMouseInControl: Boolean;
FEditStyle: TEditStyle;
procedure WMPaint(var Message: TWMPaint); message wm_Paint;
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SetCursor;
procedure WMCancelMode(var Message: TMessage); message WM_CancelMode;
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
procedure WMKillFocus(var Message: TMessage); message WM_KillFocus;
procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message wm_LButtonDblClk;
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;

protected
procedure CreateParams(var Params: TCreateParams); override;
procedure PaintWindow(DC: HDC); override;
function ButtonRect: TRect;
function OverButton(const P: TPoint): Boolean;
procedure TrackButton(X,Y: Integer);
procedure StopTracking;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure DoEditButtonClick;dynamic;
procedure KeyPress(var Key: Char); override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure BoundsChanged;

public
constructor Create(Owner: TComponent); override;
property Pressed: Boolean read FPressed;
property EditStyle: TEditStyle read FEditStyle write FEditStyle;

end;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Edit1Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
aPJP:Tpjp;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses XPMan;

{$R *.dfm}

{ Tpjp }


procedure Tpjp.BoundsChanged;
var
R: TRect;
begin
R := Rect(0, 0, Width - 2, Height);

if EditStyle <> esSimple then
Dec(R.Right, ButtonWidth+2);


SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@R));
SendMessage(Handle, EM_SCROLLCARET, 0, 0);
if SysLocale.FarEast then
SetImeCompositionWindow(Font, R.Left, R.Top);

end;

function Tpjp.ButtonRect: TRect;
begin
Result := Self.GetClientRect;
Result := Rect(Result.Right - ButtonWidth,2,Result.Right-1,Result.Bottom);

if ThemeServices.ThemesEnabled then
Dec(Result.Left,1);Dec(Result.Top,3);Inc(Result.Right,2);Inc(Result.Bottom,1);

end;

procedure Tpjp.CMMouseEnter(var Message: TMessage);
begin
inherited;

if ThemeServices.ThemesEnabled and not FMouseInControl then
begin
FMouseInControl := True;
Invalidate;
end;

end;

procedure Tpjp.CMMouseLeave(var Message: TMessage);
begin
inherited;
if ThemeServices.ThemesEnabled and FMouseInControl then
begin
FMouseInControl := False;
Invalidate;
end;

end;




constructor Tpjp.Create(Owner: TComponent);
begin
inherited Create(Owner);
ButtonWidth := GetSystemMetrics(SM_CXVSCROLL);
FPressed := False;
EditStyle := esSimple;

end;

procedure Tpjp.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or ES_MULTILINE;

end;

procedure Tpjp.DoEditButtonClick;
begin

ShowMessage('Clicked');

end;



procedure Tpjp.KeyDown(var Key: Word; Shift: TShiftState);
begin
if (EditStyle = esEllipsis) and (Key = VK_RETURN) and (Shift = [ssCtrl]) then
begin
DoEditButtonClick;
//KillMessage(Handle, WM_CHAR);
end
else
inherited KeyDown(Key, Shift);

end;

procedure Tpjp.KeyPress(var Key: Char);
begin
if Key = #13 then Key := #0;

inherited KeyPress(Key);

end;

procedure Tpjp.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
if (Button = mbLeft) and
OverButton(Point(X,Y)) and (EditStyle <> esSimple) then
begin

MouseCapture := True;
FTracking := True;
TrackButton(X, Y);

end;
inherited MouseDown(Button, Shift, X, Y);

end;

procedure Tpjp.MouseMove(Shift: TShiftState; X, Y: Integer);
var
ListPos: TPoint;
MousePos: TSmallPoint;
begin
if FTracking then
begin
TrackButton(X, Y);
ListPos := Point(X, Y);
if PtInRect(ButtonRect, ListPos) then
begin
StopTracking;
MousePos := PointToSmallPoint(ListPos);
SendMessage(Handle, WM_LBUTTONDOWN, 0, Integer(MousePos));
Exit;
end;

end;

inherited MouseMove(Shift, X, Y);

end;

procedure Tpjp.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
var
WasPressed: Boolean;
begin
WasPressed := Pressed;
StopTracking;
if (Button = mbLeft) and WasPressed then
DoEditButtonClick;
inherited MouseUp(Button, Shift, X, Y);

end;

function Tpjp.OverButton(const P: TPoint): Boolean;
begin
Result := PtInRect(ButtonRect, P);
end;

procedure Tpjp.PaintWindow(DC: HDC);
var
R: TRect;
Flags: Integer;
W, X, Y: Integer;
Details: TThemedElementDetails;
begin
if EditStyle <> esSimple then
begin
R := ButtonRect;
Flags := 0;
case EditStyle of
esPickList:
begin
if ThemeServices.ThemesEnabled then
begin
if Pressed then
Details := ThemeServices.GetElementDetails(tcDropDownButtonPressed)
else
if FMouseInControl then
Details := ThemeServices.GetElementDetails(tcDropDownButtonHot)
else
Details := ThemeServices.GetElementDetails(tcDropDownButtonNormal);
ThemeServices.DrawElement(DC, Details, R);
end
else
begin
if Pressed then
Flags := DFCS_FLAT or DFCS_PUSHED;
DrawFrameControl(DC, R, DFC_SCROLL, Flags or DFCS_SCROLLCOMBOBOX);
end;
end;
esEllipsis:
begin
if ThemeServices.ThemesEnabled then
begin
if Pressed then
Details := ThemeServices.GetElementDetails(tbPushButtonPressed)
else
if FMouseInControl then
Details := ThemeServices.GetElementDetails(tbPushButtonHot)
else
Details := ThemeServices.GetElementDetails(tbPushButtonNormal);

ThemeServices.DrawElement(DC, Details, R);
end
else
begin
if Pressed then Flags := BF_FLAT;
DrawEdge(DC, R, EDGE_RAISED, BF_RECT or BF_MIDDLE or Flags);
end;

X := R.Left + ((R.Right - R.Left) shr 1) - 1 + Ord(Pressed);
Y := R.Top + ((R.Bottom - R.Top) shr 1) - 1 + Ord(Pressed);
W := ButtonWidth shr 3;
if W = 0 then W := 1;
PatBlt(DC, X, Y, W, W, BLACKNESS);
PatBlt(DC, X - (W * 2), Y, W, W, BLACKNESS);
PatBlt(DC, X + (W * 2), Y, W, W, BLACKNESS);
end;
end;
ExcludeClipRect(DC, R.Left, R.Top, R.Right, R.Bottom);
end;
inherited PaintWindow(DC);

end;

procedure Tpjp.StopTracking;
begin
if FTracking then
begin
TrackButton(-1, -1);
FTracking := False;
MouseCapture := False;
end;

end;

procedure Tpjp.TrackButton(X, Y: Integer);
var
NewState: Boolean;
R: TRect;
begin
R := ButtonRect;
NewState := PtInRect(R, Point(X, Y));
if Pressed <> NewState then
begin
FPressed := NewState;
InvalidateRect(Handle, @R, False);
end;

end;

procedure Tpjp.WMCancelMode(var Message: TMessage);
begin
StopTracking;
inherited;

end;

procedure Tpjp.WMKillFocus(var Message: TMessage);
begin
if not SysLocale.FarEast then inherited
else
begin
ImeName := Screen.DefaultIme;
ImeMode := imDontCare;
inherited;
ActivateKeyboardLayout(Screen.DefaultKbLayout, KLF_ACTIVATE);
end;

end;

procedure Tpjp.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
with Message do
if OverButton(Point(XPos, YPos)) then
Exit;

DoEditButtonClick;

inherited;

end;

procedure Tpjp.WMPaint(var Message: TWMPaint);
begin
//-------------------
PaintHandler(Message);

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
aPJP := Tpjp.Create(Self);
with aPJP do
begin
Parent := Self;
Left := 10;
Top := 10;
EditStyle := esEllipsis;
end;

end;

procedure Tpjp.WMSetCursor(var Message: TWMSetCursor);
var
P: TPoint;
begin
GetCursorPos(P);
P := ScreenToClient(P);
if (EditStyle <> esSimple) and OverButton(P) then
Windows.SetCursor(LoadCursor(0, idc_Arrow))
else
inherited;

end;

procedure Tpjp.WMSetFocus(var Message: TWMSetFocus);
begin
inherited;
BoundsChanged;

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(aPJP) then aPJP.Free;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
ShowMessage('bbb');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Click;

end;

end.
 
TEdit 不是容器控件,你还是应该从TPanel继承。
 
var
ARect : TRect;
begin
Windows.SetParent(Button1.Handle, Edit1.Handle);
ARect := Edit1.ClientRect;
SendMessage(Edit1.Handle, EM_SETMARGINS, EC_RIGHTMARGIN,
MAKELONG(0,GetSystemMetrics(SM_CXHSCROLL)));
SetWindowPos(Button1.Handle, 0, ARect.right -
GetSystemMetrics(SM_CXHSCROLL), 0,
GetSystemMetrics(SM_CXHSCROLL), ARect.bottom, SWP_DRAWFRAME);
end;
 
用那么麻烦吗?
这样不可以吗?
var
Button: TButton;
begin
Button := TButton.Create(self);
Button.Parent := Edit1;
end;
 
后退
顶部