主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2018/08/09
突然の Win32 ネタです。
トップレベルウィンドウを列挙する場合、 EnumWindows
を使うのですが、
そのとき、見えないウィンドウなども混ざってしまいます。
そういうのを除外する方法です。
コードはこんな感じ。
NativeMethods.EnumWindows((hWnd, lParam) =>
{
// WS_VISIBLE でない
if (!NativeMethods.IsWindowVisible(hWnd))
return true;
// タイトル空
var title = new StringBuilder(1024);
NativeMethods.GetWindowText(hWnd, title, title.Capacity);
if (string.IsNullOrWhiteSpace(title.ToString()))
return true; // Skipped
// UWP
NativeMethods.DwmGetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.Cloaked, out var isCloaked, Marshal.SizeOf(typeof(bool)));
if (isCloaked)
return true;
// ここが見えるウィンドウ
return true;
}, IntPtr.Zero);
で、問題の見えないウィンドウなんですが、タスクマネージャを開くと分かるのですが、
Windows 10 の場合、いくつかの UWP アプリはバックグラウンドプロセスとして動作しており、
それらは見えないながらも、トップレベルウィンドウとして存在しています。
例えば、起動していなくても「設定」「Microsoft Edge」は普通に取得できてしまいます。
また、それらのアプリは IsWindowVisible
で除外することもできません。
そういうときに使うのが、DwmGetWindowAttribute
です。
第 2 引数に DWMWA_CLOAKED
を指定し、第 3 引数に入れられた値を見ることで、除外できます。
ということで、除外する方法でした。
(NativeMethods
の部分は、 pinvoke.net からコピーしてくれば良いと思います。)