http://d.hatena.ne.jp/cartooh/20090618
上記のページに記載されているVBAです。
動作は確認できたのですが、どのような処理の流れとなっているのかがわかりません。
どなたかコメントを付けていただけないでしょうか。
よろしくお願いいたします。
Option Explicit
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal cnm As String, ByVal cap As String) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, _
ByVal cch As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, _
ByVal lParam As Long) As Long
Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long
Const INDENT_KEY = "INDENT"
Public Function EnumChildWindowsProc(ByVal hWnd As Long, ByVal lParam As Object) As Long
EnumChildWindowsProc = EnumWindowsProc(hWnd, lParam)
End Function
Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Object) As Long
EnumWindowsProc = True
If IsWindowVisible(hWnd) = 0 Then
Exit Function
End If
Dim strClassName As String ' * 255
Dim strCaption As String ' * 255
strClassName = String(255, vbNullChar)
strCaption = String(255, vbNullChar)
GetWindowText hWnd, strCaption, Len(strCaption)
GetClassName hWnd, strClassName, Len(strClassName)
strCaption = RTrim(left(strCaption, InStr(1, strCaption, vbNullChar) - 1))
strClassName = RTrim(left(strClassName, InStr(1, strClassName, vbNullChar) - 1))
ActiveCell.Cells(1, 1).Value = Hex(hWnd)
ActiveCell.Cells(1, 2).Value = IsWindowVisible(hWnd)
ActiveCell.Cells(1, 3).Value = strCaption
ActiveCell.Cells(1, 4).Value = strClassName
ActiveCell.Cells(2, 2).Activate
Dim c As Collection
Set c = lParam
Dim indent As Long
indent = c(INDENT_KEY)
c.Add String(indent * 2, " ") & Hex(hWnd) & " " & strCaption & " " & strClassName, before:=c.Count
indent = indent + 1
c.Remove INDENT_KEY
c.Add indent, INDENT_KEY
Call EnumChildWindows(hWnd, AddressOf EnumChildWindowsProc, ObjPtr(c))
indent = c(INDENT_KEY) - 1
c.Remove INDENT_KEY
c.Add indent, INDENT_KEY
ActiveCell.Cells(1, 0).Activate
End Function
Sub hoge()
Application.ScreenUpdating = False
Dim sht As Worksheet
Set sht = ThisWorkbook.Worksheets(1)
sht.UsedRange.Clear
sht.Activate
sht.Range("A1").Activate
Dim c As Collection
Set c = New Collection
c.Add 0, INDENT_KEY
Dim ret As Long
ret = EnumWindows(AddressOf EnumWindowsProc, ObjPtr(c))
c.Remove INDENT_KEY
Set sht = ThisWorkbook.Worksheets(2)
sht.UsedRange.Clear
sht.Activate
sht.Range("A1").Activate
Dim o As Variant
For Each o In c
ActiveCell.Value = o
ActiveCell.Cells(2, 1).Activate
Next
Application.ScreenUpdating = True
End Sub
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
#1です。
このコードは、一番末の子孫から戻る時にダブルカウントが発生する様です。ちょっと考えてみましたが、何故発生するかは分かりませんでした。対象療法としては、Collectionを用いているので、Hex(ハンドル)をキーに重複カットすれば良いと思いますが...
また、会社で試したところNotesが起動されていると、ハングアップ様状態になります。途中で中断してみると、確かに非常に多数のウィンドウが存在する様ではありますが、数十分経っても終了しません。Breakキーが効くので暴走ではないのかもしれませんが、それにしても時間がかかりすぎです。ご参考まで。
mitarashi様
お世話になっております。kuharaです。
回答をいただきありがとうございます。
また、お礼が遅れ申し訳ございませんでした。
mitarashi様の回答を参考に解析を進めていますが、
なかなか難しい状況です。
今回ご回答いただいた内容もまだ理解できていませんが、
いつか理解できるようになりたいです。
No.1
- 回答日時:
これは解り難いですね(当方にとってもですが)。
骨格は下記の通りと理解しました。コメントはもっとレベルの高い回答者様にお任せします。なお、関数名がAPIと似通っていて混乱を招くので、勝手に付け替えています。なおインデントをつける部分も読み飛ばしています。
'======== procedureB ========
'EnumChildWindowsから、取得されたウィンドウのハンドルおよび、データを収納するCollectionオブジェクトのアドレスを渡して呼ばれる
Public Function procedureB(ByVal hWnd As Long, ByVal lParam As Object) As Long
'再帰的に、procedureAを呼ぶ事で、孫ウィンドウ以降も処理する
procedureB = procedureA(hWnd, lParam)
End Function
'======== procedureA ========
'EnumWindowsから、取得されたウィンドウのハンドルおよび、データを収納するCollectionオブジェクトのアドレスを渡して呼ばれる
'また同様にEnumChildWindowsからも呼ばれる
Public Function procedureA(ByVal hWnd As Long, ByVal lParam As Object) As Long
' EnumWindowss関数から戻された(またはprocedureBから渡された)ハンドルから得られる情報をワークシート1に出力
'Collectionにハンドルから得られた情報を追加
' 子ウィンドウを列挙して処理するコールバック関数を呼ぶ
' 親ウィンドウのハンドル、子ウィンドウが取得される都度実行される関数procedureBのアドレスと、
'データを収納するCollectionオブジェクトのアドレスを渡す
Call EnumChildWindows(hWnd, AddressOf procedureB, ObjPtr(c))
End Function
Sub hoge()
Dim c As Collection
' コールバック関数EnumWindowsに、ウィンドウが取得される都度実行される関数procedureAのアドレスと、データを収納するCollectionオブジェクトのアドレスを渡す
ret = EnumWindows(AddressOf procedureA, ObjPtr(c))
'得られたCollectionの中身をワークシート2に出力
For Each o In c
'...
Next
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
餃子を食べるとき、何をつけますか?
みんな大好き餃子。 ふと素朴な疑問ですが、餃子には何をつけて食べますか? 王道は醤油とお酢でしょうか。
-
大人になっても苦手な食べ物、ありますか?
大人になっても、我慢してもどうしても食べれないほど苦手なものってありますよね。 あなたにとっての今でもどうしても苦手なものはなんですか?
-
メモのコツを教えてください!
メモを取るのが苦手です。 急いでメモすると内容がごちゃごちゃになってしまったり、ひどいときには全く読めない時もあります。
-
昨日見た夢を教えて下さい
たまにすごいドラマチックな夢見ること、ありませんか? 起きてからも妙に記憶に残っているような、そんな夢。
-
高校三年生の合唱祭で何を歌いましたか?
大人になると大人数で合唱する機会ってないですよね。 思い出すと、高校三年生の合唱祭が最後でした。 そこで、みんなの思い出の合唱曲を知りたい!
-
EnumChildWindowsの使い方(VBA)
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
検索の画面がでなくなってしま...
-
ExcelのBOOKが消えた!
-
ゲームでは結局どっちが良いの?
-
勝手にウィンドウが開いて止ま...
-
名前を付けて保存のウィンドウ...
-
自作関数内でウインドウハンド...
-
EXCEL2016で新しいウィンドウを...
-
他アプリの操作(メニューバー)
-
VBA .Value=.Value ?
-
ExcelVBAでAPIを使って外部ウイ...
-
Alt+P,Alt+NをPostmessageで送...
-
MFC ダイアログ上のID取得につ...
-
C#でファイル転送プログラムWin...
-
(ショートカットキー)Alt+...
-
VBでアプリケーションを自動操...
-
アウトルックの既読、未読の設...
-
エクセルでフレーム仕様?
-
[VBA] UserForm を Excel の W...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
検索の画面がでなくなってしま...
-
ゲームでは結局どっちが良いの?
-
ExcelのBOOKが消えた!
-
VBA .Value=.Value ?
-
[VBA] UserForm を Excel の W...
-
ラジオボタンの初期指定
-
勝手にウィンドウが開いて止ま...
-
Excelの上下を固定したい
-
【VB2008】 マウス操作の一時的...
-
「&HFFFF」「&H1A」とは?
-
作成したウインドウのサイズを...
-
親ウインドウにあるOKボタンを...
-
他のアプリケーションの終了処理
-
MFC ダイアログ上のID取得につ...
-
ExcelVBAでAPIを使って外部ウイ...
-
EnumChildWindowsの使い方(VBA)
-
Alt+P,Alt+NをPostmessageで送...
-
Vba LongPtrについて教えてくだ...
おすすめ情報