gpt4 book ai didi

delphi - 来自 DLL 的 DWM 交互

转载 作者:行者123 更新时间:2023-12-01 17:56:05 25 4
gpt4 key购买 nike

大家早上好。

我目前正在尝试编写一个小型应用程序,该应用程序是围绕通过 Windows DWM API 提供的功能(例如 DWM 缩略图)构建的。其中一个功能是能够从应用程序内动态选择缩略图区域,并将其放大/放大。可以使用某种“设置区域”功能从 DWM 中执行此操作,但我在深入了解 API 之前,我想先尝试一下我自己的路线。

最近发现an example for Delphi ,我本来希望从演示中进行扩展并构建一些更具体的东西。我开始将代码转移到 Firemonkey FM2 应用程序(因为与 VCL 相比,我更喜欢该框架的视觉功能)。经过一些调整,我成功地构建了它,但不幸的是,尽管 VCL 版本运行完美,但在 FMX 应用程序中运行时,DWMRegisterThumbnail 似乎不会返回有效结果。

然后我进一步考虑,决定给 Hydra 一个机会。我将工作 VCL 示例复制到 Hydra 插件,并创建了 Firemonkey 主机应用程序。我正确设置了这两个部分并进行了编译。 DLL 正确加载,我可以按预期看到 FMX 主机内的 VCL 插件接口(interface)。然而,在尝试查看窗口的 DWM 缩略图时,我再次遇到了与运行非 Hydra FMX 应用程序时遇到的相同问题。

然后,我开始创建一个 VCL 主机应用程序,以确保这不是 VCL-FMX 交互特有的问题。我编译了VCL主机,加载了VCL插件,我再次可以在VCL主机中看到VCL插件。然而,我仍然发现无法从 DWM 查看缩略图。显然,这不是 Firemonkey-VCL 交互问题。

因此,我得出的结论是,这是从 DLL 运行 DWM 代码时出现的问题。理想情况下,我想要一个 FMX 主机应用程序,因为我更容易在缩略图上放置 TSelection ,并以这种方式处理缩放(例如,很少的代码,并且不需要寻找自定义组件)更不用说额外的好处,例如 MakeScreenshot

那么,言归正传吧; 是否可以从 Hydra 插件调用 DWM API,和/或将 DWM 缩略图输出到 Firemonkey 表面?

我的 Hydra 插件中使用的代码与 linked example 中使用的代码相同,我的主机应用程序中使用的代码是 based upon the simple example on the Remobject Youtube Channel .

最佳答案

如果没有源代码,我会猜测您没有将正确的窗口句柄传递给 DwmRegisterThumbnail功能。您可以使用 FmxHandleToHWND函数将 FMX 窗体句柄转换为 Windows 句柄。

尝试这个代码的修改版本

unit Unit28;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, Winapi.Windows, Winapi.DwmApi;

type
TForm28 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FTumbnail: HTHUMBNAIL;
FPreviewEnabled: Boolean;
{ Private declarations }
procedure PreviewWindow(const ASource, ADest: HWND; const ARect: TRect);
procedure PreviewDisable;
public
{ Public declarations }
end;

var
Form28: TForm28;

implementation

uses
FMX.Platform.Win;


{$R *.fmx}

procedure TForm28.Button1Click(Sender: TObject);
var
Index: Integer;
LRect: TRect;
begin
LRect := Rect(5, 5, Self.Width -20,Self.Height -50);
//here I'm using a fixed window handle ($000102EE) just a sample
PreviewWindow($000102EE, FmxHandleToHWND(Self.Handle), LRect);
end;

procedure TForm28.FormCreate(Sender: TObject);
begin
FPreviewEnabled := False;
end;

procedure TForm28.FormDestroy(Sender: TObject);
begin
PreviewDisable;
end;

procedure TForm28.PreviewDisable;
begin
if FPreviewEnabled then
FPreviewEnabled := NOT Succeeded(DwmUnregisterThumbnail(FTumbnail));
end;

procedure TForm28.PreviewWindow(const ASource, ADest: HWND; const ARect: TRect);
var
LResult: HRESULT;
LThumpProp: DWM_THUMBNAIL_PROPERTIES;
begin
if not DwmCompositionEnabled then begin
ShowMessage('DWM composition is NOT enabled.');
Exit;
end;
PreviewDisable;
FPreviewEnabled := Succeeded(DwmRegisterThumbnail(ADest, ASource, @FTumbnail));
if FPreviewEnabled then
begin
LThumpProp.dwFlags := DWM_TNP_SOURCECLIENTAREAONLY or DWM_TNP_VISIBLE or DWM_TNP_OPACITY or DWM_TNP_RECTDESTINATION;
LThumpProp.fSourceClientAreaOnly := False;
LThumpProp.fVisible := True;
LThumpProp.opacity := 200;
LThumpProp.rcDestination := ARect;
LResult := DwmUpdateThumbnailProperties(FTumbnail, LThumpProp);
FPreviewEnabled := (LResult = S_OK);
end else
ShowMessage('Cannot link to window ' + IntToStr(ASource));
end;

end.

enter image description here

关于delphi - 来自 DLL 的 DWM 交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14971762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com