没有人知道!!! (100分)

  • 主题发起人 主题发起人 独孤剑
  • 开始时间 开始时间

独孤剑

Unregistered / Unconfirmed
GUEST, unregistred user!
谁能帮我看看是什么原因啊:
下面的控件,放到TPanel上时,若改变Panel的大小或位置,该控件就会消失,
可能和该控件的透明有点关联,大家研究研究啊

《两个贴,一共200分,谁解决立马给分》

unit MyControls;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, math, Menus;

type
TMyImageControl = Class(TCustomControl)
Private
FText: String;
FBakBitmap: TBitmap;

FMovingBitMap: TBitmap;
FTransparentColor: TColor;
FMargin: Integer;

FModuleName: String;
Function GetText: String;
Procedure SetText(Value: String);
Procedure SetBitmap(Value: TBitmap);
Function GetFont: TFont;
Procedure SetFont(Value: TFont);

procedure WMEraseBkgnd(var Message: TWMEraseBkgnd);message WM_EraseBkgnd;
Protected
Procedure MouseMove(Shift: TShiftState; X,Y: Integer); Override;
Procedure SetBounds(ALeft,ATop,AWidth,AHeight: Integer);Override;
procedure CreateParams(var Params: TCreateParams); Override;
procedure Click; override;
Public
Constructor Create(Aowner: TComponent); Override;
Destructor Destroy; Override;
Procedure Paint; override;
Published
Property Bitmap: TBitmap Read FBakBitmap Write SetBitmap;
Property Font: TFont Read GetFont Write SetFont;
Property Text:String Read GetText Write SetText;
Property OnClick;
Property OnMouseMove;
end;

procedure Register;


implementation

procedure Register;
begin
RegisterComponents('PCP', [TMyImageControl]);
end;


Function TMyImageControl.GetFont: TFont;
begin
Result := Canvas.Font;
end;

Procedure TMyImageControl.SetFont(Value: TFont);
begin
if Value <> nil then
begin
Canvas.Font.Assign(Value);
SetBounds(Left,Top,Width,Height);
Paint;
end;
end;

Function TMyImageControl.GetText: String;
begin
Result := FText;
end;

Procedure TMyImageControl.SetText(Value: String);
begin
if Value <> FText then
begin
FText := Value;
SetBounds(Left, Top, Width, Height);
Paint;
end;
end;

Procedure TMyImageControl.SetBitmap(Value: TBitmap);
begin
if Value <> nil then
begin
FBakBitmap.Assign(Value);
SetBounds(Left,Top,Width,Height);
Paint;
end;
end;

procedure TMyImageControl.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
Message.Result := 1
end;

Procedure TMyImageControl.MouseMove(Shift: TShiftState; X,Y: Integer);
begin
if (GetCapture <> Handle) and PtInRect(ClientRect,Point(X,Y)) then
SetCapture(Handle);
if (GetCapture = Handle) and Not PtInRect(ClientRect,Point(X,Y)) then
ReleaseCapture;

if PtInRect(ClientRect,Point(X,Y)) Then
begin
Screen.Cursor:= crHandPoint;
end else
begin
Screen.Cursor:= crDefault;
end;
inherited MouseMove(Shift,X,Y);
end;

Procedure TMyImageControl.SetBounds(ALeft,ATop,AWidth,AHeight: Integer);
var lTextWidth, lTextHeight: Integer;
begin
if FBakBitmap <> nil then
begin
try
lTextWidth:= Canvas.TextWidth(FText);
lTextHeight:= Canvas.TextHeight(FText);
except
lTextWidth := 0;
lTextHeight := 0;
end;

AWidth := Max(FBakBitmap.Width, lTextWidth);
AHeight := FBakbitmap.Height + lTextHeight+5;

if (AWidth = 0) or (AHeight = 0) then
begin
AWidth:= 60;
AHeight:= 60;
end;
end;

inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;

procedure TMyImageControl.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT;
end;

Constructor TMyImageControl.Create(Aowner: TComponent);
begin
Inherited Create(AOwner);
ControlStyle:= ControlStyle + [csOpaque];
FBakBitmap:= TBitmap.Create;

FBakBitmap.Transparent:= True;
end;

Destructor TMyImageControl.Destroy;
begin
FBakBitmap.Free;

