| /* | |
| * ReactOS Task Manager | |
| * | |
| * applpage.c | |
| * | |
| * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org> | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| */ | |
| #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */ | |
| #include <windows.h> | |
| #include <commctrl.h> | |
| #include <stdlib.h> | |
| #include <malloc.h> | |
| #include <memory.h> | |
| #include <tchar.h> | |
| #include <stdio.h> | |
| #include "taskmgr.h" | |
| typedef struct | |
| { | |
| HWND hWnd; | |
| TCHAR szTitle[260]; | |
| HICON hIcon; | |
| BOOL bHung; | |
| } APPLICATION_PAGE_LIST_ITEM, *LPAPPLICATION_PAGE_LIST_ITEM; | |
| HWND hApplicationPage; /* Application List Property Page */ | |
| HWND hApplicationPageListCtrl; /* Application ListCtrl Window */ | |
| HWND hApplicationPageEndTaskButton; /* Application End Task button */ | |
| HWND hApplicationPageSwitchToButton; /* Application Switch To button */ | |
| HWND hApplicationPageNewTaskButton; /* Application New Task button */ | |
| static int nApplicationPageWidth; | |
| static int nApplicationPageHeight; | |
| static HANDLE hApplicationPageEvent = NULL; /* When this event becomes signaled then we refresh the app list */ | |
| static BOOL bSortAscending = TRUE; | |
| DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter); | |
| BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam); | |
| void AddOrUpdateHwnd(HWND hWnd, TCHAR *szTitle, HICON hIcon, BOOL bHung); | |
| void ApplicationPageUpdate(void); | |
| void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam); | |
| void ApplicationPageShowContextMenu1(void); | |
| void ApplicationPageShowContextMenu2(void); | |
| int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); | |
| #if 0 | |
| void SwitchToThisWindow ( | |
| HWND hWnd, /* Handle to the window that should be activated */ | |
| BOOL bRestore /* Restore the window if it is minimized */ | |
| ); | |
| #endif | |
| LRESULT CALLBACK ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) | |
| { | |
| RECT rc; | |
| int nXDifference; | |
| int nYDifference; | |
| LV_COLUMN column; | |
| TCHAR szTemp[256]; | |
| int cx, cy; | |
| switch (message) { | |
| case WM_INITDIALOG: | |
| /* Save the width and height */ | |
| GetClientRect(hDlg, &rc); | |
| nApplicationPageWidth = rc.right; | |
| nApplicationPageHeight = rc.bottom; | |
| /* Update window position */ | |
| SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); | |
| /* Get handles to the controls */ | |
| hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST); | |
| hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK); | |
| hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO); | |
| hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK); | |
| SetWindowText(hApplicationPageListCtrl, _T("Tasks")); | |
| /* Initialize the application page's controls */ | |
| column.mask = LVCF_TEXT|LVCF_WIDTH; | |
| _tcscpy(szTemp, _T("Task")); | |
| column.pszText = szTemp; | |
| column.cx = 250; | |
| ListView_InsertColumn(hApplicationPageListCtrl, 0, &column); /* Add the "Task" column */ | |
| column.mask = LVCF_TEXT|LVCF_WIDTH; | |
| _tcscpy(szTemp, _T("Status")); | |
| column.pszText = szTemp; | |
| column.cx = 95; | |
| ListView_InsertColumn(hApplicationPageListCtrl, 1, &column); /* Add the "Status" column */ | |
| ListView_SetImageList(hApplicationPageListCtrl, ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1), LVSIL_SMALL); | |
| ListView_SetImageList(hApplicationPageListCtrl, ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1), LVSIL_NORMAL); | |
| UpdateApplicationListControlViewSetting(); | |
| /* Start our refresh thread */ | |
| CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL); | |
| return TRUE; | |
| case WM_DESTROY: | |
| /* Close the event handle, this will make the */ | |
| /* refresh thread exit when the wait fails */ | |
| CloseHandle(hApplicationPageEvent); | |
| break; | |
| case WM_COMMAND: | |
| /* Handle the button clicks */ | |
| switch (LOWORD(wParam)) | |
| { | |
| case IDC_ENDTASK: | |
| ApplicationPage_OnEndTask(); | |
| break; | |
| case IDC_SWITCHTO: | |
| ApplicationPage_OnSwitchTo(); | |
| break; | |
| case IDC_NEWTASK: | |
| SendMessage(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0); | |
| break; | |
| } | |
| break; | |
| case WM_SIZE: | |
| if (wParam == SIZE_MINIMIZED) | |
| return 0; | |
| cx = LOWORD(lParam); | |
| cy = HIWORD(lParam); | |
| nXDifference = cx - nApplicationPageWidth; | |
| nYDifference = cy - nApplicationPageHeight; | |
| nApplicationPageWidth = cx; | |
| nApplicationPageHeight = cy; | |
| /* Reposition the application page's controls */ | |
| GetWindowRect(hApplicationPageListCtrl, &rc); | |
| cx = (rc.right - rc.left) + nXDifference; | |
| cy = (rc.bottom - rc.top) + nYDifference; | |
| SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER); | |
| InvalidateRect(hApplicationPageListCtrl, NULL, TRUE); | |
| GetClientRect(hApplicationPageEndTaskButton, &rc); | |
| MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) ); | |
| cx = rc.left + nXDifference; | |
| cy = rc.top + nYDifference; | |
| SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); | |
| InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE); | |
| GetClientRect(hApplicationPageSwitchToButton, &rc); | |
| MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) ); | |
| cx = rc.left + nXDifference; | |
| cy = rc.top + nYDifference; | |
| SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); | |
| InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE); | |
| GetClientRect(hApplicationPageNewTaskButton, &rc); | |
| MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) ); | |
| cx = rc.left + nXDifference; | |
| cy = rc.top + nYDifference; | |
| SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); | |
| InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE); | |
| break; | |
| case WM_NOTIFY: | |
| ApplicationPageOnNotify(wParam, lParam); | |
| break; | |
| } | |
| return 0; | |
| } | |
| void RefreshApplicationPage(void) | |
| { | |
| /* Signal the event so that our refresh thread */ | |
| /* will wake up and refresh the application page */ | |
| SetEvent(hApplicationPageEvent); | |
| } | |
| void UpdateApplicationListControlViewSetting(void) | |
| { | |
| DWORD dwStyle = GetWindowLong(hApplicationPageListCtrl, GWL_STYLE); | |
| dwStyle &= ~LVS_REPORT; | |
| dwStyle &= ~LVS_ICON; | |
| dwStyle &= ~LVS_LIST; | |
| dwStyle &= ~LVS_SMALLICON; | |
| if (TaskManagerSettings.View_LargeIcons) | |
| dwStyle |= LVS_ICON; | |
| else if (TaskManagerSettings.View_SmallIcons) | |
| dwStyle |= LVS_SMALLICON; | |
| else | |
| dwStyle |= LVS_REPORT; | |
| SetWindowLong(hApplicationPageListCtrl, GWL_STYLE, dwStyle); | |
| RefreshApplicationPage(); | |
| } | |
| DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter) | |
| { | |
| /* Create the event */ | |
| hApplicationPageEvent = CreateEvent(NULL, TRUE, TRUE, _T("Application Page Event")); | |
| /* If we couldn't create the event then exit the thread */ | |
| if (!hApplicationPageEvent) | |
| return 0; | |
| while (1) | |
| { | |
| DWORD dwWaitVal; | |
| /* Wait on the event */ | |
| dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE); | |
| /* If the wait failed then the event object must have been */ | |
| /* closed and the task manager is exiting so exit this thread */ | |
| if (dwWaitVal == WAIT_FAILED) | |
| return 0; | |
| if (dwWaitVal == WAIT_OBJECT_0) | |
| { | |
| /* Reset our event */ | |
| ResetEvent(hApplicationPageEvent); | |
| /* | |
| * FIXME: | |
| * | |
| * Should this be EnumDesktopWindows() instead? | |
| */ | |
| EnumWindows(EnumWindowsProc, 0); | |
| } | |
| } | |
| } | |
| BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) | |
| { | |
| HICON hIcon; | |
| TCHAR szText[260]; | |
| BOOL bLargeIcon; | |
| BOOL bHung = FALSE; | |
| typedef int (__stdcall *IsHungAppWindowProc)(HWND); | |
| IsHungAppWindowProc IsHungAppWindow; | |
| /* Skip our window */ | |
| if (hWnd == hMainWnd) | |
| return TRUE; | |
| bLargeIcon = TaskManagerSettings.View_LargeIcons ? TRUE : FALSE; | |
| GetWindowText(hWnd, szText, 260); /* Get the window text */ | |
| /* Check and see if this is a top-level app window */ | |
| if ((_tcslen(szText) <= 0) || | |
| !IsWindowVisible(hWnd) || | |
| (GetParent(hWnd) != NULL) || | |
| (GetWindow(hWnd, GW_OWNER) != NULL) || | |
| (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) | |
| { | |
| return TRUE; /* Skip this window */ | |
| } | |
| /* Get the icon for this window */ | |
| hIcon = NULL; | |
| SendMessageTimeout(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (unsigned long*)&hIcon); | |
| if (!hIcon) | |
| { | |
| hIcon = (HICON)GetClassLongPtr(hWnd, bLargeIcon ? GCLP_HICON : GCLP_HICONSM); | |
| if (!hIcon) hIcon = (HICON)GetClassLongPtr(hWnd, bLargeIcon ? GCLP_HICONSM : GCLP_HICON); | |
| if (!hIcon) SendMessageTimeout(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (unsigned long*)&hIcon); | |
| if (!hIcon) SendMessageTimeout(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (unsigned long*)&hIcon); | |
| } | |
| if (!hIcon) | |
| hIcon = LoadIcon(hInst, bLargeIcon ? MAKEINTRESOURCE(IDI_WINDOW) : MAKEINTRESOURCE(IDI_WINDOWSM)); | |
| bHung = FALSE; | |
| IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandle(_T("USER32.DLL")), "IsHungAppWindow"); | |
| if (IsHungAppWindow) | |
| bHung = IsHungAppWindow(hWnd); | |
| AddOrUpdateHwnd(hWnd, szText, hIcon, bHung); | |
| return TRUE; | |
| } | |
| void AddOrUpdateHwnd(HWND hWnd, TCHAR *szTitle, HICON hIcon, BOOL bHung) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| HIMAGELIST hImageListLarge; | |
| HIMAGELIST hImageListSmall; | |
| LV_ITEM item; | |
| int i; | |
| BOOL bAlreadyInList = FALSE; | |
| BOOL bItemRemoved = FALSE; | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| /* Get the image lists */ | |
| hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL); | |
| hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL); | |
| /* Check to see if it's already in our list */ | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) | |
| { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_IMAGE|LVIF_PARAM; | |
| item.iItem = i; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| if (pAPLI->hWnd == hWnd) | |
| { | |
| bAlreadyInList = TRUE; | |
| break; | |
| } | |
| } | |
| /* If it is already in the list then update it if necessary */ | |
| if (bAlreadyInList) | |
| { | |
| /* Check to see if anything needs updating */ | |
| if ((pAPLI->hIcon != hIcon) || | |
| (_tcsicmp(pAPLI->szTitle, szTitle) != 0) || | |
| (pAPLI->bHung != bHung)) | |
| { | |
| /* Update the structure */ | |
| pAPLI->hIcon = hIcon; | |
| pAPLI->bHung = bHung; | |
| _tcscpy(pAPLI->szTitle, szTitle); | |
| /* Update the image list */ | |
| ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon); | |
| ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon); | |
| /* Update the list view */ | |
| ListView_RedrawItems(hApplicationPageListCtrl, 0, ListView_GetItemCount(hApplicationPageListCtrl)); | |
| /* UpdateWindow(hApplicationPageListCtrl); */ | |
| InvalidateRect(hApplicationPageListCtrl, NULL, 0); | |
| } | |
| } | |
| /* It is not already in the list so add it */ | |
| else | |
| { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)malloc(sizeof(APPLICATION_PAGE_LIST_ITEM)); | |
| pAPLI->hWnd = hWnd; | |
| pAPLI->hIcon = hIcon; | |
| pAPLI->bHung = bHung; | |
| _tcscpy(pAPLI->szTitle, szTitle); | |
| /* Add the item to the list */ | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; | |
| ImageList_AddIcon(hImageListLarge, hIcon); | |
| item.iImage = ImageList_AddIcon(hImageListSmall, hIcon); | |
| item.pszText = LPSTR_TEXTCALLBACK; | |
| item.iItem = ListView_GetItemCount(hApplicationPageListCtrl); | |
| item.lParam = (LPARAM)pAPLI; | |
| ListView_InsertItem(hApplicationPageListCtrl, &item); | |
| } | |
| /* Check to see if we need to remove any items from the list */ | |
| for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--) | |
| { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_IMAGE|LVIF_PARAM; | |
| item.iItem = i; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| if (!IsWindow(pAPLI->hWnd)|| | |
| (_tcslen(pAPLI->szTitle) <= 0) || | |
| !IsWindowVisible(pAPLI->hWnd) || | |
| (GetParent(pAPLI->hWnd) != NULL) || | |
| (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) || | |
| (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) | |
| { | |
| ImageList_Remove(hImageListLarge, item.iItem); | |
| ImageList_Remove(hImageListSmall, item.iItem); | |
| ListView_DeleteItem(hApplicationPageListCtrl, item.iItem); | |
| free(pAPLI); | |
| bItemRemoved = TRUE; | |
| } | |
| } | |
| /* | |
| * If an item was removed from the list then | |
| * we need to resync all the items with the | |
| * image list | |
| */ | |
| if (bItemRemoved) | |
| { | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) | |
| { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_IMAGE; | |
| item.iItem = i; | |
| item.iImage = i; | |
| ListView_SetItem(hApplicationPageListCtrl, &item); | |
| } | |
| } | |
| ApplicationPageUpdate(); | |
| } | |
| void ApplicationPageUpdate(void) | |
| { | |
| /* Enable or disable the "End Task" & "Switch To" buttons */ | |
| if (ListView_GetSelectedCount(hApplicationPageListCtrl)) | |
| { | |
| EnableWindow(hApplicationPageEndTaskButton, TRUE); | |
| EnableWindow(hApplicationPageSwitchToButton, TRUE); | |
| } | |
| else | |
| { | |
| EnableWindow(hApplicationPageEndTaskButton, FALSE); | |
| EnableWindow(hApplicationPageSwitchToButton, FALSE); | |
| } | |
| /* If we are on the applications tab the the windows menu will */ | |
| /* be present on the menu bar so enable & disable the menu items */ | |
| if (TabCtrl_GetCurSel(hTabWnd) == 0) | |
| { | |
| HMENU hMenu; | |
| HMENU hWindowsMenu; | |
| hMenu = GetMenu(hMainWnd); | |
| hWindowsMenu = GetSubMenu(hMenu, 3); | |
| /* Only one item selected */ | |
| if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1) | |
| { | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED); | |
| } | |
| /* More than one item selected */ | |
| else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1) | |
| { | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| } | |
| /* No items selected */ | |
| else | |
| { | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| } | |
| } | |
| } | |
| void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam) | |
| { | |
| int idctrl; | |
| LPNMHDR pnmh; | |
| LPNM_LISTVIEW pnmv; | |
| LV_DISPINFO* pnmdi; | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI; | |
| idctrl = (int) wParam; | |
| pnmh = (LPNMHDR) lParam; | |
| pnmv = (LPNM_LISTVIEW) lParam; | |
| pnmdi = (LV_DISPINFO*) lParam; | |
| if (pnmh->hwndFrom == hApplicationPageListCtrl) { | |
| switch (pnmh->code) { | |
| case LVN_ITEMCHANGED: | |
| ApplicationPageUpdate(); | |
| break; | |
| case LVN_GETDISPINFO: | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam; | |
| /* Update the item text */ | |
| if (pnmdi->item.iSubItem == 0) | |
| { | |
| _tcsncpy(pnmdi->item.pszText, pAPLI->szTitle, pnmdi->item.cchTextMax); | |
| } | |
| /* Update the item status */ | |
| else if (pnmdi->item.iSubItem == 1) | |
| { | |
| if (pAPLI->bHung) | |
| _tcsncpy(pnmdi->item.pszText, _T("Not Responding"), pnmdi->item.cchTextMax); | |
| else | |
| _tcsncpy(pnmdi->item.pszText, _T("Running"), pnmdi->item.cchTextMax); | |
| } | |
| break; | |
| case NM_RCLICK: | |
| if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1) | |
| { | |
| ApplicationPageShowContextMenu1(); | |
| } | |
| else | |
| { | |
| ApplicationPageShowContextMenu2(); | |
| } | |
| break; | |
| case NM_DBLCLK: | |
| ApplicationPage_OnSwitchTo(); | |
| break; | |
| } | |
| } | |
| else if (pnmh->hwndFrom == ListView_GetHeader(hApplicationPageListCtrl)) | |
| { | |
| switch (pnmh->code) | |
| { | |
| case NM_RCLICK: | |
| if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1) | |
| { | |
| ApplicationPageShowContextMenu1(); | |
| } | |
| else | |
| { | |
| ApplicationPageShowContextMenu2(); | |
| } | |
| break; | |
| case HDN_ITEMCLICK: | |
| ListView_SortItems(hApplicationPageListCtrl, ApplicationPageCompareFunc, 0); | |
| bSortAscending = !bSortAscending; | |
| break; | |
| } | |
| } | |
| } | |
| void ApplicationPageShowContextMenu1(void) | |
| { | |
| HMENU hMenu; | |
| HMENU hSubMenu; | |
| POINT pt; | |
| GetCursorPos(&pt); | |
| hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_APPLICATION_PAGE_CONTEXT1)); | |
| hSubMenu = GetSubMenu(hMenu, 0); | |
| if (TaskManagerSettings.View_LargeIcons) | |
| CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND); | |
| else if (TaskManagerSettings.View_SmallIcons) | |
| CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND); | |
| else | |
| CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND); | |
| TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL); | |
| DestroyMenu(hMenu); | |
| } | |
| void ApplicationPageShowContextMenu2(void) | |
| { | |
| HMENU hMenu; | |
| HMENU hSubMenu; | |
| POINT pt; | |
| GetCursorPos(&pt); | |
| hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_APPLICATION_PAGE_CONTEXT2)); | |
| hSubMenu = GetSubMenu(hMenu, 0); | |
| if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1) | |
| { | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED); | |
| } | |
| else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1) | |
| { | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| } | |
| else | |
| { | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED); | |
| } | |
| SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND); | |
| TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL); | |
| DestroyMenu(hMenu); | |
| } | |
| void ApplicationPage_OnViewLargeIcons(void) | |
| { | |
| HMENU hMenu; | |
| HMENU hViewMenu; | |
| hMenu = GetMenu(hMainWnd); | |
| hViewMenu = GetSubMenu(hMenu, 2); | |
| TaskManagerSettings.View_LargeIcons = TRUE; | |
| TaskManagerSettings.View_SmallIcons = FALSE; | |
| TaskManagerSettings.View_Details = FALSE; | |
| CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND); | |
| UpdateApplicationListControlViewSetting(); | |
| } | |
| void ApplicationPage_OnViewSmallIcons(void) | |
| { | |
| HMENU hMenu; | |
| HMENU hViewMenu; | |
| hMenu = GetMenu(hMainWnd); | |
| hViewMenu = GetSubMenu(hMenu, 2); | |
| TaskManagerSettings.View_LargeIcons = FALSE; | |
| TaskManagerSettings.View_SmallIcons = TRUE; | |
| TaskManagerSettings.View_Details = FALSE; | |
| CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND); | |
| UpdateApplicationListControlViewSetting(); | |
| } | |
| void ApplicationPage_OnViewDetails(void) | |
| { | |
| HMENU hMenu; | |
| HMENU hViewMenu; | |
| hMenu = GetMenu(hMainWnd); | |
| hViewMenu = GetSubMenu(hMenu, 2); | |
| TaskManagerSettings.View_LargeIcons = FALSE; | |
| TaskManagerSettings.View_SmallIcons = FALSE; | |
| TaskManagerSettings.View_Details = TRUE; | |
| CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND); | |
| UpdateApplicationListControlViewSetting(); | |
| } | |
| void ApplicationPage_OnWindowsTileHorizontally(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| HWND* hWndArray; | |
| int nWndCount; | |
| hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl)); | |
| nWndCount = 0; | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| if (pAPLI) { | |
| hWndArray[nWndCount] = pAPLI->hWnd; | |
| nWndCount++; | |
| } | |
| } | |
| } | |
| TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray); | |
| free(hWndArray); | |
| } | |
| void ApplicationPage_OnWindowsTileVertically(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| HWND* hWndArray; | |
| int nWndCount; | |
| hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl)); | |
| nWndCount = 0; | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| if (pAPLI) { | |
| hWndArray[nWndCount] = pAPLI->hWnd; | |
| nWndCount++; | |
| } | |
| } | |
| } | |
| TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray); | |
| free(hWndArray); | |
| } | |
| void ApplicationPage_OnWindowsMinimize(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| if (pAPLI) { | |
| ShowWindow(pAPLI->hWnd, SW_MINIMIZE); | |
| } | |
| } | |
| } | |
| } | |
| void ApplicationPage_OnWindowsMaximize(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| if (pAPLI) { | |
| ShowWindow(pAPLI->hWnd, SW_MAXIMIZE); | |
| } | |
| } | |
| } | |
| } | |
| void ApplicationPage_OnWindowsCascade(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| HWND* hWndArray; | |
| int nWndCount; | |
| hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl)); | |
| nWndCount = 0; | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| if (pAPLI) { | |
| hWndArray[nWndCount] = pAPLI->hWnd; | |
| nWndCount++; | |
| } | |
| } | |
| } | |
| CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray); | |
| free(hWndArray); | |
| } | |
| void ApplicationPage_OnWindowsBringToFront(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| break; | |
| } | |
| } | |
| if (pAPLI) { | |
| if (IsIconic(pAPLI->hWnd)) | |
| ShowWindow(pAPLI->hWnd, SW_RESTORE); | |
| BringWindowToTop(pAPLI->hWnd); | |
| } | |
| } | |
| void ApplicationPage_OnSwitchTo(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| break; | |
| } | |
| } | |
| if (pAPLI) { | |
| typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL); | |
| PROCSWITCHTOTHISWINDOW SwitchToThisWindow; | |
| HMODULE hUser32 = GetModuleHandle(_T("USER32")); | |
| SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow"); | |
| if (SwitchToThisWindow) { | |
| SwitchToThisWindow(pAPLI->hWnd, TRUE); | |
| } else { | |
| if (IsIconic(pAPLI->hWnd)) | |
| ShowWindow(pAPLI->hWnd, SW_RESTORE); | |
| BringWindowToTop(pAPLI->hWnd); | |
| SetForegroundWindow(pAPLI->hWnd); | |
| } | |
| if (TaskManagerSettings.MinimizeOnUse) | |
| ShowWindow(hMainWnd, SW_MINIMIZE); | |
| } | |
| } | |
| void ApplicationPage_OnEndTask(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| if (pAPLI) { | |
| PostMessage(pAPLI->hWnd, WM_CLOSE, 0, 0); | |
| } | |
| } | |
| } | |
| } | |
| void ApplicationPage_OnGotoProcess(void) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; | |
| LV_ITEM item; | |
| int i; | |
| /* NMHDR nmhdr; */ | |
| for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) { | |
| memset(&item, 0, sizeof(LV_ITEM)); | |
| item.mask = LVIF_STATE|LVIF_PARAM; | |
| item.iItem = i; | |
| item.stateMask = (UINT)-1; | |
| ListView_GetItem(hApplicationPageListCtrl, &item); | |
| if (item.state & LVIS_SELECTED) { | |
| pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; | |
| break; | |
| } | |
| } | |
| if (pAPLI) { | |
| DWORD dwProcessId; | |
| GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId); | |
| /* | |
| * Switch to the process tab | |
| */ | |
| TabCtrl_SetCurFocus(hTabWnd, 1); | |
| /* | |
| * FIXME: Select the process item in the list | |
| */ | |
| for (i=0; i<ListView_GetItemCount(hProcessPage); i++) { | |
| } | |
| } | |
| } | |
| int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) | |
| { | |
| LPAPPLICATION_PAGE_LIST_ITEM Param1; | |
| LPAPPLICATION_PAGE_LIST_ITEM Param2; | |
| if (bSortAscending) { | |
| Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1; | |
| Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2; | |
| } else { | |
| Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2; | |
| Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1; | |
| } | |
| return _tcscmp(Param1->szTitle, Param2->szTitle); | |
| } |