delphi - 来自 DLL 的 DWM 交互

标签 delphi firemonkey dwm remobjects firemonkey-fm2

大家早上好。

我目前正在尝试编写一个小型应用程序,该应用程序是围绕通过 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/

相关文章:

multithreading - Delphi VCL 中的 AutoThread 类?

delphi - 为什么添加到 ImageList 时图片会失去质量?

firebase - Firestore 身份验证用户

c++ - 如何在 C++ Builder XE5 跨平台中获取 TAlphaColor 的 RGB 分量?

c++ - 为什么我的 DwmExtendFrameIntoClientArea() 窗口没有绘制 DWM 边框?

javascript - 如何实现 window 与无框 Electron 窗对接

delphi - 如何复制(和重命名)数据库?

delphi - 绘制六边形

c# - 如何确保启用 Aero 效果?

delphi - 在 delphi 中使用 Neo4j