You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi屏保程序截图异常:预览正常,自动运行时截图黑屏

Markdown格式示例及问题解决方案

一、格式规则示例

1. 标题

一级标题

二级标题

三级标题

2. 列表

  • 普通列表项1
  • 普通列表项2
    • 嵌套列表项1
    • 嵌套列表项2

3. 文本强调

这是斜体强调,这是粗体强调

4. 代码展示

单行代码:GetDC(GetDesktopWindow)
多行代码块:

function CaptureScreenToStream: TMemoryStream;
var
  DesktopDC: HDC;
begin
  // 代码逻辑
end;

5. 引用文本

这是一段引用内容


二、屏保截图黑屏问题解决

问题场景

Windows自动运行屏保时,用现有代码捕获的图像为黑色,但点击屏保预览功能时截图正常。原代码如下:

function CaptureScreenToStream: TMemoryStream;
var
  DesktopDC: HDC;
  CaptureBitmap: TBitmap;
  Width, Height: Integer;
begin
  DesktopDC := GetDC(GetDesktopWindow);
  try

    Width := round(GetDeviceCaps(DesktopDC, HORZRES) * strtoint(GetLastLoadedDPI) / 96);
    Height := round(GetDeviceCaps(DesktopDC, VERTRES) * strtoint(GetLastLoadedDPI) / 96);

    CaptureBitmap := TBitmap.Create;
    try
      CaptureBitmap.Width := Width;
      CaptureBitmap.Height := Height;
      BitBlt(CaptureBitmap.Canvas.Handle, 0, 0, Width, Height, DesktopDC, 0, 0, SRCCOPY);
      Result := TMemoryStream.Create;
      CaptureBitmap.SaveToStream(Result);
      Result.Position := 0;
    finally
      CaptureBitmap.Free;
    end;
  finally
    ReleaseDC(GetDesktopWindow, DesktopDC);
  end;
end;

问题原因

屏保运行时是独立的顶层窗口,GetDesktopWindow获取的桌面DC不包含屏保画面;而预览模式下屏保是在桌面窗口内渲染,因此能正常捕获。

解决方案

修改代码,优先捕获屏保窗口的内容, fallback 到原桌面捕获逻辑:

function CaptureScreenToStream: TMemoryStream;
var
  TargetDC: HDC;
  CaptureBitmap: TBitmap;
  Width, Height: Integer;
  ScreensaverWnd: HWND;
begin
  // 查找屏保窗口(类名为WindowsScreenSaverClass)
  ScreensaverWnd := FindWindow('WindowsScreenSaverClass', nil);
  if ScreensaverWnd <> 0 then
  begin
    TargetDC := GetDC(ScreensaverWnd);
    try
      Width := GetDeviceCaps(TargetDC, HORZRES);
      Height := GetDeviceCaps(TargetDC, VERTRES);
      CaptureBitmap := TBitmap.Create;
      try
        CaptureBitmap.Width := Width;
        CaptureBitmap.Height := Height;
        // 使用PrintWindow捕获窗口内容,支持后台/顶层窗口
        PrintWindow(ScreensaverWnd, CaptureBitmap.Canvas.Handle, PW_CLIENTONLY);
        Result := TMemoryStream.Create;
        CaptureBitmap.SaveToStream(Result);
        Result.Position := 0;
      finally
        CaptureBitmap.Free;
      end;
    finally
      ReleaseDC(ScreensaverWnd, TargetDC);
    end;
  end
  else
  begin
    // 原逻辑捕获桌面
    TargetDC := GetDC(GetDesktopWindow);
    try
      Width := Round(GetDeviceCaps(TargetDC, HORZRES) * StrToInt(GetLastLoadedDPI) / 96);
      Height := Round(GetDeviceCaps(TargetDC, VERTRES) * StrToInt(GetLastLoadedDPI) / 96);
      CaptureBitmap := TBitmap.Create;
      try
        CaptureBitmap.Width := Width;
        CaptureBitmap.Height := Height;
        BitBlt(CaptureBitmap.Canvas.Handle, 0, 0, Width, Height, TargetDC, 0, 0, SRCCOPY);
        Result := TMemoryStream.Create;
        CaptureBitmap.SaveToStream(Result);
        Result.Position := 0;
      finally
        CaptureBitmap.Free;
      end;
    finally
      ReleaseDC(GetDesktopWindow, TargetDC);
    end;
  end;
end;

内容的提问来源于stack exchange,提问作者MG1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:13:07