659 lines
18 KiB
C++
659 lines
18 KiB
C++
// ApplicationsDialog.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "systemstateinfo.h"
|
|
#include "ApplicationsDialog.h"
|
|
|
|
#include "UTBStrOp.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
#define APPLICATIONREF_FLAG 0xffee0000
|
|
#define WINDOWREF_FLAG 0xffdd0000
|
|
#define PROCESSREF_FLAG 0xffcc0000
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CApplicationsDialog dialog
|
|
|
|
|
|
CApplicationsDialog::CApplicationsDialog() : CPageDialog()
|
|
{
|
|
//{{AFX_DATA_INIT(CApplicationsDialog)
|
|
m_nExpandLevel = 0;
|
|
m_nExpandType = 1;
|
|
//}}AFX_DATA_INIT
|
|
m_nCurrentIndex=-1;
|
|
}
|
|
|
|
|
|
void CApplicationsDialog::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CPageDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CApplicationsDialog)
|
|
DDX_Control(pDX, IDC_SPIN_EXPANDLEVEL, m_spinExpandLevel);
|
|
DDX_Control(pDX, IDC_EDIT_EXPANDLEVEL, m_editExpandLevel);
|
|
DDX_Control(pDX, IDC_TREE_APPLICATIONS, m_tree);
|
|
DDX_Text(pDX, IDC_EDIT_EXPANDLEVEL, m_nExpandLevel);
|
|
DDX_Radio(pDX, IDC_RADIO_EXPANDLEVEL, m_nExpandType);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CApplicationsDialog, CPageDialog)
|
|
//{{AFX_MSG_MAP(CApplicationsDialog)
|
|
ON_BN_CLICKED(IDC_RADIO_EXPANDALL, OnRadioExpandall)
|
|
ON_BN_CLICKED(IDC_RADIO_EXPANDLEVEL, OnRadioExpandlevel)
|
|
ON_NOTIFY(NM_DBLCLK, IDC_TREE_APPLICATIONS, OnDblclkTreeServices)
|
|
ON_NOTIFY(NM_RCLICK, IDC_TREE_APPLICATIONS, OnRclickTreeApplications)
|
|
//}}AFX_MSG_MAP
|
|
ON_COMMAND(IDM_APP_SWITCHTO, OnAppWndSwitchTo)
|
|
ON_COMMAND(IDM_APP_BRINGTOFRONT, OnAppWndBringToFront)
|
|
ON_COMMAND(IDM_APP_MINIMIZE, OnAppWndMinimize)
|
|
ON_COMMAND(IDM_APP_MAXIMIZE, OnAppWndMaximize)
|
|
ON_COMMAND(IDM_APP_RESTORE, OnAppWndRestore)
|
|
ON_COMMAND(IDM_APP_CLOSE, OnAppWndClose)
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CApplicationsDialog message handlers
|
|
void CApplicationsDialog::OnInitDialog()
|
|
{
|
|
CPageDialog::OnInitDialog();
|
|
|
|
// TODO: Add your specialized creation code here
|
|
|
|
m_ilTree.Create(::GetSystemMetrics(SM_CXSMICON),
|
|
::GetSystemMetrics(SM_CYSMICON),ILC_COLOR8|ILC_MASK,0,0);
|
|
m_tree.SetImageList(&m_ilTree,TVSIL_NORMAL);
|
|
|
|
LV_COLUMN lvc={ sizeof(lvc) };
|
|
lvc.fmt=LVCFMT_LEFT;
|
|
lvc.cx=237;
|
|
lvc.pszText=_T("Item");
|
|
lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT;
|
|
m_tree.SetColumn(0,&lvc);
|
|
m_tree.InsertColumn(1,_T("Value"),LVCFMT_LEFT,200,1);
|
|
|
|
// set COXTreeCtrl styles
|
|
m_tree.ModifyExStyle(0,TVOXS_PICKANYWHERE|TVOXS_ROWSEL);
|
|
m_tree.ModifyStyle(0,TVS_SHOWSELALWAYS|TVS_HASBUTTONS|
|
|
TVS_HASLINES|TVS_LINESATROOT);
|
|
|
|
|
|
// spin control
|
|
m_spinExpandLevel.SetRange(0,3);
|
|
m_spinExpandLevel.SetPos(0);
|
|
|
|
// layout manager
|
|
//
|
|
m_LayoutManager.Attach(this);
|
|
|
|
// tree control
|
|
m_LayoutManager.TieChild(IDC_TREE_APPLICATIONS,OX_LMS_ANY,OX_LMT_SAME);
|
|
//////////////////
|
|
|
|
// radio buttons and expand level edit control
|
|
m_LayoutManager.TieChild(IDC_RADIO_EXPANDALL,
|
|
OX_LMS_LEFT|OX_LMS_BOTTOM,OX_LMT_SAME);
|
|
|
|
m_LayoutManager.TieChild(IDC_RADIO_EXPANDLEVEL,
|
|
OX_LMS_LEFT|OX_LMS_BOTTOM,OX_LMT_SAME);
|
|
|
|
m_LayoutManager.TieChild(IDC_EDIT_EXPANDLEVEL,OX_LMS_LEFT,
|
|
OX_LMT_OPPOSITE,IDC_RADIO_EXPANDLEVEL);
|
|
m_LayoutManager.TieChild(IDC_EDIT_EXPANDLEVEL,OX_LMS_BOTTOM,OX_LMT_SAME);
|
|
|
|
m_LayoutManager.TieChild(IDC_SPIN_EXPANDLEVEL,OX_LMS_LEFT,
|
|
OX_LMT_OPPOSITE,IDC_EDIT_EXPANDLEVEL);
|
|
m_LayoutManager.TieChild(IDC_SPIN_EXPANDLEVEL,OX_LMS_BOTTOM,OX_LMT_SAME);
|
|
//////////////////
|
|
|
|
//////////////////////////////////////
|
|
|
|
PopulateTree();
|
|
|
|
ShowControls();
|
|
}
|
|
|
|
void CApplicationsDialog::Refresh()
|
|
{
|
|
PopulateTree();
|
|
}
|
|
|
|
void CApplicationsDialog::PopulateTree()
|
|
{
|
|
if(!UpdateData())
|
|
return;
|
|
|
|
CWaitCursor waitCursor;
|
|
|
|
m_tree.SetRedraw(FALSE);
|
|
// kill and close all threads
|
|
CleanThreads();
|
|
// remove all items
|
|
m_tree.DeleteAllItems();
|
|
COXTreeHeader* pHeader=(COXTreeHeader*)m_tree.GetDlgItem(0);
|
|
ASSERT(pHeader);
|
|
pHeader->SortColumn(-1,0);
|
|
// clean up image list
|
|
for(int nIndex=0; nIndex<m_ilTree.GetImageCount(); nIndex++)
|
|
VERIFY(m_ilTree.Remove(0));
|
|
|
|
// create fonts to customize tree items appearance
|
|
LOGFONT lf;
|
|
CFont fontRoot;
|
|
CFont fontSubRoot;
|
|
CFont* pFontRoot=GetFont();
|
|
if(pFontRoot->GetLogFont(&lf))
|
|
{
|
|
lf.lfHeight=-14;
|
|
UTBStr::tcsncpy(lf.lfFaceName, LF_FACESIZE,_T("Arial"),LF_FACESIZE);
|
|
fontRoot.CreateFontIndirect(&lf);
|
|
|
|
lf.lfHeight=-12;
|
|
lf.lfWeight=FW_BOLD;
|
|
UTBStr::tcsncpy(lf.lfFaceName,LF_FACESIZE,_T("Times New Roman"),LF_FACESIZE);
|
|
fontSubRoot.CreateFontIndirect(&lf);
|
|
}
|
|
pFontRoot=((HFONT)fontRoot!=NULL) ? &fontRoot : NULL;
|
|
// CFont* pFontSubRoot=((HFONT)fontSubRoot!=NULL) ? &fontSubRoot : NULL;
|
|
|
|
CString sValue;
|
|
HTREEITEM htiRoot=NULL;
|
|
HTREEITEM htiSelectItem=NULL;
|
|
HTREEITEM htiItem=NULL;
|
|
|
|
COLORREF clrTopic=RGB(0,0,255);
|
|
COLORREF clrValue=RGB(0,128,0);
|
|
|
|
m_arrAppInfo.RemoveAll();
|
|
if(::EnumWindows(&EnumMainWindows,(LPARAM)&m_arrAppInfo))
|
|
{
|
|
for(int nIndex=0; nIndex<m_arrAppInfo.GetSize(); nIndex++)
|
|
{
|
|
CWnd* pAppWnd=CWnd::FromHandle(m_arrAppInfo[nIndex].hMainWnd);
|
|
if(pAppWnd!=NULL && ::IsWindow(pAppWnd->GetSafeHwnd()))
|
|
{
|
|
// main window text
|
|
CString sWindowText;
|
|
pAppWnd->GetWindowText(sWindowText);
|
|
///////////////////
|
|
|
|
// work out icon...
|
|
int nIconIndex=-1;
|
|
HICON hIcon=(HICON)(DWORD_PTR)::GetClassLongPtr(pAppWnd->m_hWnd,GCL_HICONSM);
|
|
if(hIcon==NULL)
|
|
hIcon=(HICON)(DWORD_PTR)::GetClassLongPtr(pAppWnd->m_hWnd,GCL_HICON);
|
|
if(hIcon==NULL && m_arrAppInfo[nIndex].bGotRespond)
|
|
{
|
|
if(!::SendMessageTimeout(m_arrAppInfo[nIndex].hMainWnd,
|
|
WM_GETICON,ICON_SMALL,0,SMTO_ABORTIFHUNG,
|
|
1000,(LPDWORD)&hIcon) || hIcon==NULL)
|
|
{
|
|
::SendMessageTimeout(m_arrAppInfo[nIndex].hMainWnd,
|
|
WM_GETICON,ICON_BIG,0,SMTO_ABORTIFHUNG,
|
|
1000,(LPDWORD)&hIcon);
|
|
}
|
|
}
|
|
if(hIcon!=NULL)
|
|
// add icon
|
|
nIconIndex=m_ilTree.Add(hIcon);
|
|
///////////////////
|
|
|
|
htiRoot=InsertItem(sWindowText,NULL,nIconIndex,
|
|
pFontRoot,clrTopic);
|
|
VERIFY(m_tree.SetSubItem(htiRoot,1,OX_SUBITEM_TEXT|
|
|
OX_SUBITEM_COLOR,(m_arrAppInfo[nIndex].bGotRespond ?
|
|
_T("Running") : _T("Not reponding")),0,NULL,clrValue));
|
|
VERIFY(m_tree.SetItemData(htiRoot,APPLICATIONREF_FLAG+nIndex));
|
|
if(htiSelectItem==NULL)
|
|
htiSelectItem=htiRoot;
|
|
///////////////////
|
|
|
|
// Executable
|
|
if(m_process.GetProcessImageFileName(
|
|
m_arrAppInfo[nIndex].dwProcessID,sValue))
|
|
{
|
|
htiItem=InsertItem(_T("Executable"),htiRoot);
|
|
VERIFY(m_tree.SetSubItem(htiItem,1,
|
|
OX_SUBITEM_TEXT|OX_SUBITEM_COLOR,
|
|
sValue,0,NULL,clrValue));
|
|
VERIFY(m_tree.
|
|
SetItemDrawEllipsis(htiItem,DT_PATH_ELLIPSIS,1));
|
|
}
|
|
///////////////////
|
|
|
|
// Process ID
|
|
htiItem=InsertItem(_T("Process ID"),htiRoot);
|
|
sValue.Format(_T("0x%x"),m_arrAppInfo[nIndex].dwProcessID);
|
|
VERIFY(m_tree.SetSubItem(htiItem,1,
|
|
OX_SUBITEM_TEXT|OX_SUBITEM_COLOR,
|
|
sValue,0,NULL,clrValue));
|
|
VERIFY(m_tree.SetItemData(htiItem,PROCESSREF_FLAG+nIndex));
|
|
///////////////////
|
|
|
|
// Main Window
|
|
htiItem=InsertItem(_T("Main window handle"),htiRoot);
|
|
sValue.Format(_T("0x%x"),m_arrAppInfo[nIndex].hMainWnd);
|
|
VERIFY(m_tree.SetSubItem(htiItem,1,
|
|
OX_SUBITEM_TEXT|OX_SUBITEM_COLOR,
|
|
sValue,0,NULL,clrValue));
|
|
VERIFY(m_tree.SetItemData(htiItem,WINDOWREF_FLAG+nIndex));
|
|
///////////////////
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
ExpandTree((m_nExpandType==0 ? m_nExpandLevel : -1));
|
|
|
|
m_tree.SetFocus();
|
|
m_tree.SelectItem(htiSelectItem);
|
|
|
|
m_tree.SetRedraw(TRUE);
|
|
}
|
|
|
|
|
|
void CApplicationsDialog::ExpandTree(int nExpandLevel/*=-1*/,
|
|
HTREEITEM htiParent/*=NULL*/)
|
|
{
|
|
if(nExpandLevel==0)
|
|
return;
|
|
|
|
if(htiParent==NULL)
|
|
{
|
|
htiParent=m_tree.GetRootItem();
|
|
ASSERT(htiParent!=NULL);
|
|
}
|
|
|
|
HTREEITEM hti=m_tree.GetNextItem(htiParent,TVGN_CHILD);
|
|
while(hti!=NULL)
|
|
{
|
|
m_tree.Expand(hti,TVE_EXPAND);
|
|
|
|
COXTreeItem* xti=m_tree.GetXItem(hti);
|
|
ASSERT(xti!=NULL);
|
|
if(xti->ItemHasChildren())
|
|
ExpandTree((nExpandLevel==-1 ? -1 : nExpandLevel-1),hti);
|
|
|
|
hti=m_tree.GetNextItem(hti,TVGN_NEXT);
|
|
}
|
|
}
|
|
|
|
HTREEITEM CApplicationsDialog::InsertItem(CString sItem,
|
|
HTREEITEM htiParent/*=NULL*/,
|
|
int nImage/*=-1*/,
|
|
CFont* pFont/*=NULL*/,
|
|
COLORREF clr/*=CLR_NONE*/)
|
|
{
|
|
HTREEITEM hti=m_tree.InsertItem(sItem,htiParent);
|
|
ASSERT(hti!=NULL);
|
|
|
|
// associate new font
|
|
if(pFont!=NULL)
|
|
VERIFY(m_tree.SetItemFont(hti,pFont));
|
|
// and new color
|
|
if(clr!=CLR_NONE)
|
|
VERIFY(m_tree.SetItemColor(hti,clr));
|
|
|
|
m_tree.SetItemImage(hti,nImage,nImage);
|
|
|
|
return hti;
|
|
}
|
|
|
|
void CApplicationsDialog::ShowControls()
|
|
{
|
|
if(UpdateData())
|
|
{
|
|
CWnd* pDlgItem=GetDlgItem(IDC_EDIT_EXPANDLEVEL);
|
|
ASSERT(pDlgItem!=NULL);
|
|
pDlgItem->EnableWindow((m_nExpandType==0));
|
|
pDlgItem=GetDlgItem(IDC_SPIN_EXPANDLEVEL);
|
|
ASSERT(pDlgItem!=NULL);
|
|
pDlgItem->EnableWindow((m_nExpandType==0));
|
|
}
|
|
}
|
|
|
|
void CApplicationsDialog::OnRadioExpandall()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
|
|
ShowControls();
|
|
}
|
|
|
|
void CApplicationsDialog::OnRadioExpandlevel()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
|
|
ShowControls();
|
|
}
|
|
|
|
void CApplicationsDialog::OnDblclkTreeServices(NMHDR* pNMHDR,
|
|
LRESULT* pResult)
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
UNREFERENCED_PARAMETER(pNMHDR);
|
|
|
|
CPoint point;
|
|
if(::GetCursorPos(&point))
|
|
{
|
|
m_tree.ScreenToClient(&point);
|
|
UINT nFlags;
|
|
int nItem=m_tree.HitTest(point,&nFlags);
|
|
if(nItem!=-1)
|
|
{
|
|
HTREEITEM hti=m_tree.GetItemFromIndex(nItem);
|
|
ASSERT(hti!=NULL);
|
|
if(m_tree.GetItemIndent(hti)<point.x &&
|
|
(nFlags&TVHT_ONITEM)==TVHT_ONITEM)
|
|
{
|
|
DWORD dwData=m_tree.GetItemData(hti);
|
|
if((dwData&WINDOWREF_FLAG)==WINDOWREF_FLAG)
|
|
{
|
|
int nIndex=dwData&0x0000ffff;
|
|
ASSERT(nIndex>=0 && nIndex<m_arrAppInfo.GetSize());
|
|
if(m_arrAppInfo[nIndex].bGotRespond)
|
|
{
|
|
m_nCurrentIndex=nIndex;
|
|
PostMessage(WM_COMMAND,IDM_APP_SWITCHTO);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
|
|
void CApplicationsDialog::OnRclickTreeApplications(NMHDR* pNMHDR,
|
|
LRESULT* pResult)
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
UNREFERENCED_PARAMETER(pNMHDR);
|
|
|
|
CPoint point;
|
|
if(::GetCursorPos(&point))
|
|
{
|
|
m_tree.ScreenToClient(&point);
|
|
UINT nFlags;
|
|
int nItem=m_tree.HitTest(point,&nFlags);
|
|
if(nItem!=-1)
|
|
{
|
|
HTREEITEM hti=m_tree.GetItemFromIndex(nItem);
|
|
ASSERT(hti!=NULL);
|
|
if(m_tree.GetItemIndent(hti)<point.x &&
|
|
(nFlags&TVHT_ONITEM)==TVHT_ONITEM)
|
|
{
|
|
DWORD dwData=m_tree.GetItemData(hti);
|
|
// if((dwData&WINDOWREF_FLAG)==WINDOWREF_FLAG ||
|
|
// (dwData&APPLICATIONREF_FLAG)==APPLICATIONREF_FLAG)
|
|
{
|
|
int nIndex=dwData&0x0000ffff;
|
|
ASSERT(nIndex>=0 && nIndex<m_arrAppInfo.GetSize());
|
|
m_nCurrentIndex=nIndex;
|
|
|
|
CMenu popMenu;
|
|
VERIFY(popMenu.LoadMenu(IDR_APPLICATION_POPUPMENU));
|
|
|
|
MENUITEMINFO itemInfo={ sizeof(MENUITEMINFO) };
|
|
itemInfo.fMask=MIIM_STATE;
|
|
if(m_arrAppInfo[nIndex].bGotRespond)
|
|
{
|
|
if(m_arrAppInfo[nIndex].dwProcessID!=m_process.GetProcessID())
|
|
{
|
|
// set default item
|
|
itemInfo.fState=MFS_DEFAULT;
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_SWITCHTO,FALSE,&itemInfo);
|
|
}
|
|
else
|
|
{
|
|
// disable items
|
|
itemInfo.fState=MFS_DISABLED;
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_SWITCHTO,FALSE,&itemInfo);
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_BRINGTOFRONT,FALSE,&itemInfo);
|
|
}
|
|
|
|
DWORD dwStyle=::GetWindowLong(
|
|
m_arrAppInfo[m_nCurrentIndex].hMainWnd,GWL_STYLE);
|
|
BOOL bSysMenu=(dwStyle&WS_SYSMENU)!=0;
|
|
BOOL bMaximizeBtn=bSysMenu &
|
|
((dwStyle&WS_MAXIMIZEBOX)!=0);
|
|
BOOL bCanMaximize=bMaximizeBtn &
|
|
((dwStyle&WS_MAXIMIZE)==0);
|
|
BOOL bMinimizeBtn=bSysMenu &
|
|
((dwStyle&WS_MINIMIZEBOX)!=0);
|
|
BOOL bCanMinimize=bMinimizeBtn &
|
|
((dwStyle&WS_MINIMIZE)==0);
|
|
|
|
itemInfo.fState=MFS_DISABLED;
|
|
if(!bCanMaximize)
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_MAXIMIZE,FALSE,&itemInfo);
|
|
if(!bCanMinimize)
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_MINIMIZE,FALSE,&itemInfo);
|
|
if((bCanMaximize && bCanMinimize) ||
|
|
(!bMaximizeBtn && bCanMinimize) || !bSysMenu)
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_RESTORE,FALSE,&itemInfo);
|
|
}
|
|
else
|
|
{
|
|
// disable items
|
|
itemInfo.fState=MFS_DISABLED;
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_SWITCHTO,FALSE,&itemInfo);
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_BRINGTOFRONT,FALSE,&itemInfo);
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_MINIMIZE,FALSE,&itemInfo);
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_MAXIMIZE,FALSE,&itemInfo);
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_RESTORE,FALSE,&itemInfo);
|
|
}
|
|
|
|
if(m_arrAppInfo[nIndex].dwProcessID==m_process.GetProcessID())
|
|
{
|
|
// disable items
|
|
itemInfo.fState=MFS_DISABLED;
|
|
::SetMenuItemInfo(popMenu.m_hMenu,
|
|
IDM_APP_CLOSE,FALSE,&itemInfo);
|
|
}
|
|
// show menu
|
|
m_tree.ClientToScreen(&point);
|
|
popMenu.GetSubMenu(0)->
|
|
TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,
|
|
point.x, point.y,this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
void CApplicationsDialog::OnAppWndSwitchTo()
|
|
{
|
|
ASSERT(m_nCurrentIndex>=0 && m_nCurrentIndex<m_arrAppInfo.GetSize());
|
|
ASSERT(m_arrAppInfo[m_nCurrentIndex].dwProcessID!=m_process.GetProcessID());
|
|
ASSERT(m_arrAppInfo[m_nCurrentIndex].bGotRespond);
|
|
if(m_nCurrentIndex<0 || m_nCurrentIndex>=m_arrAppInfo.GetSize() ||
|
|
!m_arrAppInfo[m_nCurrentIndex].bGotRespond ||
|
|
m_arrAppInfo[m_nCurrentIndex].dwProcessID==m_process.GetProcessID())
|
|
return;
|
|
|
|
::SetForegroundWindow(m_arrAppInfo[m_nCurrentIndex].hMainWnd);
|
|
if((::GetWindowLong(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
GWL_STYLE)&WS_MINIMIZE)==WS_MINIMIZE)
|
|
{
|
|
::SendMessage(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
WM_SYSCOMMAND,SC_RESTORE,
|
|
(LPARAM)m_arrAppInfo[m_nCurrentIndex].hMainWnd);
|
|
}
|
|
}
|
|
|
|
void CApplicationsDialog::OnAppWndBringToFront()
|
|
{
|
|
ASSERT(m_nCurrentIndex>=0 && m_nCurrentIndex<m_arrAppInfo.GetSize());
|
|
ASSERT(m_arrAppInfo[m_nCurrentIndex].dwProcessID!=m_process.GetProcessID());
|
|
ASSERT(m_arrAppInfo[m_nCurrentIndex].bGotRespond);
|
|
if(m_nCurrentIndex<0 || m_nCurrentIndex>=m_arrAppInfo.GetSize() ||
|
|
!m_arrAppInfo[m_nCurrentIndex].bGotRespond ||
|
|
m_arrAppInfo[m_nCurrentIndex].dwProcessID==m_process.GetProcessID())
|
|
return;
|
|
|
|
if(::GetWindowLong(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
GWL_STYLE)&WS_MINIMIZE)
|
|
{
|
|
OnAppWndRestore();
|
|
AfxGetMainWnd()->SetForegroundWindow();
|
|
}
|
|
else
|
|
{
|
|
::SetWindowPos(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
AfxGetMainWnd()->GetSafeHwnd(),0,0,0,0,
|
|
SWP_SHOWWINDOW|SWP_ASYNCWINDOWPOS|SWP_NOACTIVATE|
|
|
SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
|
|
}
|
|
}
|
|
|
|
void CApplicationsDialog::OnAppWndMinimize()
|
|
{
|
|
ASSERT(m_nCurrentIndex>=0 && m_nCurrentIndex<m_arrAppInfo.GetSize());
|
|
ASSERT(m_arrAppInfo[m_nCurrentIndex].bGotRespond);
|
|
if(m_nCurrentIndex<0 || m_nCurrentIndex>=m_arrAppInfo.GetSize() ||
|
|
!m_arrAppInfo[m_nCurrentIndex].bGotRespond)
|
|
return;
|
|
|
|
::SendMessage(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
WM_SYSCOMMAND,SC_MINIMIZE,
|
|
(LPARAM)m_arrAppInfo[m_nCurrentIndex].hMainWnd);
|
|
}
|
|
|
|
void CApplicationsDialog::OnAppWndMaximize()
|
|
{
|
|
ASSERT(m_nCurrentIndex>=0 && m_nCurrentIndex<m_arrAppInfo.GetSize());
|
|
ASSERT(m_arrAppInfo[m_nCurrentIndex].bGotRespond);
|
|
if(m_nCurrentIndex<0 || m_nCurrentIndex>=m_arrAppInfo.GetSize() ||
|
|
!m_arrAppInfo[m_nCurrentIndex].bGotRespond)
|
|
return;
|
|
|
|
if(::GetWindowLong(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
GWL_STYLE)&WS_MINIMIZE)
|
|
{
|
|
::SendMessage(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
WM_SYSCOMMAND,SC_MAXIMIZE,
|
|
(LPARAM)m_arrAppInfo[m_nCurrentIndex].hMainWnd);
|
|
AfxGetMainWnd()->SetForegroundWindow();
|
|
}
|
|
else
|
|
{
|
|
::SendMessage(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
WM_SYSCOMMAND,SC_MAXIMIZE,
|
|
(LPARAM)m_arrAppInfo[m_nCurrentIndex].hMainWnd);
|
|
}
|
|
}
|
|
|
|
void CApplicationsDialog::OnAppWndRestore()
|
|
{
|
|
ASSERT(m_nCurrentIndex>=0 && m_nCurrentIndex<m_arrAppInfo.GetSize());
|
|
ASSERT(m_arrAppInfo[m_nCurrentIndex].bGotRespond);
|
|
if(m_nCurrentIndex<0 || m_nCurrentIndex>=m_arrAppInfo.GetSize() ||
|
|
!m_arrAppInfo[m_nCurrentIndex].bGotRespond)
|
|
return;
|
|
|
|
if(::GetWindowLong(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
GWL_STYLE)&WS_MINIMIZE)
|
|
{
|
|
::SendMessage(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
WM_SYSCOMMAND,SC_RESTORE,
|
|
(LPARAM)m_arrAppInfo[m_nCurrentIndex].hMainWnd);
|
|
AfxGetMainWnd()->SetForegroundWindow();
|
|
}
|
|
else
|
|
{
|
|
::SendMessage(m_arrAppInfo[m_nCurrentIndex].hMainWnd,
|
|
WM_SYSCOMMAND,SC_RESTORE,
|
|
(LPARAM)m_arrAppInfo[m_nCurrentIndex].hMainWnd);
|
|
}
|
|
}
|
|
|
|
void CApplicationsDialog::OnAppWndClose()
|
|
{
|
|
ASSERT(m_nCurrentIndex>=0 && m_nCurrentIndex<m_arrAppInfo.GetSize());
|
|
ASSERT(m_arrAppInfo[m_nCurrentIndex].dwProcessID!=m_process.GetProcessID());
|
|
if(m_nCurrentIndex<0 || m_nCurrentIndex>=m_arrAppInfo.GetSize() ||
|
|
m_arrAppInfo[m_nCurrentIndex].dwProcessID==m_process.GetProcessID())
|
|
return;
|
|
|
|
if(m_arrAppInfo[m_nCurrentIndex].bGotRespond)
|
|
{
|
|
::PostMessage(m_arrAppInfo[m_nCurrentIndex].hMainWnd,WM_QUIT,0,0);
|
|
Refresh();
|
|
return;
|
|
}
|
|
|
|
HANDLE hProcess=::OpenProcess(PROCESS_TERMINATE,FALSE,
|
|
m_arrAppInfo[m_nCurrentIndex].dwProcessID);
|
|
if(hProcess!=NULL)
|
|
{
|
|
::TerminateProcess(hProcess,FALSE);
|
|
Refresh();
|
|
}
|
|
|
|
}
|
|
|
|
void CApplicationsDialog::CleanThreads()
|
|
{
|
|
// kill and close all threads
|
|
for(int nIndex=0; nIndex<m_arrThreads.GetSize(); nIndex++)
|
|
{
|
|
HANDLE hThread=m_arrThreads[nIndex];
|
|
DWORD dwExitCode;
|
|
if(::GetExitCodeThread(hThread,&dwExitCode) && dwExitCode==STILL_ACTIVE)
|
|
::TerminateThread(hThread,TRUE);
|
|
::CloseHandle(hThread);
|
|
}
|
|
m_arrThreads.RemoveAll();
|
|
}
|
|
|
|
|
|
|
|
BOOL CALLBACK CApplicationsDialog::EnumMainWindows(HWND hWnd, LPARAM lParam)
|
|
{
|
|
ASSERT(lParam!=NULL);
|
|
CAppInfoArray* parrAppInfo=(CAppInfoArray*)lParam;
|
|
|
|
// Window should be not-owned (to exclude dialogs)
|
|
if(::GetWindow(hWnd,GW_OWNER)==NULL &&
|
|
(::GetWindowLong(hWnd,GWL_EXSTYLE)&WS_EX_TOOLWINDOW)==0 &&
|
|
(::GetWindowLong(hWnd,GWL_STYLE)&WS_VISIBLE)==WS_VISIBLE)
|
|
{
|
|
APPLICATIONINFO appInfo;
|
|
::GetWindowThreadProcessId(hWnd,&appInfo.dwProcessID);
|
|
appInfo.hMainWnd=hWnd;
|
|
|
|
// application status
|
|
DWORD dwResult;
|
|
appInfo.bGotRespond=PtrToInt(::SendMessageTimeout(hWnd,WM_NULL,0,0,
|
|
SMTO_ABORTIFHUNG,5000,&dwResult));
|
|
///////////////////
|
|
|
|
parrAppInfo->Add(appInfo);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|