Categories: Cシャープ

C#でウィンドウハンドル(hWnd)を取得する方法と実践例

C#で外部アプリケーションや自分のウィンドウに対して操作を行いたい場合、ウィンドウハンドル(hWnd)の取得は重要なステップとなります。ウィンドウハンドルは、Windows OS上のGUI操作の基本単位であり、アプリケーション間の制御や自動化、API連携の基盤です。この記事では、C#でウィンドウハンドルを取得する方法について、Win32 APIの活用方法や具体的なコード例を交えてわかりやすく解説します。


ウィンドウハンドルとは何か?

ウィンドウハンドル(Window Handle)は、Windows OSが各ウィンドウを識別するためのユニークな識別子です。C言語などでは HWND と呼ばれる型で表され、C#では通常 IntPtr 型として扱われます。

ウィンドウハンドルを使うことで、ウィンドウの表示・非表示、移動、サイズ変更、メッセージ送信などの制御が可能になります。


C#でウィンドウハンドルを扱うには?

C#単体ではウィンドウハンドルを直接扱う機能は限られていますが、DllImportを使ってWindows APIを呼び出すことで、詳細な制御が可能になります。具体的には、以下のようなAPIを利用します。

  • FindWindow
  • FindWindowEx
  • GetForegroundWindow
  • GetDesktopWindow
  • GetWindowThreadProcessId

これらの関数は全て user32.dll というWindowsの基本ライブラリに含まれています。


アプリケーション名からウィンドウハンドルを取得する

using System;
using System.Runtime.InteropServices;

class Program
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

static void Main()
{
IntPtr hWnd = FindWindow(null, "メモ帳");
if (hWnd != IntPtr.Zero)
{
Console.WriteLine($"ハンドルを取得しました: {hWnd}");
}
else
{
Console.WriteLine("ウィンドウが見つかりません。");
}
}
}

このコードでは、ウィンドウタイトルが「メモ帳」となっているウィンドウのハンドルを取得します。lpClassNamenull にすると、タイトルだけで検索が行われます。


フォアグラウンドのウィンドウハンドルを取得する

現在アクティブになっているウィンドウ(最前面のウィンドウ)のハンドルを取得したい場合は、GetForegroundWindow を使用します。

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

static void GetActiveWindowHandle()
{
IntPtr hWnd = GetForegroundWindow();
Console.WriteLine($"フォアグラウンドのウィンドウハンドル: {hWnd}");
}

この方法は、ショートカットキー連動やウィンドウ監視の処理に使われます。


子ウィンドウのハンドルを取得する(FindWindowEx)

複数のウィンドウがある場合、親ウィンドウ内の特定のコントロールや子ウィンドウを取得する必要があります。その場合は FindWindowEx を使います。

csharpコピーする編集する[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

static void GetChildWindow()
{
    IntPtr parentHandle = FindWindow(null, "電卓");
    IntPtr childHandle = FindWindowEx(parentHandle, IntPtr.Zero, null, null);
    Console.WriteLine($"子ウィンドウのハンドル: {childHandle}");
}

ウィンドウハンドルからプロセスIDを取得する

特定のウィンドウがどのプロセスから起動されたかを知るには、GetWindowThreadProcessId を使います。

[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

static void GetProcessIdFromHandle(IntPtr hWnd)
{
GetWindowThreadProcessId(hWnd, out uint processId);
Console.WriteLine($"プロセスID: {processId}");
}

この情報を使えば、プロセスの詳細情報をさらに System.Diagnostics 名前空間を使って取得することも可能です。


自分自身のウィンドウハンドルを取得する方法

C#で作成した自アプリケーションのフォームのウィンドウハンドルは、this.Handle プロパティから取得できます。

public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
IntPtr myHandle = this.Handle;
Console.WriteLine($"自分のウィンドウハンドル: {myHandle}");
}
}

WinFormsやWPFで開発している場合は、WindowInteropHelper を使うこともできます。


ハンドルを活用してできることの例

ウィンドウハンドルを取得すれば、以下のような操作が可能です:

  • 他のアプリケーションに対して「閉じる」などのメッセージ送信
  • 自動操作(RPA的用途)
  • 画面キャプチャ(対象を特定するため)
  • ウィンドウの移動・サイズ変更
  • フォーカス操作

このように、UI自動化や管理ツール開発において不可欠な技術です。


まとめ

C#でウィンドウハンドルを取得するには、Windows APIの user32.dll を使った方法が主流です。FindWindowGetForegroundWindow を活用することで、任意のウィンドウやコントロールのハンドルが取得でき、さらにプロセス情報の取得や操作へとつなげることができます。

GUIの自動化やツール開発、あるいはシステム監視を行ううえで、ウィンドウハンドルは非常に有効な手段です。今回紹介したコードを参考に、実際のアプリケーションでも活用してみてください。

upandup

Web制作の記事を中心に、暮らし、ビジネスに役立つ情報を発信します。 アフィリエイトにも参加しています。よろしくお願いいたします。