C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: 画面に表示されているウィンドウを列挙したい


(過去ログ 57 を表示中)

[トピック内 24 記事 (1 - 20 表示)]  << 0 | 1 >>

■32398 / inTopicNo.1)  画面に表示されているウィンドウを列挙したい
  
□投稿者/ ken (22回)-(2009/02/06(Fri) 09:48:40)

分類:[VB.NET/VB2005 以降] 

2009/02/06(Fri) 10:03:23 編集(投稿者)

画面に表示(というより、最小化されていないもの)されているウィンドウを列挙したい

現在、デスクトップ上に表示されているウィンドウ(Excelやエクスプロラなど)を取得したく
下記サイトの方法を試したのですが、最小化されいるものまで取得されてしまいます。
また、IEやエクスプローラを複数起動していても、プロセスとしてひとつしか取得できません。

http://www.atmarkit.co.jp/fdotnet/dotnettips/233enumwin/enumwin.html

デスクトップ上に表示されている最小化されているウィンドウ以外(画面の領域外でもよい)を
取得するにはどうすればよいでしょうか。(プロセス単位ではなくウィンドウ(フォーム?)単位で)

すべてのウィンドウを列挙してから、ウィンドウのサイズ?位置?から判断するしかないのでしょうか

よろしくお願い致します。
引用返信 編集キー/
■32399 / inTopicNo.2)  Re[1]: 画面に表示されているウィンドウを列挙したい
□投稿者/ επιστημη (1659回)-(2009/02/06(Fri) 10:12:52)
επιστημη さんの Web サイト
2009/02/06(Fri) 10:31:35 編集(投稿者)

> 画面に表示(というより、最小化されていないもの)されているウィンドウを列挙したい

System.Diagnostics.Process p に対し、
p.MainWindowHandle で得られたハンドルを引数に WindowsAPI: IsIconic を呼べば
そいつが最小化されてるか否かが得られます。

VB.NETから IsIconic-API を呼ぶには
Private Declare Auto Function IsIconic Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean
なんてな宣言しとけばおっけぃなんですが、C#からだと...えーと、ふぉろーよろしく > だれぞ

> IEやエクスプローラを複数起動していても、プロセスとしてひとつしか取得できません。

プロセスとしては一個しか立ち上がってないってことでしょうかね。
EnumWindows-API で(プロセスじゃなく)toplevel-windowを列挙せにゃならんかな。
ここらへん↓が使えそう。
http://msdn.microsoft.com/ja-jp/library/843s5s5x.aspx


引用返信 編集キー/
■32401 / inTopicNo.3)  Re[2]: 画面に表示されているウィンドウを列挙したい
□投稿者/ επιστημη (1660回)-(2009/02/06(Fri) 10:19:39)
επιστημη さんの Web サイト
2009/02/06(Fri) 10:38:54 編集(投稿者)
> VB.NETから IsIconic-API を呼ぶには
> Private Declare Auto Function IsIconic Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean
> なんてな宣言しとけばおっけぃなんですが、C#からだと...えーと、ふぉろーよろしく > だれぞ

こんなんでいいのかな。
VBおんちなのでC#版です。VB版だれぞよろ。

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

public class EnumWindows {

  // P/InvokeによるIsIconic召喚の呪文
  [DllImport("user32.dll")]
  [return: MarshalAs(UnmanagedType.Bool)]
  static extern bool IsIconic(IntPtr hWnd);

  static void Main() {
    // プロセスを列挙して
    foreach (Process p in Process.GetProcesses()) {
      // MainWindowHandleを持ち、かつそれが最小化されてないなら
      if (p.MainWindowHandle != IntPtr.Zero && !IsIconic(p.MainWindowHandle) ) {
        // プリントしる!
        Console.WriteLine(p.ProcessName + " : " + p.MainWindowTitle);
      }
    }
  }
}

引用返信 編集キー/
■32403 / inTopicNo.4)  Re[3]: 画面に表示されているウィンドウを列挙したい
□投稿者/ はつね (943回)-(2009/02/06(Fri) 10:56:31)
はつね さんの Web サイト
2009/02/06(Fri) 11:33:12 編集(投稿者)
No32401 (επιστημη さん) に返信
> VBおんちなのでC#版です。VB版だれぞよろ。

こんなんかなー

Imports System
Imports System.Diagnostics
Imports System.Runtime.InteropServices

