一开始使用 shell ,这样可以得到打开程序的 hwnd,在使用 WaitForSingleObject 就可以实现。可我想让系统使用默认程序任意文件,于是改用 ShellExecute ,可以这个 Api 不返回句柄。于是在用 EnumWindows 枚举出所有的程序来查找,可是在 ShellExecute 时打开的程序有可能很慢,这样往往在EnumWindows 时第一次找不到,还要在中间加上 Sleep(n)。假如说枚举的所有程序中有我想要的我又怎么知道是哪一个呢?

解决方案 »

  1.   

    先关注...   finding....
      

  2.   

    我参照 msdn 添加了以下 Api 声明:
    Private Declare Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" (ShellInfo As SHELLEXECUTEINFO) As LongPrivate Type SHELLEXECUTEINFO
            cbSize As Long
            fMask As Long
            hwnd As Long
            lpVerb As String
            lpFile As String
            lpParameters As String
            lpDirectory As String
            nShow As Long
            hInstApp As Long
            '  Optional fields
            lpIDList As Long
            lpClass As String
            hkeyClass As Long
            dwHotKey As Long
            hIcon As Long
            hProcess As Long
    End Typedim sInfo as SHELLEXECUTEINFO
    sInfo.hwnd 是指传入的父句柄吗?
      

  3.   

    读注册表,得到默认的程序,用shell programpath & " " & filepath
    即可
      

  4.   

    'ShellExecuteEx 的例子
    Option Explicit
    Private Declare Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" (ShellInfo As SHELLEXECUTEINFO) As Long
    Private Const SEE_MASK_FLAG_DDEWAIT = &H100
    Private Const SEE_MASK_NOCLOSEPROCESS = &H40
    Private Const SEE_MASK_FLAG_NO_UI = &H400
    Private Const PROCESS_QUERY_INFORMATION = &H400
    Private Type SHELLEXECUTEINFO
            cbSize As Long
            fMask As Long
            hwnd As Long
            lpVerb As String
            lpFile As String
            lpParameters As String
            lpDirectory As String
            nShow As Long
            hInstApp As Long
            '  Optional fields
            lpIDList As Long
            lpClass As String
            hkeyClass As Long
            dwHotKey As Long
            hIcon As Long
            hProcess As Long
    End Type
    Private Function Fileopen(sPath As String) As Long
        On Error Resume Next
        Dim she As SHELLEXECUTEINFO
        she.cbSize = 60
        she.fMask = SEE_MASK_FLAG_DDEWAIT + SEE_MASK_NOCLOSEPROCESS + SEE_MASK_FLAG_NO_UI
        she.hwnd = Me.hwnd
        she.lpVerb = "open"
        she.lpFile = sPath
        she.lpParameters = vbNullString
        she.lpDirectory = vbNullString
        she.nShow = 1 '设为0则不可见
        she.hInstApp = 0
        she.lpIDList = 0
        she.lpClass = vbNullString
        she.hkeyClass = 0
        she.dwHotKey = 0
        she.hIcon = 0
        she.hProcess = 0
        Fileopen = ShellExecuteEx(she)
    End FunctionPrivate Sub Command1_Click()
    Dim x As Long
    Dim sfile As String
    sfile = "d:\mc\aa.bmp"
    x = Fileopen(sfile)
    End Sub
      

  5.   

    sippey(sippey) :
    读注册表,得到默认的程序,用shell programpath & " " & filepath 即可---------------------
    我用过这种方法,但是不是所有的程序都能调用 .exe " " filename 打开的,比如:
    acdsee.exe(假设是 acdsee的执行文件) " " & c:\1.jpg,这样就不行。*********************
    我先试试 rainstormmaster(rainstormmaster) 的方法:不过我想实现的是等待 ShellExecute 打开的程序结束后,源程序在继续执行。
    之所以使用 ShellExecuteEx 是因为它的结构中有 she.hwnd,she.hProcess 值,我想知道在调用之前设置这些值或者在执行之后这些值被 Api 修改,以实现我找到被打开程序的目的。谢谢大家,请继续指教。
      

  6.   

    找到了更简单的方法:一开始使用 shell ,这样可以得到打开程序的 hwnd,在使用 WaitForSingleObject 就可以实现。可我想让系统使用默认程序任意文件这是问题的关键所在
    这样解决还是用shell语句
    这样写:
    Dim pid As Long
    pid = Shell("start d:\mc\aa.bmp")
    试试看,你发现了什么?
      

  7.   

    rainstormmaster(rainstormmaster):哈哈,方法够简便,我也尝想过是不是有什么通用的东西可以直接使用。可是我在刚试的时候报错:
    "Shell("start c:\odbcconf.log")" 
    “文件未找到!”,start 是个什么东西,start.exe?
      

  8.   

    是window的起动,在其中可以找到相关的程序起动快捷方式,但也要你的机器中安装得有相关程序才行。