2

みんなおはよう。

私は現在、Windows DWM API(DWMサムネイルなど)で利用できる機能を中心に構築された小さなアプリケーションを作成しようとしています。そのような機能の1つは、アプリケーション内からサムネイルの領域を動的に選択し、それを拡大/拡大する機能です。これは、ある種の「領域の設定」機能を使用してDWMから実行できる場合がありますが、私はAPIに入る前に、まず自分のルートを試してみたかったのです。

最近Delphiの例を見つけたので、デモから拡張して、より具体的なものを構築したいと思っていました。私はコードをFiremonkey FM2アプリケーションに移動することに着手しました(VCLよりもフレームワークの視覚的機能を非常に好むため)。いくつかの調整を加えることで、なんとかビルドできましたが、残念ながらDWMRegisterThumbnail、VCLバージョンが問題なく動作しているにもかかわらず、FMXアプリケーションで実行すると有効な結果が返されないようです。

それから私はもう少し調べて、Hydraを試してみることにしました。動作するVCLの例をHydraプラグインにコピーし、Firemonkeyホストアプリケーションを作成しました。両方のパーツを正しくセットアップしてコンパイルしました。DLLが正しくロードされ、FMXホスト内のVCLプラグインインターフェイスが期待どおりに表示されました。ただし、ウィンドウのDWMサムネイルを表示しようとすると、非HydraFMXアプリケーションを実行したときと同じ問題が再び発生しました。

次に、VCLとFMXの相互作用に固有の問題ではないことを確認するために、VCLホストアプリケーションの作成に取り掛かりました。VCLプラグインにロードされたVCLホストをコンパイルしましたが、VCLホスト内にVCLプラグインが表示されました。しかし、もう一度、DWMからサムネイルを表示できないことに気づきました。明らかに、これはFiremonkeyとVCLの相互作用の問題ではありません。

したがって、DLLからDWMコードを実行する際の問題であると結論付けました。理想的には、サムネイルの上にドロップする方が簡単であるという理由だけでFMXホストアプリケーションを作成TSelectionし、その方法でスケーリングを処理したいと思います(たとえば、コードが非常に少なく、カスタムコンポーネントを探す必要がない)。などの追加のボーナスについて言及しMakeScreenshotます。

だから、追いかけるために; HydraプラグインからDWMAPIを呼び出したり、DWMサムネイルをFiremonkeyサーフェスに出力したりすることは可能ですか?

私のHydraプラグインで使用されているコードは、リンクされた例で使用されているコードと同じです。ホストアプリケーションで使用されているコードは、RemobjectYoutubeChannelの簡単な例に基づいています。

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 に答える