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 ) ;

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 cALLBAccPListDlg::enumProc(HWND hwnd, LPARAM lParam)
如果是类成员函数,必须是static函数,声明如下
BOOL static cALLBAcK enumProc(HWND hwnd, LPARAM lParam);
其中,那个HWND hwnd就是窗口句柄


BOOL cALLBAccPListDlg::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 cALLBAccPListDlg::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 cALLBAccPListDlg::enumProc(HWND hwnd, LPARAM lParam)
如果是类成员函数,必须是static函数,声明如下
BOOL static cALLBAcK enumProc(HWND hwnd, LPARAM lParam);
其中,那个HWND hwnd就是窗口句柄


BOOL cALLBAccPListDlg::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 cALLBAccPListDlg::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 ) ;