• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:EnumChildWindowsの使い方(VBA))

EnumChildWindowsの使い方(VBA)

このQ&Aのポイント
  • 64bit版ExcelのVBAでEnumChildWindowsを使用して、子ウィンドウのウィンドウハンドルを取得する方法について教えてください。
  • サンプルコードを作成しましたが、コールバック関数でExcelが異常終了してしまいます。また、コールバック関数の引数の型を変えても同様の結果となります。
  • なお、32bit版のExcelでは正常に動作しました。64bit版ExcelでのEnumChildWindowsの使い方を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

こんにちは。 ご提示のサンプルですが、当方のVBA7x64環境でも (実行の度に無条件で必ず)Excelの異常終了を再現できました。 この問題の解決については、私の力量を越えていますので、 情報提供、という形でお応えします。 『APPS PRO > VBA Tips > How Can I Locate a Specific Child Window Handle?』 http://www.appspro.com/Tips/VBA%20Tips.htm こちらのページの一番下の[EnumChildWindows]をクリックすると x32|x64両方対応のサンプルコードが入手できます。 そのままこちらで試してみた処、 (このサンプルは、ThisWorkbook.Windows(1)のハンドル'だけ'を取得するものなので) エラーにはなりませんでした。 コールバック関数側で、条件分岐を書き換えてみたり、 無条件でWindowClassやWindowTitleを取得するよう試みたりして、 約30(重複を含む)の子ウィンドウのウィンドウハンドルが取得出来る所までは確認しましたが、 すべてを取得出来ていないか、うまく終了させることが出来ていないか、どちらかで、 完全な動作を確認するには至りませんでした。 デバッグのヒントにはなりそうな気はしますので、サンプル試してみては如何でしょう。 もしうまく行く方法があるとすれば、 WindowClassとWindowTitleでの条件分岐を整理して、 適切に列挙を終了させることになるような気がしています。 例えばThisWorkbook.Windows(1)のWindowClassとWindowTitleが確認できたら、 (そこから数えてx番目の子ウィンドウで、、、x = 0 かも?) コールバック関数の戻りを0にして列挙を終了する、、、、みたいな? 或いは、特定の子ウィンドウに限定できるなら、同様にうまく扱えるようにも思えます。 実践的には、同じハンドルが重複して戻る場合があることを考慮して、 ハンドル列挙の受け皿としてCollectionオブジェクト等を用いることになるかと思いますが、 もしかしたら、この戻り値の重複についてもチェックしてみた方がいいのかも??知れません。 参考になるか解りませんが、以上です。

mmvba002
質問者

お礼

早速、大変ご丁寧な回答をいただき、 ありがとうございます。 示していただいた参照先についてはまだ確認できていませんが、回答いただいた内容と合わせ、試してみたいと思います。 取り急ぎお礼まで。

mmvba002
質問者

補足

教えていただいた参照先のサンプルコードを確認し、 本質問の異常終了の原因がわかりました。 (原因) 4行目のコールバック関数引数の宣言が間違っていました(「ByVal」が抜けていました)。 下記のように修正することでうまく動作することが確認できました。大変お世話になりありがとうございました。 04 Function ListupChildWindows(ByVal hWnd as LongPtr, ByVal lParam as Long) as Boolean