请教vb高手一段“关于获取正在系统中运行的窗口标题”原代码的调试(极具挑战性!)(25分)

  • 主题发起人 主题发起人 mazunini
  • 开始时间 开始时间
M

mazunini

Unregistered / Unconfirmed
GUEST, unregistred user!
有原代码是关于“VB获取正在系统中运行的窗口标题”问题的,代码如下:
模块中:
Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDLAST = 1
Public Const GW_HWNDNEXT = 2
Public Const GW_HWNDPREV = 3
Public Const GW_OWNER = 4

Sub FindTitle()
'查找桌面上的所有窗口标题
Dim currwnd As Integer
Combo1.Clear
currwnd = GetWindow(hwnd, GW - HWNDFIRST)
While currwnd <> 0
length = GetWindowTextLength(currwnd)
listitem = Space(length + 1)
length = GetWindowText(currwnd, listitem, length + 1)
If length > 0 then

Combo1.Addltem listitem
End If
currwnd = GetWindow(currwnd, GW_HWNDNEXT)
If Combl1.ListCount > 0 then

Combo1.Text = Combol.List(0)
Combo1.ListIndex = 0
else

MsgBox "没有发现可活动的窗口", 16, "活动"
End If
Wend
End Sub
Sub Sift()
'测试窗口能否活动
i = 0
Combo2.Clear
Do
On Local Error Resume Next
AppActivate Combo1.List(i)
If Err = 0 then

Combo2.AddItem Combo1.List(i)
End If
i = i + 1
Loop
i = Combo1.ListCount - 1
AppActivate Form1.Caption
If Combo2.ListCount > 0 then

Combo2.Text = Combo2.List(0)
Combo2.ListIndex = 0
else

MsgBox "没有发现可活动窗口", 16, "活动"
End If
End Sub
form1中代码:
Private Sub Command1_Click()
F = Combo2.Text
On Local Error Resume Next
AppActivate F

End Sub
Private Sub Command2_Click()
Call FindTitle
Call Sift
End Sub
Private Sub Form_Load()
Form1.Show '首先将本窗体显示出来,否则查找出的窗体标题没有本身
MsgBox "开始查找窗口标题"
Call FindTitle
Call Sift
End Sub
在form1中添加两个combo和command控件!该段程序我始终调不出来!在
combo1.clear和combo2.clear这两句话上报错,注销不用后运行死机,请问
该段程序哪里有问题??不做大的修改,如何调试??
 
你这代码里边还有许多语法错误,先把这个改了吧
 
你不会用debug.print吗?
 
没有语法错误了!我已经改过了!!(除了combo控件抱错)你说说看哪里有语法错误呀??
 
你这段代码毛病太多,无论是语法,基本的VB编程常识,你真的运行过这段代码吗?
像这句:Combo1.Clear
这句代码在模块中,编译程序知道是哪个Combo1啊,它怎么找到这个对象啊?
难道它可以自动知道是form1的?
还有:Combo1.Addltem listitem 有Addltem()这个方法吗?!
......
 
还有啊,以后没事不要老拿【极具挑战性】这种东西吓人
 
怎么说话的呀!我可没吓人呀!我也是在别的网页上看到的文章的!我急着要用,所以就调试
一下想用的,但没成功!这样,明天我把该篇文章原文给你看,看你能调的出!
 
还是那句话:这些代码里边还有些语法方面地错误。
 
该文章全文如下(如要原文,可告之mail地址):
用VB5.0获取正在系统中运行的窗口标题
山东德州 胥智强

--------------------------------------------------------------------------------
熟悉Visual Basic的读者都知道,AppActivate语句是激活一个应用程序窗口其后所带的参数是指要被子激活的应用程序窗口标题条的字符串。如果要激活的是一个常见的应用程序,我们在编写程序时就可以直接写上此程序的窗口标题。例如,我们想激活Windows95的计算器,可先运行程序x=SHELL("Calc.exe",1),然后再激活计算器窗口AppActivate“计算器”,则程序焦点自动转到计算器窗口上。然而单纯使用该方法局限性非常大,比如上述例子,如果我们放在英文Windows95上运行,计算器的窗口标题就不是“计算器”,而是“Calculator”。再一个局限性就是在很多情况下我们并不知道要激活的程序窗口标题名称,如何编制一个能自动查找程序窗口标题名称的程序是本文要解决的问题。
我们可以采取如下办法,来获取正在系统运行的窗口标题。
在WindowsAPI中有一个函数:
Get Windows (ByVal hWnd As Long ,ByVal wCmd As Long) As Long
其中,hWnd是当前窗口句柄,wCmd是与hWnd有联系的常量,其含义如下:
wCmd值
含义

