3

I need to search for maximized windows from Win32 (by using EnumWindows) but I also want to filter for windows which are on the current virtual desktop. On MSDN, I found a page about the IVirtualDesktopManager interface but there seems to be no information on how to use this interface.

IVirtualDesktopManager::IsWindowOnCurrentVirtualDesktop(/*args...*/);

Throws the following error:

Non static member reference must be relative to a specific object

VirtualDesktopManager mVirtualDeskManager;
mVirtualDesktopManager.IsWindowOnCurrentVirtualDesktop(/args...*/)

Throws this error:

Incomplete type is not allowed

I have only found solutions on using the IVirtualDesktopManager interface in C# yet.

Jan Böhm
  • 89
  • 1
  • 11

1 Answers1

7

IVirtualDesktopManager is a COM interface. You need to instantiate the COM object that implements the interface.

Based on code from this blog, you can use IServiceProvider to access IVirtualDesktopManager (and IVirtualDesktopManagerInternal, which has much more functionality than IVirtualDesktopManager has), eg:

IServiceProvider* pServiceProvider = NULL;
HRESULT hr = ::CoCreateInstance(
    CLSID_ImmersiveShell, NULL, CLSCTX_LOCAL_SERVER,
    __uuidof(IServiceProvider), (PVOID*)&pServiceProvider);

if (SUCCEEDED(hr))
{
    IVirtualDesktopManager *pDesktopManager = NULL;
    hr = pServiceProvider->QueryService(__uuidof(IVirtualDesktopManager), &pDesktopManager);

    if (SUCCEEDED(hr))
    {
        BOOL bIsOnCurrentDesktop = FALSE;
        hr = pDesktopManager->IsWindowOnCurrentVirtualDesktop(hWnd, &bIsOnCurrentDesktop);

        if (SUCCEEDED(hr))
        {
            // use bIsOnCurrentDesktop as needed...
        }

        pDesktopManager->Release();
    }

    pServiceProvider->Release();
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for the answer and for the link. I've got a question regarding this, how did they manage to find how the interface looks like? I found IVirtualDesktopManagerInternals by going to the registry, so, I also found its GUID. However, I did not manage yet to find more information about the interface. – David Peicho Feb 21 '18 at 10:39
  • `IVirtualDesktopManager` is documented on MSDN. Other interfaces mentioned in that blog were likely determined through 3rd party sources, reverse engineering, etc. – Remy Lebeau Feb 21 '18 at 16:55
  • Yeah sure, I was obviously talking about the other interfaces. It would be nice to have more information from the author about how he did it. Maybe I should just contact him. – David Peicho Feb 24 '18 at 02:54
  • Does this work (didn't tested)? https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/cc678966%28v%3dvs.85%29 receives 3 args. – CristiFati Jul 23 '19 at 13:43
  • @CristiFati I honestly could not tell you, I've never used it myself. But I've seen examples that use both 2 and 3 parameter versions of `QueryService()`, such as [this one](https://github.com/Eun/MoveToDesktop/blob/master/Hook/hook.cpp) – Remy Lebeau Jul 23 '19 at 17:36
  • 1
    Sorry, I started typing the comment, but somehow I browsed away from the page. It does work since the 2 arg form is a template overload that calls the 3 arg one. This is the equivalent: `hr = pServiceProvider->QueryService(__uuidof(IVirtualDesktopManager), __uuidof(IVirtualDesktopManager), (void**)(&pDesktopManager));` (strange, as the same *IID* is passed twice). – CristiFati Jul 23 '19 at 17:55