枚举所有的任务,任务管理器的一些资料的整理

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] = {0};     ::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 = %s/n", 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 = {0};

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

 

你可能感兴趣的:(随手笔记,任务,callback,winapi,manager,null,windows)