请教一个关于TEdit背景色透明问题(100分)

  • 主题发起人 renaihao
  • 开始时间
R

renaihao

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大侠
我想用TEdit的系统消息机制 拦截 TEdit的画背景 这样能行吗?
如果知道的请说下是哪个消息 消息太多了 找不到。。。
(我不想使用3方控件,也不想继承,不知道拦截好不好使啊)
 
用 CN_CTLCOLOREDIT 消息。
 
能具体说说吗?
 
对不起,没看清题目。请看下面解答(已测试通过)。
 
TForm1 = class(TForm)
Edit1: TEdit;
private
{ Private declarations }
public
// 处理TEdit控件的WM_CTLCOLOREDIT消息。
procedure WmCtlColorEdit(var Msg:TWmCtlColorEdit);
message WM_CTLCOLOREDIT;
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.WmCtlColorEdit(var Msg: TWmCtlColorEdit);
begin
inherited;
//先交回给基类处理其它任务。
// 在这里返回一个空的刷子就可以让TEdit不能填充背景了。
Msg.Result := Integer(GetStockObject(NULL_BRUSH));
end;
 
先创建一个单元 TransEdit:
unit TransEdit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
TWM_RbsInvalidate=WM_USER+1;
type
TransparentEdit = class(TEdit)
private
{ Private declarations }
procedure RbsInvalidate(var Message:TMessage);
message
TWM_RbsInvalidate;
procedure CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
message
CN_CTLCOLOREDIT;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd);
message WM_ERASEBKGND;
procedure WMMove(var Message: TMessage);
message WM_MOVE;
protected
{ Protected declarations }
FTransparent: boolean;
procedure CreateWnd;
override;
procedure CreateParams(var Params: TCreateParams);
override;
proceduredo
Exit;
override;
proceduredo
Enter;
override;
public
{ Public declarations }
constructor Create(AOwner: TComponent);
override;
procedure Invalidate;
override;
published
{ Published declarations }
end;

implementation
constructor TransparentEdit.Create(AOwner:TComponent);
begin
inherited create(AOwner);
ftransparent:=true;
end;

procedure TransparentEdit.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 TransparentEdit.RbsInvalidate(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 TransparentEdit.CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
begin
if FTransparent then
with Messagedo
begin
SetBkMode(ChildDC,Windows.TRANSPARENT);
Result:=GetStockObject(HOLLOW_BRUSH)
end
else
inherited;
end;


procedure TransparentEdit.WMEraseBkgnd(var Message:TWMERASEBKGND);
begin
if FTransparent and not (csDesigning in ComponentState) then
PostMessage(Handle,TWM_RbsInvalidate,0,0)
else
inherited;
end;

procedure TransparentEdit.WMMove(var message:TMessage);
begin
inherited;
if FTransparent then
SendMessage(Handle,TWM_RbsInvalidate,0,0)
else
Invalidate;
end;

procedure TransparentEdit.CreateParams(var Params:TCreateParams);
begin
inherited CreateParams(Params);
if (CsDesigning in ComponentState) then
exit;
with Paramsdo
begin
ExStyle:=ExStyle or WS_EX_TRANSPARENT;
end;
end;

procedure TransparentEdit.DoExit;
begin
inherited;
FTransparent:=true;
SetCursor(0);
RecreateWnd;
end;

procedure TransparentEdit.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 TransparentEdit.Invalidate;
begin
if FTransparent then
SendMessage(Handle,TWM_RbsInvalidate,0,0)
else
inherited;
end;

end.
=================
然后在你需要的地方引用 TransEdit;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TransEdit;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ed: TransparentEdit;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ed := TransparentEdit.Create(Self);
with eddo
begin
Parent := Form1;
Left := 100;
Top := 20;
Text := 'Edit1';
Color := clYellow;
end;
end;

end.
以上已测试通过。
 
用DrawParentImage函数获取EDIT所在父控件的图形,然后在WM_CTLCOLOREDIT时绘制上去这个图形。你把DrawParentImage中坐标计算在调整一下,好像有点不对,原理是对的。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, jpeg, ExtCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
procedure HandleCTLColorEdit(var Msg: TWMCTLCOLOREDIT);message WM_CTLCOLOREDIT;
{ Public declarations }
end;

function DrawParentImage(Sneder:TWinControl):TBitMap;
var
Form1: TForm1;
implementation
{$R *.dfm}
function DrawParentImage(Sneder:TWinControl):TBitMap;
var
iSaveIndex:integer;
Position:TPoint;
begin
result:=TBitMap.Create;
result.Height:=Sneder.Height;
result.Width:=Sneder.Width;
//保存当前场景状态
iSaveIndex:=SaveDC(result.Canvas.Handle);
//获取设备场景的坐标原点
GetViewportOrgEx(Sneder.Handle,Position);
//将设备类型的没映射到窗口原点
SetViewportOrgEx(Sneder.handle,Position.x-Sneder.left,Position.y-Sneder.Top,nil);
//创建一个新的剪切区域
IntersectClipRect(result.Canvas.Handle,0,0,Sneder.Parent.ClientWidth,Sneder.Parent.ClientHeight);
Sneder.Parent.PerForm(WM_ERASEBKGND,result.Canvas.Handle,0);
Sneder.Parent.PerForm(WM_PAINT,result.Canvas.Handle,0);
RestoreDC(Sneder.handle,iSaveIndex);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
edit1.Brush.Bitmap:=DrawParentImage(Edit1);//这里背景图片取image1里的图片
edit1.Repaint;
end;

procedure TForm1.HandleCTLColorEdit(var Msg: TWMCTLCOLOREDIT);
begin

if Msg.ChildWnd = Edit1.Handle then
begin
//设置字体颜色如果需要设置字体颜色用如下语句
SetTextColor(Msg.ChildDC,RGB(255,0,0));
//绘制背景
SetBkMode(Msg.ChildDC, TRANSPARENT);
Msg.Result := Edit1.Brush.Handle;
end;
end;

end.
 

Similar threads

I
回复
0
查看
1K
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
516
import
I
顶部