我的代码是这样写的:
    CommonDialog3.InitDir = App.Path & "\Anal_Temp\"
    CommonDialog3.Filter = "文档文件(*.txt)|*.TXT|所有文件(*.*)|*.*" 
    CommonDialog3.DialogTitle = "打开"
    CommonDialog3.FileName = "T_OUT.TXT"
    CommonDialog3.ShowOpen
        
    Dim Phwnd As Long, ChildHwnd As Long
    Phwnd = FindWindow(vbNullString, "打开")
    If Phwnd <> 0 Then
      ChildHwnd = FindWindowEx(Phwnd, 0, "Button", "取消")
      SendMessage ChildHwnd, BM_CLICK, 0, ByVal 0&
    End If结果跟踪显示Phwnd的值总是等于0,请问各位,到底是怎么回事?

解决方案 »

  1.   

    CommonDialog3.ShowOpen 是阻塞执行.....在你关闭"打开"窗口前后面语句不会执行.而你关闭后,窗体已经不存在了....要是此时返回了句柄,那就见鬼了.....楼主的调试基本功还需要练习......这问题就算想不到,通过调试也能轻易发现.
      

  2.   

    对话框是个模式窗口,打开后代码执行暂停,等待你对对话框处理完才继续执行.在对话框打开期间,你后面的代码并没有被执行.而当你手动处理完对话框后,对话框关闭,FindWindow就检查不到了. 你可以另写个程序来检测.
      

  3.   


    那我该怎么弄才能让commonDialog3不用我点“取消”就自动关闭呢?直接删除CommonDialog3.ShowOpen这一句,好像就相当于对话框没打开过,整段都白写了。
      

  4.   


    我现在在用了一个timer1,代码改成:
    Form_Load中:
        Me.Timer1.Enabled = False
        Me.Timer1.Interval = 1
    cmd_click中:
        Me.Timer1.Enabled = True
        CommonDialog3.InitDir = App.Path & "\Anal_Temp\"
        CommonDialog3.Filter = "文档文件(*.txt)|*.TXT|所有文件(*.*)|*.*"
        CommonDialog3.DialogTitle = "打开"
        CommonDialog3.FileName = "T_OUT.TXT"
        CommonDialog3.ShowOpen
    Timer1_Timer中:
        Timer1.Enabled = False
        Phwnd = FindWindow(vbNullString, "打开")
        If Phwnd <> 0 Then
          ChildHwnd = FindWindowEx(Phwnd, 0, "Button", "取消")
          SendMessage ChildHwnd, BM_CLICK, 0, ByVal 0&
          Unload Me
       End If“打开”对话框打开后,还是不能自动关闭,一点反应也没有,该怎么办?:(
    注:我是shell一个外部exe程序,那个程序一定得打开一次对话框,所以我只好模拟来一次,然后马上让它关闭。
      

  5.   

    你要注意一下:
    Phwnd = FindWindow(vbNullString, "打开")
    这一句,那个外部exe程序的打开对话框的标题栏内容是不是“打开”呀?
    你要按它的实际内容把‘打开’替换。
      

  6.   

    用timer的话就要在编译后才有效果,在 showopen之前一句启动timer,
    或者用 settimer 也可以
      

  7.   

    用Windows消息的处理过程来处理是可以的,你按照以下方式来测试:
    建议一个新的EXE工程,默认窗口,名为Form1,然后在窗口中添加一个CommonDialog控件,
    名称为默认的CommonDialog1,然后再添加一个Label控件,名称也是默认的Label1然后再向工程添加一个模块,名称为默认的Module1
    Form1窗口全部代码如下:Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Const GWL_WNDPROC = (-4)
    Private Sub Command1_Click()
        ysWindowProc = GetWindowLong(Me.hWnd, GWL_WNDPROC)
        FunctionProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf WindowProc)
        CommonDialog1.DialogTitle = "打开"
        CommonDialog1.ShowOpen
    End SubModule1模块全部代码如下:Public ysWindowProc As Long
    Public FunctionProc As Long
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Const GWL_WNDPROC = (-4)Public Function WindowProc(ByVal hWnd As Long, _
                               ByVal wMsg As Long, _
                               ByVal wParam As Long, _
                               ByVal lParam As Long) As Long    Dim dghWnd As Long
        dghWnd = FindWindow("#32770", "打开")
        If dghWnd <> 0 Then
            Form1.Label1.Caption = "目标窗口:" & dghWnd
            SetWindowLong hWnd, GWL_WNDPROC, ysWindowProc
        Else
            WindowProc = CallWindowProc(FunctionProc, hWnd, wMsg, wParam, lParam)
        End If
    End Function
    然后运行,当点击按钮时,会弹出打开对话框,可以看到,窗口中的Label1的文字改变成了:
    "目标窗口:"和找到的对话框句柄,以上步骤在Win2003+VB6+SP6调试通过。
      

  8.   


    有可能是因为你的时间间隔太快了,“打开”对话框还没被创建,Timer 函数就被执行了!
    而你在 Timer 函数中未经过任何验证就把 Timer 禁止了,而没有继续执行下去你可以尝试把 Timer1.Enabled 写在 If Phwnd <> 0 Then 里面,就是当找到了窗口才停止计时器
      

  9.   


    如果真像楼主说的那样是为了拦截外部程序的对话框,那么我觉得你的这段代码没什么用了。
    楼主只是为了测试才在自己的窗口创建“打开”对话框~~~
    如果是外部程序的话,估计楼主的程序也不需要使用窗体了,所以也接收不到窗口消息。
    只需要在 Sub Main 函数里使用循环(加DoEvents 和一个 Sleep(1) 来防止CPU占用问题)来查找窗口就行了。如果楼主的程序需要一个窗口,那么你这段代码就一定要在外部程序运行之后,才能运行。
    估计用户也不会这么傻点完这个再点另外一个程序吧,那我还不如直接点“打开”对话框的关闭按钮~~那么如果先运行你的代码,再去打开外部程序的话,那么你的窗口已经失去焦点。
    外部程序运行后,你的窗口也不会有任何消息了。那么子类化函数中的代码也执行不了~
      

  10.   

    看来你的逻辑很不清楚。如果是外部程序,根本就不会遇到外部程序的模式窗口弹出而影响内部Timer
    事件产生的问题,当然不用这么做。
    但是,他现在的问题是因为本身程序的模式窗口弹出后,中止了Timer事件的产生,才会遇到这样的问题。
      

  11.   

    估计你自己都不知道这个是怎么回事。
    你最好自己测试一下,建一个窗口,里面放个Timer控件,然后在Timer事件里不停的加一个数字并显示
    在你的窗口上,然后做个按钮,里面就是作弹出对话框的操作,你可以看看,当你电击按钮弹出打开对话
    框的时候,下面窗口的数字还动不动?不可能是因为太快或是很么其他的原因,因为当模式窗口弹出后,
    Timer事件根本就停止了,所以将捕获这种模式窗口的工作放到Timer事件里根本就不可能被执行。
      

  12.   


    好吧,经过测试,的确我11楼的想法错了~~~~~但是呢,我还是觉得你在10楼的代码中(我没测试过外部程序),如果楼主在真正应用中真把你的代码写到他自己的窗口中,那么就不会有用了吧!
    楼主只是为了方便测试,所以才在自己的程序里头创建模态对话框。
    真正的问题还是外部程序的问题,除非你的程序是全局钩子咯。那么如果真要用Timer来检测外部程序的话,按照楼主5楼的代码,在按钮的处理函数中把创建模态对话框的代码删去,还是会遇到一个先后运行的顺序问题。
    如果楼主的程序先运行,那么在Timer函数中,还没找到目标句柄就过早的关闭了计时器。
    而如果先运行外部程序,再运行楼主的程序,也是不行,不能达到楼主所要的效果,即外部程序的模态对话框还是会弹出来,起码可以让用户看得见。