GW-GHILD
第一个子窗口

GW-HWNDFIRST
子窗口的第一兄弟窗口,其第一个顶层窗口

GW-HWNDLAST
子窗口的最后一个兄弟窗口,或最后一个顶层窗口

GW-HWNDNEXT
后继窗口

GW-HWNDPRCV
先前窗口

GW-OWNER
窗口拥有者

此函数返回值是wCmd所指的窗口的句柄。
我们利用此句柄 ,再用函数Get WindowsText (ByVal hWnd As Long ,ByVal Ipstring As String, ByVal cch As Long) As Long,将句柄hWnd指定的窗口标题放入一个字符串变量Ipstring中,cch是指放入Ipstring中的最大字符数。此函数成功时返回字符串长度,如果窗口无标题则返回零。
在使用Get WindowsText函数前,还要先用函数Get WindowsTextLength (ByVal hWnd As Long )As Long得到hWnd指定窗口标题的长度,放入cch中。
自编一个过程FindTitle()查找系统中正在运行的所有标题,首先获得第一个顶层窗口句柄currwnd,而后采用While…Wend循环结构,当currwnd不为零而且标题文本长度不为零时,将获得的标题存入列表框Combo1,再找后继窗口的句柄,当句柄currwnd=0时表示已没有了后继窗口,退出循环。这样就将系统中所有的窗口句柄及标题找出来了。
然而调试中发现用此方法找到的窗口标题非常多,这说明Windows系统运行时有许多隐含的窗口,而这些窗口是我们所不需要的,而且用AppActivate激活时也出现错误。
因此我们再自编一个过程Sift ()查找可激活的窗口。其方法是用AppActivate逐个激活所有窗口,出现错误的丢掉,保留可激活的窗口标题,放入列表框Combo2。
首先新建窗体Form1,Caption=“获取窗口标题”,在窗体Form1上建立两个标签,Label1,Caption=“所有窗口标题”,Label2.Caption=“可激活的窗口标题”;建立两个下拉列表框,Combo1存放系统中的所有标题名称,Combo2存放可激活的标题名称;再建立两个命令按钮,Command1.Caption=“激活窗体”,可对所列窗体进行测试,命令按钮Command2.Caption=“刷新”,点击它可重新查找所有在系统中的窗体名称,当本程序运行以后又运行了新程序时使用此按钮。
从VB系统菜单上选取Project中的Add Module,将下述API函数及一些常量录入。
'Module 模块
Declare Function GetWindow Lib "user32"(ByVal hwnd As Long, ByVal wCmd As Long)As Long
Declare Function GetWindowText Lib "user32" Aias"GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String,ByVal cch As Long)As Long
Declare Function GetWindowText Length Lib "user32" Aias"GetWindowTextLengthA" (ByVal hwnd As Long)As Long
Public Const GW-HWNDFIRST=0
Public Const GW-HWNDLAST=1
Public Const GW-HWNDNEXT=2
Public Const GW-HWNDPREV=3
Public Const GW-OWNER=4
建立两个子程序:
Sub FindTitle ()
'查找桌面上的所有窗口标题
Dim currwnd As Integer
Combo1.Clear
Currwnd=GetWindow (hwnd, GW-HWNDFIRST)
While currwnd<>0
Length= GetWindow TextLength (currwnd)
listitem$=Space $(length +1)
length= GetWindow Text (currwnd,listitem$,length+1)
if length>0 then

Combo1.Addltem listitem $
End if
currwnd= GetWindow (currwnd, GW-HWNDNEXT)
if Combl1.ListCount>0 then

Combo1.Text=Combol.List (0)
Combo1.Listindex =0
else

MsgBox“没有发现可活动的窗口”,16,“活动”
End if
Wend
End Sub
Sub Sift ()
'测试窗口能否活动
i=0
Combo2.Clear
Do
On Local Error Resume Next
AppActivate Combo1.List (i)
If Err =0 then

Combo2.Additem Combo1.List(i)
End if
i=i+1
Loop Unti 1 i=Combo1.ListCount-1
AppActivate Form1.Caption
If Combo2.ListCount>0 then

Combo2.Text =Combo2.List (0)
Combo2.Listindex =0
else

MsgBox “没有发现可活动窗口”,16,“活动”
End if
End Sub
Private Sub Form-Load ()
Form1.Show'首先将本窗体显示出来,否则查找出的窗体标题没有本身
MsgBox "开始查找窗口标题"
Call FindTitle
Call Sift
End Sub
Private Sub Command1-Click ()
F $=Combo2.Text
On Local Error Resume Next
AppActivate F $
End Sub
Private Sub Command2-Click ()
Call FindTitle
Call Sift
End Sub
本程序在Visual Basic5.0上调试通过。
 
这段代码不过是一段引用API地代码而已,并没什么。
里边有那么多排版的错误,起码因为这个就报错了。
 
那么请问,根据这段原代码,您修改后能否完成该功能呢??我的目的就是要实现上述功能呀??
能否请楼上的朋友花些时间将该段程序调试成功后发给我,不胜感激!(mail address:
mazunini@sina.com)
 
我考,把vb的代码写成这个样子也好意思发表!那个作者学了多长时间vb啊!
你把on local error resume next 去掉, 仔细看看!
 
我就仁慈一把,帮你改一下吧!
 
这是form1的代码:
Option Explicit

Private Sub Command1_Click()
Dim F
F = Combo2.Text
On Local Error Resume Next
AppActivate F

End Sub
Private Sub Command2_Click()
Call FindTitle
Call Sift
End Sub
Private Sub Form_Load()
Form1.Show '首先将本窗体显示出来,否则查找出的窗体标题没有本身
'MsgBox "开始查找窗口标题"
Call FindTitle
Call Sift
End Sub
 
这是模块的代码:
Option Explicit
Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDLAST = 1
Public Const GW_HWNDNEXT = 2
Public Const GW_HWNDPREV = 3
Public Const GW_OWNER = 4

Public hwnd As Long
Public length As Long
Public listitem As String
Sub FindTitle()
'查找桌面上的所有窗口标题
Dim currwnd As Long
Form1.Combo1.Clear
currwnd = GetWindow(Form1.hwnd, GW_HWNDFIRST)
While currwnd <> 0
length = GetWindowTextLength(currwnd)
listitem = Space(length + 1)
length = GetWindowText(currwnd, listitem, length + 1)
If length > 0 then
Form1.Combo1.AddItem listitem
End If
currwnd = GetWindow(currwnd, GW_HWNDNEXT)
If Form1.Combo1.ListCount > 0 then
Form1.Combo1.Text = Form1.Combo1.List(0)
Form1.Combo1.ListIndex = 0
else
MsgBox "没有发现可活动的窗口", 16, "活动"
End If
Wend
End Sub
Sub Sift()
'测试窗口能否活动
Dim i As Long
i = 0
Form1.Combo2.Clear
For i = 0 To Form1.Combo1.ListCount - 1
On Local Error Resume Next
AppActivate Form1.Combo1.List(i)
If Err = 0 then
Form1.Combo2.AddItem Form1.Combo1.List(i)
End If
Next
i = Form1.Combo1.ListCount - 1
AppActivate Form1.Caption
If Form1.Combo2.ListCount > 0 then
Form1.Combo2.Text = Form1.Combo2.List(0)
Form1.Combo2.ListIndex = 0
else
MsgBox "没有发现可活动窗口", 16, "活动"
End If
End Sub
 
这个程序的关键在于AppActivate,他可以是窗口标题,也可以是句柄,
但是窗口标题中的字符不能有中文!
关于microyzy写的模块的代码其实不用改,直接放在form的代码中就可以用了!
 
我看也没改什么地方嘛!除了form1.combo1.clear该了一下,其它地方我修改的都是对的吧!上
是不是呀microyzy??form1开头的这句Option Explicit是否可以不要??加上有什么用呀》》
 
靠!你原来有那么多排版错误,你没仔细看吗?
还有,你知道为什么死机吗?死循环!
还有诸如.......等等
我坦言,这个程序确实没什么难度,但你。。。!
这么简单为什么你自己还调不出来啊!
 
我倒,我有DELPHI的源码,你要不要:)
VB的实在不想去看(如果你有换行的话我还会看看的)
BTW
VB中的option explicit是用来限定VB中的变量一定要先定义才能使用,如果不加这句,
程序中出现个变量名错误,VB不会检查,只会当是个新变量:)
 
microyzy能把你的qq告诉我吗??给你20分,5分给其他人!(这样可以吗?)以后还要
多向你请教!望不吝赐教!
 
后退
顶部