找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 4206|回复: 0

[开源] 【分享】VC中枚举所有的任务,任务管理器的一些资料的整理

[复制链接]

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

发表于 2009-7-20 23:08:15 | 显示全部楼层 |阅读模式
<p>1.列举所有的任务</p>
<p>调用EnumWindows这个函数<br/>BOOL EnumWindows(<br/>&nbsp;&nbsp; WNDENUMPROC lpEnumFunc,&nbsp;&nbsp; // callback function<br/>&nbsp;&nbsp; LPARAM lParam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // application-defined value<br/>); <br/>如: <br/>::EnumWindows((WNDENUMPROC)enumProc,(LPARAM)this);</p>
<p><br/>enumProc就是那个回调函数,真正的操作,都在这个函数里实现<br/>第二个参数,是用户自定义传送的,比如这里,可以是对话框的指针</p>
<p><br/>enumProc的原型是<br/>BOOL CALLBACK CPListDlg::enumProc(HWND hwnd, LPARAM lParam)<br/>如果是类成员函数,必须是static函数,声明如下<br/>BOOL static CALLBACK enumProc(HWND hwnd, LPARAM lParam);<br/>其中,那个HWND hwnd就是窗口句柄</p>
<p><br/>BOOL CALLBACK CPListDlg::enumProc(HWND hwnd, LPARAM lParam)<br/>{<br/>CPListDlg * pDlg = (CPListDlg *)lParam;</p>
<p>if (hwnd == NULL)<br/>{<br/>&nbsp;&nbsp; return FALSE;<br/>}</p>
<p>if (hwnd == pDlg-&gt;m_hWnd) //这是为了不把自己这个程序列出来,呵呵<br/>{<br/>&nbsp;&nbsp; return TRUE;<br/>}</p>
<p>if (::IsWindow(hwnd) &amp;&amp; ::IsWindowVisible(hwnd) &amp;&amp; ((GetWindowLong(hwnd, GWL_EXSTYLE)&amp;WS_EX_TOOLWINDOW)!</p>
<p>=WS_EX_TOOLWINDOW) &amp;&amp;<br/>(GetWindowLong(hwnd, GWL_HWNDPARENT)==0))<br/>{<br/>        TCHAR szCap[255] = {0};<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp; ::GetWindowText(hwnd, szCap, 255);</p>
<p>        if (strlen(szCap) == 0)<br/>&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp; return TRUE;<br/>&nbsp;&nbsp; }<br/>&nbsp;&nbsp; if (lstrcmp(_T("Program Manager"),szCap) == 0)<br/>&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp; return TRUE;<br/>&nbsp;&nbsp; }</p>
<p><br/>&nbsp;&nbsp; DWORD dwProcessID = 0;<br/>&nbsp;&nbsp; ::GetWindowThreadProcessId(hwnd,&amp;dwProcessID);<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp; TRACE( "id = %d, name = %s\n", dwProcessID, szCap );<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;<br/>}<br/>return TRUE;</p>
<p>}</p>
<p>GetWindowThreadProcessId是获取进行的ID的</p>
<p>if (lstrcmp(_T("Program Manager"),szCap) == 0) </p>
<p>是为了区别出Program Manager这个程序,不知道为什么,会列出这个东西来,晕</p>
<p></p>
<p>2.获取窗口的图标</p>
<p>&nbsp;&nbsp; HICON hIcon = NULL;<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp; hIcon = (HICON)::GetClassLong(hwnd,GCL_HICONSM);</p>
<p>&nbsp;&nbsp; if(hIcon == NULL)<br/>&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp; hIcon = (HICON)::GetClassLong(hwnd,GCL_HICON);<br/>&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp; if(hIcon == NULL)<br/>&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp; hIcon = (HICON)::SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0);<br/>&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp; if(hIcon == NULL)<br/>&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp; hIcon = (HICON)::SendMessage(hwnd, WM_GETICON, ICON_BIG, 0);<br/>&nbsp;&nbsp; }</p>
<p>记得当时做的时候,有这些代码是因为,有些窗口的图标不能获得,用了上述办法以后,才能全部获得</p>
<p><br/>3.判断窗口是否是正常运行还是未响应的<br/>首先定义两个函数指针,<br/>typedef BOOL (WINAPI *PROCISHUNGAPPWINDOW)(HWND);<br/>typedef BOOL (WINAPI *PROCISHUNGTHREAD)(DWORD);</p>
<p>然后定义<br/>PROCISHUNGAPPWINDOW&nbsp;&nbsp;&nbsp; m_pIsHungAppWindow;<br/>PROCISHUNGTHREAD&nbsp;&nbsp;&nbsp; m_pIsHungThread;</p>
<p>定义一个bool型,来判断当前操作系统是否是Windows NT/2000以上<br/>因为不同的操作系统,判断程序是否运行正常的方式是不一样的</p>
<p>BOOL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_bIsNT;</p>
<p>获取版本信息<br/>OSVERSIONINFO osver = {0};</p>
<p>osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);<br/>if (!GetVersionEx(&amp;osver))<br/>{<br/>bRetVal = FALSE;<br/>}</p>
<p><br/>if(bRetVal == TRUE)<br/>{<br/>if (osver.dwPlatformId&amp;VER_PLATFORM_WIN32_NT)<br/>{<br/>&nbsp;&nbsp; m_bIsNT = TRUE;<br/>}<br/>else<br/>{<br/>&nbsp;&nbsp; m_bIsNT = FALSE;<br/>}</p>
<p>}</p>
<p>获取那两个函数指针<br/>HMODULE hUser32 = ::GetModuleHandle("user32");<br/><br/>if (!hUser32)<br/>{<br/>&nbsp;&nbsp; bRetVal = FALSE;<br/>}<br/>&nbsp;&nbsp;</p>
<p>if(bRetVal == TRUE)<br/>{<br/>&nbsp;&nbsp; m_pIsHungAppWindow = (PROCISHUNGAPPWINDOW)<br/>&nbsp;&nbsp; GetProcAddress( hUser32,<br/>&nbsp;&nbsp; "IsHungAppWindow" );</p>
<p>&nbsp;&nbsp; m_pIsHungThread = (PROCISHUNGTHREAD) GetProcAddress( hUser32,<br/>&nbsp;&nbsp; "IsHungThread" );</p>
<p>&nbsp;&nbsp; if (!m_pIsHungAppWindow &amp;&amp; !m_pIsHungThread)<br/>&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp; bRetVal = FALSE;<br/>&nbsp;&nbsp; }</p>
<p>}</p>
<p>于是判断,窗口是否是正常运行,还是未响应<br/>代码如下</p>
<p>if(m_bIsNT == TRUE)<br/>{&nbsp;&nbsp;<br/>BOOL bIsHung = m_pIsHungAppWindow(hwnd);<br/>if(bIsHung)<br/>{<br/>&nbsp;&nbsp; //没有响应<br/>}<br/>else<br/>{ <br/>&nbsp;&nbsp; //正在运行&nbsp;&nbsp;&nbsp;&nbsp;<br/>}<br/>}&nbsp;&nbsp;&nbsp;<br/>else<br/>{<br/>BOOL bIsHung =m_pIsHungThread(GetWindowThreadProcessId(hwnd,NULL));<br/>if(bIsHung)<br/>{<br/>&nbsp;&nbsp; //没有响应<br/>}<br/>else<br/>{ <br/>&nbsp;&nbsp; //正在运行&nbsp;&nbsp;&nbsp;&nbsp;<br/>}<br/>}</p>
<p><br/>4.结束任务<br/>:ostMessage(hwnd,WM_CLOSE,0,0);</p>
<p>不过调用这个,有时候不一定一下能把窗口关了,比如窗口没响应了,就关不了<br/>于是,得继续想办法</p>
<p>:ostMessage(hwnd,WM_CLOSE,0,0);<br/>::Sleep(300);<br/>//如果窗口还没有被关,继续想办法<br/>if(::IsWindow(hwnd))<br/>{   <br/>DWORD dwProcessID = 0;<br/>::GetWindowThreadProcessId(hwnd,&amp;dwProcessID);</p>
<p>    if(TerminateApp(dwProcessID,500) != TA_FAILED)<br/>    {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //结束成功了<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>}</p>
<p><br/>TerminateApp是这样的</p>
<p>DWORD WINAPI CPListDlg::TerminateApp( DWORD dwPID, DWORD dwTimeout )<br/>{<br/>HANDLE&nbsp;&nbsp;&nbsp; hProc ;<br/>DWORD&nbsp;&nbsp;&nbsp; dwRet ;<br/><br/>// If we can't open the process with PROCESS_TERMINATE rights,<br/>// then we give up immediately.<br/>hProc = ::OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,<br/>&nbsp;&nbsp; dwPID);<br/><br/>if(hProc == NULL)<br/>{<br/>&nbsp;&nbsp; return TA_FAILED ;<br/>}<br/><br/>// TerminateAppEnum() posts WM_CLOSE to all windows whose PID<br/>// matches your process's.<br/>EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;<br/><br/>// Wait on the handle. If it signals, great. If it times out,<br/>// then you kill it.<br/>if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0)<br/>&nbsp;&nbsp; dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);<br/>else<br/>&nbsp;&nbsp; dwRet = TA_SUCCESS_CLEAN ;<br/><br/>CloseHandle(hProc) ;<br/><br/>return dwRet ;</p>
<p>}</p>
<p>又有一个回调函数</p>
<p><br/>BOOL CALLBACK CPListDlg::TerminateAppEnum( HWND hwnd, LPARAM lParam )<br/>{<br/>DWORD dwID ;</p>
<p>::GetWindowThreadProcessId(hwnd, &amp;dwID) ;</p>
<p>if(dwID == (DWORD)lParam)<br/>{<br/>&nbsp;&nbsp; :ostMessage(hwnd, WM_CLOSE, 0, 0) ;<br/>}</p>
<p>return TRUE ;</p>
<p>}<br/>原型是<br/>BOOL static CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;</p>
<p></p>
<p>这是以前做的一个任务管理器的相关代码,有很多欠缺的地方,也一直没有改进,这次把它整理出来了,如果有不对的地方,希望得到大家的指正~~~</p>
<p><br/>关于,如何把这些信息显示出来,比如在listctrl中显示出来,我就不多说了,可以参考博客中的另一文章,“VC中使用ListCtrl经验总结(1)”</p>
<p>参考文章<br/>关于如何判断程序的状态……………………<br/><a href="http://www.vckbase.com/bbs/prime/viewprime.asp?id=334">http://www.vckbase.com/bbs/prime/viewprime.asp?id=334</a> </p>
【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表