我的代码是这样写的:
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,请问各位,到底是怎么回事?
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,请问各位,到底是怎么回事?
那我该怎么弄才能让commonDialog3不用我点“取消”就自动关闭呢?直接删除CommonDialog3.ShowOpen这一句,好像就相当于对话框没打开过,整段都白写了。
我现在在用了一个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程序,那个程序一定得打开一次对话框,所以我只好模拟来一次,然后马上让它关闭。
Phwnd = FindWindow(vbNullString, "打开")
这一句,那个外部exe程序的打开对话框的标题栏内容是不是“打开”呀?
你要按它的实际内容把‘打开’替换。
或者用 settimer 也可以
建议一个新的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调试通过。
有可能是因为你的时间间隔太快了,“打开”对话框还没被创建,Timer 函数就被执行了!
而你在 Timer 函数中未经过任何验证就把 Timer 禁止了,而没有继续执行下去你可以尝试把 Timer1.Enabled 写在 If Phwnd <> 0 Then 里面,就是当找到了窗口才停止计时器
如果真像楼主说的那样是为了拦截外部程序的对话框,那么我觉得你的这段代码没什么用了。
楼主只是为了测试才在自己的窗口创建“打开”对话框~~~
如果是外部程序的话,估计楼主的程序也不需要使用窗体了,所以也接收不到窗口消息。
只需要在 Sub Main 函数里使用循环(加DoEvents 和一个 Sleep(1) 来防止CPU占用问题)来查找窗口就行了。如果楼主的程序需要一个窗口,那么你这段代码就一定要在外部程序运行之后,才能运行。
估计用户也不会这么傻点完这个再点另外一个程序吧,那我还不如直接点“打开”对话框的关闭按钮~~那么如果先运行你的代码,再去打开外部程序的话,那么你的窗口已经失去焦点。
外部程序运行后,你的窗口也不会有任何消息了。那么子类化函数中的代码也执行不了~
事件产生的问题,当然不用这么做。
但是,他现在的问题是因为本身程序的模式窗口弹出后,中止了Timer事件的产生,才会遇到这样的问题。
你最好自己测试一下,建一个窗口,里面放个Timer控件,然后在Timer事件里不停的加一个数字并显示
在你的窗口上,然后做个按钮,里面就是作弹出对话框的操作,你可以看看,当你电击按钮弹出打开对话
框的时候,下面窗口的数字还动不动?不可能是因为太快或是很么其他的原因,因为当模式窗口弹出后,
Timer事件根本就停止了,所以将捕获这种模式窗口的工作放到Timer事件里根本就不可能被执行。
好吧,经过测试,的确我11楼的想法错了~~~~~但是呢,我还是觉得你在10楼的代码中(我没测试过外部程序),如果楼主在真正应用中真把你的代码写到他自己的窗口中,那么就不会有用了吧!
楼主只是为了方便测试,所以才在自己的程序里头创建模态对话框。
真正的问题还是外部程序的问题,除非你的程序是全局钩子咯。那么如果真要用Timer来检测外部程序的话,按照楼主5楼的代码,在按钮的处理函数中把创建模态对话框的代码删去,还是会遇到一个先后运行的顺序问题。
如果楼主的程序先运行,那么在Timer函数中,还没找到目标句柄就过早的关闭了计时器。
而如果先运行外部程序,再运行楼主的程序,也是不行,不能达到楼主所要的效果,即外部程序的模态对话框还是会弹出来,起码可以让用户看得见。