Public Class Form1
    Private Declare Auto Function IsIconic Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.ListBox1.Items.Clear()
    End Sub

    Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        For Each p As Process In Process.GetProcesses
            If p.MainWindowHandle <> IntPtr.Zero AndAlso Not isiconic(p.MainWindowHandle) Then
                Me.ListBox1.Items.Add(String.Concat(p.ProcessName, " ", p.MainWindowTitle))
            End If
        Next
    End Sub
End Class


##追記:
ちなみにこのサンプルだと例えばIEなどを複数立ち上げてどちらも「最小化」以外になっていたときに1つしか表示されません。
Processの列挙ですものねー。

引用返信 編集キー/
■32404 / inTopicNo.5)  Re[2]: 画面に表示されているウィンドウを列挙したい
□投稿者/ ken (23回)-(2009/02/06(Fri) 10:57:23)
No32399 (επιστημη さん) に返信
>>IEやエクスプローラを複数起動していても、プロセスとしてひとつしか取得できません。
>
> プロセスとしては一個しか立ち上がってないってことでしょうかね。
> EnumWindows-API で(プロセスじゃなく)toplevel-windowを列挙せにゃならんかな。
> ここらへん↓が使えそう。
> http://msdn.microsoft.com/ja-jp/library/843s5s5x.aspx

Process.GetProcesses()では無理で、EnumWindows-APIを使用するということでしょうか?

引用返信 編集キー/
■32405 / inTopicNo.6)  Re[3]: 画面に表示されているウィンドウを列挙したい
□投稿者/ επιστημη (1662回)-(2009/02/06(Fri) 11:10:06)
επιστημη さんの Web サイト
2009/02/06(Fri) 11:12:33 編集(投稿者)

> Process.GetProcesses()では無理で、EnumWindows-APIを使用するということでしょうか?

だって列挙したいのはWindowなんでしょ? Processじゃないんでしょ?
四の五の言わんとやってみたらえぇやん。

# はつねタン さんきゅ。

引用返信 編集キー/
■32407 / inTopicNo.7)  Re[4]: 画面に表示されているウィンドウを列挙したい
□投稿者/ ken (24回)-(2009/02/06(Fri) 11:14:03)
No32405 (επιστημη さん) に返信
> だって列挙したいのはWindowなんでしょ? Processじゃないんでしょ?

やりたくないのではなく、Process.GetProcesses()では無理なのかと聞いたのです。
無理ということでよろしいですね?
引用返信 編集キー/
■32408 / inTopicNo.8)  Re[5]: 画面に表示されているウィンドウを列挙したい
□投稿者/ επιστημη (1663回)-(2009/02/06(Fri) 11:17:22)
επιστημη さんの Web サイト
2009/02/06(Fri) 11:21:25 編集(投稿者)

> やりたくないのではなく、Process.GetProcesses()では無理なのかと聞いたのです。
> 無理ということでよろしいですね?

僕はそんなのに責任もてないす。
とはいえひとつのプロセスが複数のWindowを開けてたらまずダメなのは明らかですわね。

「Windowを列挙したいならそれにふさわしいやり方がありますよ」
ってことで。

引用返信 編集キー/
■32409 / inTopicNo.9)  Re[4]: 画面に表示されているウィンドウを列挙したい
□投稿者/ ken (25回)-(2009/02/06(Fri) 11:18:06)
επιστημη さん、はつね さん

サンプルソースまで、ありがとうございます。


> プロセスとしては一個しか立ち上がってないってことでしょうかね。
> EnumWindows-API で(プロセスじゃなく)toplevel-windowを列挙せにゃならんかな。
> ここらへん↓が使えそう。
> http://msdn.microsoft.com/ja-jp/library/843s5s5x.aspx

επιστημη さんから提示いただいた情報とともに一度試してみます。
また、報告します。
引用返信 編集キー/
■32410 / inTopicNo.10)  Re[1]: 画面に表示されているウィンドウを列挙したい
□投稿者/ 渋木宏明(ひどり) (1067回)-(2009/02/06(Fri) 11:23:29)
渋木宏明(ひどり) さんの Web サイト
> また、IEやエクスプローラを複数起動していても、プロセスとしてひとつしか取得できません。

EnumWindows() API を使ってください。

> すべてのウィンドウを列挙してから、ウィンドウのサイズ?位置?から判断するしかないのでしょうか

列挙してから、あるいは列挙しながら判定するしかないです。

