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

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

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

Re[4]: 同じフォルダーウインドウを閉じる方法


(過去ログ 141 を表示中)

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

■82781 / inTopicNo.1)  同じフォルダーウインドウを閉じる方法
  
□投稿者/ メンラー (1回)-(2017/02/04(Sat) 10:32:35)

分類:[.NET 全般] 

Windowsで作業をしていて
同じフォルダーを二つ以上開いてしまうことがあります。

同じフォルダーが開かれている場合
一つを残してそれ以外を閉じるプログラムを作りたいと考えています。


以下のコードを作ったのですが
この方法だと、
例えば

C:\testフォルダーと
D:\textフォルダーが開かれている場合、
フルパスは異なるのに、フォルダー名は同じなので
同じフォルダーだと認識されてしまい、
片方が閉じられてしまいます。

フルパスが違っている場合には、
フォルダー名が同じでも閉じないようにしたいのですが
どうすれば良いでしょうか?





Imports System.Runtime.InteropServices
Imports System.Text


'http://dobon.net/vb/dotnet/process/enumwindows.html
Public Class Program
    ''' <summary>
    ''' エントリポイント
    ''' </summary>

    Declare Function SetCurrentDirectoryW Lib "kernel32" (ByVal lpPathName As Long) As Long
    Private Declare Function MoveWindow Lib "user32" Alias "MoveWindow" _
    (ByVal hwnd As IntPtr, ByVal x As Integer, ByVal y As Integer, _
    ByVal nWidth As Integer, ByVal nHeight As Integer, _
    ByVal bRepaint As Integer) As Integer



    Public Shared Sub Main()


        'ウィンドウを列挙する
        EnumWindows(New EnumWindowsDelegate(AddressOf EnumWindowCallBack), _
                    IntPtr.Zero)

        Beep()
    End Sub

    Public Delegate Function EnumWindowsDelegate(ByVal hWnd As IntPtr, _
        ByVal lparam As IntPtr) As Boolean

    <DllImport("user32.dll")> _
    Public Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsDelegate, _
        ByVal lparam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

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

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function GetClassName(ByVal hWnd As IntPtr, _
        ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function

    'クローズメッセージを選択されたウィンドウに送る 
Public Const WM_CLOSE = &H10
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
         (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer



Public Const SC_CLOSE = &HF060
Public Const WM_SYSCOMMAND = &H112

Private Shared Win_hai() As String
Private Shared filenum As Integer = 0


    Private Shared Function EnumWindowCallBack(ByVal hWnd As IntPtr, _
            ByVal lparam As IntPtr) As Boolean


        'ウィンドウのタイトルの長さを取得する
        Dim textLen As Integer = GetWindowTextLength(hWnd)
        If 0 < textLen Then
            'ウィンドウのタイトルを取得する
            Dim tsb As New StringBuilder(textLen + 1)
            GetWindowText(hWnd, tsb, tsb.Capacity)

            'ウィンドウのクラス名を取得する
            Dim csb As New StringBuilder(256)
            GetClassName(hWnd, csb, csb.Capacity)

            If csb.ToString() = "CabinetWClass" Then        'ウインドウの場合



                If filenum >= 1 Then


                    For i As Integer = 1 To filenum

                        If Win_hai(i) = tsb.ToString() Then

                            SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0%)
                            Return True

                        End If

                    Next i


                End If


                    filenum = filenum + 1
                    ReDim Preserve Win_hai(filenum)
                     Win_hai(filenum) = tsb.ToString()


            End If
        End If

        Return True
    End Function
End Class



引用返信 編集キー/
■82782 / inTopicNo.2)  Re[1]: 同じフォルダーウインドウを閉じる方法
□投稿者/ Hongliang (494回)-(2017/02/04(Sat) 11:27:37)
2017/02/04(Sat) 11:33:25 編集(投稿者)
こんなのはどうでしょうか。

Dim shell = CreateObject("Shell.Application")
Dim wins = shell.Windows()
Dim count As Integer = wins.Count
Dim paths As New HashSet(Of String)
Dim targets As New List(Of Object)
For i As Integer = 0 To count - 1
    Dim win = wins.Item(CObj(i))
    Dim name = Path.GetFileNameWithoutExtension(CStr(win.FullName))
    If name.ToUpper() = "EXPLORER" Then
        Dim path = CStr(win.Document.Folder.Self.Path)
        If Not (paths.Add(path)) Then
            targets.Add(win)
        End If
    End If
Next
For Each target As Object In targets
    target.Quit()
Next

引用返信 編集キー/
■82783 / inTopicNo.3)  Re[2]: 同じフォルダーウインドウを閉じる方法
□投稿者/ メンラー (2回)-(2017/02/04(Sat) 11:43:45)
ありがとうございます。

実行してみたのですが
うまく動作しないのですが・・・

デバッグしてみたのですが

同じフォルダーが開かれている場合
targets.Add(win)
は実行されているようです
その後、次のforループに回って
Dim win = wins.Item(CObj(i))

を実行しようとした時にプログラムが終了してしまっているようです

一体何が原因でしょうか?
 
引用返信 編集キー/
■82784 / inTopicNo.4)  Re[3]: 同じフォルダーウインドウを閉じる方法
□投稿者/ メンラー (3回)-(2017/02/04(Sat) 11:54:35)
やはり

Dim name = Path.GetFileNameWithoutExtension(CStr(win.FullName))
でエラーが出ているようです
オブジェクト変数または With ブロック変数が設定されていません。


全てのオブジェクトに対してではないですが、このエラーが出てクラッシュしてしまいます
 


引用返信 編集キー/
■82785 / inTopicNo.5)  Re[4]: 同じフォルダーウインドウを閉じる方法
□投稿者/ メンラー (5回)-(2017/02/04(Sat) 12:05:27)

If win IsNot Nothing Then


でうまくいきました

どうもありがとうございました。
 
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -