如何获取任务栏里的窗口

jinder 2009-09-06 12:54:48

怎么才能获取到任务栏里的窗口(程序)呢?系统托盘的不需要。
用API枚举扩展样式WS_EX_APPWINDOW不完善,不少没有出现在任务栏里的窗口也带有此样式,例如QQ。而且要做出一个万全的样式过滤器也不可能,不少窗口的样式都很不守规矩,判断不了。
用c#的Process.GetProcesses()也不完善,文件夹窗口会被忽略。
...全文
1014 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinder 2009-10-01
  • 打赏
  • 举报
回复
无时间继续实验,先结了吧.
chinaboyzyq 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 jinder 的回复:]
你试试QQ2009,是一个窗口、是一个主窗口、窗口有标题。。。
条件都符合,但它却没有出现在任务栏里。。。

[/Quote]
它没有出现在任务栏里,也没有出现在我的程序的列表框里,这不正好符合你的题意吗?
怎么才能获取到任务栏里的窗口
-------------------------------------------------------------------------------
刚下载qq2009(原来用2008),运行qq2009,然后执行我的程序,qq2009并没有显示在我程序的列表框里.
qq2009,是一个窗口,是一个主窗口,窗口有标题,但是它没有所有者窗口,也就是说经过If GetWindow(hwnd, GW_OWNER) <> 0 Then GoTo continu过滤,qq2009不会显示在我的列表框,你要的是任务栏里的窗口,我的程序完全符合你的要求.
------------------------------------------------------------------------------
看以下说明:
GW_OWNER:返回的句柄标识了指定窗口的所有者窗口(如果存在)。 返回值:如果函数成功,返回值为窗口句柄;如果与指定窗口有特定关系的窗口不存在,则返回值为NULL。
jinder 2009-09-09
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 chinaboyzyq 的回复:]
If GetWindow(hwnd, GW_OWNER) <> 0 Then GoTo continu
[/Quote]


上回没细看,以为那是过滤掉子窗口的语句,原来你是在过滤有所有者窗口的窗口,这个我倒还没试过.
这几天接新项目,得忙活几天,过几天闲下来了试试看效果怎样.
(不过隐约记得QQ的主窗口好像是有所有者窗口的,记得用SPY++看过.
不过既然你说你这样过滤得掉它,那倒是值得一试.)

对于先去我的不细看就回复,先表示歉意.
king06 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 chinaboyzyq 的回复:]
看看我的VB6答案如何[怎么才能获取到任务栏里的窗口(程序)]:
[/Quote]
顶一个~~
chinaboyzyq 2009-09-08
  • 打赏
  • 举报
回复

'form1添加Command1和List1
Private Sub Command1_Click()
List1.Clear
EnumWindows AddressOf lpfunc, ByVal 0&
End Sub

chinaboyzyq 2009-09-08
  • 打赏
  • 举报
回复
看看我的VB6答案如何[怎么才能获取到任务栏里的窗口(程序)]:

'建立Module1添加以下内容
Option Explicit
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Public Const GW_OWNER = 4

Function lpfunc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
Dim pstr As String, Ret As Long

If IsWindowVisible(hwnd) = False Then GoTo continu
If GetWindow(hwnd, GW_OWNER) <> 0 Then GoTo continu
Ret = GetWindowTextLength(hwnd)
pstr = Space(Ret)
If GetWindowText(hwnd, pstr, Ret + 1) = 0 Then GoTo continu
If pstr <> "" And pstr <> "Program Manager" Then Form1.List1.AddItem pstr

continu:
lpfunc = True
End Function

chinaboyzyq 2009-09-08
  • 打赏
  • 举报
回复
~~~~~~~~~~~~~~~~~
jinder 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 chinaboyzyq 的回复:]
看看我的VB6答案如何[怎么才能获取到任务栏里的窗口(程序)]:
[/Quote]


你试试QQ2009,是一个窗口、是一个主窗口、窗口有标题。。。
条件都符合,但它却没有出现在任务栏里。。。
jinder 2009-09-07
  • 打赏
  • 举报
回复
自己顶一下.
zou8923 2009-09-07
  • 打赏
  • 举报
回复
ding le
悔说话的哑巴 2009-09-07
  • 打赏
  • 举报
回复
我汗,这个问题帮不了。
jinder 2009-09-06
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 dancingbit 的回复:]
所以用GetProcesses取不准。
[/Quote]

所以我来此询问准的方法...
dancingbit 2009-09-06
  • 打赏
  • 举报
回复
所以用GetProcesses取不准。
jinder 2009-09-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 dancingbit 的回复:]
Explorer和Internet Exploerer不管开几个窗口,它就是一个进程。

