2

大家早上好。

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

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

然后我再看远一点,决定试一试九头蛇。我将工作的 VCL 示例复制到 Hydra 插件中,并创建了一个 Firemonkey 主机应用程序。我正确设置了两个部分并进行了编译。DLL 正确加载,我可以按预期在 FMX 主机内看到 VCL 插件接口。但是,在尝试查看窗口的 DWM 缩略图时,我再次遇到了运行非 hydra FMX 应用程序时遇到的相同问题。

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

因此,我得出的结论是从 DLL 运行 DWM 代码存在问题。理想情况下,我想要一个 FMX 主机应用程序,因为我更容易将 aTSelection放在缩略图上,并以这种方式处理缩放(例如非常少的代码,并且无需寻找自定义组件)提及额外的奖金,例如MakeScreenshot

所以,切入正题;是否可以从 Hydra 插件调用 DWM API,和/或将 DWM 缩略图输出到 Firemonkey 表面?

我的 Hydra 插件中使用的代码与链接示例中使用的代码相同,并且我的主机应用程序中使用的代码基于 Remobject Youtube 频道上的简单示例

4

1 回答 1

11

如果没有源代码,我猜你没有将正确的窗口句柄传递给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. 

在此处输入图像描述

于 2013-02-20T05:00:57.147 回答