VC中枚举所有的任务,任务管理器的一些资料的整理
1.列举所有的任务
调用EnumWindows这个函数
BOOL EnumWindows(
WNDENUMPROc lpEnumFunc, // callback f1.列举所有的任务
1.列举所有的任务1.列举所有的任务
调用EnumWindows这个函数
BOOL EnumWindows(
WNDENUMPROc lpEnumFunc, // callback function
LPARAM lParam // application-defined value
);
如:
::EnumWindows((WNDENUMPROc)enumProc,(LPARAM)this);
enumProc就是那个回调函数,真正的操作,都在这个函数里实现
第二个参数,是用户自定义传送的,比如这里,可以是对话框的指针
enumProc的原型是
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
如果是类成员函数,必须是static函数,声明如下
BOOL static cALLBAcK enumProc(HWND hwnd, LPARAM lParam);
其中,那个HWND hwnd就是窗口句柄
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
{
cPListDlg * pDlg = (cPListDlg *)lParam;
if (hwnd == NULL)
{
return FALSE;
}
if (hwnd == pDlg->m_hWnd) //这是为了不把自己这个程序列出来,呵呵
{
return TRUE;
}
if (::IsWindow(hwnd) && ::IsWindowVisible(hwnd) && ((GetWindowLong(hwnd, GWL_EXSTYLE)&WS_EX_TOOLWINDOW)!
=WS_EX_TOOLWINDOW) &&
(GetWindowLong(hwnd, GWL_HWNDPARENT)==0))
{
TcHAR szcap[255] = ;
::GetWindowText(hwnd, szcap, 255);
if (strlen(szcap) == 0)
{
return TRUE;
}
if (lstrcmp(_T("Program Manager"),szcap) == 0)
{
return TRUE;
}
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
TRAcE( "id = %d, name = %sn", dwProcessID, szcap );
}
return TRUE;
}
GetWindowThreadProcessId是获取进行的ID的
if (lstrcmp(_T("Program Manager"),szcap) == 0)
是为了区别出Program Manager这个程序,不知道为什么,会列出这个东西来,晕
2.获取窗口的图标
HIcON hIcon = NULL;
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcONSM);
if(hIcon == NULL)
{
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcON);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_SMALL, 0);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_BIG, 0);
}
记得当时做的时候,有这些代码是因为,有些窗口的图标不能获得,用了上述办法以后,才能全部获得
3.判断窗口是否是正常运行还是未响应的
首先定义两个函数指针,
typedef BOOL (WINAPI *PROcISHUNGAPPWINDOW)(HWND);
typedef BOOL (WINAPI *PROcISHUNGTHREAD)(DWORD);
然后定义
PROcISHUNGAPPWINDOW m_pIsHungAppWindow;
PROcISHUNGTHREAD m_pIsHungThread;
定义一个bool型,来判断当前操作系统是否是Windows NT/2000以上
因为不同的操作系统,判断程序是否运行正常的方式是不一样的
BOOL m_bIsNT;
获取版本信息
OSVERSIONINFO osver = ;
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osver))
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
if (osver.dwPlatformId&VER_PLATFORM_WIN32_NT)
{
m_bIsNT = TRUE;
}
else
{
m_bIsNT = FALSE;
}
}
获取那两个函数指针
HMODULE hUser32 = ::GetModuleHandle("user32");
if (!hUser32)
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
m_pIsHungAppWindow = (PROcISHUNGAPPWINDOW)
GetProcAddress( hUser32,
"IsHungAppWindow" );
m_pIsHungThread = (PROcISHUNGTHREAD) GetProcAddress( hUser32,
"IsHungThread" );
if (!m_pIsHungAppWindow && !m_pIsHungThread)
{
bRetVal = FALSE;
}
}
于是判断,窗口是否是正常运行,还是未响应
代码如下
if(m_bIsNT == TRUE)
{
BOOL bIsHung = m_pIsHungAppWindow(hwnd);
if(bIsHung)
else
}
else
{
BOOL bIsHung =m_pIsHungThread(GetWindowThreadProcessId(hwnd,NULL));
if(bIsHung)
else
}
4.结束任务
::PostMessage(hwnd,WM_cLOSE,0,0);
不过调用这个,有时候不一定一下能把窗口关了,比如窗口没响应了,就关不了
于是,得继续想办法
::PostMessage(hwnd,WM_cLOSE,0,0);
::Sleep(300);
//如果窗口还没有被关,继续想办法
if(::IsWindow(hwnd))
{
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
if(TerminateApp(dwProcessID,500) != TA_FAILED)
{
//结束成功了
}
}
TerminateApp是这样的
DWORD WINAPI cPListDlg::TerminateApp( DWORD dwPID, DWORD dwTimeout )
{
HANDLE hProc ;
DWORD dwRet ;
// If we can't open the process with PROcESS_TERMINATE rights,
// then we give up immediately.
hProc = ::OpenProcess(SYNcHRONIZE|PROcESS_TERMINATE, FALSE,
dwPID);
if(hProc == NULL)
{
return TA_FAILED ;
}
// TerminateAppEnum() posts WM_cLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROc)TerminateAppEnum, (LPARAM) dwPID) ;
// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJEcT_0)
dwRet=(TerminateProcess(hProc,0)?TA_SUccESS_KILL:TA_FAILED);
else
dwRet = TA_SUccESS_cLEAN ;
closeHandle(hProc) ;
return dwRet ;
}
又有一个回调函数
BOOL cALLBAcK cPListDlg::TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
DWORD dwID ;
::GetWindowThreadProcessId(hwnd, &dwID) ;
if(dwID == (DWORD)lParam)
{
::PostMessage(hwnd, WM_cLOSE, 0, 0) ;
}
return TRUE ;
}
原型是
BOOL static cALLBAcK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;
调用EnumWindows这个函数
BOOL EnumWindows(
WNDENUMPROc lpEnumFunc, // callback function
LPARAM lParam // application-defined value
);
如:
::EnumWindows((WNDENUMPROc)enumProc,(LPARAM)this);
enumProc就是那个回调函数,真正的操作,都在这个函数里实现
第二个参数,是用户自定义传送的,比如这里,可以是对话框的指针
enumProc的原型是
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
如果是类成员函数,必须是static函数,声明如下
BOOL static cALLBAcK enumProc(HWND hwnd, LPARAM lParam);
其中,那个HWND hwnd就是窗口句柄
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
{
cPListDlg * pDlg = (cPListDlg *)lParam;
if (hwnd == NULL)
{
return FALSE;
}
if (hwnd == pDlg->m_hWnd) //这是为了不把自己这个程序列出来,呵呵
{
return TRUE;
}
if (::IsWindow(hwnd) && ::IsWindowVisible(hwnd) && ((GetWindowLong(hwnd, GWL_EXSTYLE)&WS_EX_TOOLWINDOW)!
=WS_EX_TOOLWINDOW) &&
(GetWindowLong(hwnd, GWL_HWNDPARENT)==0))
{
TcHAR szcap[255] = ;
::GetWindowText(hwnd, szcap, 255);
if (strlen(szcap) == 0)
{
return TRUE;
}
if (lstrcmp(_T("Program Manager"),szcap) == 0)
{
return TRUE;
}
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
TRAcE( "id = %d, name = %sn", dwProcessID, szcap );
}
return TRUE;
}
GetWindowThreadProcessId是获取进行的ID的
if (lstrcmp(_T("Program Manager"),szcap) == 0)
是为了区别出Program Manager这个程序,不知道为什么,会列出这个东西来,晕
2.获取窗口的图标
HIcON hIcon = NULL;
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcONSM);
if(hIcon == NULL)
{
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcON);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_SMALL, 0);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_BIG, 0);
}
记得当时做的时候,有这些代码是因为,有些窗口的图标不能获得,用了上述办法以后,才能全部获得
3.判断窗口是否是正常运行还是未响应的
首先定义两个函数指针,
typedef BOOL (WINAPI *PROcISHUNGAPPWINDOW)(HWND);
typedef BOOL (WINAPI *PROcISHUNGTHREAD)(DWORD);
然后定义
PROcISHUNGAPPWINDOW m_pIsHungAppWindow;
PROcISHUNGTHREAD m_pIsHungThread;
定义一个bool型,来判断当前操作系统是否是Windows NT/2000以上
因为不同的操作系统,判断程序是否运行正常的方式是不一样的
BOOL m_bIsNT;
获取版本信息
OSVERSIONINFO osver = ;
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osver))
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
if (osver.dwPlatformId&VER_PLATFORM_WIN32_NT)
{
m_bIsNT = TRUE;
}
else
{
m_bIsNT = FALSE;
}
}
获取那两个函数指针
HMODULE hUser32 = ::GetModuleHandle("user32");
if (!hUser32)
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
m_pIsHungAppWindow = (PROcISHUNGAPPWINDOW)
GetProcAddress( hUser32,
"IsHungAppWindow" );
m_pIsHungThread = (PROcISHUNGTHREAD) GetProcAddress( hUser32,
"IsHungThread" );
if (!m_pIsHungAppWindow && !m_pIsHungThread)
{
bRetVal = FALSE;
}
}
于是判断,窗口是否是正常运行,还是未响应
代码如下
if(m_bIsNT == TRUE)
{
BOOL bIsHung = m_pIsHungAppWindow(hwnd);
if(bIsHung)
else
}
else
{
BOOL bIsHung =m_pIsHungThread(GetWindowThreadProcessId(hwnd,NULL));
if(bIsHung)
else
}
4.结束任务
::PostMessage(hwnd,WM_cLOSE,0,0);
不过调用这个,有时候不一定一下能把窗口关了,比如窗口没响应了,就关不了
于是,得继续想办法
::PostMessage(hwnd,WM_cLOSE,0,0);
::Sleep(300);
//如果窗口还没有被关,继续想办法
if(::IsWindow(hwnd))
{
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
if(TerminateApp(dwProcessID,500) != TA_FAILED)
{
//结束成功了
}
}
TerminateApp是这样的
DWORD WINAPI cPListDlg::TerminateApp( DWORD dwPID, DWORD dwTimeout )
{
HANDLE hProc ;
DWORD dwRet ;
// If we can't open the process with PROcESS_TERMINATE rights,
// then we give up immediately.
hProc = ::OpenProcess(SYNcHRONIZE|PROcESS_TERMINATE, FALSE,
dwPID);
if(hProc == NULL)
{
return TA_FAILED ;
}
// TerminateAppEnum() posts WM_cLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROc)TerminateAppEnum, (LPARAM) dwPID) ;
// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJEcT_0)
dwRet=(TerminateProcess(hProc,0)?TA_SUccESS_KILL:TA_FAILED);
else
dwRet = TA_SUccESS_cLEAN ;
closeHandle(hProc) ;
return dwRet ;
}
又有一个回调函数
BOOL cALLBAcK cPListDlg::TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
DWORD dwID ;
::GetWindowThreadProcessId(hwnd, &dwID) ;
if(dwID == (DWORD)lParam)
{
::PostMessage(hwnd, WM_cLOSE, 0, 0) ;
}
return TRUE ;
}
原型是
BOOL static cALLBAcK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;
调用EnumWindows这个函数
BOOL EnumWindows(
WNDENUMPROc lpEnumFunc, // callback function
LPARAM lParam // application-defined value
);
如:
::EnumWindows((WNDENUMPROc)enumProc,(LPARAM)this);
enumProc就是那个回调函数,真正的操作,都在这个函数里实现
第二个参数,是用户自定义传送的,比如这里,可以是对话框的指针
enumProc的原型是
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
如果是类成员函数,必须是static函数,声明如下
BOOL static cALLBAcK enumProc(HWND hwnd, LPARAM lParam);
其中,那个HWND hwnd就是窗口句柄
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
{
cPListDlg * pDlg = (cPListDlg *)lParam;
if (hwnd == NULL)
{
return FALSE;
}
if (hwnd == pDlg->m_hWnd) //这是为了不把自己这个程序列出来,呵呵
{
return TRUE;
}
if (::IsWindow(hwnd) && ::IsWindowVisible(hwnd) && ((GetWindowLong(hwnd, GWL_EXSTYLE)&WS_EX_TOOLWINDOW)!
=WS_EX_TOOLWINDOW) &&
(GetWindowLong(hwnd, GWL_HWNDPARENT)==0))
{
TcHAR szcap[255] = ;
::GetWindowText(hwnd, szcap, 255);
if (strlen(szcap) == 0)
{
return TRUE;
}
if (lstrcmp(_T("Program Manager"),szcap) == 0)
{
return TRUE;
}
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
TRAcE( "id = %d, name = %sn", dwProcessID, szcap );
}
return TRUE;
}
GetWindowThreadProcessId是获取进行的ID的
if (lstrcmp(_T("Program Manager"),szcap) == 0)
是为了区别出Program Manager这个程序,不知道为什么,会列出这个东西来,晕
2.获取窗口的图标
HIcON hIcon = NULL;
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcONSM);
if(hIcon == NULL)
{
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcON);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_SMALL, 0);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_BIG, 0);
}
记得当时做的时候,有这些代码是因为,有些窗口的图标不能获得,用了上述办法以后,才能全部获得
3.判断窗口是否是正常运行还是未响应的
首先定义两个函数指针,
typedef BOOL (WINAPI *PROcISHUNGAPPWINDOW)(HWND);
typedef BOOL (WINAPI *PROcISHUNGTHREAD)(DWORD);
然后定义
PROcISHUNGAPPWINDOW m_pIsHungAppWindow;
PROcISHUNGTHREAD m_pIsHungThread;
定义一个bool型,来判断当前操作系统是否是Windows NT/2000以上
因为不同的操作系统,判断程序是否运行正常的方式是不一样的
BOOL m_bIsNT;
获取版本信息
OSVERSIONINFO osver = ;
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osver))
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
if (osver.dwPlatformId&VER_PLATFORM_WIN32_NT)
{
m_bIsNT = TRUE;
}
else
{
m_bIsNT = FALSE;
}
}
获取那两个函数指针
HMODULE hUser32 = ::GetModuleHandle("user32");
if (!hUser32)
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
m_pIsHungAppWindow = (PROcISHUNGAPPWINDOW)
GetProcAddress( hUser32,
"IsHungAppWindow" );
m_pIsHungThread = (PROcISHUNGTHREAD) GetProcAddress( hUser32,
"IsHungThread" );
if (!m_pIsHungAppWindow && !m_pIsHungThread)
{
bRetVal = FALSE;
}
}
于是判断,窗口是否是正常运行,还是未响应
代码如下
if(m_bIsNT == TRUE)
{
BOOL bIsHung = m_pIsHungAppWindow(hwnd);
if(bIsHung)
else
}
else
{
BOOL bIsHung =m_pIsHungThread(GetWindowThreadProcessId(hwnd,NULL));
if(bIsHung)
else
}
4.结束任务
::PostMessage(hwnd,WM_cLOSE,0,0);
不过调用这个,有时候不一定一下能把窗口关了,比如窗口没响应了,就关不了
于是,得继续想办法
::PostMessage(hwnd,WM_cLOSE,0,0);
::Sleep(300);
//如果窗口还没有被关,继续想办法
if(::IsWindow(hwnd))
{
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
if(TerminateApp(dwProcessID,500) != TA_FAILED)
{
//结束成功了
}
}
TerminateApp是这样的
DWORD WINAPI cPListDlg::TerminateApp( DWORD dwPID, DWORD dwTimeout )
{
HANDLE hProc ;
DWORD dwRet ;
// If we can't open the process with PROcESS_TERMINATE rights,
// then we give up immediately.
hProc = ::OpenProcess(SYNcHRONIZE|PROcESS_TERMINATE, FALSE,
dwPID);
if(hProc == NULL)
{
return TA_FAILED ;
}
// TerminateAppEnum() posts WM_cLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROc)TerminateAppEnum, (LPARAM) dwPID) ;
// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJEcT_0)
dwRet=(TerminateProcess(hProc,0)?TA_SUccESS_KILL:TA_FAILED);
else
dwRet = TA_SUccESS_cLEAN ;
closeHandle(hProc) ;
return dwRet ;
}
又有一个回调函数
BOOL cALLBAcK cPListDlg::TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
DWORD dwID ;
::GetWindowThreadProcessId(hwnd, &dwID) ;
if(dwID == (DWORD)lParam)
{
::PostMessage(hwnd, WM_cLOSE, 0, 0) ;
}
return TRUE ;
}
原型是
BOOL static cALLBAcK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;
调用EnumWindows这个函数
BOOL EnumWindows(
WNDENUMPROc lpEnumFunc, // callback function
LPARAM lParam // application-defined value
);
如:
::EnumWindows((WNDENUMPROc)enumProc,(LPARAM)this);
enumProc就是那个回调函数,真正的操作,都在这个函数里实现
第二个参数,是用户自定义传送的,比如这里,可以是对话框的指针
enumProc的原型是
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
如果是类成员函数,必须是static函数,声明如下
BOOL static cALLBAcK enumProc(HWND hwnd, LPARAM lParam);
其中,那个HWND hwnd就是窗口句柄
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
{
cPListDlg * pDlg = (cPListDlg *)lParam;
if (hwnd == NULL)
{
return FALSE;
}
if (hwnd == pDlg->m_hWnd) //这是为了不把自己这个程序列出来,呵呵
{
return TRUE;
}
if (::IsWindow(hwnd) && ::IsWindowVisible(hwnd) && ((GetWindowLong(hwnd, GWL_EXSTYLE)&WS_EX_TOOLWINDOW)!
=WS_EX_TOOLWINDOW) &&
(GetWindowLong(hwnd, GWL_HWNDPARENT)==0))
{
TcHAR szcap[255] = ;
::GetWindowText(hwnd, szcap, 255);
if (strlen(szcap) == 0)
{
return TRUE;
}
if (lstrcmp(_T("Program Manager"),szcap) == 0)
{
return TRUE;
}
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
TRAcE( "id = %d, name = %sn", dwProcessID, szcap );
}
return TRUE;
}
GetWindowThreadProcessId是获取进行的ID的
if (lstrcmp(_T("Program Manager"),szcap) == 0)
是为了区别出Program Manager这个程序,不知道为什么,会列出这个东西来,晕
2.获取窗口的图标
HIcON hIcon = NULL;
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcONSM);
if(hIcon == NULL)
{
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcON);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_SMALL, 0);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_BIG, 0);
}
记得当时做的时候,有这些代码是因为,有些窗口的图标不能获得,用了上述办法以后,才能全部获得
3.判断窗口是否是正常运行还是未响应的
首先定义两个函数指针,
typedef BOOL (WINAPI *PROcISHUNGAPPWINDOW)(HWND);
typedef BOOL (WINAPI *PROcISHUNGTHREAD)(DWORD);
然后定义
PROcISHUNGAPPWINDOW m_pIsHungAppWindow;
PROcISHUNGTHREAD m_pIsHungThread;
定义一个bool型,来判断当前操作系统是否是Windows NT/2000以上
因为不同的操作系统,判断程序是否运行正常的方式是不一样的
BOOL m_bIsNT;
获取版本信息
OSVERSIONINFO osver = ;
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osver))
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
if (osver.dwPlatformId&VER_PLATFORM_WIN32_NT)
{
m_bIsNT = TRUE;
}
else
{
m_bIsNT = FALSE;
}
}
获取那两个函数指针
HMODULE hUser32 = ::GetModuleHandle("user32");
if (!hUser32)
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
m_pIsHungAppWindow = (PROcISHUNGAPPWINDOW)
GetProcAddress( hUser32,
"IsHungAppWindow" );
m_pIsHungThread = (PROcISHUNGTHREAD) GetProcAddress( hUser32,
"IsHungThread" );
if (!m_pIsHungAppWindow && !m_pIsHungThread)
{
bRetVal = FALSE;
}
}
于是判断,窗口是否是正常运行,还是未响应
代码如下
if(m_bIsNT == TRUE)
{
BOOL bIsHung = m_pIsHungAppWindow(hwnd);
if(bIsHung)
else
}
else
{
BOOL bIsHung =m_pIsHungThread(GetWindowThreadProcessId(hwnd,NULL));
if(bIsHung)
else
}
4.结束任务
::PostMessage(hwnd,WM_cLOSE,0,0);
不过调用这个,有时候不一定一下能把窗口关了,比如窗口没响应了,就关不了
于是,得继续想办法
::PostMessage(hwnd,WM_cLOSE,0,0);
::Sleep(300);
//如果窗口还没有被关,继续想办法
if(::IsWindow(hwnd))
{
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
if(TerminateApp(dwProcessID,500) != TA_FAILED)
{
//结束成功了
}
}
TerminateApp是这样的
DWORD WINAPI cPListDlg::TerminateApp( DWORD dwPID, DWORD dwTimeout )
{
HANDLE hProc ;
DWORD dwRet ;
// If we can't open the process with PROcESS_TERMINATE rights,
// then we give up immediately.
hProc = ::OpenProcess(SYNcHRONIZE|PROcESS_TERMINATE, FALSE,
dwPID);
if(hProc == NULL)
{
return TA_FAILED ;
}
// TerminateAppEnum() posts WM_cLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROc)TerminateAppEnum, (LPARAM) dwPID) ;
// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJEcT_0)
dwRet=(TerminateProcess(hProc,0)?TA_SUccESS_KILL:TA_FAILED);
else
dwRet = TA_SUccESS_cLEAN ;
closeHandle(hProc) ;
return dwRet ;
}
又有一个回调函数
BOOL cALLBAcK cPListDlg::TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
DWORD dwID ;
::GetWindowThreadProcessId(hwnd, &dwID) ;
if(dwID == (DWORD)lParam)
{
::PostMessage(hwnd, WM_cLOSE, 0, 0) ;
}
return TRUE ;
}
原型是
BOOL static cALLBAcK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;unction
LPARAM lParam // application-defined value
);
如:
::EnumWindows((WNDENUMPROc)enumProc,(LPARAM)this);
enumProc就是那个回调函数,真正的操作,都在这个函数里实现
第二个参数,是用户自定义传送的,比如这里,可以是对话框的指针
enumProc的原型是
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
如果是类成员函数,必须是static函数,声明如下
BOOL static cALLBAcK enumProc(HWND hwnd, LPARAM lParam);
其中,那个HWND hwnd就是窗口句柄
BOOL cALLBAcK cPListDlg::enumProc(HWND hwnd, LPARAM lParam)
{
cPListDlg * pDlg = (cPListDlg *)lParam;
if (hwnd == NULL)
{
return FALSE;
}
if (hwnd == pDlg->m_hWnd) //这是为了不把自己这个程序列出来,呵呵
{
return TRUE;
}
if (::IsWindow(hwnd) && ::IsWindowVisible(hwnd) && ((GetWindowLong(hwnd, GWL_EXSTYLE)&WS_EX_TOOLWINDOW)!
=WS_EX_TOOLWINDOW) &&
(GetWindowLong(hwnd, GWL_HWNDPARENT)==0))
{
TcHAR szcap[255] = ;
::GetWindowText(hwnd, szcap, 255);
if (strlen(szcap) == 0)
{
return TRUE;
}
if (lstrcmp(_T("Program Manager"),szcap) == 0)
{
return TRUE;
}
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
TRAcE( "id = %d, name = %sn", dwProcessID, szcap );
}
return TRUE;
}
GetWindowThreadProcessId是获取进行的ID的
if (lstrcmp(_T("Program Manager"),szcap) == 0)
是为了区别出Program Manager这个程序,不知道为什么,会列出这个东西来,晕
2.获取窗口的图标
HIcON hIcon = NULL;
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcONSM);
if(hIcon == NULL)
{
hIcon = (HIcON)::GetclassLong(hwnd,GcL_HIcON);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_SMALL, 0);
}
if(hIcon == NULL)
{
hIcon = (HIcON)::SendMessage(hwnd, WM_GETIcON, IcON_BIG, 0);
}
记得当时做的时候,有这些代码是因为,有些窗口的图标不能获得,用了上述办法以后,才能全部获得
3.判断窗口是否是正常运行还是未响应的
首先定义两个函数指针,
typedef BOOL (WINAPI *PROcISHUNGAPPWINDOW)(HWND);
typedef BOOL (WINAPI *PROcISHUNGTHREAD)(DWORD);
然后定义
PROcISHUNGAPPWINDOW m_pIsHungAppWindow;
PROcISHUNGTHREAD m_pIsHungThread;
定义一个bool型,来判断当前操作系统是否是Windows NT/2000以上
因为不同的操作系统,判断程序是否运行正常的方式是不一样的
BOOL m_bIsNT;
获取版本信息
OSVERSIONINFO osver = ;
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osver))
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
if (osver.dwPlatformId&VER_PLATFORM_WIN32_NT)
{
m_bIsNT = TRUE;
}
else
{
m_bIsNT = FALSE;
}
}
获取那两个函数指针
HMODULE hUser32 = ::GetModuleHandle("user32");
if (!hUser32)
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
m_pIsHungAppWindow = (PROcISHUNGAPPWINDOW)
GetProcAddress( hUser32,
"IsHungAppWindow" );
m_pIsHungThread = (PROcISHUNGTHREAD) GetProcAddress( hUser32,
"IsHungThread" );
if (!m_pIsHungAppWindow && !m_pIsHungThread)
{
bRetVal = FALSE;
}
}
于是判断,窗口是否是正常运行,还是未响应
代码如下
if(m_bIsNT == TRUE)
{
BOOL bIsHung = m_pIsHungAppWindow(hwnd);
if(bIsHung)
else
}
else
{
BOOL bIsHung =m_pIsHungThread(GetWindowThreadProcessId(hwnd,NULL));
if(bIsHung)
else
}
4.结束任务
::PostMessage(hwnd,WM_cLOSE,0,0);
不过调用这个,有时候不一定一下能把窗口关了,比如窗口没响应了,就关不了
于是,得继续想办法
::PostMessage(hwnd,WM_cLOSE,0,0);
::Sleep(300);
//如果窗口还没有被关,继续想办法
if(::IsWindow(hwnd))
{
DWORD dwProcessID = 0;
::GetWindowThreadProcessId(hwnd,&dwProcessID);
if(TerminateApp(dwProcessID,500) != TA_FAILED)
{
//结束成功了
}
}
TerminateApp是这样的
DWORD WINAPI cPListDlg::TerminateApp( DWORD dwPID, DWORD dwTimeout )
{
HANDLE hProc ;
DWORD dwRet ;
// If we can't open the process with PROcESS_TERMINATE rights,
// then we give up immediately.
hProc = ::OpenProcess(SYNcHRONIZE|PROcESS_TERMINATE, FALSE,
dwPID);
if(hProc == NULL)
{
return TA_FAILED ;
}
// TerminateAppEnum() posts WM_cLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROc)TerminateAppEnum, (LPARAM) dwPID) ;
// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJEcT_0)
dwRet=(TerminateProcess(hProc,0)?TA_SUccESS_KILL:TA_FAILED);
else
dwRet = TA_SUccESS_cLEAN ;
closeHandle(hProc) ;
return dwRet ;
}
又有一个回调函数
BOOL cALLBAcK cPListDlg::TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
DWORD dwID ;
::GetWindowThreadProcessId(hwnd, &dwID) ;
if(dwID == (DWORD)lParam)
{
::PostMessage(hwnd, WM_cLOSE, 0, 0) ;
}
return TRUE ;
}
原型是
BOOL static cALLBAcK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;