引用返信 編集キー/
■32411 / inTopicNo.11)  Re[2]: 画面に表示されているウィンドウを列挙したい
□投稿者/ 渋木宏明(ひどり) (1068回)-(2009/02/06(Fri) 11:26:10)
渋木宏明(ひどり) さんの Web サイト
> VB.NETから IsIconic-API を呼ぶには
> Private Declare Auto Function IsIconic Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean
> なんてな宣言しとけばおっけぃなんですが、C#からだと...えーと、ふぉろーよろしく > だれぞ

pinvoke.net みれ。

http://pinvoke.net/default.aspx/user32/EnumWindows.html
http://pinvoke.net/default.aspx/user32/IsIconic.html
引用返信 編集キー/
■32413 / inTopicNo.12)  Re[3]: 画面に表示されているウィンドウを列挙したい
□投稿者/ επιστημη (1664回)-(2009/02/06(Fri) 11:42:36)
επιστημη さんの Web サイト
> pinvoke.net みれ。

みた。

あたしゃ C++/CLI だからP/Invokeなんか要らないもんねーだ♪

引用返信 編集キー/
■32414 / inTopicNo.13)  Re[5]: 画面に表示されているウィンドウを列挙したい
□投稿者/ たくボン (142回)-(2009/02/06(Fri) 12:21:23)
No32407 (ken さん) に返信
> ■No32405 (επιστημη さん) に返信
> やりたくないのではなく、Process.GetProcesses()では無理なのかと聞いたのです。
> 無理ということでよろしいですね?

なんだ?この上から目線は?
人に物を聞いてこの態度もどうかと思うぞ。

大体、こんなレベルの質問でろくに調べもせずに答えだけ聞きたいなら単なるクレクレ君やん。
答えだけ知りたいなら、お金払ってどっかの人に聞けばいいよ。

#最近忙しくてあんま見れないから、久しぶりに見たらこんなスレだし。
引用返信 編集キー/
■32417 / inTopicNo.14)  Re[6]: 画面に表示されているウィンドウを列挙したい
□投稿者/ ken (26回)-(2009/02/06(Fri) 13:12:02)
No32414 (たくボン さん) に返信

> なんだ?この上から目線は?
> 人に物を聞いてこの態度もどうかと思うぞ。
>
> 大体、こんなレベルの質問でろくに調べもせずに答えだけ聞きたいなら単なるクレクレ君やん。
> 答えだけ知りたいなら、お金払ってどっかの人に聞けばいいよ。

こちらから提示した方法では無理なんですか?という問いに
「四の五の言わんとやってみたらえぇやん。」と言われたので、
それでは可能なのか不可能なのか、判断できなかったのでそう質問してしまいました。

読み返してみて、確かに聞き方が悪かったと感じますし、
そんなの断言できないですよね。

とにかく、みなさんには不快な思いをさせてしまい申訳ありませんでした。

まだ、解決には至ってませんが、もうちょっと頑張ってみます。
引用返信 編集キー/
■32418 / inTopicNo.15)  Re[7]: 画面に表示されているウィンドウを列挙したい
□投稿者/ επιστημη (1666回)-(2009/02/06(Fri) 13:17:47)
επιστημη さんの Web サイト
> こちらから提示した方法では無理なんですか?という問いに
> 「四の五の言わんとやってみたらえぇやん。」と言われたので、
> それでは可能なのか不可能なのか、判断できなかったのでそう質問してしまいました。

ケツまくってるよな印象を与えちゃったですね、ごめんなさい。

いやね、ProcessからMainWindowHandle一個しかもらえないんだから複数個開けてたら
ダメダメなのは自明やないですか。なんとかしようとぐぢぐぢ訊いてるよか、
別解示されたんだからまずは試してみいひん? ってことです。

引用返信 編集キー/
■32419 / inTopicNo.16)  Re[8]: 画面に表示されているウィンドウを列挙したい
□投稿者/ ken (28回)-(2009/02/06(Fri) 13:28:10)
2009/02/06(Fri) 13:38:32 編集(投稿者)
2009/02/06(Fri) 13:29:14 編集(投稿者)

No32418 (επιστημη さん) に返信
> いやね、ProcessからMainWindowHandle一個しかもらえないんだから複数個開けてたら
> ダメダメなのは自明やないですか。なんとかしようとぐぢぐぢ訊いてるよか、
> 別解示されたんだからまずは試してみいひん? ってことです。

はい、全くその通りです。
ただあの時は、別解を試すより、ここまで作ったものを
なんとか活かせないものかということに執着してしまいました。
(これでは進歩はないですよね・・・。)

まだ、実現できてませんのでもうちょっと頑張ってみます。

