我想在Windows 10的Turbo Delphi中使用IVirtualDesktopManager。 我没有得到任何错误,但IsWindowOnCurrentVirtualDesktop和GetWindowDesktopId不返回任何有用的东西。有谁知道我在这里做错了吗?谢谢。在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,那么如果您切换到另一个桌面并再次返回,则会正确返回false,以便检查备注中的内容。 我觉得这很了不起,因为我认为一个应用程序可以有多个窗口显示在不同的桌面上?
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.
你的代码工作正常。有一些古怪。你应该使用'HWND'来代替'cardinal'。你的'GetWindowDesktopId'包装应该返回'TGUID'。你的'MoveWindowToDesktop'包装应该接受一个const'TGUID'。但是,你的代码工作得很好。看起来像是一个误会。如果你想提供[mcve],那么我们就有机会弄清楚它是什么。 –
此外,您必须将'IsTrue'参数声明为'BOOL'而不是'boolean',因为这些类型具有不同的大小,您当前的代码会覆盖堆栈并导致崩溃。 – EugeneK
谢谢,更正! 我注意到别的奇怪。当我检查窗体(form1.handle)是否在当前桌面上时,我总是得到答案是。但是当我使用application.handle时,当桌面切换到另一个桌面时,我得到了正确的答案。 因此,似乎我只能检查应用程序句柄? –