加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 将透明消息绘制到屏幕提供了超出系统资源

发布时间:2020-12-15 09:49:18 所属栏目:大数据 来源:网络整理
导读:我有一个代码,它将消息str直接绘制到屏幕的中心而没有可见的窗口. 为什么首先使用此代码可以正常工作,但是经过几十次调用后,它会提供系统资源. ?它似乎免费BM好,我没有看到它分配其他资源. procedure ttsplash.UpdateSplash(const Str: string);var R: TRect
我有一个代码,它将消息str直接绘制到屏幕的中心而没有可见的窗口.

为什么首先使用此代码可以正常工作,但是经过几十次调用后,它会提供系统资源.
?它似乎免费BM好,我没有看到它分配其他资源.

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,禁用优化.
>当您退出资源错误时,点击“Break”.
>检查调用堆栈:

调用GDICheck时,问题发生在CopyBitmap中 – >双击GDICheck去那里.

放一个断点.运行程序 – 计算错误出现之前所需的次数,并在预期错误之前中断.

环顾四周可能有些奇怪的事情.一个好的起点是位图本身.你的第一个线索应该是,每当你调用这种方法时,你的文字就会爬到你看不见的形状的角落里.

让我们检查位图标题,看看发生了什么:

您的位图尺寸看起来是负面的.我想知道这是怎么发生的.事实上,如果你每次调用它时都会看到,你的位图每次都在缩小.事实上,它的宽度缩小了16px,高度缩小了38px–窗框的大小.

每次调用UpdateLayeredWindow时,您都要将窗体(其外部尺寸)的大小调整为客户区的大小 – 没有窗口框架的大小.您的新窗口将获得一个新框架,客户区域将缩小.

最终没有任何东西,你正在尝试制作负尺寸的位图.因此,在构建位图时应考虑帧大小.使用表单宽度和高度而不是客户端大小:

bm.Width := Width;
 bm.height := Height;

此外,在进行API调用时,请养成检查错误返回值的习惯,如相关函数的文档中所述.如果您没有检查错误,那么您会遇到问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读