Skip to content

Commit

Permalink
Filter ApplicationFrameWindows that don't actively host programs #54
Browse files Browse the repository at this point in the history
The ApplicationFrameWindows that host Windows Store Apps like to
hang around in Windows 10 even after the underlying program has been
closed. A way to figure out if the ApplicationFrameWindow is
currently hosting an application is to check if it has a property called
"ApplicationViewCloakType", and that the value != 1.

I've stumbled upon these values of "ApplicationViewCloakType":
 0 = Program is running on current virtual desktop
 1 = Program is not running
 2 = Program is running on a different virtual desktop
  • Loading branch information
kvakulo committed Sep 15, 2015
1 parent b00385f commit fa52660
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
34 changes: 34 additions & 0 deletions Core/AppWindow.cs
Expand Up @@ -113,6 +113,7 @@ public bool IsAltTabWindow()
if (!IsOwnerOrOwnerNotVisible()) return false;
if (HasITaskListDeletedProperty()) return false;
if (IsCoreWindow()) return false;
if (IsApplicationFrameWindow() && !HasAppropriateApplicationViewCloakType()) return false;

return true;
}
Expand Down Expand Up @@ -176,6 +177,39 @@ private bool IsCoreWindow()
return ClassName == "Windows.UI.Core.CoreWindow";
}

private bool IsApplicationFrameWindow()
{
return ClassName == "ApplicationFrameWindow";
}

private bool HasAppropriateApplicationViewCloakType()
{
// The ApplicationFrameWindows that host Windows Store Apps like to
// hang around in Windows 10 even after the underlying program has been
// closed. A way to figure out if the ApplicationFrameWindow is
// currently hosting an application is to check if it has a property called
// "ApplicationViewCloakType", and that the value != 1.
//
// I've stumbled upon these values of "ApplicationViewCloakType":
// 0 = Program is running on current virtual desktop
// 1 = Program is not running
// 2 = Program is running on a different virtual desktop

var hasAppropriateApplicationViewCloakType = false;
WinApi.EnumPropsEx(HWnd, (hwnd, lpszString, data, dwData) =>
{
var propName = Marshal.PtrToStringAnsi(lpszString);
if (propName == "ApplicationViewCloakType")
{
hasAppropriateApplicationViewCloakType = data != 1;
return 0;
}
return 1;
}, IntPtr.Zero);

return hasAppropriateApplicationViewCloakType;
}

// This method only works on Windows >= Windows Vista
private static string GetExecutablePath(int processId)
{
Expand Down
4 changes: 4 additions & 0 deletions Core/WinApi.cs
Expand Up @@ -307,5 +307,9 @@ public enum SendMessageTimeoutFlags : uint

[DllImport("user32.dll")]
public static extern IntPtr GetProp(IntPtr hWnd, string lpString);

[DllImport("user32.dll")]
public static extern int EnumPropsEx(IntPtr hWnd, EnumPropsExDelegate lpEnumFunc, IntPtr lParam);
public delegate int EnumPropsExDelegate(IntPtr hwnd, IntPtr lpszString, long hData, long dwData);
}
}

0 comments on commit fa52660

Please sign in to comment.