我的思想:当前运行程序的句柄是以DESKTOPWND为根的一棵树,只要遍历些树
就可得到所有窗口句柄。::GetWindow用GW_CHILD是下一层,而GW_NEXT是同层。
以下是程序,仅供参考。struct MYHWND{
HWND hwnd;
CString caption;
CString classname;
};void CCommand::hwndGetAll()
{
MYHWND myhwnd;
HWND temphwnd;  hwndDeskTop = ::GetDesktopWindow();
temphwnd = ::GetWindow(hwndDeskTop, GW_CHILD); do{
//Get Wnd Handle
myhwnd.hwnd = temphwnd;
//Get Wnd Class Name
if(!::GetClassName(temphwnd, myhwnd.classname.GetBuffer(100), 100))
myhwnd.classname.Empty();
myhwnd.classname.ReleaseBuffer();
//Find Sys Tab Control
if(myhwnd.classname == "Shell_TrayWnd")
{
HWND temp = ::GetWindow(temphwnd, GW_CHILD);
CString name;
while(temp)
{
::GetClassName(temp, name.GetBuffer(100), 100);
name.ReleaseBuffer();
if(name == "Button")
hwndStart = temp;
else if(name == "MSTaskSwWClass")
{
HWND temp2 = ::GetWindow(temp, GW_CHILD);
CString name2;
while(temp2)
{
::GetClassName(temp2, name2.GetBuffer(100), 100);
name2.ReleaseBuffer();
if(name2 == "SysTabControl32") 
{
hwndSysTab = temp2;
break;
}
temp2 = ::GetWindow(temp2, GW_HWNDNEXT);
}
}
temp = ::GetWindow(temp, GW_HWNDNEXT);
}
}
//Find Sys List View Control
if(myhwnd.classname == "Progman")
{
HWND temp = ::GetWindow(temphwnd, GW_CHILD);
CString name;
while(temp)
{
::GetClassName(temp, name.GetBuffer(100), 100);
name.ReleaseBuffer();
if(name == "SHELLDLL_DefView") break;
temp = ::GetWindow(temp, GW_HWNDNEXT);
}
if(name == "SHELLDLL_DefView")
{
HWND temp2 = ::GetWindow(temp, GW_CHILD);
CString name2;
while(temp2)
{
::GetClassName(temp2, name2.GetBuffer(100), 100);
name2.ReleaseBuffer();
if(name2 == "SysListView32") 
{
hwndSysListView = temp2;
break;
}
temp2 = ::GetWindow(temp2, GW_HWNDNEXT);
}
}
}
//Get Wnd Title
if(!::GetWindowText(temphwnd, myhwnd.caption.GetBuffer(100), 100)) 
myhwnd.caption.Empty();
myhwnd.caption.ReleaseBuffer();
//Add It To Array
hwndArray.Add(myhwnd); temphwnd = ::GetWindow(temphwnd, GW_HWNDNEXT);
}while(temphwnd);
}

解决方案 »

  1.   

    通过注册的窗口类名用FindWindow()函数;查找记事本:
    HWND = ::FindWindow(_T("Notepad"),NULL);
    if(IsWindow(HWND))
    {
        ...
    }
    窗口类名可以自定义,在虚拟函数PreCreateWindow()函数里面注册。
    外部程序可以用SPY++查找类名。
      

  2.   

    先使用GetDesktopWindow得到一个窗口句柄,再使用GetNextWindow遍历所有窗口就行了!
    代码如下:
        HWND pWnd;
        pWnd=::GetDesktopWindow();//得到第一个窗口句柄
        pWnd=::GetNextWindow(pWnd,GW_HWNDNEXT);//得到下一个窗口句柄    
      

  3.   

    lgs的方法只能知道指定的程序的窗口句柄,但是如果我想要知道所有在任务栏中的程序的句柄呢?
      

  4.   

    stanley:
       你的方法我也试过了,得到了很多句柄不是任务栏中的程序,能不能把这些不是任务栏中的程序过滤掉?
      

  5.   

    有些窗口是隐藏的,在任务栏显示不出来。可以用EnumWindows将所有看得见的,在任务栏有按钮的主窗口枚举出来,MSDN上面有例子。