Windows 10でTurbo DelphiでIVirtualDesktopManagerを使用しようとしています。 エラーは発生しませんが、IsWindowOnCurrentVirtualDesktopとGetWindowDesktopIdは何も役に立ちません。誰も私がここで間違っていることを知っていますか?ありがとう。ここで[OK]をDelphiでIVirtualDesktopManagerを使用する
unit VDMUnit;
interface
uses ActiveX, Comobj;
Const
IID_VDM: TGUID ='{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}';
CLSID_VDM: TGUID ='{AA509086-5CA9-4C25-8F95-589D3C07B48A}';
type
{$EXTERNALSYM IVirtualDesktopManager}
IVirtualDesktopManager = interface(IUnknown)
['{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}']
function IsWindowOnCurrentVirtualDesktop(Wnd:cardinal; var IsTrue: boolean): HResult; stdcall;
function GetWindowDesktopId(Wnd:cardinal; pDesktopID: PGUID): HResult; stdcall;
function MoveWindowToDesktop(Wnd:cardinal; DesktopID: PGUID): HResult; stdcall;
end;
function IsOnCurrentDesktop(wnd:cardinal):boolean;
procedure GetWindowDesktopId(Wnd:cardinal; pDesktopID: PGUID);
procedure MoveWindowToDesktop(Wnd:cardinal; DesktopID: PGUID);
implementation
var
vdm:IVirtualDesktopManager;
function IsOnCurrentDesktop(wnd:cardinal):boolean;
begin
CoInitialize(nil);
OleCheck(CoCreateInstance(CLSID_VDM, nil, CLSCTX_INPROC_SERVER,IVirtualDesktopManager,vdm));
OleCheck(vdm.IsWindowOnCurrentVirtualDesktop(wnd,result));
CoUninitialize;
end;
procedure GetWindowDesktopId(Wnd:cardinal; pDesktopID: PGUID);
begin
CoInitialize(nil);
OleCheck(CoCreateInstance(CLSID_VDM, nil, CLSCTX_INPROC_SERVER ,IVirtualDesktopManager,vdm));
OleCheck(vdm.GetWindowDesktopId(wnd,pDesktopID));
CoUninitialize;
end;
procedure MoveWindowToDesktop(Wnd:cardinal; DesktopID: PGUID);
begin
CoInitialize(nil);
OleCheck(CoCreateInstance(CLSID_VDM, nil, CLSCTX_INPROC_SERVER,IVirtualDesktopManager,vdm));
OleCheck(vdm.MoveWindowToDesktop(wnd,DesktopID));
CoUninitialize;
end;
end.
は簡単な例です。このプロジェクトはTMemoオブジェクトとその上にTTIMERとだけフォームです。 Form1.handleを使用して、ウィンドウが現在のデスクトップにあるかどうかを確認することはできません。しかし、Application.Handleをチェックすると、別のデスクトップに切り替えてもう一度やり直すと正しくメモを返しますので、メモに書かれている内容を確認してください。 私は、1つのアプリケーションが異なるデスクトップ上に複数のウィンドウを表示できると仮定しているので、これは注目に値すると思いますか?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ActiveX, Comobj, StdCtrls, ExtCtrls;
const
IID_VDM: TGUID = '{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}';
CLSID_VDM: TGUID ='{AA509086-5CA9-4C25-8F95-589D3C07B48A}';
type
IVirtualDesktopManager = interface(IUnknown)
['{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}']
function IsWindowOnCurrentVirtualDesktop(Wnd: HWND; out IsTrue: BOOL): HResult; stdcall;
function GetWindowDesktopId(Wnd: HWND; out DesktopID: TGUID): HResult; stdcall;
function MoveWindowToDesktop(Wnd: HWND; const DesktopID: TGUID): HResult; stdcall;
end;
type
TForm1 = class(TForm)
Memo1: TMemo;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function GetVDM: IVirtualDesktopManager;
begin
Result := nil;
OleCheck(CoCreateInstance(CLSID_VDM, nil, CLSCTX_INPROC_SERVER, IVirtualDesktopManager, Result));
end;
function IsOnCurrentDesktop(wnd: HWND): Boolean;
var
value: BOOL;
begin
OleCheck(GetVDM.IsWindowOnCurrentVirtualDesktop(Wnd, value));
Result := value;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if IsOnCurrentDesktop(Form1.Handle) then
Memo1.Lines.Add('Yes')
else
Memo1.Lines.Add('No');
end;
end.
あなたのコードは正常に動作します。いくつかの奇妙なことがあります。 'cardinal'の代わりに' HWND'を使うべきです。 'GetWindowDesktopId'ラッパーは' TGUID'を返します。あなたの 'MoveWindowToDesktop'ラッパーはconst' TGUID'を受け入れます。しかし、ええ、あなたのコードはうまく動作します。誤解のように見える。あなたが[mcve]を提供するなら、それが何であるかを考え出すチャンスがあります。 –
また、 'IsTrue'パラメータを' boolean'ではなく 'BOOL'と宣言する必要があります。これらの型はサイズが異なるため、現在のコードがスタックを上書きし、クラッシュする可能性があります。 – EugeneK
ありがとう、訂正のため! 私は何か変わったことに気づいた。フォーム(form1.handle)が現在のデスクトップ上にあるかどうかをチェックすると、私はいつも答えをyesにします。しかし、私がapplication.handleを使うと、デスクトップが別のデスクトップに切り替えられたときに正しい答えが得られます。 アプリケーションハンドルのみを確認できるようですか? –