引用返信 編集キー/
■32426 / inTopicNo.17)  Re[2]: 画面に表示されているウィンドウを列挙したい
□投稿者/ ken (29回)-(2009/02/06(Fri) 13:56:18)
下記ソースで、複数表示されているIEやエクスプローラも画面毎に取得できました。
しかし、ダイアログや、VBで作った画面でも、form.ShowInTaskbarがFalseの場合(?)のウィンドウなどは
取得できません。
こういったフォーム(画面)はどうやったら取得できるのでしょうか。

Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
    Private Delegate Function Callback(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Integer

    ' EnumWindows
    <DllImport("user32", EntryPoint:="EnumWindows")> _
    Private Shared Function EnumWindows( _
        ByVal lpEnumFunc As Callback, _
        ByVal lParam As Integer) _
        As Integer
    End Function

    ' GetWindowText
    <DllImport("user32", EntryPoint:="GetWindowText", CharSet:=CharSet.Auto)> _
    Private Shared Function GetWindowText( _
        ByVal hWnd As IntPtr, _
        ByVal lpString As StringBuilder, _
        ByVal nMaxCount As Integer) _
        As Integer
    End Function

    ' IsWindowVisible
    <DllImport("user32", EntryPoint:="IsWindowVisible")> _
    Private Shared Function IsWindowVisible( _
        ByVal hWnd As IntPtr) _
        As Integer
    End Function


    Public Function EnumerateWindows(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Integer
        Dim sb As New StringBuilder(&H1000)
        If IsWindowVisible(hWnd) <> 0 Then
            If GetWindowText(hWnd, sb, &H1000) <> 0 Then
                Me.ListBox1.Items.Add(sb.ToString())
            End If
        End If
        Return Not 0
    End Function

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Me.ListBox1.Items.Clear()
        ' 列挙を開始
        EnumWindows(AddressOf EnumerateWindows, 0)
    End Sub

End Class

引用返信 編集キー/
■32427 / inTopicNo.18)  Re[3]: 画面に表示されているウィンドウを列挙したい
□投稿者/ 渋木宏明(ひどり) (1069回)-(2009/02/06(Fri) 14:11:17)
渋木宏明(ひどり) さんの Web サイト
> しかし、ダイアログや、VBで作った画面でも、form.ShowInTaskbarがFalseの場合(?)のウィンドウなどは
> 取得できません。

EnumWindows はトップレベルウィンドウを列挙する API です。

なので、EnumWindows でトップレベルウィンドウ以外のウィンドウが列挙されないのは仕様であり、正しい動作です。

> こういったフォーム(画面)はどうやったら取得できるのでしょうか。

「こういったフォーム(画面)」が何を指しているのか曖昧で分かりません。

仮に、トップレベルウィンドウだけなく、子ウィンドウの列挙が必要なのだとしたら、EnumWindows で列挙されたそれぞれのウィンドウハンドルに対して EnumChildWindows でもしてみるとか。
引用返信 編集キー/
■32428 / inTopicNo.19)  Re[4]: 画面に表示されているウィンドウを列挙したい
□投稿者/ ken (30回)-(2009/02/06(Fri) 14:21:26)
2009/02/06(Fri) 14:53:23 編集(投稿者)

No32427 (渋木宏明(ひどり) さん) に返信
> 「こういったフォーム(画面)」が何を指しているのか曖昧で分かりません。
>
> 仮に、トップレベルウィンドウだけなく、子ウィンドウの列挙が必要なのだとしたら、EnumWindows で列挙されたそれぞれのウィンドウハンドルに対して EnumChildWindows でもしてみるとか。

1.ファイルを開くなどのダイアログ系画面
2.VB.netで作ったShowInTaskbarプロパティ=Falseの画面

を言いたかったです。すみません。

2.については、.ShowDialogしているわけではないのですが、子ウィンドウになるのでしょうか?
EnumChildWindows ではとれませんでした。

引用返信 編集キー/
■32441 / inTopicNo.20)  Re[5]: 画面に表示されているウィンドウを列挙したい
 
□投稿者/ ken (31回)-(2009/02/06(Fri) 15:23:54)
No32428 (ken さん) に返信
> 2.については、.ShowDialogしているわけではないのですが、子ウィンドウになるのでしょうか?
> EnumChildWindows ではとれませんでした。

すいません。ウソでした。EnumChildWindows で取れてました。

EnumChildWindows で取得したウィンドウハンドルのうち、
ウィンドウ(画面)のもの、かつMDI子フォームは除きたいのですが、
どのように判断すればよいのでしょうか?
引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -