我在上一个问题中收到了各种反馈和帮助(阻止delphi(亚历山大)中的屏幕截图或屏幕捕获),经过一些搜索和研究,我发现了以下源代码:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.Menus, Vcl.ExtCtrls, Vcl.FileCtrl,
System.IOUtils, System.Types, System.UITypes, Forms, Math, ShellAPI, Vcl.Imaging.jpeg,
Winapi.TlHelp32, PsAPI, System.StrUtils;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses Unit2;
function SetWindowDisplayAffinity(hWnd: HWND; dwAffinity: DWORD): BOOL; stdcall; external 'user32.dll' name 'SetWindowDisplayAffinity';
function ShowWindow(hWnd: HWND; nCmdShow: Integer): BOOL; stdcall; external 'user32.dll' name 'ShowWindow';
procedure TForm1.FormCreate(Sender: TObject);
var
Handle: Winapi.Windows.HWND;
begin
// Get the handle of the main form window
Handle := Self.Handle;
// Set the display affinity of the window to monitor
SetWindowDisplayAffinity(Handle, WDA_MONITOR);
// Call SetWindowDisplayAffinity
if not SetWindowDisplayAffinity(Handle, WDA_MONITOR) then
begin
ShowMessage(SysErrorMessage(GetLastError));
end else
begin
ShowMessage('OK');
end;
// Show the window
ShowWindow(Handle, SW_NORMAL);
end;
但是,我仍然无法用我的软件页面替换黑屏或空白页面,或阻止捕获我的软件页面。
我的源代码有问题吗?
我不打算写安全软件,所以请不要重复回答,比如这个方法无效、过时、不实用等等。我想学习方法和过程,相信任何有一点技术知识的人都知道可以使用数码相机或移动相机捕获或记录屏幕,并且这些方法无法阻止。或者通过其他方法,比如逆向工程等,可以绕过这些限制。
我的目标只是学习,我并不打算写出完美的软件!
这些答案非常有帮助,但我仍然无法在 Delphi 11 Alexandria 中成功使用此方法: “我在 Delphi 11 Alexandria 中安装和运行 DirectX SDK 方法没有成功,所以我更喜欢使用 SetWindowDisplayAffinity 方法(如果这个方法兼容大多数Windows系统,特别是Windows 7到11,对我来说就足够了。)”
你的代码在很多方面都很奇怪:
SetWindowDisplayAffinity
两次(一次没有错误检查,一次有错误检查)?肯定一次就够了不是吗?
为什么在
ShowWindow
处理程序中调用 OnCreate
?为什么您觉得需要自己声明这个函数,而实际上它是 Windows.pas
中找到的标准 Windows API 函数?
为什么您的示例中包含大量单位? (这几乎就像你想要通过制造转移注意力来迷惑我们和你自己!)
我刚刚在 Delphi 12 中使用以下
OnClick
处理程序创建了一个新的 VCL 应用程序:
procedure TForm1.FormClick(Sender: TObject);
begin
if not SetWindowDisplayAffinity(Handle, WDA_MONITOR) then
RaiseLastOSError;
end;
我还在表单中添加了一个按钮(只是为了查看子窗口在屏幕截图中的显示方式)以及表单本身上的一些 GDI 绘图:
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.Brush.Color := clWhite;
Canvas.FillRect(ClientRect);
Canvas.Pen.Color := clRed;
Canvas.Pen.Width := 4;
Canvas.Ellipse(ClientRect)
end;
现在,我运行该应用程序并(立即)创建它及其邻域的屏幕截图:
然后我单击表单的客户区域(不是按钮)并尝试再次在屏幕截图中捕获它:
通过将对
SetWindowDisplayAffinity
的调用移至表单的 OnCreate
处理程序,它将从一开始就“不可捕获”。 (实际上,CreateWnd
可能是一个更好的地方。)
所以关于“在Delphi中使用SetWindowDisplayAffinity的问题”这个问题,我想说这个问题不存在。