布団が俺を呼んでいる

丘山大一のぶろぐ

他のアプリケーションウィンドウを操作する

この前出した「ぷるまど」の内部実装の話。

やっぱWinAPIだよね

他のアプリケーションを操作する場合、基本的にはウィンドウハンドルをどうやって取得するか、という問題に絞られます。
プロセスが分かっている場合はもちろんプロセスから攻めるわけですが、今回は「ウィンドウ」があるものをを取得したい。
というわけで、それを取得するAPIがEnumWindowsです。

    public class WinAPI
    {
        [DllImport("user32")]
        public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, IntPtr lParam);
        [DllImport("user32")]
        public static extern bool IsWindowVisible(IntPtr hWnd);
        [DllImport("USER32.DLL", SetLastError = true)]
        public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
    }

みたいな感じでテキトーに定義して、EnumWindowsを呼び出してくるくる回せば色々できます。

        WinAPI.EnumWindows((h, i) =>
        {
            if (WinAPI.IsWindowVisible(h))
            {
                WinAPI.GetWindowThreadProcessId(h,out int id);
                result.Add((h, Process.GetProcessById(id).ProcessName)); //このresultに結果を蓄えているので、後はご随意に
            }
            return true;//Trueを返すと処理が継続する
        },
        IntPtr.Zero);

「WinAPI.IsWindowVisible」を呼び出して、ウィンドウが表示されているかどうかを判定していますが、「ウィンドウは持っているけど表示されない」みたいな例外動作をするアプリケーションもあります。
代表例がexplorerのProgram Manager。
こういった特殊なアプリケーションをどう扱うかは仕様次第だと思います。
「ぷるまど」は汎用的、かつ雑なアプリということもあり、そのあたりはあまり考えないことにしました。「ぷるまど」には、他のアプリケーションの都合が分からないから、とりあえず表示しておけ、てな動作をしています。


ウィンドウ操作系API等

他にはこの辺りを、こんな感じで定義して使っています。

        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll")]
        public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        public const int SW_RESTORE = 9;  // 画面を元の大きさに戻す
        public const int SW_SHOWNORMAL = 1;
        [DllImport("User32.dll")]
        public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
        [DllImport("user32.dll")]
        public static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, int bRepaint);
        [DllImport("USER32.DLL", CharSet = CharSet.Auto)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

何をするAPIかは、名前を見てもらえば大体わかるかと……

窓断熱シート マジックミラー フィルム ガラス透明断熱フィルム 建築建物ガラスフィルム 目隠しフィルム 窓のサングラス省エネフィルム めかくしシート 窓フィルム マジックミラー 紫外線カット 飛散防止 ミラー(90cm×200cm, シルバー)

新品価格
¥2,378から
(2018/7/20 17:14時点)

布団が俺を呼んでいる | Blog

布団が俺を呼んでいる

丘山大一のぶろぐ

IISのお勉強 WordPressのインストール その1

http://fnya.cocolog-nifty.com/blog/2013/11/wordpress-windo.htmlhttp://techblog.hilife-jp.info/2013/0 [もっと読む]

おしえて! ギャル子ちゃん  アニメ化

マジっすか。http://www.galko-chan.com/気になるのは、ギャルンギャルンという擬音の演出。どうやって表現するんだろう? [もっと読む]

PowerShell ファイル数を数えての分岐

ファイル数を数えて、その数が一定数以下の場合、条件を満たしていないとして処理を中断させたかった。if((Get-ChildItem $Path | Measure-Object | %{ $_.Cou [もっと読む]

PowerShell Invoke-Sqlcmdが動かない場合の一時対応

地味にはまった。SQL Server2008R2 の入ったクライアントPCで、Invoke-Sqlcmdが通らず。他人のPCなので、あまり設定をゴチャゴチャ弄りたくない。そんな時は、下記コマンドを突っ [もっと読む]

PowerShell Invoke-Sqlcmd で SQLServerの名前付インスタンスにアクセス

地味~に苦戦。こことか見ながら。https://msdn.microsoft.com/ja-jp/library/hh231287.aspx上記サイト通りの「read-host 」を実行すると、パスワ [もっと読む]

PowerShell 64ビット判定

PowerShell バージョンによって違う? かもしれません。動作を確認したのはWindows7からアップグレードした直後のWindows10。なのでバージョン5.0。とりあえずProgramFil [もっと読む]

PowerShell 物理ドライブのドライブレター取得

やり方あるんですね。取得自体は簡単でした。Get-WmiObject Win32_LogicalDisk使う時はこんな感じ?foreach($Drive in Get-WmiObject Win32_ [もっと読む]

PowerShell ローカルアカウント一覧の取得

どうやるのが正解なのか今一つ分からなかった。Get-CimInstance -ClassName Win32_UserAccount -Filter "LocalAccount='true'"こちらで [もっと読む]

PowerShell Hostsファイルの更新 と 確認

Add-Content [もっと読む]

PowerShell Windows Server 終了時の理由入力を止める

正攻法は「ローカルグループポリシーエディター」-「コンピューターの構成」-「管理用テンプレート」-「システム」-「シャットダウン イベントの追跡ツールを表示する」から。でもあえてPowerShell [もっと読む]