Inherited Destroy;
end;

Procedure TMyImageControl.Paint;
var lBitmap: TBitmap;
lTextWidth: Integer;
begin
lBitMap:= FBakBitmap;

lTextWidth := Canvas.TextWidth(FText);

Canvas.Brush.Color:= Color;
Canvas.FillRect(ClientRect);

SetBkMode(Canvas.Handle, TRANSPARENT);
if lBitmap.Width > lTextWidth then
begin
Canvas.Draw(0, 0, lBitmap);
Canvas.TextOut((lBitmap.Width - lTextWidth) div 2,lBitmap.Height, FText);
end
else begin
Canvas.Draw((lTextWidth - lBitmap.Width) div 2, 0, lbitmap);
Canvas.TextOut(0, lBitmap.Height, FText);
end;
end;

procedure TMyImageControl.Click;
begin
Screen.Cursor:= crDefault;
inherited Click;
end;

end.
 
直接响应消息
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
重载Paint不好,如果重载,你就必须在随时注意刷新控件,响应如控件改变大小,移动位置,被其他窗口挡住等很多消息,重画窗口,否者你画的东西就会消失。如果你从TGraphControl或者TImage继承,就不会有这些问题,可是可能有不符合你的要求,这是由于VCL的封装造成的。

具体地说,就是,如果你的控件大小变化,不一定会触发Paint函数,但一定会触发
WM_PAINT消息,虽然不触发Paint函数,但是父窗口它会重绘背景,这样你的控件就更消失
了一样,当然其实还在
 
这个问题奇怪,后来我测试了一下,该控件得不到WM_PAINT消息,甚至得不到任何消息。
但如果没有
Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT;
这句就没事,有它就不行。
看来得从WS_EX_TRANSPARENT这个属性上着手
 
》SS2000
谢谢你的回答,其实就是控件透明(Image透明)的原因,我已经实现它了,可惜就是这个问题一直困扰我很久
不知道到底问题出在哪里
曾经有一个帖子几乎让我看到了希望,是一个叫Another_eYes说的那段话:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=0359380

但是我是试过了,照着他的说法,仍然不行,不知道他有没有看过这个帖子,哎,这个问题得不到解决,始终是个麻烦啊,关键是我想知道到底是什么原因导致的

我以为诸位能够和我一样想知道到底是什么问题,可惜回帖的人太少了,其实大家帮我提前一下就行,顺便关注一下这个帖子也好,

我期待大家的关注——
 
在响应事件里加上MyImageControl.Invalidate;就可以了。至于原因吗~~我也不知道。期待楼下的给出答案
 
csOpaque The control completely fills its client rectangle.
csOpaque这个标志的意思是控件完全占据它本身的客户区,看你的控件中有这么一句:
ControlStyle:= ControlStyle + [csOpaque];
在这种情况下是要求你自己画背景的,如果只是设置了WS_EX_TRANSPARENT让系统来处理,那就应该去掉这个标志,即:
ControlStyle:= ControlStyle - [csOpaque];

如果这样还是不行,你就只能采用自己画背景的方法了。

其实我在你的另一个帖子中已经说的很清楚了。
 
>>thx1180
谢谢,你真是热心啊,回头给你发分
这个问题在大富翁上一直没有得到很好的解决,郁闷啊
 
嗬嗬,我看到了。
最近忙于传奇反外挂,外加做MSMQ通讯和一堆完成端口方面的通讯控件。很久没时间做界面方面的控件了(有一套界面控件写了一半扔那了)。

不过我说的都是我自己的经验,而且是我成功的经验。 遗憾的是有些小毛病,特别是控件移动后有时会造成不刷新或者刷新延时,不过这是操作系统的问题了,我无能为力。

所以我后来就在做不需要ws_ex_transparent标记的wincontrol透明控件,原理很简单--就是所有要透明的wincontrol控件在运行时都是不可见的(设置它的region为(-2,-2,-1,-1))然后通过我的程序自己在form上画出所有的相关显示内容,实现起来非常复杂,特别是处理鼠标操作相关的显示时。 不过现在只做了一点底层的工作,离完成还远着呢,而且看来今年是没时间作者玩意了。
 

Similar threads

后退
顶部