怎么才能获取到任务栏里的窗口(程序)呢?系统托盘的不需要。
用API枚举扩展样式WS_EX_APPWINDOW不完善,不少没有出现在任务栏里的窗口也带有此样式,例如QQ。而且要做出一个万全的样式过滤器也不可能,不少窗口的样式都很不守规矩,判断不了。
用c#的Process.GetProcesses()也不完善,文件夹窗口会被忽略。

解决方案 »

  1.   

    那就直接访问任务栏好了。
    任务栏按钮实际上是任务栏的一个子窗口,而且是一个标准的选项卡控件。
    你可以用SPY++看下。
      

  2.   


                Process[] vProcesses = Process.GetProcesses();
                foreach (Process vProcess in vProcesses)
                    if (vProcess.MainWindowHandle != IntPtr.Zero && !string.IsNullOrEmpty(vProcess.MainWindowTitle))
                        Console.WriteLine(vProcess.MainWindowTitle);
      

  3.   



    貌似你只看题目不看内容的...
    Process.GetProcesses()也不完善,文件夹窗口会被忽略。 
      

  4.   

    好像是发通知消息,要看sdk documents了。
      

  5.   

    任务栏是个Toolbar,而Toolbar的子窗口句柄无法通过一般窗口操作获得.我认为,如果要弄清正在运行的是哪些程度应枚举进程而不是任务栏的子窗口.
      

  6.   

    支持10楼的说法。IE、Word、Excel 等等都可以在任务栏开数个窗口。
    在C#中的FORM,ShowInTaskBar=True。也能在任务栏中显示数个窗口。操作一个进程的子窗体,有什么用呢?当然,枚举任务栏中的子窗体用API是可以实现的。
      

  7.   

    解题思路(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)通过该句柄,随你怎么操作了。
      

  8.   


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

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

  9.   


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

  10.   

    Explorer和Internet Exploerer不管开几个窗口,它就是一个进程。只有你自己手动启动的副本才会是另外的新进程。
      

  11.   

    看看我的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 = 4Function 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
      

  12.   


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

  13.   

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

  14.   



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