質問: enumchildwindowsの使い方(vba) 64bit版excelのvbaでenumchildwindowsを使用して、子ウィンドウのウィンドウハンドルを 取得したいと考えています。 下記のようなサンプルを作ってみましたが、コールバック関数でexcelが異常終了します。 (05行目にブレークポイントを設定、各変数の値を参照しようとした時点でexcelが異常終了) また、コールバック関数の第3引数(lparam)の型をinteger,long,longptr等変えてみましたが、 いずれもexcelの異常終了となりました。 つきまして、64bit excelでの本apiの使い方を教えていただきたくよろしくお願いいたします。 (なお、32bit版のexcelでは正常に動作しました) <以下サンプルコード> 行 コード 01 declare ptrsafe function enumchildwindows lib "user32.dll" (byval parenthwnd as longptr, byval enumwindosproc as longptr,byval lparam as long) as integer 02 03 04 function listupchildwindows(hwnd as longptr,lparam as long) as boolean 05 msgbox hwnd 06 listupchildwindows =true 07 end function 08 09 sub test_cwinlist 10 dim thishwnd as longptr 11 12 thishwnd=excel.application.hwnd 13 call enumchildwindows (thishwnd , addressof listupchildwindows ,0) 14 end sub
回答: こんにちは。 ご提示のサンプルですが、当方の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オブジェクト等を用いることになるかと思いますが、 もしかしたら、この戻り値の重複についてもチェックしてみた方がいいのかも??知れません。 参考になるか解りませんが、以上です。