只有你自己手动启动的副本才会是另外的新进程。
[/Quote]

我只要窗口,进程我不要...
dancingbit 2009-09-06
  • 打赏
  • 举报
回复
Explorer和Internet Exploerer不管开几个窗口,它就是一个进程。

只有你自己手动启动的副本才会是另外的新进程。
jinder 2009-09-06
  • 打赏
  • 举报
回复

目前我自己想到的方法是:
用c#的Process.GetProcesses()枚举+枚举所有Explorer窗口,这样貌似就能获取到所有任务栏里的窗口了。
只是还有点不放心,怕Process.GetProcesses()漏掉的不止是Explorer。因为刚发现IExplorer也有部分被漏掉(只能获取最后激活的那个窗口),所有更是不放心了。
发帖只为寻求能有比较直接的100%保证的方法,任务栏里显示的窗口,应该是个常见的概念呀,怎么关于它的编程资料会那么少呢,就连获取里边的枚举方法也没?但愿只是我孤陋寡闻。
jinder 2009-09-06
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 lzsh0622 的回复:]
解题思路(API):

(1)通过枚举句柄把所有窗口都列出来,EnumWindows或者FindWindow都可以。
  (枚举出来窗体的是所有的进程的,任务栏中不一定可视。)

(2)查找符合下面条件的窗口句柄
  a.是窗口,    IsWindow(hWnd)
  b.窗口是可见   IsWindowVisible(hWnd)
  c.有任务栏标题  GetWindowLong(hWnd, GWL_EXSTYLE) 和 WS_EX_TOOLWINDOW)!=WS_EX_TOOLWINDOW
  d.不存在父窗口  GetWindowLong(hWnd, GWL_HWNDPARENT)==0

(3)通过该句柄,随你怎么操作了。
[/Quote]


此法我也试过,效果算不错,不过还是不够完善,有部分窗口没显示在任务栏里也被枚举出来,例如QQ2009,除非将其最小化到系统托盘,否则仅用是不是工具窗口来判断是排除不了它的(它不是工具窗口,却也没显示在任务栏里).
我想,既然有例外了,那例外就不可能只有它一个.寻求更保证的方法.
当然,也许你会说,那就多加几个样式过滤掉这些例外,只是这样可能吗,各个程序员编写出来的窗口五花八门,不守规矩得程序员并不少见,有可能做出个保证通用的过滤条件吗.
lzsh0622 2009-09-06
  • 打赏
  • 举报
回复
更正:12楼
lzsh0622 2009-09-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 jinder 的回复:]
引用 10 楼 syssz 的回复:
任务栏是个Toolbar,而Toolbar的子窗口句柄无法通过一般窗口操作获得.我认为,如果要弄清正在运行的是哪些程度应枚举进程而不是任务栏的子窗口.


那枚举进程后如何判断哪些进程是显示在任务栏里的呢?这个才是我要的重点.


引用 11 楼 lzsh0622 的回复:
支持10楼的说法。

IE、Word、Excel 等等都可以在任务栏开数个窗口。
在C#中的FORM,ShowInTaskBar=True。也能在任务栏中显示数个窗口。

操作一个进程的子窗体,有什么用呢?

当然,枚举任务栏中的子窗体用API是可以实现的。


我要操作的是所有显示在任务栏里的窗口,当然也就包括了你所说的子窗口,例如:我不是要操作IE这个进程,我要操作每一个用IE打开的网页窗口(IE6);再例如,我不是要操作explorer,我是要操作每个已经打开的文件夹窗口.

[/Quote]

楼主怎么不引用11楼的,11楼的写成代码就基本是答案了。
jinder 2009-09-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 syssz 的回复:]
任务栏是个Toolbar,而Toolbar的子窗口句柄无法通过一般窗口操作获得.我认为,如果要弄清正在运行的是哪些程度应枚举进程而不是任务栏的子窗口.
[/Quote]

那枚举进程后如何判断哪些进程是显示在任务栏里的呢?这个才是我要的重点.


[Quote=引用 11 楼 lzsh0622 的回复:]
支持10楼的说法。

IE、Word、Excel 等等都可以在任务栏开数个窗口。
在C#中的FORM,ShowInTaskBar=True。也能在任务栏中显示数个窗口。

操作一个进程的子窗体,有什么用呢?

当然,枚举任务栏中的子窗体用API是可以实现的。
[/Quote]

我要操作的是所有显示在任务栏里的窗口,当然也就包括了你所说的子窗口,例如:我不是要操作IE这个进程,我要操作每一个用IE打开的网页窗口(IE6);再例如,我不是要操作explorer,我是要操作每个已经打开的文件夹窗口.
加载更多回复(12)

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