W
web_lance
Unregistered / Unconfirmed
GUEST, unregistred user!
需增加的属性:
Transparent(True, False) → 透明效果
//Alignment(taLeftJustify, taRightJustify, taCenter) → 水平对齐
Layout(tlTop, tlCenter, tlBottom) → 垂直对齐
要求:
1、属性需在对象监视器的Properties选项卡中出现,对其属性的改变,在设计/运行阶段都能体现;
2、修改后的控件最好做到跟Delphi原有的控件表现一致,如在程序设计/运行时能够动态生成、移动控件时比较流畅等;
参考离线数据库的资料和StdCtrls,尝试为编辑框增加属性,但因本人水平有限,未能一一实现,还望各位仁兄多多帮忙。
(请贴出源码,如果不方便的可发E-mail至weblance@163.com,请注明标题是“控件源码”)
以下是本人借鉴已有的资料修改而成的控件代码:
注:1、水平对齐属性已完全可以实现,各位不必再考虑;
2、垂直对齐属性本人不会实现;
3、透明效果可以实现,但不理想。
具体发现的问题有:
设计阶段 选择多个控件后,选择标记残留在控件上,Transparent=False时控件丢失边框;
运行阶段 若控件获取焦点时也透明(//DoEnter),当修改字符时旧的内容会残留,失去焦点后正常;
(以下源码是发表时贴出,未作更改;上面的说明已作修改)
unit EditPro;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls, Graphics, Forms, Dialogs;
const
TWM_Invalidate = WM_USER+1;
type
TEditPro = class(TEdit)
private
FAlignment: TAlignment;
procedure SetAlignment(Value: TAlignment);
procedure TInvalidate(var Message: TMessage); message TWM_Invalidate;
procedure CNCTLCOLOREDIT(var Message: TWMCTLCOLOREDIT); message CN_CTLCOLOREDIT;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
procedure WMMove(var Message: TMessage); message WM_MOVE;
{ Private declarations }
protected
FTransparent: Boolean;
procedure CreateWnd; override;
procedure CreateParams(var Params: TCreateParams); override;
procedure DoExit; override;
procedure DoEnter; override;
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
procedure Invalidate; override;
{ Public declarations }
published
property Alignment: TAlignment Read FAlignment Write SetAlignment Default taLeftJustify;
{ Published declarations }
end;
procedure Register;
implementation
constructor TEditPro.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FTransparent := True;
end;
procedure TEditPro.CreateWnd;
begin
inherited CreateWnd;
if FTransparent then
begin
SetWindowLong(Parent.Handle, GWL_STYLE,
GetWindowLong(Parent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
end;
end;
procedure TEditPro.SetAlignment(Value: TAlignment);
begin
if Value <> FAlignment then
begin
FAlignment := Value;
RecreateWnd;
end;
end;
procedure TEditPro.TInvalidate(var Message:TMessage);
var
r: TRect;
begin
if (Parent <> nil) and FTransparent then
begin
r := ClientRect;
r.TopLeft := Parent.ScreenToClient(ClientToScreen(r.TopLeft));
r.BottomRight := Parent.ScreenToClient(ClientToScreen(r.BottomRight));
RedrawWindow(Handle, nil, 0, RDW_FRAME + RDW_INVALIDATE);
end;
end;
procedure TEditPro.CNCTLCOLOREDIT(var Message: TWMCTLCOLOREDIT);
begin
if FTransparent then
with Message do
begin
SetBkMode(ChildDC, Windows.TRANSPARENT);
Result := GetStockObject(HOLLOW_BRUSH)
end
else inherited;
end;
procedure TEditPro.WMEraseBkgnd(var Message: TWMERASEBKGND);
begin
if FTransparent and not (csDesigning in ComponentState) then
PostMessage(Handle, TWM_Invalidate, 0, 0)
else inherited;
end;
procedure TEditPro.WMMove(var message: TMessage);
begin
inherited;
if FTransparent then SendMessage(Handle, TWM_Invalidate, 0, 0)
else Invalidate;
end;
procedure TEditPro.CreateParams(var Params: TCreateParams);
const
Alignments: array[TAlignment] of word = (DT_LEFT, DT_RIGHT, DT_CENTER);
begin
inherited CreateParams(Params);
if (CsDesigning in ComponentState) then Exit;
with Params do
begin
Style := Style or Alignments[FAlignment];
ExStyle := ExStyle or WS_EX_TRANSPARENT;
end;
end;
procedure TEditPro.DoExit;
begin
inherited;
FTransparent := True;
SetCursor(0);
RecreateWnd;
end;
procedure TEditPro.DoEnter;
var
exstyle, stdstyle: LongInt;
begin
inherited;
FTransparent := False;
StdStyle:= Windows.GetWindowLong(handle, GWL_EXSTYLE);
exStyle:= StdStyle and not WS_EX_TRANSPARENT;
Windows.SetWindowLong(handle, GWL_EXSTYLE, exStyle);
invalidate;
end;
procedure TEditPro.Invalidate;
begin
if FTransparent then SendMessage(Handle, TWM_Invalidate, 0, 0)
else inherited;
end;
procedure Register;
begin
RegisterComponents('Samples', [TEditPro]);
end;
end.
Transparent(True, False) → 透明效果
//Alignment(taLeftJustify, taRightJustify, taCenter) → 水平对齐
Layout(tlTop, tlCenter, tlBottom) → 垂直对齐
要求:
1、属性需在对象监视器的Properties选项卡中出现,对其属性的改变,在设计/运行阶段都能体现;
2、修改后的控件最好做到跟Delphi原有的控件表现一致,如在程序设计/运行时能够动态生成、移动控件时比较流畅等;
参考离线数据库的资料和StdCtrls,尝试为编辑框增加属性,但因本人水平有限,未能一一实现,还望各位仁兄多多帮忙。
(请贴出源码,如果不方便的可发E-mail至weblance@163.com,请注明标题是“控件源码”)
以下是本人借鉴已有的资料修改而成的控件代码:
注:1、水平对齐属性已完全可以实现,各位不必再考虑;
2、垂直对齐属性本人不会实现;
3、透明效果可以实现,但不理想。
具体发现的问题有:
设计阶段 选择多个控件后,选择标记残留在控件上,Transparent=False时控件丢失边框;
运行阶段 若控件获取焦点时也透明(//DoEnter),当修改字符时旧的内容会残留,失去焦点后正常;
(以下源码是发表时贴出,未作更改;上面的说明已作修改)
unit EditPro;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls, Graphics, Forms, Dialogs;
const
TWM_Invalidate = WM_USER+1;
type
TEditPro = class(TEdit)
private
FAlignment: TAlignment;
procedure SetAlignment(Value: TAlignment);
procedure TInvalidate(var Message: TMessage); message TWM_Invalidate;
procedure CNCTLCOLOREDIT(var Message: TWMCTLCOLOREDIT); message CN_CTLCOLOREDIT;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
procedure WMMove(var Message: TMessage); message WM_MOVE;
{ Private declarations }
protected
FTransparent: Boolean;
procedure CreateWnd; override;
procedure CreateParams(var Params: TCreateParams); override;
procedure DoExit; override;
procedure DoEnter; override;
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
procedure Invalidate; override;
{ Public declarations }
published
property Alignment: TAlignment Read FAlignment Write SetAlignment Default taLeftJustify;
{ Published declarations }
end;
procedure Register;
implementation
constructor TEditPro.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FTransparent := True;
end;
procedure TEditPro.CreateWnd;
begin
inherited CreateWnd;
if FTransparent then
begin
SetWindowLong(Parent.Handle, GWL_STYLE,
GetWindowLong(Parent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
end;
end;
procedure TEditPro.SetAlignment(Value: TAlignment);
begin
if Value <> FAlignment then
begin
FAlignment := Value;
RecreateWnd;
end;
end;
procedure TEditPro.TInvalidate(var Message:TMessage);
var
r: TRect;
begin
if (Parent <> nil) and FTransparent then
begin
r := ClientRect;
r.TopLeft := Parent.ScreenToClient(ClientToScreen(r.TopLeft));
r.BottomRight := Parent.ScreenToClient(ClientToScreen(r.BottomRight));
RedrawWindow(Handle, nil, 0, RDW_FRAME + RDW_INVALIDATE);
end;
end;
procedure TEditPro.CNCTLCOLOREDIT(var Message: TWMCTLCOLOREDIT);
begin
if FTransparent then
with Message do
begin
SetBkMode(ChildDC, Windows.TRANSPARENT);
Result := GetStockObject(HOLLOW_BRUSH)
end
else inherited;
end;
procedure TEditPro.WMEraseBkgnd(var Message: TWMERASEBKGND);
begin
if FTransparent and not (csDesigning in ComponentState) then
PostMessage(Handle, TWM_Invalidate, 0, 0)
else inherited;
end;
procedure TEditPro.WMMove(var message: TMessage);
begin
inherited;
if FTransparent then SendMessage(Handle, TWM_Invalidate, 0, 0)
else Invalidate;
end;
procedure TEditPro.CreateParams(var Params: TCreateParams);
const
Alignments: array[TAlignment] of word = (DT_LEFT, DT_RIGHT, DT_CENTER);
begin
inherited CreateParams(Params);
if (CsDesigning in ComponentState) then Exit;
with Params do
begin
Style := Style or Alignments[FAlignment];
ExStyle := ExStyle or WS_EX_TRANSPARENT;
end;
end;
procedure TEditPro.DoExit;
begin
inherited;
FTransparent := True;
SetCursor(0);
RecreateWnd;
end;
procedure TEditPro.DoEnter;
var
exstyle, stdstyle: LongInt;
begin
inherited;
FTransparent := False;
StdStyle:= Windows.GetWindowLong(handle, GWL_EXSTYLE);
exStyle:= StdStyle and not WS_EX_TRANSPARENT;
Windows.SetWindowLong(handle, GWL_EXSTYLE, exStyle);
invalidate;
end;
procedure TEditPro.Invalidate;
begin
if FTransparent then SendMessage(Handle, TWM_Invalidate, 0, 0)
else inherited;
end;
procedure Register;
begin
RegisterComponents('Samples', [TEditPro]);
end;
end.