試行しているコードは、個々のボタンのキャプションに依存してボタンを識別します。たとえば、次のコードを使用して「1」ボタンへのハンドルを取得します。
hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "1");
これは、ウィンドウクラスの名前に「ボタン」を指定し、ウィンドウの名前に「1」を指定します(ボタンの場合、これはボタン自体に表示されるキャプションテキストと同じです)。
このコードは、電卓のボタンがテキストのキャプションで識別されていたWindows XP(および以前のバージョン)で正常に機能しました。「1」ボタンのウィンドウ名は「1」であるため、ボタンのキャプションとして「1」が表示されていました。
ただし、Windows 7では状況が変わったようです(Vistaでも同様ですが、そのようなシステムにアクセスできないため、これを確認することはできません)。Spy ++を使用して電卓ウィンドウを調査すると、「1」ボタンのウィンドウ名が「1」ではなくなっていることが確認されます。実際、ウィンドウ名はまったくありません。キャプションはNULLです。おそらく、電卓の新しい派手な外観では、ボタンをカスタム描画する必要がありました。したがって、どのボタンがどの機能に対応するかを示すためにキャプションは不要になりました。カスタムペイントルーチンは、必要なキャプションの描画を処理します。
指定したウィンドウテキストのボタンが見つからないNULL
ため、ウィンドウハンドルに値0()が返されます。
関数のドキュメントにはFindWindowEx
NULL
、パラメーターを指定できることが示されていますlpszWindow
が、これはもちろん、指定されたクラスのすべてのウィンドウに一致します。電卓アプリにはたくさんのボタンがあるので、この場合はおそらくあなたが望むものではありません。
良い回避策はわかりません。電卓はこのように「自動化」されるようには設計されておらず、Microsoftは内部の動作を変更しないことを保証していませんでした。これは、他のアプリケーションのウィンドウを混乱させるためにこのアプローチを使用する際に取るリスクです。
編集:あなたがリンクしたコードは、以前のバージョンのWindowsでも、別のかなり深刻な方法で間違っています。hwnd
変数を型int
ではなく型として宣言しますIntPtr
。ウィンドウハンドルはポインタであるため、常に型として保存する必要がありますIntPtr
。FindWindowEx
これにより、赤旗を送信するはずだった関数呼び出しの醜いキャストも修正されます。
SendMessage
また、の宣言を修正して、最初のパラメーターがタイプになるようにする必要がありますIntPtr
。
コードは次のように記述されている必要があります。
IntPtr hwnd = IntPtr.Zero;
IntPtr hwndChild = IntPtr.Zero;
//Get a handle for the Calculator Application main window
hwnd = FindWindow(null, "Calculator");
if(hwnd == IntPtr.Zero)
{
if(MessageBox.Show("Couldn't find the calculator" +
" application. Do you want to start it?",
"TestWinAPI",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
System.Diagnostics.Process.Start("Calc");
}
}
else
{
//Get a handle for the "1" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "1");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//Get a handle for the "+" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "+");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//Get a handle for the "2" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "2");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
//Get a handle for the "=" button
hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "=");
//send BN_CLICKED message
SendMessage(hwndChild, BN_CLICKED, 0, IntPtr.Zero);
}