2

In C# in Windows 8, how can I pInvoke the IMetroMode::IsLauncherVisible method?

Details for the method are found here: http://msdn.microsoft.com/en-us/library/windows/desktop/hh404166(v=vs.85).aspx

cvocvo
  • 1,586
  • 2
  • 23
  • 38

2 Answers2

4

Use the IAppVisibility interface instead of the obsolete IMetroMode interface

Here is the sample code:

/* From ShObjIdl.idl
// CLSID_AppVisibility
[ uuid(7E5FE3D9-985F-4908-91F9-EE19F9FD1514)] coclass AppVisibility { interface IAppVisibility; }
 */
Type tIAppVisibility = Type.GetTypeFromCLSID(new Guid("7E5FE3D9-985F-4908-91F9-EE19F9FD1514"));
IAppVisibility appVisibility = (IAppVisibility)Activator.CreateInstance(tIAppVisibility);
bool launcherVisible;
if(HRESULT.S_OK == appVisibility.IsLauncherVisible(out launcherVisible)) {
    // Here you can use the launcherVisible flag
}

The IAppVisibility interface definition:

[ComImport, Guid("2246EA2D-CAEA-4444-A3C4-6DE827E44313"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAppVisibility {
    HRESULT GetAppVisibilityOnMonitor([In] IntPtr hMonitor, [Out] out MONITOR_APP_VISIBILITY pMode);
    HRESULT IsLauncherVisible([Out] out bool pfVisible);
    HRESULT Advise([In] IAppVisibilityEvents pCallback, [Out] out int pdwCookie);
    HRESULT Unadvise([In] int dwCookie);
}
//...
public enum HRESULT : long {
    S_FALSE = 0x0001,
    S_OK = 0x0000,
    E_INVALIDARG = 0x80070057,
    E_OUTOFMEMORY = 0x8007000E
}
public enum MONITOR_APP_VISIBILITY {
    MAV_UNKNOWN = 0,         // The mode for the monitor is unknown
    MAV_NO_APP_VISIBLE = 1,
    MAV_APP_VISIBLE = 2
}
[ComImport, Guid("6584CE6B-7D82-49C2-89C9-C6BC02BA8C38"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAppVisibilityEvents {
    HRESULT AppVisibilityOnMonitorChanged(
        [In] IntPtr hMonitor,
        [In] MONITOR_APP_VISIBILITY previousMode,
        [In] MONITOR_APP_VISIBILITY currentMode);

    HRESULT LauncherVisibilityChange([In] bool currentVisibleState);
}
DmitryG
  • 17,677
  • 1
  • 30
  • 53
  • I tried the sample code provided by DmitryG in Windows 8.1. 1. The Desktop is detected properly only if an App is started from the Start window. 2. If you recall the same App clicking on it from the upper left corner of the Desktop, the code returns a wrong answer. – user3407781 Apr 01 '14 at 02:02
  • Thanks! Just to note that this code also worked for me in Windows 10, with WPF-based application. There's also a [C++ version on MSDN](https://code.msdn.microsoft.com/windowsapps/Start-screen-visibility-b1a72059/) – Yoav Feuerstein Aug 07 '17 at 09:35
1

Couple of things:

  1. Looks like IMetroMode was removed from the RC and RTM builds of Windows 8.
  2. You don't use P/Invoke on WinRT calls, instead you should add a reference in your C# project to the appropriate WinMD file from C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral\. This will provide interop services complete with auto-completion that should provide access to whatever WinRT facilities you require. You can find more info here.
sblom
  • 26,911
  • 4
  • 71
  • 95
  • 1
    `IMetroMode`/`IAppVisibility` are not part of WinRT; they are standard COM interfaces (provided by the shell), that happen to return information to regarding WinRT-based applications. – dlev Aug 17 '12 at 19:21