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调用时,请养成检查错误返回值的习惯,如相关函数的文档中所述.如果您没有检查错误,那么您会遇到问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |