我想写一个句柄的比较。但是写到句柄储存到数组后有些不知道如何写了。请教一下大家。
我用了EnumWindows的EnumWindowsProc来得到指定的窗口类的句柄。句柄得到写入数组a()然后在EnumWindowsProc用x=x+1来redim a(1 to x)确定了数组a()的大小。然后我建立了一个数组b()然后确定一个值y。重新定义b()为b(1 to y)然后想把a(x)数组里相应的值给b(y),因为2个数组都是从下标1开始的。假如y=3我就想程序把b(1)=a(1),b(2)=a(2),b(3)=a(3)然后a(x)中多出来其他值不要。然后利用b(y)里存的值跟a(x)中对应位数的值比较。不同就对句柄发出关闭。就是想把a(x)里多出b(y)的句柄给关掉。 我觉得也可以x-y后把多余的个数句柄放入c(1 to x-y)直接对c(1 to x-y)里的句柄都发送关闭。大家看哪个好实现就给点代码。复制内存的API用了下好像写的不对。老是不行。觉得麻烦的给个思路。把用什么API或者怎么写赋值循环大概说下谢谢。
主要是把a(x)里的值对应的给b(y)把我难到了。因为EnumWindowsProc是每次都运行的。像个循环。我不知道这个是不是叫指针。希望能理解清楚的各位解释一下。自学的VB基础不行。在EnumWindowsProc里把a(x)里的值对应的给b(y)我觉得不方便。但是在FROM的代码里又没有办法直接引用到模块EnumWindowsProc里的数组a(x)b(y)。希望会的朋友也教我下。不多啰嗦了。代码贴出来。
FORM里的代码:
Option Explicit
Private Sub Form_Load()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
End Sub
模块里的代码:
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Dim a() As Long
Dim b() As Long
Dim x As Integer
Dim y As Integer
Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "IEFrame" + Chr(0) '定义要判断的窗口类IEFrame为IE窗口类
If GetParent(hwnd) = 0 Then '是否是父窗口
If IsWindowVisible(hwnd) Then '是否可见
lei = ""
GetClassName hwnd, lei, 128
If lei = diylei Then '判断是否是定义的类
If y = 0 Then 'Y不存在定义Y的值
y = InputBox("", "")
Ret = GetWindowTextLength(hwnd)
sSave = Space(Ret)
GetWindowText hwnd, sSave, Ret + 1
Form1.Print Str$(hwnd) + " " + sSave '输出句柄和标题
x = x + 1
ReDim a(1 To x)
a(x) = Str$(hwnd)
Form1.Print "x"; x; a(x)
If y >= x Then '如果Y>=X
ReDim b(1 To y)
End If
Form1.Print "y"; y; b(y)
Form1.Print x <= y
Else 'Y存在值时
Ret = GetWindowTextLength(hwnd)
sSave = Space(Ret)
GetWindowText hwnd, sSave, Ret + 1
Form1.Print Str$(hwnd) + " " + sSave
x = x + 1
ReDim a(1 To x)
a(x) = Str$(hwnd)
Form1.Print "x"; x; a(x)
If y >= x Then
ReDim b(1 To y)
End If
Form1.Print "y"; y; b(y)
Form1.Print x <= y
End If
End If
End If
End If
'继续enumeration
EnumWindowsProc = True
End Function
14 个解决方案
#1
看了半天,真绕得有点头晕。
你说得内容似乎都没有必要,既然a(1 to x)前y个元素与b(1 to y)的元素是对应相等的,
就没有必要去搞这个b了,再搞个c更没必要了,你直接在一个循环里关闭a()中下标大于
y的所有元素中存的句柄不就行了。
for i= y+1 to ubound(a)
‘关闭a(i)中的句柄
next
你说得内容似乎都没有必要,既然a(1 to x)前y个元素与b(1 to y)的元素是对应相等的,
就没有必要去搞这个b了,再搞个c更没必要了,你直接在一个循环里关闭a()中下标大于
y的所有元素中存的句柄不就行了。
for i= y+1 to ubound(a)
‘关闭a(i)中的句柄
next
#2
哦对哦。但是这个FOR循环写在哪好点呢?写在模块的EnumWindowsProc里它是每次都要运行的。我想让它都取完值后来对a()里的句柄进行操作。写在FORM里又不能引用到a()数组。请教下谢谢。
#3
Dim a() As Long
to
public a() As Long
这样窗体里就能访问了
to
public a() As Long
这样窗体里就能访问了
#4
现在改了代码了。但是有面临一个新问题。A()每次都是重新写入的。当我新开一个窗口多于Y时。它关闭了不是我最新开的窗口。而是原来的一个,这个比较郁闷。有办法吗各位?
模块:Option Explicit
'Add this code to a module
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Public Const WM_CLOSE = &H10
Dim a() As Long
Public x As Integer
Public y As Integer
Dim i As Integer
Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "360se_Frame" + Chr(0) '定义要判断的窗口类
If GetParent(hwnd) = 0 Then '是否是父窗口
If IsWindowVisible(hwnd) Then '是否可见
lei = ""
GetClassName hwnd, lei, 128
If lei = diylei Then '判断是否是定义的类
'Form1.Print Str$(hwnd) + " " + sSave 输出句柄和标题
Ret = GetWindowTextLength(hwnd)
sSave = Space(Ret)
GetWindowText hwnd, sSave, Ret + 1
x = x + 1
ReDim a(1 To x)
a(x) = Str$(hwnd)
For i = y + 1 To UBound(a)
PostMessage a(i), WM_CLOSE, 0, 0
Next i
Form1.Print "x"; x; a(x)
End If
End If
End If
'continue enumeration
EnumWindowsProc = True
End Function
FORM里有一个TIMER和一个COMMADN。开始TIMER的ENABLED为FLASE代码如下:
Option Explicit
Dim time As Single
Private Sub Command1_Click()
Select Case Timer1.Enabled
Case 0
time = InputBox("请输入要监测的360浏览器时间间隔(秒)", "时间间隔")
y = InputBox("请输入要保留的360浏览器的个数", "个数")
Timer1.Interval = time * 1000
Timer1.Enabled = 1
Command1.Caption = "360浏览器监测(开)"
Case 1
Timer1.Enabled = 0
Command1.Caption = "360浏览器监测(关)"
End Select
End Sub
Private Sub Timer1_Timer()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
x = 0
End Sub
现在这个问题解决就OK了。。。完了马上给分。
模块:Option Explicit
'Add this code to a module
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Public Const WM_CLOSE = &H10
Dim a() As Long
Public x As Integer
Public y As Integer
Dim i As Integer
Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "360se_Frame" + Chr(0) '定义要判断的窗口类
If GetParent(hwnd) = 0 Then '是否是父窗口
If IsWindowVisible(hwnd) Then '是否可见
lei = ""
GetClassName hwnd, lei, 128
If lei = diylei Then '判断是否是定义的类
'Form1.Print Str$(hwnd) + " " + sSave 输出句柄和标题
Ret = GetWindowTextLength(hwnd)
sSave = Space(Ret)
GetWindowText hwnd, sSave, Ret + 1
x = x + 1
ReDim a(1 To x)
a(x) = Str$(hwnd)
For i = y + 1 To UBound(a)
PostMessage a(i), WM_CLOSE, 0, 0
Next i
Form1.Print "x"; x; a(x)
End If
End If
End If
'continue enumeration
EnumWindowsProc = True
End Function
FORM里有一个TIMER和一个COMMADN。开始TIMER的ENABLED为FLASE代码如下:
Option Explicit
Dim time As Single
Private Sub Command1_Click()
Select Case Timer1.Enabled
Case 0
time = InputBox("请输入要监测的360浏览器时间间隔(秒)", "时间间隔")
y = InputBox("请输入要保留的360浏览器的个数", "个数")
Timer1.Interval = time * 1000
Timer1.Enabled = 1
Command1.Caption = "360浏览器监测(开)"
Case 1
Timer1.Enabled = 0
Command1.Caption = "360浏览器监测(关)"
End Select
End Sub
Private Sub Timer1_Timer()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
x = 0
End Sub
现在这个问题解决就OK了。。。完了马上给分。
#5
再说具体点好了。就是A()这个数组我定义要它保存Y个数。当A()里个数小于Y。则重新写入。A()个数大于等于Y。则保持不变。好让我来比较新开的窗口句柄跟保存在A()里的相同不。不同就KILL了。相同不管它。
这个程序的原意是:
本人是新学VB,因在网上浏览一些小说什么的时候。经常会跳出一些广告。每次都要自己去关闭。觉得很麻烦。就想用VB编一个控制多开的程序。
思路是这样的:
指定一个程序X
当程序多于指定个数N时
关闭新开的程序
原程序不关闭
我也想了下。也可以不用数组去关闭多余Y的句柄。可以判断X>Y就直接对句柄发送关闭。但是新开的句柄依旧辨别不出来。
这个程序的原意是:
本人是新学VB,因在网上浏览一些小说什么的时候。经常会跳出一些广告。每次都要自己去关闭。觉得很麻烦。就想用VB编一个控制多开的程序。
思路是这样的:
指定一个程序X
当程序多于指定个数N时
关闭新开的程序
原程序不关闭
我也想了下。也可以不用数组去关闭多余Y的句柄。可以判断X>Y就直接对句柄发送关闭。但是新开的句柄依旧辨别不出来。
#6
Preserve 关键字,当改变原有数组最末维的大
小时,使用此关键字可以保持数组中原来的数
据。 然后可以对a()进行相应操作。
ReDim Preserve a(1 To x)
小时,使用此关键字可以保持数组中原来的数
据。 然后可以对a()进行相应操作。
ReDim Preserve a(1 To x)
#7
ReDim Preserve a(1 To x)
依旧还是那样。我写的A()是在EnumWindowsProc里的。这个EnumWindowsProc是不是叫指针我不知道。TIMER每次运行EnumWindowsProc都会循环到结束。就是每次TIMER运行的时候EnumWindowsProc都是重新开始的。所以每次A()都是重写的。Preserve 只是保留这次循环里的值不被破坏。下次整个循环开始时候。A()又空了。所以我觉得还是写个B()好点。用来保存Y个句柄。当目前有的X个句柄大于Y时。比较不同的就是多出的句柄关闭。当X<=Y时。把A()写入B()这样如何?每次都重新循环EnumWindowsProc重置A()比较郁闷。到底怎么写好呢。给个思路。谢谢了。
依旧还是那样。我写的A()是在EnumWindowsProc里的。这个EnumWindowsProc是不是叫指针我不知道。TIMER每次运行EnumWindowsProc都会循环到结束。就是每次TIMER运行的时候EnumWindowsProc都是重新开始的。所以每次A()都是重写的。Preserve 只是保留这次循环里的值不被破坏。下次整个循环开始时候。A()又空了。所以我觉得还是写个B()好点。用来保存Y个句柄。当目前有的X个句柄大于Y时。比较不同的就是多出的句柄关闭。当X<=Y时。把A()写入B()这样如何?每次都重新循环EnumWindowsProc重置A()比较郁闷。到底怎么写好呢。给个思路。谢谢了。
#8
关注。。。学习!
#9
求思路!帮帮我各位。。卡着很郁闷。。。
#10
昏...卡不在你数组复制赋值上,而是你程序其它部分...变量赋值的速度是相当快的
#11
我说是卡着思路。不是程序卡
#12
我最怕弄的就是数组操作了,也没有个指针操作,得借助API
#13
按下按钮timer1.enabled=true时里装入你定义的N个360浏览器,循环枚举时x不要从0开始而要从x=N+1开始重新定义数组,注意使用Preserve关键字保留前N个自定义保留的360浏览器,这样就好比较了。
当按下按钮使timer1.enabled=false时,重新定义x=0,重新枚举前N个
#14
KO了用了B()保留了指定的Y个句柄。然后写了循环比较。不啰嗦了。代码扔出来。有兴趣的朋友帮我优化下。而且第一次定义个数Y还有些问题。必须有程序开着。而且第一次定义不能少于现有个数。
模块里的:
Option Explicit
'Add this code to a module
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Public Const WM_CLOSE = &H10
Public a() As Long
Public b() As Long
Public X As Integer
Public Y As Integer
Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "360se_Frame" + Chr(0) '定义要判断的窗口类关于窗口类用SPY++自己找。
If GetParent(hWnd) = 0 Then '是否是父窗口
If IsWindowVisible(hWnd) Then '是否可见
lei = ""
GetClassName hWnd, lei, 128
If lei = diylei Then '判断是否是定义的类
'Form1.Print Str$(hwnd) + " " + sSave 输出句柄和标题
Ret = GetWindowTextLength(hWnd)
sSave = Space(Ret)
GetWindowText hWnd, sSave, Ret + 1
X = X + 1
ReDim Preserve a(1 To X)
a(X) = Str$(hWnd)
End If
End If
End If
'continue enumeration
EnumWindowsProc = True
End Function
FORM1里的:一个COMMADN一个TIMER。设置TIMER为FLASE
:
Option Explicit
Public time As Single
Public c As Integer
Public i As Integer
Private Sub Command1_Click()
Select Case Timer1.Enabled
Case 0
time = InputBox("请输入要监测的360浏览器时间间隔(秒)", "时间间隔")
Y = InputBox("请输入要保留的360浏览器的个数", "个数")
Timer1.Interval = time * 1000
Timer1.Enabled = 1
Command1.Caption = "360浏览器监测(开)"
Case 1
Timer1.Enabled = 0
Command1.Caption = "360浏览器监测(关)"
End Select
End Sub
Private Sub Timer1_Timer()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
If UBound(a) <= Y Then
For i = 1 To Y
If UBound(a) < Y Then
ReDim Preserve a(1 To Y)
End If
ReDim Preserve b(1 To Y)
b(i) = a(i)
Next i
End If
'For i = 1 To x
'Print "a"; i; a(i)
'Next i
'For i = 1 To y
'Print "B"; i; b(i)
'Next i
For i = 1 To X
For c = 1 To Y
If a(i) = b(c) Then
Exit For
End If
Next c
If c = Y + 1 Then
PostMessage a(i), WM_CLOSE, 0, 0
End If
Next i
X = 0
End Sub
模块里的:
Option Explicit
'Add this code to a module
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Public Const WM_CLOSE = &H10
Public a() As Long
Public b() As Long
Public X As Integer
Public Y As Integer
Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "360se_Frame" + Chr(0) '定义要判断的窗口类关于窗口类用SPY++自己找。
If GetParent(hWnd) = 0 Then '是否是父窗口
If IsWindowVisible(hWnd) Then '是否可见
lei = ""
GetClassName hWnd, lei, 128
If lei = diylei Then '判断是否是定义的类
'Form1.Print Str$(hwnd) + " " + sSave 输出句柄和标题
Ret = GetWindowTextLength(hWnd)
sSave = Space(Ret)
GetWindowText hWnd, sSave, Ret + 1
X = X + 1
ReDim Preserve a(1 To X)
a(X) = Str$(hWnd)
End If
End If
End If
'continue enumeration
EnumWindowsProc = True
End Function
FORM1里的:一个COMMADN一个TIMER。设置TIMER为FLASE
:
Option Explicit
Public time As Single
Public c As Integer
Public i As Integer
Private Sub Command1_Click()
Select Case Timer1.Enabled
Case 0
time = InputBox("请输入要监测的360浏览器时间间隔(秒)", "时间间隔")
Y = InputBox("请输入要保留的360浏览器的个数", "个数")
Timer1.Interval = time * 1000
Timer1.Enabled = 1
Command1.Caption = "360浏览器监测(开)"
Case 1
Timer1.Enabled = 0
Command1.Caption = "360浏览器监测(关)"
End Select
End Sub
Private Sub Timer1_Timer()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
If UBound(a) <= Y Then
For i = 1 To Y
If UBound(a) < Y Then
ReDim Preserve a(1 To Y)
End If
ReDim Preserve b(1 To Y)
b(i) = a(i)
Next i
End If
'For i = 1 To x
'Print "a"; i; a(i)
'Next i
'For i = 1 To y
'Print "B"; i; b(i)
'Next i
For i = 1 To X
For c = 1 To Y
If a(i) = b(c) Then
Exit For
End If
Next c
If c = Y + 1 Then
PostMessage a(i), WM_CLOSE, 0, 0
End If
Next i
X = 0
End Sub
#1
看了半天,真绕得有点头晕。
你说得内容似乎都没有必要,既然a(1 to x)前y个元素与b(1 to y)的元素是对应相等的,
就没有必要去搞这个b了,再搞个c更没必要了,你直接在一个循环里关闭a()中下标大于
y的所有元素中存的句柄不就行了。
for i= y+1 to ubound(a)
‘关闭a(i)中的句柄
next
你说得内容似乎都没有必要,既然a(1 to x)前y个元素与b(1 to y)的元素是对应相等的,
就没有必要去搞这个b了,再搞个c更没必要了,你直接在一个循环里关闭a()中下标大于
y的所有元素中存的句柄不就行了。
for i= y+1 to ubound(a)
‘关闭a(i)中的句柄
next
#2
哦对哦。但是这个FOR循环写在哪好点呢?写在模块的EnumWindowsProc里它是每次都要运行的。我想让它都取完值后来对a()里的句柄进行操作。写在FORM里又不能引用到a()数组。请教下谢谢。
#3
Dim a() As Long
to
public a() As Long
这样窗体里就能访问了
to
public a() As Long
这样窗体里就能访问了
#4
现在改了代码了。但是有面临一个新问题。A()每次都是重新写入的。当我新开一个窗口多于Y时。它关闭了不是我最新开的窗口。而是原来的一个,这个比较郁闷。有办法吗各位?
模块:Option Explicit
'Add this code to a module
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Public Const WM_CLOSE = &H10
Dim a() As Long
Public x As Integer
Public y As Integer
Dim i As Integer
Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "360se_Frame" + Chr(0) '定义要判断的窗口类
If GetParent(hwnd) = 0 Then '是否是父窗口
If IsWindowVisible(hwnd) Then '是否可见
lei = ""
GetClassName hwnd, lei, 128
If lei = diylei Then '判断是否是定义的类
'Form1.Print Str$(hwnd) + " " + sSave 输出句柄和标题
Ret = GetWindowTextLength(hwnd)
sSave = Space(Ret)
GetWindowText hwnd, sSave, Ret + 1
x = x + 1
ReDim a(1 To x)
a(x) = Str$(hwnd)
For i = y + 1 To UBound(a)
PostMessage a(i), WM_CLOSE, 0, 0
Next i
Form1.Print "x"; x; a(x)
End If
End If
End If
'continue enumeration
EnumWindowsProc = True
End Function
FORM里有一个TIMER和一个COMMADN。开始TIMER的ENABLED为FLASE代码如下:
Option Explicit
Dim time As Single
Private Sub Command1_Click()
Select Case Timer1.Enabled
Case 0
time = InputBox("请输入要监测的360浏览器时间间隔(秒)", "时间间隔")
y = InputBox("请输入要保留的360浏览器的个数", "个数")
Timer1.Interval = time * 1000
Timer1.Enabled = 1
Command1.Caption = "360浏览器监测(开)"
Case 1
Timer1.Enabled = 0
Command1.Caption = "360浏览器监测(关)"
End Select
End Sub
Private Sub Timer1_Timer()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
x = 0
End Sub
现在这个问题解决就OK了。。。完了马上给分。
模块:Option Explicit
'Add this code to a module
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Public Const WM_CLOSE = &H10
Dim a() As Long
Public x As Integer
Public y As Integer
Dim i As Integer
Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "360se_Frame" + Chr(0) '定义要判断的窗口类
If GetParent(hwnd) = 0 Then '是否是父窗口
If IsWindowVisible(hwnd) Then '是否可见
lei = ""
GetClassName hwnd, lei, 128
If lei = diylei Then '判断是否是定义的类
'Form1.Print Str$(hwnd) + " " + sSave 输出句柄和标题
Ret = GetWindowTextLength(hwnd)
sSave = Space(Ret)
GetWindowText hwnd, sSave, Ret + 1
x = x + 1
ReDim a(1 To x)
a(x) = Str$(hwnd)
For i = y + 1 To UBound(a)
PostMessage a(i), WM_CLOSE, 0, 0
Next i
Form1.Print "x"; x; a(x)
End If
End If
End If
'continue enumeration
EnumWindowsProc = True
End Function
FORM里有一个TIMER和一个COMMADN。开始TIMER的ENABLED为FLASE代码如下:
Option Explicit
Dim time As Single
Private Sub Command1_Click()
Select Case Timer1.Enabled
Case 0
time = InputBox("请输入要监测的360浏览器时间间隔(秒)", "时间间隔")
y = InputBox("请输入要保留的360浏览器的个数", "个数")
Timer1.Interval = time * 1000
Timer1.Enabled = 1
Command1.Caption = "360浏览器监测(开)"
Case 1
Timer1.Enabled = 0
Command1.Caption = "360浏览器监测(关)"
End Select
End Sub
Private Sub Timer1_Timer()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
x = 0
End Sub
现在这个问题解决就OK了。。。完了马上给分。
#5
再说具体点好了。就是A()这个数组我定义要它保存Y个数。当A()里个数小于Y。则重新写入。A()个数大于等于Y。则保持不变。好让我来比较新开的窗口句柄跟保存在A()里的相同不。不同就KILL了。相同不管它。
这个程序的原意是:
本人是新学VB,因在网上浏览一些小说什么的时候。经常会跳出一些广告。每次都要自己去关闭。觉得很麻烦。就想用VB编一个控制多开的程序。
思路是这样的:
指定一个程序X
当程序多于指定个数N时
关闭新开的程序
原程序不关闭
我也想了下。也可以不用数组去关闭多余Y的句柄。可以判断X>Y就直接对句柄发送关闭。但是新开的句柄依旧辨别不出来。
这个程序的原意是:
本人是新学VB,因在网上浏览一些小说什么的时候。经常会跳出一些广告。每次都要自己去关闭。觉得很麻烦。就想用VB编一个控制多开的程序。
思路是这样的:
指定一个程序X
当程序多于指定个数N时
关闭新开的程序
原程序不关闭
我也想了下。也可以不用数组去关闭多余Y的句柄。可以判断X>Y就直接对句柄发送关闭。但是新开的句柄依旧辨别不出来。
#6
Preserve 关键字,当改变原有数组最末维的大
小时,使用此关键字可以保持数组中原来的数
据。 然后可以对a()进行相应操作。
ReDim Preserve a(1 To x)
小时,使用此关键字可以保持数组中原来的数
据。 然后可以对a()进行相应操作。
ReDim Preserve a(1 To x)
#7
ReDim Preserve a(1 To x)
依旧还是那样。我写的A()是在EnumWindowsProc里的。这个EnumWindowsProc是不是叫指针我不知道。TIMER每次运行EnumWindowsProc都会循环到结束。就是每次TIMER运行的时候EnumWindowsProc都是重新开始的。所以每次A()都是重写的。Preserve 只是保留这次循环里的值不被破坏。下次整个循环开始时候。A()又空了。所以我觉得还是写个B()好点。用来保存Y个句柄。当目前有的X个句柄大于Y时。比较不同的就是多出的句柄关闭。当X<=Y时。把A()写入B()这样如何?每次都重新循环EnumWindowsProc重置A()比较郁闷。到底怎么写好呢。给个思路。谢谢了。
依旧还是那样。我写的A()是在EnumWindowsProc里的。这个EnumWindowsProc是不是叫指针我不知道。TIMER每次运行EnumWindowsProc都会循环到结束。就是每次TIMER运行的时候EnumWindowsProc都是重新开始的。所以每次A()都是重写的。Preserve 只是保留这次循环里的值不被破坏。下次整个循环开始时候。A()又空了。所以我觉得还是写个B()好点。用来保存Y个句柄。当目前有的X个句柄大于Y时。比较不同的就是多出的句柄关闭。当X<=Y时。把A()写入B()这样如何?每次都重新循环EnumWindowsProc重置A()比较郁闷。到底怎么写好呢。给个思路。谢谢了。
#8
关注。。。学习!
#9
求思路!帮帮我各位。。卡着很郁闷。。。
#10
昏...卡不在你数组复制赋值上,而是你程序其它部分...变量赋值的速度是相当快的
#11
我说是卡着思路。不是程序卡
#12
我最怕弄的就是数组操作了,也没有个指针操作,得借助API
#13
按下按钮timer1.enabled=true时里装入你定义的N个360浏览器,循环枚举时x不要从0开始而要从x=N+1开始重新定义数组,注意使用Preserve关键字保留前N个自定义保留的360浏览器,这样就好比较了。
当按下按钮使timer1.enabled=false时,重新定义x=0,重新枚举前N个
#14
KO了用了B()保留了指定的Y个句柄。然后写了循环比较。不啰嗦了。代码扔出来。有兴趣的朋友帮我优化下。而且第一次定义个数Y还有些问题。必须有程序开着。而且第一次定义不能少于现有个数。
模块里的:
Option Explicit
'Add this code to a module
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Public Const WM_CLOSE = &H10
Public a() As Long
Public b() As Long
Public X As Integer
Public Y As Integer
Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "360se_Frame" + Chr(0) '定义要判断的窗口类关于窗口类用SPY++自己找。
If GetParent(hWnd) = 0 Then '是否是父窗口
If IsWindowVisible(hWnd) Then '是否可见
lei = ""
GetClassName hWnd, lei, 128
If lei = diylei Then '判断是否是定义的类
'Form1.Print Str$(hwnd) + " " + sSave 输出句柄和标题
Ret = GetWindowTextLength(hWnd)
sSave = Space(Ret)
GetWindowText hWnd, sSave, Ret + 1
X = X + 1
ReDim Preserve a(1 To X)
a(X) = Str$(hWnd)
End If
End If
End If
'continue enumeration
EnumWindowsProc = True
End Function
FORM1里的:一个COMMADN一个TIMER。设置TIMER为FLASE
:
Option Explicit
Public time As Single
Public c As Integer
Public i As Integer
Private Sub Command1_Click()
Select Case Timer1.Enabled
Case 0
time = InputBox("请输入要监测的360浏览器时间间隔(秒)", "时间间隔")
Y = InputBox("请输入要保留的360浏览器的个数", "个数")
Timer1.Interval = time * 1000
Timer1.Enabled = 1
Command1.Caption = "360浏览器监测(开)"
Case 1
Timer1.Enabled = 0
Command1.Caption = "360浏览器监测(关)"
End Select
End Sub
Private Sub Timer1_Timer()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
If UBound(a) <= Y Then
For i = 1 To Y
If UBound(a) < Y Then
ReDim Preserve a(1 To Y)
End If
ReDim Preserve b(1 To Y)
b(i) = a(i)
Next i
End If
'For i = 1 To x
'Print "a"; i; a(i)
'Next i
'For i = 1 To y
'Print "B"; i; b(i)
'Next i
For i = 1 To X
For c = 1 To Y
If a(i) = b(c) Then
Exit For
End If
Next c
If c = Y + 1 Then
PostMessage a(i), WM_CLOSE, 0, 0
End If
Next i
X = 0
End Sub
模块里的:
Option Explicit
'Add this code to a module
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
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
Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Public Const WM_CLOSE = &H10
Public a() As Long
Public b() As Long
Public X As Integer
Public Y As Integer
Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
Dim sSave As String, Ret As Long
Dim lei As String * 128
Dim diylei As String * 128
diylei = "360se_Frame" + Chr(0) '定义要判断的窗口类关于窗口类用SPY++自己找。
If GetParent(hWnd) = 0 Then '是否是父窗口
If IsWindowVisible(hWnd) Then '是否可见
lei = ""
GetClassName hWnd, lei, 128
If lei = diylei Then '判断是否是定义的类
'Form1.Print Str$(hwnd) + " " + sSave 输出句柄和标题
Ret = GetWindowTextLength(hWnd)
sSave = Space(Ret)
GetWindowText hWnd, sSave, Ret + 1
X = X + 1
ReDim Preserve a(1 To X)
a(X) = Str$(hWnd)
End If
End If
End If
'continue enumeration
EnumWindowsProc = True
End Function
FORM1里的:一个COMMADN一个TIMER。设置TIMER为FLASE
:
Option Explicit
Public time As Single
Public c As Integer
Public i As Integer
Private Sub Command1_Click()
Select Case Timer1.Enabled
Case 0
time = InputBox("请输入要监测的360浏览器时间间隔(秒)", "时间间隔")
Y = InputBox("请输入要保留的360浏览器的个数", "个数")
Timer1.Interval = time * 1000
Timer1.Enabled = 1
Command1.Caption = "360浏览器监测(开)"
Case 1
Timer1.Enabled = 0
Command1.Caption = "360浏览器监测(关)"
End Select
End Sub
Private Sub Timer1_Timer()
Me.AutoRedraw = True
'call the Enumwindows-function
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
If UBound(a) <= Y Then
For i = 1 To Y
If UBound(a) < Y Then
ReDim Preserve a(1 To Y)
End If
ReDim Preserve b(1 To Y)
b(i) = a(i)
Next i
End If
'For i = 1 To x
'Print "a"; i; a(i)
'Next i
'For i = 1 To y
'Print "B"; i; b(i)
'Next i
For i = 1 To X
For c = 1 To Y
If a(i) = b(c) Then
Exit For
End If
Next c
If c = Y + 1 Then
PostMessage a(i), WM_CLOSE, 0, 0
End If
Next i
X = 0
End Sub