自行建立VCL时碰到的困惑,有自制构件经验的高手请回答。(100分)

  • 主题发起人 主题发起人 hamsoft
  • 开始时间 开始时间
H

hamsoft

Unregistered / Unconfirmed
GUEST, unregistred user!
自行建立VCL时碰到的困惑,有自制构件经验的高手请回答。
某构件属性中有两upGlyph、downGlyph,可装入bmp显示,我继承了该构件,
增加了Glyph 属性,装入bmp后自动对分,一半给upGlyph,另一半给downGlyph。
现在地问题是:在开发环境,给Glyph装入bmp文件后,
upGlyph和downGlyph的确皆分配到bmp的半幅图。
但若在运行中Glyph采用LoadFromFile的方法装入bmp后,没看到效果,使用repaint也没用。
但直接给upGlyph和downGlyph用LoadFromFile装入bmp却能看到效果。
我百思不得其解,只得求助于各位高手。
 
加父窗口
给出代码
 
增加了Glyph 属性,装入bmp后自动对分,一半给upGlyph,另一半给downGlyph。

这段代码是怎么实现的,拿出来看看,才知道怎么解决
 
我猜是不是这样。 你的控件虽然GLYPH属性被分配了一个BMP的资源。
但是在它运行中被建立后,并没有装入那BMP 或是时序不对。
你试试重载 WM_PAINT 消息。 这样当它创建完自己后,在SHOW的时候就会引起WM_PAINT
消息,这时它载入资源,重画自己.
 
某控件是不是可用的?
 
>>装入bmp后自动对分
你自动对分的程序是写在哪个事件里?
 
可能是两幅图片合并时有某些东西少了!
 
unit HSButton;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
VCLBase, epMorph;

type
THSButton = class(TepMorphButton)
private
{ Private declarations }
FGlyph: TBitMap;
BmpTemp: Tbitmap;
procedure SetGlyph(Value: TBitMap);
protected
{ Protected declarations }

public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

published
{ Published declarations }
property Glyph: TBitMap read FGlyph write SetGlyph;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('HSVCL', [THSButton]);
end;

procedure THSButton.SetGlyph(Value: TBitMap);
var
W, H: Integer;
begin
FGlyph.Assign(Value);
if Value = nil then
exit;

W := FGlyph.Width div 3;
H := FGlyph.Height;
Height := H;
Width := W;

BmpTemp.Width := W;
BmpTemp.Height := H;

UpGlyph.Assign(nil);
BmpTemp.Canvas.Draw(0, 0, FGlyph);
UpGlyph.Assign(BmpTemp);

ActiveGlyph.Assign(nil);
BmpTemp.Canvas.Draw(-1 * W, 0, FGlyph);
ActiveGlyph.Assign(BmpTemp);

DownGlyph.Assign(nil);
BmpTemp.Canvas.Draw(-2 * W, 0, FGlyph);
DownGlyph.Assign(BmpTemp);

Xpaint;
end;

constructor THSButton.Create;
begin
inherited Create(AOwner);
FGlyph := TBitMap.Create;
BmpTemp := TBitMap.Create;
end;

destructor THSButton.Destroy;
begin
BmpTemp.free;
FGlyph.Free;
inherited Destroy;
end;

end.

 
这个建议 跟踪一下运行过程.就知道了.看看各个bmp的H,W对不对.
 
我发现在运行中使用
HSButton1.Glyph.LoadFromFile('d:/hamsoft/xp_close.bmp');
caption:=inttostr(HSButton1.DownGlyph.Width);
HSButton1.downGlyph.SaveToFile('d:/d.bmp');
HSButton1.Glyph.SaveToFile('d:/g.bmp');

其结果是
DownGlyph.Width=0,而 g.bmp就是xp_close.bmp,
但d.bmp字节为0,就是说根本上没执行SetGlyph(Value: TBitMap)过程。
奇怪!!!为什么在开发时装入bmp却很正确??有执行SetGlyph(Value: TBitMap)过程。
 
在SetGlyph(Value: TBitMap)过程中一般只写 FGlyph.Assign(Value)
其余的代码是不会被执行的,应该放到其他过程中去。
 
非常感谢lzjnuaa,代码修正如下,在object inspector 中很正常,
但使用HSButton1.Glyph.LoadFromFile('d:/hamsoft/xp_close.bmp')时一定要再加一句
HSButton1.Refresh;

否则不会马上显示,待form 重画时才显示。

看来,分全要给你了。在给之前,我顺便再问一个问题:

我的另一控件,有显示背景图和是否显示二属性。如果我先使用LoadFromFile装入图象,
再设置显示为true,很正常。若在object inspector 也装入再显示也正常,但运行后
却出错,原因是显示已为true,但画图出错,是没位图。若只装入bmp,运行后再设置
显示为true,又正常。

---****--------

unit HSButton;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
VCLBase, epMorph;

type
THSButton = class(TepMorphButton)
private
{ Private declarations }
FGlyph: TBitMap;
BmpTemp: Tbitmap;
procedure SetGlyph(Value: TBitMap);
protected
{ Protected declarations }
procedure PaintFace; override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

published
{ Published declarations }
property Glyph: TBitMap read FGlyph write SetGlyph;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('HSVCL', [THSButton]);
end;

procedure THSButton.SetGlyph(Value: TBitMap);
begin
FGlyph.Assign(Value);
XPaint;
end;

constructor THSButton.Create;
begin
inherited Create(AOwner);
FGlyph := TBitMap.Create;
BmpTemp := TBitMap.Create;
end;

destructor THSButton.Destroy;
begin
BmpTemp.free;
FGlyph.Free;
inherited Destroy;
end;

procedure THSButton.PaintFace;
var
W, H: Integer;
begin

W := FGlyph.Width div 3;
H := FGlyph.Height;

if (W < 10) or (H < 3) then
begin
UpGlyph.Assign(nil);
ActiveGlyph.Assign(nil);
DownGlyph.Assign(nil);
end
else
begin
Height := H;
Width := W;
BmpTemp.Width := W;
BmpTemp.Height := H;

BmpTemp.Canvas.Draw(0, 0, FGlyph);
UpGlyph.Assign(BmpTemp);

BmpTemp.Canvas.Draw(-1 * W, 0, FGlyph);
ActiveGlyph.Assign(BmpTemp);

BmpTemp.Canvas.Draw(-2 * W, 0, FGlyph);
DownGlyph.Assign(BmpTemp);
end;
inherited PaintFace;
end;
end.
 
那好办,原因你自己找吧,解决的办法:
你判断是组件是处于什么状态:用TComponent.ComponentState
 
结束算了。
 
后退
顶部