| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 904 人关注过本帖
标题:为什么生成EXE文件后找到的句柄就不对?
只看楼主 加入收藏
comb007
Rank: 2
等 级:论坛游民
帖 子:20
专家分:12
注 册:2013-12-26
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:7 
为什么生成EXE文件后找到的句柄就不对?
请问论坛里前辈,我最近在写一个程序,要点击第三方程序的对话框。在VB里调试时,一点问题都没有,对话框和按钮句柄都找到,也能点击。
但我一生成EXE文件,就点击不了。经研究,对话框句柄仍然是对的,但按钮句柄就不对了。可是调试时总是对的。

b=findwindowex(a,0,"button","否(&)")  '按钮句柄有类名有标题,调试时一直正确,生成EXE就不正确。

不知道什么原因,望前辈们赐教!
搜索更多相关主题的帖子: button 第三方 对话框 
2015-06-10 16:16
lianyicq
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:26
帖 子:737
专家分:3488
注 册:2013-1-26
收藏
得分:0 
生成了exe试记事本的另存为界面下的按钮没有问题.
能不能看看相关代码

大开眼界
2015-06-10 16:52
comb007
Rank: 2
等 级:论坛游民
帖 子:20
专家分:12
注 册:2013-12-26
收藏
得分:0 
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal Hwnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal WParam As Long, lParam As Any) As Long
Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Public Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByRef lParam As Long) As Long
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Public Declare Function SetFocus Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Const BM_CLICK = &HF5
Const WM_GETTEXT = &HD
Dim gg_2, m

Sub Main()
m = 1
time1 = Now + TimeValue("00:00:10")
Do Until gg_2 <> 0 Or Now >= time1
If EnumWindows(AddressOf EnumProc1, 0) = 0 Then
Else
End If
DoEvents
Loop

End Sub


Public Function EnumProc1(ByVal app_hwnd As Long, ByVal lParam As Long) As Boolean
Dim s As String
s = String(255, 0)
GetClassName app_hwnd, s, Len(s)
If s Like "*32770*" Then
      If EnumChildWindows(app_hwnd, AddressOf EnumchildProc2, 0) = 0 Then
         gg_2 = FindWindowEx(app_hwnd, 0, "Button", "否(&N)")
         If gg_2 <> 0 Then SendMessage gg_2, BM_CLICK, 0, 0
         'SetFocus (gg_2)
         If gg_2 <> 0 Then EnumProc1 = False Else EnumProc1 = True
      Else
         EnumProc1 = True
      End If
      'End If
Else
EnumProc1 = True
End If

End Function


Public Function EnumchildProc2(ByVal app_hwnd As Long, ByVal lParam As Long) As Boolean
Dim s As String
s = String(255, 0)
SendMessage app_hwnd, WM_GETTEXT, 255, ByVal s
If s Like "*请问您真的要这样操作*" Then
Open "d:\" & m & ".txt" For Output As #1          '这一段和m是为了检测错误加进去的。当调试时,只找到一次s,只有一个m文件,然后可以点击按钮。当生产EXE文件后,同样的s能找到2000次,能生成2000个m文件,并且内容是一样的。。最后按钮也没点到。
Print #1, GetParent(app_hwnd)
Print #1, app_hwnd
Print #1, s
Close #1
m = m + 1
    EnumchildProc2 = False
    Else
    EnumchildProc2 = True
    End If
End Function
2015-06-10 19:49
lianyicq
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:26
帖 子:737
专家分:3488
注 册:2013-1-26
收藏
得分:0 
回复 3楼 comb007
感觉用EnumChildWindows(app_hwnd, AddressOf EnumchildProc2, 0) = 0作为后续代码的分支条件不合适.
EnumChildWindows的返回值虽然定义为布尔型,但微软根本就没使用它。
EnumWindows的返回值为0时表示调用失败,这也不能作为分支条件。
在Public Function EnumProc1(ByVal app_hwnd As Long, ByVal lParam As Long) As Boolean这个函数中,如果当前窗体类名满足like "*32770*"时,执行后续操作后就应该返回false中止枚举。但代码中竟还有继续枚举的。
自己再调整看看,另外32770这个类有点特殊,有可能出现一些不好理解的问题

大开眼界
2015-06-11 11:06
comb007
Rank: 2
等 级:论坛游民
帖 子:20
专家分:12
注 册:2013-12-26
收藏
得分:0 
谢谢版主,但是我还想讲下,
1,EnumWindows和EnumChildWindows我一直都用得很好,就是在这个对话框上运行不正常。
2,“EnumWindows的返回值为0时表示调用失败"不太理解。我一直认为,返回值为0表示调用成功并枚举到了符合条件的句柄,未枚举到了符合条件的句柄返回-1,调用失败没遇到过,我理解的调用失败是除非桌面上一个窗体都没有,EnumWindows才会出现调用失败。
3,上述例子中,即使按钮句柄找对了,即gg_2没问题,但回到main程序gg_2会=0(在生成EXE情况下,调试状态没问题),无法实现全局变量的功能。程序会反复执行直到10秒。这也解释了上述例子为什么m会有2000个,因为我发现,不管gg_2找对没有,到main程序gg_2会=0,程序反复执行。

麻烦版主和各位前辈重点帮我看看3
2015-06-11 12:44
comb007
Rank: 2
等 级:论坛游民
帖 子:20
专家分:12
注 册:2013-12-26
收藏
得分:0 
我昨天测试了下,在EnumProc1下面gg_2<>0,然后EnumProc1 = False,但回到main程序gg_2会=0
2015-06-11 12:47
lianyicq
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:26
帖 子:737
专家分:3488
注 册:2013-1-26
收藏
得分:20 
回复 5楼 comb007
来自msdn
EnumWindows function
Enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.
Parameters
lpEnumFunc [in]
Type: WNDENUMPROC
A pointer to an application-defined callback function. For more information, see EnumWindowsProc.
lParam [in]
Type: LPARAM
An application-defined value to be passed to the callback function.
Return value
Type:
Type: BOOL
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
If EnumWindowsProc returns zero, the return value is also zero. In this case, the callback function should call SetLastError to obtain a meaningful error code to be returned to the caller of EnumWindows.

注意红字

大开眼界
2015-06-11 15:21
comb007
Rank: 2
等 级:论坛游民
帖 子:20
专家分:12
注 册:2013-12-26
收藏
得分:0 
谢谢版主!
2015-06-11 17:12
快速回复:为什么生成EXE文件后找到的句柄就不对?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.101022 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved