I'm trying to use IVirtualDesktopManager in Turbo Delphi on Windows 10. I don't get any errors but the IsWindowOnCurrentVirtualDesktop and GetWindowDesktopId do not return anything useful. Does anyone know what I'm doing wrong here? Thanks.
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.
Ok here is a simple example: this project is just a form with a TMemo and a Ttimer on it. It is showing that Form1.handle can not be used to check if the window is on the current desktop. However, if you check Application.Handle then is will return correctly false if you switch to another desktop and back again so check what is written in the memo. I find this remarkable since I presume one application can have more then one window showing on different desktops?
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.