CreateProcessからのウィンドウのハンドルの取得について

解決


たく  2003-08-06 04:40:40  No: 107977

今XPとVB6でファイル操作のプログラムを書いているのですが
VBからエクスプローラを起動した時にエクスプローラのウィンドウの
ハンドルがなぜか取得できません^^;

CreateProcessでプロセスを作成し、そのプロセスで
EnumWindowsで検索しているのですが、ウィンドウは
作成されているのですが列挙されるプロセスの中に
一致するのがみつからないです。

ためしにエクスプローラではなく、メモ帳でやったところ
うまくいったのですが、エクスプローラウィンドウの場合は
EnumWindowsでは列挙されないのでしょうか?

参考までに以下にソースを記載します。
よろしくおねがいします

Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, lPalam As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Public m_Handle '取得ハンドル

Public Function EnumWindowsProc(ByVal Handle As Long, ByVal lpParam As Long) As Boolean
    
    Dim m_Thread As Long
    Dim m_Process As Long

      
        m_Process = 0
      'プロセスIDを取得する
        m_Thread = GetWindowThreadProcessId(Handle, m_Process)

        If m_Process = lpParam Then
            m_Handle = Handle
            EnumWindowsProc = False
            Exit Function
        End If
    EnumWindowsProc = True
End Function

-------------------------------------------

一部抜粋

    
 'セキュリティ構造体を初期化
    udtProcessAttributes.nLength = Len(udtProcessAttributes)
    udtThreadAttributes.nLength = Len(udtThreadAttributes)
    
    sCurrentDri = vbNullString  'カレントディレクトリを指定
    udtStartupInfo.cb = Len(udtStartupInfo) 
                '新しいプロセスのメインウインドウの表示状態を指定
    
    '新しいプロセスの作成
    lngResult = CreateProcess(vbNullString, _
                                            "explorer.exe " & sComLine, _
                                            udtProcessAttributes, _
                                            udtThreadAttributes, _
                                            False, _
                                            0, _
                                            ByVal vbNullString, _
                                            sCurrentDri, _
                                            udtStartupInfo, _
                                            udtProcessInformation)
                                            
                                            
    If lngResult <> 0 Then
        
        '対象ウインドウのハンドルを検索
        
    
      Ret = EnumWindows(AddressOf EnumWindowsProc, udtProcessInformation.dwProcessId)
    
-------------------以下省略------------------


たく  2003-08-06 05:38:44  No: 107978

補足ですが、起動したEXPLORERのウィンドウのプロセスIDを
別の方法で確かめてみたのですが、そのIDはCreateProcessで取得した
IDとは異なっていました。

CreateProcessでexplorerを起動する場合は何か特別な方法が
必要なのでしょうか?


たかみちえ  URL  2003-08-06 08:42:32  No: 107979

エクスプローラは特殊なものです。
ファイラにもなりうるし、同時にシェルでもあります。
  シェルとして起動中ファイラとして起動した場合、
ファイラとして起動したものは、シェルとして起動したエクスプローラに統合されますね?
(タスクマネージャで見ても、常にexplorerは一個以下しかないでしょう?)
  ですから、CreateProcessから起動したから、それを操作できるだろうと考えるのは、ちょっとこの場合無理そうです。


魔界の仮面弁士  2003-08-06 11:38:27  No: 107980

> 今XPとVB6でファイル操作のプログラムを書いているのですが
> VBからエクスプローラを起動した時にエクスプローラのウィンドウの
> ハンドルがなぜか取得できません^^;

エクスプローラウインドウのハンドルを得てから、その後、
最終的に何をしたいのかにもよりますが、APIでエクスプローラの
ウィンドウハンドルを取得し、それをAPIで操作する替わりに、
エクスプローラをCreateObjectで起動し、それを操作するという
手法もあります。

# あるいは、CreateObjectで新規に起動するのではなく、
# 起動済みのエクスプローラを、ShellWindowsオブジェクトで
# 列挙して使う事もできます。

たとえば、このような事もできます。

Option Explicit

Private Sub Command1_Click()
    Dim obj As Object
    Dim fis As Object
    Dim sfv As Object
    Dim S As String

    'エクスプローラを起動し、Cドライブを開く
    Set obj = CreateObject("InternetExplorer.Application", "localhost")
    obj.Navigate2 "C:\", CVar(&H20)

    '画面左上に、画面の3/4の大きさで表示
    obj.Left = 0
    obj.Top = 0
    obj.Width = (Screen.Width / Screen.TwipsPerPixelX) * 0.75
    obj.Height = (Screen.Height / Screen.TwipsPerPixelY) * 0.75
    obj.ShowBrowserBar "{EFA24E64-B078-11D0-89E4-00C04FC9E26E}", True
    obj.Visible = True

    Set sfv = obj.document
    Set fis = sfv.Application.NameSpace("C:\").Items()

    '"C:\Program Files"フォルダを選択させた状態にする
    sfv.SelectItem fis.Item("Program Files"), 3&

    '"C:\Documents and Settings"にフォーカスをあてる(選択はしない)
    sfv.SelectItem fis.Item("Documents and Settings"), 16&

    Set fis = Nothing
    Set sfv = Nothing

    'エクスプローラのウィンドウハンドルを取得
    S = Right(String(8, "0") & Hex(obj.hWnd), 8)

    '終了処理
    S = "エクスプローラ(0x" & S & ")を閉じます。"
    If MsgBox(S, vbOKCancel Or vbSystemModal Or vbInformation, "Sample") = vbOK Then
        obj.Quit
    End If
    Set obj = Nothing
End Sub


たく  2003-08-08 00:43:45  No: 107981

遅くなってしまいました・・・アセアセ

解答ありがとうございました>たかみちえさん、魔界の仮面弁士さん
ペコリ(o_ _)o))


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加