delphi – 将透明消息绘制到屏幕提供了超出系统资源
|
我有一个代码,它将消息str直接绘制到屏幕的中心而没有可见的窗口.
为什么首先使用此代码可以正常工作,但是经过几十次调用后,它会提供系统资源. procedure ttsplash.UpdateSplash(const Str: string);
var
R: TRect;
P: TPoint;
S: TPoint;
bm: TBitmap;
bf: TBlendFunction;
EXSTYLE: DWORD;
x,y: integer;
pixel: PRGBQuad;
TextRed,TextGreen,TextBlue: byte;
begin
if str='' then exit;
EXSTYLE := GetWindowLong(Handle,GWL_EXSTYLE);
SetWindowLong(Handle,GWL_EXSTYLE,EXSTYLE or $80000);
R := ClientRect;
bm := TBitmap.Create;
try
bm.PixelFormat := pf32bit;
// bm.SetSize(ClientWidth,ClientHeight);
bm.Width := clientwidth;
bm.height := clientheight;
bm.Canvas.Brush.Color := clBlack;
bm.Canvas.FillRect(ClientRect);
bm.Canvas.Font.Assign(Self.Font);
bm.Canvas.Font.Color := clWhite;
DrawText(bm.Canvas.Handle,PChar(Str),Length(Str),R,DT_SINGLELINE or DT_VCENTER or DT_CENTER or DT_WORD_ELLIPSIS);
TextRed := GetRValue(ColorToRGB(Font.Color));
TextGreen := GetGValue(ColorToRGB(Font.Color));
TextBlue := GetBValue(ColorToRGB(Font.Color));
for y := 0 to bm.Height - 1 do
begin
pixel := bm.ScanLine[y];
x := 0;
while x < bm.Width do
begin
with pixel^ do
begin
rgbReserved := (rgbRed + rgbGreen + rgbBlue) div 3;
rgbBlue := TextBlue * rgbReserved div 255;
rgbGreen := TextGreen * rgbReserved div 255;
rgbRed := TextRed * rgbReserved div 255;
end;
inc(pixel);
inc(x);
end;
end;
P := Point(0,0);
S := Point(bm.Width,bm.Height);
bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.SourceConstantAlpha := 255;
bf.AlphaFormat := AC_SRC_ALPHA;
UpdateLayeredWindow(Handle,nil,@S,bm.Canvas.Handle,@P,@bf,ULW_ALPHA)
finally
bm.Free;
end;
end;
解决方法
如何调试这个.
>在项目选项中启用调试DCU,禁用优化. 调用GDICheck时,问题发生在CopyBitmap中 – >双击GDICheck去那里. 放一个断点.运行程序 – 计算错误出现之前所需的次数,并在预期错误之前中断. 环顾四周可能有些奇怪的事情.一个好的起点是位图本身.你的第一个线索应该是,每当你调用这种方法时,你的文字就会爬到你看不见的形状的角落里. 让我们检查位图标题,看看发生了什么: 您的位图尺寸看起来是负面的.我想知道这是怎么发生的.事实上,如果你每次调用它时都会看到,你的位图每次都在缩小.事实上,它的宽度缩小了16px,高度缩小了38px–窗框的大小. 每次调用UpdateLayeredWindow时,您都要将窗体(其外部尺寸)的大小调整为客户区的大小 – 没有窗口框架的大小.您的新窗口将获得一个新框架,客户区域将缩小. 最终没有任何东西,你正在尝试制作负尺寸的位图.因此,在构建位图时应考虑帧大小.使用表单宽度和高度而不是客户端大小: bm.Width := Width; bm.height := Height; 此外,在进行API调用时,请养成检查错误返回值的习惯,如相关函数的文档中所述.如果您没有检查错误,那么您会遇到问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
