re-added some files and fixed a few errors
[reactos.git] / rosapps / taskmgr / applpage.c
1 /*
2 * ReactOS Task Manager
3 *
4 * applicationpage.cpp
5 *
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
24 #include <windows.h>
25 #include <commctrl.h>
26 #include <stdlib.h>
27 #include <malloc.h>
28 #include <memory.h>
29 #include <tchar.h>
30 #include <process.h>
31 #include <stdio.h>
32
33 #include "taskmgr.h"
34 #include "applpage.h"
35 #include "procpage.h"
36
37 typedef struct
38 {
39 HWND hWnd;
40 TCHAR szTitle[260];
41 HICON hIcon;
42 BOOL bHung;
43 } APPLICATION_PAGE_LIST_ITEM, *LPAPPLICATION_PAGE_LIST_ITEM;
44
45 HWND hApplicationPage; // Application List Property Page
46
47 HWND hApplicationPageListCtrl; // Application ListCtrl Window
48 HWND hApplicationPageEndTaskButton; // Application End Task button
49 HWND hApplicationPageSwitchToButton; // Application Switch To button
50 HWND hApplicationPageNewTaskButton; // Application New Task button
51
52 static int nApplicationPageWidth;
53 static int nApplicationPageHeight;
54
55 static HANDLE hApplicationPageEvent = NULL; // When this event becomes signaled then we refresh the app list
56
57 static BOOL bSortAscending = TRUE;
58
59 void ApplicationPageRefreshThread(void *lpParameter);
60 BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
61 void AddOrUpdateHwnd(HWND hWnd, TCHAR *szTitle, HICON hIcon, BOOL bHung);
62 void ApplicationPageUpdate(void);
63 void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam);
64 void ApplicationPageShowContextMenu1(void);
65 void ApplicationPageShowContextMenu2(void);
66 int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
67
68 //void SwitchToThisWindow (
69 //HWND hWnd, // Handle to the window that should be activated
70 //BOOL bRestore // Restore the window if it is minimized
71 //);
72
73 LRESULT CALLBACK ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
74 {
75 RECT rc;
76 int nXDifference;
77 int nYDifference;
78 LV_COLUMN column;
79 TCHAR szTemp[256];
80 int cx, cy;
81
82 switch (message) {
83 case WM_INITDIALOG:
84
85 // Save the width and height
86 GetClientRect(hDlg, &rc);
87 nApplicationPageWidth = rc.right;
88 nApplicationPageHeight = rc.bottom;
89
90 // Update window position
91 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
92
93 // Get handles to the controls
94 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
95 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
96 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
97 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
98
99 SetWindowText(hApplicationPageListCtrl, _T("Tasks"));
100
101 // Initialize the application page's controls
102 column.mask = LVCF_TEXT|LVCF_WIDTH;
103 _tcscpy(szTemp, _T("Task"));
104 column.pszText = szTemp;
105 column.cx = 250;
106 ListView_InsertColumn(hApplicationPageListCtrl, 0, &column); // Add the "Task" column
107 column.mask = LVCF_TEXT|LVCF_WIDTH;
108 _tcscpy(szTemp, _T("Status"));
109 column.pszText = szTemp;
110 column.cx = 95;
111 ListView_InsertColumn(hApplicationPageListCtrl, 1, &column); // Add the "Status" column
112
113 ListView_SetImageList(hApplicationPageListCtrl, ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1), LVSIL_SMALL);
114 ListView_SetImageList(hApplicationPageListCtrl, ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1), LVSIL_NORMAL);
115
116 UpdateApplicationListControlViewSetting();
117
118 // Start our refresh thread
119 _beginthread(ApplicationPageRefreshThread, 0, NULL);
120
121 return TRUE;
122
123 case WM_DESTROY:
124 // Close the event handle, this will make the
125 // refresh thread exit when the wait fails
126 CloseHandle(hApplicationPageEvent);
127 break;
128
129 case WM_COMMAND:
130
131 // Handle the button clicks
132 switch (LOWORD(wParam))
133 {
134 case IDC_ENDTASK:
135 ApplicationPage_OnEndTask();
136 break;
137 case IDC_SWITCHTO:
138 ApplicationPage_OnSwitchTo();
139 break;
140 case IDC_NEWTASK:
141 SendMessage(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
142 break;
143 }
144
145 break;
146
147 case WM_SIZE:
148 if (wParam == SIZE_MINIMIZED)
149 return 0;
150
151 cx = LOWORD(lParam);
152 cy = HIWORD(lParam);
153 nXDifference = cx - nApplicationPageWidth;
154 nYDifference = cy - nApplicationPageHeight;
155 nApplicationPageWidth = cx;
156 nApplicationPageHeight = cy;
157
158 // Reposition the application page's controls
159 GetWindowRect(hApplicationPageListCtrl, &rc);
160 cx = (rc.right - rc.left) + nXDifference;
161 cy = (rc.bottom - rc.top) + nYDifference;
162 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
163 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
164
165 GetClientRect(hApplicationPageEndTaskButton, &rc);
166 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
167 cx = rc.left + nXDifference;
168 cy = rc.top + nYDifference;
169 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
170 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
171
172 GetClientRect(hApplicationPageSwitchToButton, &rc);
173 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
174 cx = rc.left + nXDifference;
175 cy = rc.top + nYDifference;
176 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
177 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
178
179 GetClientRect(hApplicationPageNewTaskButton, &rc);
180 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
181 cx = rc.left + nXDifference;
182 cy = rc.top + nYDifference;
183 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
184 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
185
186 break;
187
188 case WM_NOTIFY:
189 ApplicationPageOnNotify(wParam, lParam);
190 break;
191
192 }
193
194 return 0;
195 }
196
197 void RefreshApplicationPage(void)
198 {
199 // Signal the event so that our refresh thread
200 // will wake up and refresh the application page
201 SetEvent(hApplicationPageEvent);
202 }
203
204 void UpdateApplicationListControlViewSetting(void)
205 {
206 DWORD dwStyle = GetWindowLong(hApplicationPageListCtrl, GWL_STYLE);
207
208 dwStyle &= ~LVS_REPORT;
209 dwStyle &= ~LVS_ICON;
210 dwStyle &= ~LVS_LIST;
211 dwStyle &= ~LVS_SMALLICON;
212
213 if (TaskManagerSettings.View_LargeIcons)
214 dwStyle |= LVS_ICON;
215 else if (TaskManagerSettings.View_SmallIcons)
216 dwStyle |= LVS_SMALLICON;
217 else
218 dwStyle |= LVS_REPORT;
219
220 SetWindowLong(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
221
222 RefreshApplicationPage();
223 }
224
225 void ApplicationPageRefreshThread(void *lpParameter)
226 {
227 // Create the event
228 hApplicationPageEvent = CreateEvent(NULL, TRUE, TRUE, _T("Application Page Event"));
229
230 // If we couldn't create the event then exit the thread
231 if (!hApplicationPageEvent)
232 return;
233
234 while (1)
235 {
236 DWORD dwWaitVal;
237
238 // Wait on the event
239 dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE);
240
241 // If the wait failed then the event object must have been
242 // closed and the task manager is exiting so exit this thread
243 if (dwWaitVal == WAIT_FAILED)
244 return;
245
246 if (dwWaitVal == WAIT_OBJECT_0)
247 {
248 // Reset our event
249 ResetEvent(hApplicationPageEvent);
250
251 /*
252 * FIXME:
253 *
254 * Should this be EnumDesktopWindows() instead?
255 */
256 EnumWindows(EnumWindowsProc, 0);
257 }
258 }
259 }
260
261 BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
262 {
263 HICON hIcon;
264 TCHAR szText[260];
265 BOOL bLargeIcon;
266 BOOL bHung = FALSE;
267 typedef int (FAR __stdcall *IsHungAppWindowProc)(HWND);
268 IsHungAppWindowProc IsHungAppWindow;
269
270
271 // Skip our window
272 if (hWnd == hMainWnd)
273 return TRUE;
274
275 bLargeIcon = TaskManagerSettings.View_LargeIcons ? TRUE : FALSE;
276
277 GetWindowText(hWnd, szText, 260); // Get the window text
278
279 // Get the icon for this window
280 hIcon = NULL;
281 SendMessageTimeout(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (unsigned long*)&hIcon);
282
283 if (!hIcon)
284 {
285 hIcon = (HICON)GetClassLong(hWnd, bLargeIcon ? GCL_HICON : GCL_HICONSM);
286 if (!hIcon) hIcon = (HICON)GetClassLong(hWnd, bLargeIcon ? GCL_HICONSM : GCL_HICON);
287 if (!hIcon) SendMessageTimeout(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (unsigned long*)&hIcon);
288 if (!hIcon) SendMessageTimeout(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (unsigned long*)&hIcon);
289 }
290
291 if (!hIcon)
292 hIcon = LoadIcon(hInst, bLargeIcon ? MAKEINTRESOURCE(IDI_WINDOW) : MAKEINTRESOURCE(IDI_WINDOWSM));
293
294 // Check and see if this is a top-level app window
295 if ((_tcslen(szText) <= 0) ||
296 !IsWindowVisible(hWnd) ||
297 (GetParent(hWnd) != NULL) ||
298 (GetWindow(hWnd, GW_OWNER) != NULL) ||
299 (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
300 {
301 return TRUE; // Skip this window
302 }
303
304 bHung = FALSE;
305
306 //IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandle(_T("USER32.DLL")), _T("IsHungAppWindow"));
307 //IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandle("USER32.DLL"), _T("IsHungAppWindow"));
308 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandle(_T("USER32.DLL")), "IsHungAppWindow");
309
310 if (IsHungAppWindow)
311 bHung = IsHungAppWindow(hWnd);
312
313 AddOrUpdateHwnd(hWnd, szText, hIcon, bHung);
314
315 return TRUE;
316 }
317
318 void AddOrUpdateHwnd(HWND hWnd, TCHAR *szTitle, HICON hIcon, BOOL bHung)
319 {
320 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
321 HIMAGELIST hImageListLarge;
322 HIMAGELIST hImageListSmall;
323 LV_ITEM item;
324 int i;
325 BOOL bAlreadyInList = FALSE;
326 BOOL bItemRemoved = FALSE;
327
328 memset(&item, 0, sizeof(LV_ITEM));
329
330 // Get the image lists
331 hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL);
332 hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL);
333
334 // Check to see if it's already in our list
335 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
336 {
337 memset(&item, 0, sizeof(LV_ITEM));
338 item.mask = LVIF_IMAGE|LVIF_PARAM;
339 item.iItem = i;
340 ListView_GetItem(hApplicationPageListCtrl, &item);
341
342 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
343 if (pAPLI->hWnd == hWnd)
344 {
345 bAlreadyInList = TRUE;
346 break;
347 }
348 }
349
350 // If it is already in the list then update it if necessary
351 if (bAlreadyInList)
352 {
353 // Check to see if anything needs updating
354 if ((pAPLI->hIcon != hIcon) ||
355 (_tcsicmp(pAPLI->szTitle, szTitle) != 0) ||
356 (pAPLI->bHung != bHung))
357 {
358 // Update the structure
359 pAPLI->hIcon = hIcon;
360 pAPLI->bHung = bHung;
361 _tcscpy(pAPLI->szTitle, szTitle);
362
363 // Update the image list
364 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
365 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
366
367 // Update the list view
368 ListView_RedrawItems(hApplicationPageListCtrl, 0, ListView_GetItemCount(hApplicationPageListCtrl));
369 //UpdateWindow(hApplicationPageListCtrl);
370 InvalidateRect(hApplicationPageListCtrl, NULL, 0);
371 }
372 }
373 // It is not already in the list so add it
374 else
375 {
376 //pAPLI = new APPLICATION_PAGE_LIST_ITEM;
377 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)malloc(sizeof(APPLICATION_PAGE_LIST_ITEM));
378
379 pAPLI->hWnd = hWnd;
380 pAPLI->hIcon = hIcon;
381 pAPLI->bHung = bHung;
382 _tcscpy(pAPLI->szTitle, szTitle);
383
384 // Add the item to the list
385 memset(&item, 0, sizeof(LV_ITEM));
386 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
387 ImageList_AddIcon(hImageListLarge, hIcon);
388 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
389 item.pszText = LPSTR_TEXTCALLBACK;
390 item.iItem = ListView_GetItemCount(hApplicationPageListCtrl);
391 item.lParam = (LPARAM)pAPLI;
392 ListView_InsertItem(hApplicationPageListCtrl, &item);
393 }
394
395
396 // Check to see if we need to remove any items from the list
397 for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--)
398 {
399 memset(&item, 0, sizeof(LV_ITEM));
400 item.mask = LVIF_IMAGE|LVIF_PARAM;
401 item.iItem = i;
402 ListView_GetItem(hApplicationPageListCtrl, &item);
403
404 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
405 if (!IsWindow(pAPLI->hWnd)||
406 (_tcslen(pAPLI->szTitle) <= 0) ||
407 !IsWindowVisible(pAPLI->hWnd) ||
408 (GetParent(pAPLI->hWnd) != NULL) ||
409 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
410 (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
411 {
412 ImageList_Remove(hImageListLarge, item.iItem);
413 ImageList_Remove(hImageListSmall, item.iItem);
414
415 ListView_DeleteItem(hApplicationPageListCtrl, item.iItem);
416 //delete pAPLI;
417 free(pAPLI);
418 bItemRemoved = TRUE;
419 }
420 }
421
422 //
423 // If an item was removed from the list then
424 // we need to resync all the items with the
425 // image list
426 //
427 if (bItemRemoved)
428 {
429 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++)
430 {
431 memset(&item, 0, sizeof(LV_ITEM));
432 item.mask = LVIF_IMAGE;
433 item.iItem = i;
434 item.iImage = i;
435 ListView_SetItem(hApplicationPageListCtrl, &item);
436 }
437 }
438
439 ApplicationPageUpdate();
440 }
441
442 void ApplicationPageUpdate(void)
443 {
444 // Enable or disable the "End Task" & "Switch To" buttons
445 if (ListView_GetSelectedCount(hApplicationPageListCtrl))
446 {
447 EnableWindow(hApplicationPageEndTaskButton, TRUE);
448 EnableWindow(hApplicationPageSwitchToButton, TRUE);
449 }
450 else
451 {
452 EnableWindow(hApplicationPageEndTaskButton, FALSE);
453 EnableWindow(hApplicationPageSwitchToButton, FALSE);
454 }
455
456 // If we are on the applications tab the the windows menu will
457 // be present on the menu bar so enable & disable the menu items
458 if (TabCtrl_GetCurSel(hTabWnd) == 0)
459 {
460 HMENU hMenu;
461 HMENU hWindowsMenu;
462
463 hMenu = GetMenu(hMainWnd);
464 hWindowsMenu = GetSubMenu(hMenu, 3);
465
466 // Only one item selected
467 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1)
468 {
469 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
470 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
471 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
472 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
473 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
474 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
475 }
476 // More than one item selected
477 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1)
478 {
479 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
480 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
481 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
482 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
483 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
484 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
485 }
486 // No items selected
487 else
488 {
489 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
490 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
491 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
492 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
493 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
494 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
495 }
496 }
497 }
498
499 void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
500 {
501 int idctrl;
502 LPNMHDR pnmh;
503 LPNM_LISTVIEW pnmv;
504 LV_DISPINFO* pnmdi;
505 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
506
507
508 idctrl = (int) wParam;
509 pnmh = (LPNMHDR) lParam;
510 pnmv = (LPNM_LISTVIEW) lParam;
511 pnmdi = (LV_DISPINFO*) lParam;
512
513 if (pnmh->hwndFrom == hApplicationPageListCtrl) {
514 switch (pnmh->code) {
515 case LVN_ITEMCHANGED:
516 ApplicationPageUpdate();
517 break;
518
519 case LVN_GETDISPINFO:
520 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
521
522 // Update the item text
523 if (pnmdi->item.iSubItem == 0)
524 {
525 _tcsncpy(pnmdi->item.pszText, pAPLI->szTitle, pnmdi->item.cchTextMax);
526 }
527
528 // Update the item status
529 else if (pnmdi->item.iSubItem == 1)
530 {
531 if (pAPLI->bHung)
532 _tcsncpy(pnmdi->item.pszText, _T("Not Responding"), pnmdi->item.cchTextMax);
533 else
534 _tcsncpy(pnmdi->item.pszText, _T("Running"), pnmdi->item.cchTextMax);
535 }
536
537 break;
538
539 case NM_RCLICK:
540
541 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1)
542 {
543 ApplicationPageShowContextMenu1();
544 }
545 else
546 {
547 ApplicationPageShowContextMenu2();
548 }
549
550 break;
551
552 case NM_DBLCLK:
553
554 ApplicationPage_OnSwitchTo();
555
556 break;
557 }
558 }
559 else if (pnmh->hwndFrom == ListView_GetHeader(hApplicationPageListCtrl))
560 {
561 switch (pnmh->code)
562 {
563 case NM_RCLICK:
564
565 if (ListView_GetSelectedCount(hApplicationPageListCtrl) < 1)
566 {
567 ApplicationPageShowContextMenu1();
568 }
569 else
570 {
571 ApplicationPageShowContextMenu2();
572 }
573
574 break;
575
576 case HDN_ITEMCLICK:
577
578 ListView_SortItems(hApplicationPageListCtrl, ApplicationPageCompareFunc, 0);
579 bSortAscending = !bSortAscending;
580
581 break;
582 }
583 }
584
585 }
586
587 void ApplicationPageShowContextMenu1(void)
588 {
589 HMENU hMenu;
590 HMENU hSubMenu;
591 POINT pt;
592
593 GetCursorPos(&pt);
594
595 hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_APPLICATION_PAGE_CONTEXT1));
596 hSubMenu = GetSubMenu(hMenu, 0);
597
598 if (TaskManagerSettings.View_LargeIcons)
599 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
600 else if (TaskManagerSettings.View_SmallIcons)
601 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
602 else
603 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
604
605 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
606
607 DestroyMenu(hMenu);
608 }
609
610 void ApplicationPageShowContextMenu2(void)
611 {
612 HMENU hMenu;
613 HMENU hSubMenu;
614 POINT pt;
615
616 GetCursorPos(&pt);
617
618 hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_APPLICATION_PAGE_CONTEXT2));
619 hSubMenu = GetSubMenu(hMenu, 0);
620
621 if (ListView_GetSelectedCount(hApplicationPageListCtrl) == 1)
622 {
623 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
624 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
625 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
626 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
627 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
628 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
629 }
630 else if (ListView_GetSelectedCount(hApplicationPageListCtrl) > 1)
631 {
632 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
633 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
634 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
635 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
636 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
637 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
638 }
639 else
640 {
641 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
642 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
643 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
644 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
645 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
646 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
647 }
648
649 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
650
651 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
652
653 DestroyMenu(hMenu);
654 }
655
656 void ApplicationPage_OnViewLargeIcons(void)
657 {
658 HMENU hMenu;
659 HMENU hViewMenu;
660
661 hMenu = GetMenu(hMainWnd);
662 hViewMenu = GetSubMenu(hMenu, 2);
663
664 TaskManagerSettings.View_LargeIcons = TRUE;
665 TaskManagerSettings.View_SmallIcons = FALSE;
666 TaskManagerSettings.View_Details = FALSE;
667 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
668
669 UpdateApplicationListControlViewSetting();
670 }
671
672 void ApplicationPage_OnViewSmallIcons(void)
673 {
674 HMENU hMenu;
675 HMENU hViewMenu;
676
677 hMenu = GetMenu(hMainWnd);
678 hViewMenu = GetSubMenu(hMenu, 2);
679
680 TaskManagerSettings.View_LargeIcons = FALSE;
681 TaskManagerSettings.View_SmallIcons = TRUE;
682 TaskManagerSettings.View_Details = FALSE;
683 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
684
685 UpdateApplicationListControlViewSetting();
686 }
687
688 void ApplicationPage_OnViewDetails(void)
689 {
690 HMENU hMenu;
691 HMENU hViewMenu;
692
693 hMenu = GetMenu(hMainWnd);
694 hViewMenu = GetSubMenu(hMenu, 2);
695
696 TaskManagerSettings.View_LargeIcons = FALSE;
697 TaskManagerSettings.View_SmallIcons = FALSE;
698 TaskManagerSettings.View_Details = TRUE;
699 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
700
701 UpdateApplicationListControlViewSetting();
702 }
703
704 void ApplicationPage_OnWindowsTileHorizontally(void)
705 {
706 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
707 LV_ITEM item;
708 int i;
709 HWND* hWndArray;
710 int nWndCount;
711
712 hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
713 nWndCount = 0;
714
715 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
716 memset(&item, 0, sizeof(LV_ITEM));
717 item.mask = LVIF_STATE|LVIF_PARAM;
718 item.iItem = i;
719 item.stateMask = (UINT)-1;
720 ListView_GetItem(hApplicationPageListCtrl, &item);
721
722 if (item.state & LVIS_SELECTED) {
723 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
724
725 if (pAPLI) {
726 hWndArray[nWndCount] = pAPLI->hWnd;
727 nWndCount++;
728 }
729 }
730 }
731 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
732 //delete[] hWndArray;
733 free(hWndArray);
734 }
735
736 void ApplicationPage_OnWindowsTileVertically(void)
737 {
738 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
739 LV_ITEM item;
740 int i;
741 HWND* hWndArray;
742 int nWndCount;
743
744 //hWndArray = new HWND[ListView_GetItemCount(hApplicationPageListCtrl)];
745 hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
746 nWndCount = 0;
747
748 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
749 memset(&item, 0, sizeof(LV_ITEM));
750 item.mask = LVIF_STATE|LVIF_PARAM;
751 item.iItem = i;
752 item.stateMask = (UINT)-1;
753 ListView_GetItem(hApplicationPageListCtrl, &item);
754
755 if (item.state & LVIS_SELECTED) {
756 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
757 if (pAPLI) {
758 hWndArray[nWndCount] = pAPLI->hWnd;
759 nWndCount++;
760 }
761 }
762 }
763
764 TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
765 //delete[] hWndArray;
766 free(hWndArray);
767 }
768
769 void ApplicationPage_OnWindowsMinimize(void)
770 {
771 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
772 LV_ITEM item;
773 int i;
774
775 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
776 memset(&item, 0, sizeof(LV_ITEM));
777 item.mask = LVIF_STATE|LVIF_PARAM;
778 item.iItem = i;
779 item.stateMask = (UINT)-1;
780 ListView_GetItem(hApplicationPageListCtrl, &item);
781 if (item.state & LVIS_SELECTED) {
782 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
783 if (pAPLI) {
784 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
785 }
786 }
787 }
788 }
789
790 void ApplicationPage_OnWindowsMaximize(void)
791 {
792 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
793 LV_ITEM item;
794 int i;
795
796 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
797 memset(&item, 0, sizeof(LV_ITEM));
798 item.mask = LVIF_STATE|LVIF_PARAM;
799 item.iItem = i;
800 item.stateMask = (UINT)-1;
801 ListView_GetItem(hApplicationPageListCtrl, &item);
802 if (item.state & LVIS_SELECTED) {
803 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
804 if (pAPLI) {
805 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
806 }
807 }
808 }
809 }
810
811 void ApplicationPage_OnWindowsCascade(void)
812 {
813 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
814 LV_ITEM item;
815 int i;
816 HWND* hWndArray;
817 int nWndCount;
818
819 //hWndArray = new HWND[ListView_GetItemCount(hApplicationPageListCtrl)];
820 hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
821 nWndCount = 0;
822
823 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
824 memset(&item, 0, sizeof(LV_ITEM));
825 item.mask = LVIF_STATE|LVIF_PARAM;
826 item.iItem = i;
827 item.stateMask = (UINT)-1;
828 ListView_GetItem(hApplicationPageListCtrl, &item);
829 if (item.state & LVIS_SELECTED) {
830 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
831 if (pAPLI) {
832 hWndArray[nWndCount] = pAPLI->hWnd;
833 nWndCount++;
834 }
835 }
836 }
837 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
838 //delete[] hWndArray;
839 free(hWndArray);
840 }
841
842 void ApplicationPage_OnWindowsBringToFront(void)
843 {
844 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
845 LV_ITEM item;
846 int i;
847
848 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
849 memset(&item, 0, sizeof(LV_ITEM));
850 item.mask = LVIF_STATE|LVIF_PARAM;
851 item.iItem = i;
852 item.stateMask = (UINT)-1;
853 ListView_GetItem(hApplicationPageListCtrl, &item);
854 if (item.state & LVIS_SELECTED) {
855 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
856 break;
857 }
858 }
859 if (pAPLI) {
860 if (IsIconic(pAPLI->hWnd))
861 ShowWindow(pAPLI->hWnd, SW_RESTORE);
862 BringWindowToTop(pAPLI->hWnd);
863 }
864 }
865
866 void ApplicationPage_OnSwitchTo(void)
867 {
868 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
869 LV_ITEM item;
870 int i;
871
872 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
873 memset(&item, 0, sizeof(LV_ITEM));
874 item.mask = LVIF_STATE|LVIF_PARAM;
875 item.iItem = i;
876 item.stateMask = (UINT)-1;
877 ListView_GetItem(hApplicationPageListCtrl, &item);
878
879 if (item.state & LVIS_SELECTED) {
880 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
881 break;
882 }
883 }
884 if (pAPLI) {
885 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
886 PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
887
888 HMODULE hUser32 = GetModuleHandle(_T("USER32"));
889 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
890 if (SwitchToThisWindow) {
891 SwitchToThisWindow(pAPLI->hWnd, TRUE);
892 } else {
893 if (IsIconic(pAPLI->hWnd))
894 ShowWindow(pAPLI->hWnd, SW_RESTORE);
895 BringWindowToTop(pAPLI->hWnd);
896 SetForegroundWindow(pAPLI->hWnd);
897 }
898 if (TaskManagerSettings.MinimizeOnUse)
899 ShowWindow(hMainWnd, SW_MINIMIZE);
900 }
901 }
902
903 void ApplicationPage_OnEndTask(void)
904 {
905 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
906 LV_ITEM item;
907 int i;
908
909 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
910 memset(&item, 0, sizeof(LV_ITEM));
911 item.mask = LVIF_STATE|LVIF_PARAM;
912 item.iItem = i;
913 item.stateMask = (UINT)-1;
914 ListView_GetItem(hApplicationPageListCtrl, &item);
915 if (item.state & LVIS_SELECTED) {
916 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
917 if (pAPLI) {
918 PostMessage(pAPLI->hWnd, WM_CLOSE, 0, 0);
919 }
920 }
921 }
922 }
923
924 void ApplicationPage_OnGotoProcess(void)
925 {
926 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
927 LV_ITEM item;
928 int i;
929 //NMHDR nmhdr;
930
931 for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
932 memset(&item, 0, sizeof(LV_ITEM));
933 item.mask = LVIF_STATE|LVIF_PARAM;
934 item.iItem = i;
935 item.stateMask = (UINT)-1;
936 ListView_GetItem(hApplicationPageListCtrl, &item);
937 if (item.state & LVIS_SELECTED) {
938 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
939 break;
940 }
941 }
942 if (pAPLI) {
943 DWORD dwProcessId;
944
945 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
946 //
947 // Switch to the process tab
948 //
949 TabCtrl_SetCurFocus(hTabWnd, 1);
950 //
951 // FIXME: Select the process item in the list
952 //
953 for (i=0; i<ListView_GetItemCount(hProcessPage); i++) {
954 }
955 }
956 }
957
958 int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
959 {
960 LPAPPLICATION_PAGE_LIST_ITEM Param1;
961 LPAPPLICATION_PAGE_LIST_ITEM Param2;
962
963 if (bSortAscending) {
964 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
965 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
966 } else {
967 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
968 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
969 }
970 return _tcscmp(Param1->szTitle, Param2->szTitle);
971 }