dポイントプレゼントキャンペーン実施中!

おせわになります。

Zオーダーが上から2番目のウインドウのハンドル知る必要がありましたので、
GetWindowが使えるのではないかと思い、プログラムを作りましたがうまくいきませんでした。
次のようにしてみました。

Form1という名前の自作のフォームがメモ帳の上に重なっていたとします。
このとき、
Text1.Text = GetWindow(Form1.hwnd, GW_HWNDNEXT)

こようにしてもメモ帳のハンドルが得られませんでした。

Zオーダーが上から2番目のウインドウのハンドルを知る方法を教えて頂けないでしょうか。

よろしくお願い致します。

A 回答 (3件)

 解決しているかもしれませんが、サンプルを作ってみたので


回答しておきます。

>Form1という名前の自作のフォームがメモ帳の上に重なっていたとします。
>このとき、
>Text1.Text = GetWindow(Form1.hwnd, GW_HWNDNEXT)

 このイメージで、ボタンを押したら自分の下のウィンドウの
キャプションを表示します。(VB6.0のサンプルです。)
 ウィンドウを選択する条件は、アプリによって変わってくる
と思いますので、見直してください。

Private Sub Command1_Click()
Dim lngReturnValue As Long
Dim strWindowTextBuffer As String * 516
Dim strWindowText As String

glngOwnerHwnd = GetWindow(Me.hwnd, GW_OWNER)
glngPrevHwnd = 0
gblnFound = False
Call EnumWindows(AddressOf EnumWindowsSubProc, 0)

If glngPrevHwnd <> 0 Then
lngReturnValue = GetWindowText(glngPrevHwnd, strWindowTextBuffer, Len(strWindowTextBuffer))
strWindowText = Left(strWindowTextBuffer, InStr(strWindowTextBuffer, vbNullChar) - 1)
MsgBox strWindowText
End If

End Sub

コールバックルーチンです。標準モジュールに記載してください。
Public glngOwnerHwnd As Long
Public glngPrevHwnd As Long
Public gblnFound As Boolean

'
' コールバック関数 - トップレベルウィンドウを列挙
'
Function EnumWindowsSubProc(ByVal hwnd As Long, ByVal lParam As Long) As Long

If gblnFound = True Then
If (IsWindowVisible(hwnd) = WIN32API_TRUE) And _
(GetWindowTextLength(hwnd) > 0) And _
(GetWindow(hwnd, GW_OWNER) = 0) Then
glngPrevHwnd = GetLastActivePopup(hwnd)
EnumWindowsSubProc = WIN32API_FALSE
Else
EnumWindowsSubProc = WIN32API_TRUE
End If
Else
' ウィンドウハンドルを保存
If glngOwnerHwnd = hwnd Then
gblnFound = True
End If
' 戻り値をセット
EnumWindowsSubProc = WIN32API_TRUE
End If

End Function

 APIの定義です。標準モジュールに記載してください。

' Win32API における、True、False
Public Const WIN32API_TRUE As Long = 1
Public Const WIN32API_FALSE As Long = 0

' トップレベルウィンドウを列挙する関数
Public Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, _
ByVal lParam As Long) As Long

' ウィンドウのキャプションを取得する関数
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long

' ウィンドウのキャプションの長さを取得する関数
Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hwnd As Long) As Long

' ウィンドウが表示されているか調べる関数
Public Declare Function IsWindowVisible Lib "user32" _
(ByVal hwnd As Long) As Long

' 指定した関係のウィンドウハンドルを取得する関数
Public Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Public Const GW_OWNER = 4

' 最後にアクティブなポップアップウィンドウを調べる関数
Public Declare Function GetLastActivePopup Lib "user32" _
(ByVal hwndOwnder As Long) As Long
    • good
    • 0
この回答へのお礼

ありがとうございます。
 
> If (IsWindowVisible(hwnd) = WIN32API_TRUE) And _
>   (GetWindowTextLength(hwnd) > 0) And _
>   (GetWindow(hwnd, GW_OWNER) = 0) Then
>   glngPrevHwnd = GetLastActivePopup(hwnd)
>   EnumWindowsSubProc = WIN32API_FALSE
> Else
>   EnumWindowsSubProc = WIN32API_TRUE
> End If

私の場合IsWindowVisible(hwnd)だけでふるい分けていたのですが、
上のようにしなければならなかったのですね。
勉強になりました。

どうもありがとうございました。

お礼日時:2007/01/10 03:18

 サンプルは、タスクマネージャのタスクに表示されるものしか


対象になってなせん。一部のウィンドウは、選択されない場合が
あります。

 yamamoto99さんのやられたように、以下のようにvisibleだけの
チェックにして、visible以外にも、キャプションの有無、最小化
されているか、ウィンドウスタイル(ツールウィンドウなどかどうか)
などを、必要に応じてチェックを追加されるのがよいと思います。

If (IsWindowVisible(hwnd) = WIN32API_TRUE) Then
glngPrevHwnd = hwnd
EnumWindowsSubProc = WIN32API_FALSE
Else
EnumWindowsSubProc = WIN32API_TRUE
End If
    • good
    • 0
この回答へのお礼

度重なるアドバイスどうもありがとうございます。
 
> キャプションの有無、最小化されているか、
> ウィンドウスタイル(ツールウィンドウなどかどうか)
> などを、必要に応じてチェックを追加されるのがよいと思います。

なるほどそうですね。
最初、なぜ
 GetWindow(hwnd, GW_OWNER) = 0
が必要なのか理解できずいろいろ調べていたら、VBのフォームがオーナーウインドウではないということがわかり驚きました。

ご親切にいろいろとどうもありがとうございました。

お礼日時:2007/01/10 20:20

★簡単にアドバイス


・ウインドウの列挙は『EnumWindows』で行ってみましょう。
・この関数の方が、Zオーダーを正しく探せます。というよりも
 トップレベル・ウィンドウのハンドルをリストアップ出来るため
 子ウインドウのハンドルはカットしてくれます。使いやすいかな。
・列挙用のコールバック関数 EnumWindowsProc() は自作関数になります。
・この関数でウインドウを列挙して、2つ目が列挙されたら終了すれば
 ちょうど、Zオーダーの上から2番目のウインドウのハンドルを取得
 できます。
・EnumWindowsProc関数の引数 LPARAM に、ウインドウハンドルへの
 ポインタを指定しておき、そこへ列挙されるウインドウハンドルを
 セットしましょう。または、グローバル変数で用意したハンドルに
 保存して返します。
・あと、EnumWindowsProc で自作フォームのウインドウハンドルの次を
 取得したいのならば、列挙されるハンドルと Form1.hwnd を比較して
 一致したら、次に列挙されるハンドルを返す工夫が必要です。
・以上。おわり。→私は、C/C++ なのでサンプルは紹介できません。

関連:
http://www.winapi-database.com/Window/Change/Enu …
http://www.winapi-database.com/Window/Change/Enu …

参考URL:http://www.winapi-database.com/Window/Change/
    • good
    • 0
この回答へのお礼

ありがとうございます。

> ・ウインドウの列挙は『EnumWindows』で行ってみましょう。
> ・この関数の方が、Zオーダーを正しく探せます。

そうだったんですか!!
EnumWindowsは以前使ったことがあったのですが、zオーダー順に返してくれるとは知りませんでした。

さっそく作ってみたところ、うまくいきました!!

どうもありがとうございました。

お礼日時:2007/01/09 23:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!