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