crypt32: Fix filetime_to_str() for the case where it is called twice for a single...
[wine/multimedia.git] / programs / taskmgr / applpage.c
blob3a51dd81134fa8a61bface05ce9ae0955ee95d0a
1 /*
2 * ReactOS Task Manager
4 * applpage.c
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 * Copyright (C) 2008 Vladimir Pankratov
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
25 #include <windows.h>
26 #include <commctrl.h>
27 #include <stdlib.h>
28 #include <memory.h>
29 #include <stdio.h>
31 #include "wine/unicode.h"
32 #include "taskmgr.h"
34 typedef struct
36 HWND hWnd;
37 WCHAR wszTitle[256];
38 HICON hIcon;
39 BOOL bHung;
40 } APPLICATION_PAGE_LIST_ITEM, *LPAPPLICATION_PAGE_LIST_ITEM;
42 HWND hApplicationPage; /* Application List Property Page */
43 HWND hApplicationPageListCtrl; /* Application ListCtrl Window */
44 HWND hApplicationPageEndTaskButton; /* Application End Task button */
45 HWND hApplicationPageSwitchToButton; /* Application Switch To button */
46 HWND hApplicationPageNewTaskButton; /* Application New Task button */
47 static int nApplicationPageWidth;
48 static int nApplicationPageHeight;
49 static HANDLE hApplicationPageEvent = NULL; /* When this event becomes signaled then we refresh the app list */
50 static BOOL bSortAscending = TRUE;
52 static const WCHAR wszUser32[] = {'U','S','E','R','3','2','.','D','L','L',0};
53 #if 0
54 void SwitchToThisWindow (
55 HWND hWnd, /* Handle to the window that should be activated */
56 BOOL bRestore /* Restore the window if it is minimized */
58 #endif
60 static void ApplicationPageUpdate(void)
62 /* Enable or disable the "End Task" & "Switch To" buttons */
63 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0))
65 EnableWindow(hApplicationPageEndTaskButton, TRUE);
66 EnableWindow(hApplicationPageSwitchToButton, TRUE);
68 else
70 EnableWindow(hApplicationPageEndTaskButton, FALSE);
71 EnableWindow(hApplicationPageSwitchToButton, FALSE);
74 /* If we are on the applications tab, then the windows menu will */
75 /* be present on the menu bar so enable & disable the menu items */
76 if (SendMessageW(hTabWnd, TCM_GETCURSEL, 0, 0) == 0)
78 HMENU hMenu;
79 HMENU hWindowsMenu;
80 UINT count;
82 hMenu = GetMenu(hMainWnd);
83 hWindowsMenu = GetSubMenu(hMenu, 3);
84 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
86 /* Only one item selected */
87 if (count == 1)
89 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
90 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
91 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
92 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
93 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
94 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
96 /* More than one item selected */
97 else if (count > 1)
99 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
100 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
101 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
102 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
103 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
104 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
106 /* No items selected */
107 else
109 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
110 EnableMenuItem(hWindowsMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
111 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
112 EnableMenuItem(hWindowsMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
113 EnableMenuItem(hWindowsMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
114 EnableMenuItem(hWindowsMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
119 static void AddOrUpdateHwnd(HWND hWnd, WCHAR *wszTitle, HICON hIcon, BOOL bHung)
121 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
122 HIMAGELIST hImageListLarge;
123 HIMAGELIST hImageListSmall;
124 LV_ITEMW item;
125 int i, count;
126 BOOL bAlreadyInList = FALSE;
127 BOOL bItemRemoved = FALSE;
129 memset(&item, 0, sizeof(LV_ITEMW));
131 /* Get the image lists */
132 hImageListLarge = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_NORMAL, 0);
133 hImageListSmall = (HIMAGELIST)SendMessageW(hApplicationPageListCtrl, LVM_GETIMAGELIST, LVSIL_SMALL, 0);
135 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
136 /* Check to see if it's already in our list */
137 for (i=0; i<count; i++)
139 memset(&item, 0, sizeof(LV_ITEMW));
140 item.mask = LVIF_IMAGE|LVIF_PARAM;
141 item.iItem = i;
142 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
144 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
145 if (pAPLI->hWnd == hWnd)
147 bAlreadyInList = TRUE;
148 break;
152 /* If it is already in the list then update it if necessary */
153 if (bAlreadyInList)
155 /* Check to see if anything needs updating */
156 if ((pAPLI->hIcon != hIcon) ||
157 (strcmpW(pAPLI->wszTitle, wszTitle) != 0) ||
158 (pAPLI->bHung != bHung))
160 /* Update the structure */
161 pAPLI->hIcon = hIcon;
162 pAPLI->bHung = bHung;
163 strcpyW(pAPLI->wszTitle, wszTitle);
165 /* Update the image list */
166 ImageList_ReplaceIcon(hImageListLarge, item.iItem, hIcon);
167 ImageList_ReplaceIcon(hImageListSmall, item.iItem, hIcon);
169 /* Update the list view */
170 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
171 SendMessageW(hApplicationPageListCtrl, LVM_REDRAWITEMS, 0, count);
172 /* UpdateWindow(hApplicationPageListCtrl); */
173 InvalidateRect(hApplicationPageListCtrl, NULL, 0);
176 /* It is not already in the list so add it */
177 else
179 pAPLI = HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM));
181 pAPLI->hWnd = hWnd;
182 pAPLI->hIcon = hIcon;
183 pAPLI->bHung = bHung;
184 strcpyW(pAPLI->wszTitle, wszTitle);
186 /* Add the item to the list */
187 memset(&item, 0, sizeof(LV_ITEMW));
188 item.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
189 ImageList_AddIcon(hImageListLarge, hIcon);
190 item.iImage = ImageList_AddIcon(hImageListSmall, hIcon);
191 item.pszText = LPSTR_TEXTCALLBACKW;
192 item.iItem = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
193 item.lParam = (LPARAM)pAPLI;
194 SendMessageW(hApplicationPageListCtrl, LVM_INSERTITEMW, 0, (LPARAM) &item);
198 /* Check to see if we need to remove any items from the list */
199 for (i=SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0)-1; i>=0; i--)
201 memset(&item, 0, sizeof(LV_ITEMW));
202 item.mask = LVIF_IMAGE|LVIF_PARAM;
203 item.iItem = i;
204 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
206 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
207 if (!IsWindow(pAPLI->hWnd)||
208 (strlenW(pAPLI->wszTitle) <= 0) ||
209 !IsWindowVisible(pAPLI->hWnd) ||
210 (GetParent(pAPLI->hWnd) != NULL) ||
211 (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) ||
212 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
214 ImageList_Remove(hImageListLarge, item.iItem);
215 ImageList_Remove(hImageListSmall, item.iItem);
217 SendMessageW(hApplicationPageListCtrl, LVM_DELETEITEM, item.iItem, 0);
218 HeapFree(GetProcessHeap(), 0, pAPLI);
219 bItemRemoved = TRUE;
224 * If an item was removed from the list then
225 * we need to resync all the items with the
226 * image list
228 if (bItemRemoved)
230 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
231 for (i=0; i<count; i++)
233 memset(&item, 0, sizeof(LV_ITEMW));
234 item.mask = LVIF_IMAGE;
235 item.iItem = i;
236 item.iImage = i;
237 SendMessageW(hApplicationPageListCtrl, LVM_SETITEMW, 0, (LPARAM) &item);
241 ApplicationPageUpdate();
244 static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
246 HICON hIcon;
247 WCHAR wszText[256];
248 BOOL bLargeIcon;
249 BOOL bHung = FALSE;
250 typedef int (__stdcall *IsHungAppWindowProc)(HWND);
251 IsHungAppWindowProc IsHungAppWindow;
254 /* Skip our window */
255 if (hWnd == hMainWnd)
256 return TRUE;
258 bLargeIcon = TaskManagerSettings.View_LargeIcons ? TRUE : FALSE;
260 /* Check and see if this is a top-level app window */
261 if (!GetWindowTextW(hWnd, wszText, sizeof(wszText)/sizeof(WCHAR)) ||
262 !IsWindowVisible(hWnd) ||
263 (GetParent(hWnd) != NULL) ||
264 (GetWindow(hWnd, GW_OWNER) != NULL) ||
265 (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
267 return TRUE; /* Skip this window */
270 /* Get the icon for this window */
271 hIcon = NULL;
272 SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_BIG /*1*/ : ICON_SMALL /*0*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
274 if (!hIcon)
276 hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICON : GCLP_HICONSM);
277 if (!hIcon) hIcon = (HICON)GetClassLongPtrW(hWnd, bLargeIcon ? GCLP_HICONSM : GCLP_HICON);
278 if (!hIcon) SendMessageTimeoutW(hWnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (PDWORD_PTR)&hIcon);
279 if (!hIcon) SendMessageTimeoutW(hWnd, WM_GETICON, bLargeIcon ? ICON_SMALL /*0*/ : ICON_BIG /*1*/, 0, 0, 1000, (PDWORD_PTR)&hIcon);
282 if (!hIcon)
283 hIcon = LoadIconW(hInst, bLargeIcon ? MAKEINTRESOURCEW(IDI_WINDOW) : MAKEINTRESOURCEW(IDI_WINDOWSM));
285 bHung = FALSE;
287 IsHungAppWindow = (IsHungAppWindowProc)(FARPROC)GetProcAddress(GetModuleHandleW(wszUser32), "IsHungAppWindow");
289 if (IsHungAppWindow)
290 bHung = IsHungAppWindow(hWnd);
292 AddOrUpdateHwnd(hWnd, wszText, hIcon, bHung);
294 return TRUE;
297 static DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter)
299 /* Create the event */
300 hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
302 /* If we couldn't create the event then exit the thread */
303 if (!hApplicationPageEvent)
304 return 0;
306 while (1)
308 DWORD dwWaitVal;
310 /* Wait on the event */
311 dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE);
313 /* If the wait failed then the event object must have been */
314 /* closed and the task manager is exiting so exit this thread */
315 if (dwWaitVal == WAIT_FAILED)
316 return 0;
318 if (dwWaitVal == WAIT_OBJECT_0)
320 /* Reset our event */
321 ResetEvent(hApplicationPageEvent);
324 * FIXME:
326 * Should this be EnumDesktopWindows() instead?
328 EnumWindows(EnumWindowsProc, 0);
333 static void ApplicationPageShowContextMenu1(void)
335 HMENU hMenu;
336 HMENU hSubMenu;
337 POINT pt;
339 GetCursorPos(&pt);
341 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT1));
342 hSubMenu = GetSubMenu(hMenu, 0);
344 if (TaskManagerSettings.View_LargeIcons)
345 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
346 else if (TaskManagerSettings.View_SmallIcons)
347 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
348 else
349 CheckMenuRadioItem(hSubMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
351 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
353 DestroyMenu(hMenu);
356 static void ApplicationPageShowContextMenu2(void)
358 HMENU hMenu;
359 HMENU hSubMenu;
360 UINT count;
361 POINT pt;
363 GetCursorPos(&pt);
365 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATION_PAGE_CONTEXT2));
366 hSubMenu = GetSubMenu(hMenu, 0);
368 count = SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
369 if (count == 1)
371 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
372 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
373 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
374 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
375 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
376 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_ENABLED);
378 else if (count > 1)
380 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_ENABLED);
381 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_ENABLED);
382 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_ENABLED);
383 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_ENABLED);
384 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_ENABLED);
385 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
387 else
389 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEHORIZONTALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
390 EnableMenuItem(hSubMenu, ID_WINDOWS_TILEVERTICALLY, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
391 EnableMenuItem(hSubMenu, ID_WINDOWS_MINIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
392 EnableMenuItem(hSubMenu, ID_WINDOWS_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
393 EnableMenuItem(hSubMenu, ID_WINDOWS_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
394 EnableMenuItem(hSubMenu, ID_WINDOWS_BRINGTOFRONT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
397 SetMenuDefaultItem(hSubMenu, ID_APPLICATION_PAGE_SWITCHTO, MF_BYCOMMAND);
399 TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hMainWnd, NULL);
401 DestroyMenu(hMenu);
404 static int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
406 LPAPPLICATION_PAGE_LIST_ITEM Param1;
407 LPAPPLICATION_PAGE_LIST_ITEM Param2;
409 if (bSortAscending) {
410 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
411 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
412 } else {
413 Param1 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam2;
414 Param2 = (LPAPPLICATION_PAGE_LIST_ITEM)lParam1;
416 return strcmpW(Param1->wszTitle, Param2->wszTitle);
419 static void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam)
421 LPNMHDR pnmh;
422 LV_DISPINFOW* pnmdi;
423 LPAPPLICATION_PAGE_LIST_ITEM pAPLI;
424 WCHAR wszNotResponding[255];
425 WCHAR wszRunning[255];
427 LoadStringW(hInst, IDS_APPLICATION_NOT_RESPONDING, wszNotResponding, sizeof(wszNotResponding)/sizeof(WCHAR));
428 LoadStringW(hInst, IDS_APPLICATION_RUNNING, wszRunning, sizeof(wszRunning)/sizeof(WCHAR));
430 pnmh = (LPNMHDR) lParam;
431 pnmdi = (LV_DISPINFOW*) lParam;
433 if (pnmh->hwndFrom == hApplicationPageListCtrl) {
434 switch (pnmh->code) {
435 case LVN_ITEMCHANGED:
436 ApplicationPageUpdate();
437 break;
439 case LVN_GETDISPINFOW:
440 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)pnmdi->item.lParam;
442 /* Update the item text */
443 if (pnmdi->item.iSubItem == 0)
445 lstrcpynW(pnmdi->item.pszText, pAPLI->wszTitle, pnmdi->item.cchTextMax);
448 /* Update the item status */
449 else if (pnmdi->item.iSubItem == 1)
451 if (pAPLI->bHung)
452 lstrcpynW(pnmdi->item.pszText, wszNotResponding, pnmdi->item.cchTextMax);
453 else
454 lstrcpynW(pnmdi->item.pszText, wszRunning, pnmdi->item.cchTextMax);
457 break;
459 case NM_RCLICK:
461 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
463 ApplicationPageShowContextMenu1();
465 else
467 ApplicationPageShowContextMenu2();
470 break;
472 case NM_DBLCLK:
474 ApplicationPage_OnSwitchTo();
476 break;
479 else if (pnmh->hwndFrom == (HWND)SendMessageW(hApplicationPageListCtrl, LVM_GETHEADER, 0, 0))
481 switch (pnmh->code)
483 case NM_RCLICK:
485 if (SendMessageW(hApplicationPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0) < 1)
487 ApplicationPageShowContextMenu1();
489 else
491 ApplicationPageShowContextMenu2();
494 break;
496 case HDN_ITEMCLICKW:
498 SendMessageW(hApplicationPageListCtrl, LVM_SORTITEMS, 0, (LPARAM) ApplicationPageCompareFunc);
499 bSortAscending = !bSortAscending;
501 break;
507 void RefreshApplicationPage(void)
509 /* Signal the event so that our refresh thread */
510 /* will wake up and refresh the application page */
511 SetEvent(hApplicationPageEvent);
514 static void UpdateApplicationListControlViewSetting(void)
516 DWORD dwStyle = GetWindowLongW(hApplicationPageListCtrl, GWL_STYLE);
518 dwStyle &= ~LVS_REPORT;
519 dwStyle &= ~LVS_ICON;
520 dwStyle &= ~LVS_LIST;
521 dwStyle &= ~LVS_SMALLICON;
523 if (TaskManagerSettings.View_LargeIcons)
524 dwStyle |= LVS_ICON;
525 else if (TaskManagerSettings.View_SmallIcons)
526 dwStyle |= LVS_SMALLICON;
527 else
528 dwStyle |= LVS_REPORT;
530 SetWindowLongW(hApplicationPageListCtrl, GWL_STYLE, dwStyle);
532 RefreshApplicationPage();
535 void ApplicationPage_OnViewLargeIcons(void)
537 HMENU hMenu;
538 HMENU hViewMenu;
540 hMenu = GetMenu(hMainWnd);
541 hViewMenu = GetSubMenu(hMenu, 2);
543 TaskManagerSettings.View_LargeIcons = TRUE;
544 TaskManagerSettings.View_SmallIcons = FALSE;
545 TaskManagerSettings.View_Details = FALSE;
546 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
548 UpdateApplicationListControlViewSetting();
551 void ApplicationPage_OnViewSmallIcons(void)
553 HMENU hMenu;
554 HMENU hViewMenu;
556 hMenu = GetMenu(hMainWnd);
557 hViewMenu = GetSubMenu(hMenu, 2);
559 TaskManagerSettings.View_LargeIcons = FALSE;
560 TaskManagerSettings.View_SmallIcons = TRUE;
561 TaskManagerSettings.View_Details = FALSE;
562 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
564 UpdateApplicationListControlViewSetting();
567 void ApplicationPage_OnViewDetails(void)
569 HMENU hMenu;
570 HMENU hViewMenu;
572 hMenu = GetMenu(hMainWnd);
573 hViewMenu = GetSubMenu(hMenu, 2);
575 TaskManagerSettings.View_LargeIcons = FALSE;
576 TaskManagerSettings.View_SmallIcons = FALSE;
577 TaskManagerSettings.View_Details = TRUE;
578 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
580 UpdateApplicationListControlViewSetting();
583 void ApplicationPage_OnWindowsTileHorizontally(void)
585 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
586 LV_ITEMW item;
587 int i, count;
588 HWND* hWndArray;
589 int nWndCount;
591 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
592 hWndArray = HeapAlloc(GetProcessHeap(), 0,
593 sizeof(HWND) * count);
594 nWndCount = 0;
596 for (i=0; i<count; i++) {
597 memset(&item, 0, sizeof(LV_ITEMW));
598 item.mask = LVIF_STATE|LVIF_PARAM;
599 item.iItem = i;
600 item.stateMask = (UINT)-1;
601 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
603 if (item.state & LVIS_SELECTED) {
604 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
606 if (pAPLI) {
607 hWndArray[nWndCount] = pAPLI->hWnd;
608 nWndCount++;
612 TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
613 HeapFree(GetProcessHeap(), 0, hWndArray);
616 void ApplicationPage_OnWindowsTileVertically(void)
618 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
619 LV_ITEMW item;
620 int i, count;
621 HWND* hWndArray;
622 int nWndCount;
624 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
625 hWndArray = HeapAlloc(GetProcessHeap(), 0,
626 sizeof(HWND) * count);
627 nWndCount = 0;
629 for (i=0; i<count; i++) {
630 memset(&item, 0, sizeof(LV_ITEMW));
631 item.mask = LVIF_STATE|LVIF_PARAM;
632 item.iItem = i;
633 item.stateMask = (UINT)-1;
634 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
636 if (item.state & LVIS_SELECTED) {
637 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
638 if (pAPLI) {
639 hWndArray[nWndCount] = pAPLI->hWnd;
640 nWndCount++;
645 TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
646 HeapFree(GetProcessHeap(), 0, hWndArray);
649 void ApplicationPage_OnWindowsMinimize(void)
651 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
652 LV_ITEMW item;
653 int i, count;
655 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
656 for (i=0; i<count; i++) {
657 memset(&item, 0, sizeof(LV_ITEMW));
658 item.mask = LVIF_STATE|LVIF_PARAM;
659 item.iItem = i;
660 item.stateMask = (UINT)-1;
661 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
662 if (item.state & LVIS_SELECTED) {
663 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
664 if (pAPLI) {
665 ShowWindow(pAPLI->hWnd, SW_MINIMIZE);
671 void ApplicationPage_OnWindowsMaximize(void)
673 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
674 LV_ITEMW item;
675 int i, count;
677 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
678 for (i=0; i<count; i++) {
679 memset(&item, 0, sizeof(LV_ITEMW));
680 item.mask = LVIF_STATE|LVIF_PARAM;
681 item.iItem = i;
682 item.stateMask = (UINT)-1;
683 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
684 if (item.state & LVIS_SELECTED) {
685 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
686 if (pAPLI) {
687 ShowWindow(pAPLI->hWnd, SW_MAXIMIZE);
693 void ApplicationPage_OnWindowsCascade(void)
695 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
696 LV_ITEMW item;
697 int i, count;
698 HWND* hWndArray;
699 int nWndCount;
701 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
702 hWndArray = HeapAlloc(GetProcessHeap(), 0,
703 sizeof(HWND) * count);
704 nWndCount = 0;
706 for (i=0; i<count; i++) {
707 memset(&item, 0, sizeof(LV_ITEMW));
708 item.mask = LVIF_STATE|LVIF_PARAM;
709 item.iItem = i;
710 item.stateMask = (UINT)-1;
711 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
712 if (item.state & LVIS_SELECTED) {
713 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
714 if (pAPLI) {
715 hWndArray[nWndCount] = pAPLI->hWnd;
716 nWndCount++;
720 CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
721 HeapFree(GetProcessHeap(), 0, hWndArray);
724 void ApplicationPage_OnWindowsBringToFront(void)
726 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
727 LV_ITEMW item;
728 int i, count;
730 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
731 for (i=0; i<count; i++) {
732 memset(&item, 0, sizeof(LV_ITEMW));
733 item.mask = LVIF_STATE|LVIF_PARAM;
734 item.iItem = i;
735 item.stateMask = (UINT)-1;
736 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
737 if (item.state & LVIS_SELECTED) {
738 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
739 break;
742 if (pAPLI) {
743 if (IsIconic(pAPLI->hWnd))
744 ShowWindow(pAPLI->hWnd, SW_RESTORE);
745 BringWindowToTop(pAPLI->hWnd);
749 void ApplicationPage_OnSwitchTo(void)
751 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
752 LV_ITEMW item;
753 int i, count;
755 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
756 for (i=0; i<count; i++) {
757 memset(&item, 0, sizeof(LV_ITEMW));
758 item.mask = LVIF_STATE|LVIF_PARAM;
759 item.iItem = i;
760 item.stateMask = (UINT)-1;
761 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
763 if (item.state & LVIS_SELECTED) {
764 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
765 break;
768 if (pAPLI) {
769 typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL);
770 PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
772 HMODULE hUser32 = GetModuleHandleW(wszUser32);
773 SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
774 if (SwitchToThisWindow) {
775 SwitchToThisWindow(pAPLI->hWnd, TRUE);
776 } else {
777 if (IsIconic(pAPLI->hWnd))
778 ShowWindow(pAPLI->hWnd, SW_RESTORE);
779 BringWindowToTop(pAPLI->hWnd);
780 SetForegroundWindow(pAPLI->hWnd);
782 if (TaskManagerSettings.MinimizeOnUse)
783 ShowWindow(hMainWnd, SW_MINIMIZE);
787 void ApplicationPage_OnEndTask(void)
789 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
790 LV_ITEMW item;
791 int i, count;
793 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
794 for (i=0; i<count; i++) {
795 memset(&item, 0, sizeof(LV_ITEMW));
796 item.mask = LVIF_STATE|LVIF_PARAM;
797 item.iItem = i;
798 item.stateMask = (UINT)-1;
799 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
800 if (item.state & LVIS_SELECTED) {
801 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
802 if (pAPLI) {
803 PostMessageW(pAPLI->hWnd, WM_CLOSE, 0, 0);
809 void ApplicationPage_OnGotoProcess(void)
811 LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL;
812 LV_ITEMW item;
813 int i, count;
814 /* NMHDR nmhdr; */
816 count = SendMessageW(hApplicationPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
817 for (i=0; i<count; i++) {
818 memset(&item, 0, sizeof(LV_ITEMW));
819 item.mask = LVIF_STATE|LVIF_PARAM;
820 item.iItem = i;
821 item.stateMask = (UINT)-1;
822 SendMessageW(hApplicationPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &item);
823 if (item.state & LVIS_SELECTED) {
824 pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam;
825 break;
828 if (pAPLI) {
829 DWORD dwProcessId;
831 GetWindowThreadProcessId(pAPLI->hWnd, &dwProcessId);
833 * Switch to the process tab
835 SendMessageW(hTabWnd, TCM_SETCURFOCUS, 1, 0);
837 * FIXME: Select the process item in the list
842 INT_PTR CALLBACK
843 ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
845 RECT rc;
846 int nXDifference;
847 int nYDifference;
848 int cx, cy;
849 LVCOLUMNW column;
851 WCHAR wszTask[255];
852 WCHAR wszStatus[255];
854 LoadStringW(hInst, IDS_APPLICATION_TASK, wszTask, sizeof(wszTask)/sizeof(WCHAR));
855 LoadStringW(hInst, IDS_APPLICATION_STATUS, wszStatus, sizeof(wszStatus)/sizeof(WCHAR));
857 switch (message) {
858 case WM_INITDIALOG:
860 /* Save the width and height */
861 GetClientRect(hDlg, &rc);
862 nApplicationPageWidth = rc.right;
863 nApplicationPageHeight = rc.bottom;
865 /* Update window position */
866 SetWindowPos(hDlg, NULL, 15, 30, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
868 /* Get handles to the controls */
869 hApplicationPageListCtrl = GetDlgItem(hDlg, IDC_APPLIST);
870 hApplicationPageEndTaskButton = GetDlgItem(hDlg, IDC_ENDTASK);
871 hApplicationPageSwitchToButton = GetDlgItem(hDlg, IDC_SWITCHTO);
872 hApplicationPageNewTaskButton = GetDlgItem(hDlg, IDC_NEWTASK);
874 /* Initialize the application page's controls */
875 column.mask = LVCF_TEXT|LVCF_WIDTH;
876 column.pszText = wszTask;
877 column.cx = 250;
878 /* Add the "Task" column */
879 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM) &column);
880 column.mask = LVCF_TEXT|LVCF_WIDTH;
881 column.pszText = wszStatus;
882 column.cx = 95;
883 /* Add the "Status" column */
884 SendMessageW(hApplicationPageListCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
886 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_SMALL,
887 (LPARAM) ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 1));
888 SendMessageW(hApplicationPageListCtrl, LVM_SETIMAGELIST, LVSIL_NORMAL,
889 (LPARAM) ImageList_Create(32, 32, ILC_COLOR8|ILC_MASK, 0, 1));
891 UpdateApplicationListControlViewSetting();
893 /* Start our refresh thread */
894 CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL);
896 return TRUE;
898 case WM_DESTROY:
899 /* Close the event handle, this will make the */
900 /* refresh thread exit when the wait fails */
901 CloseHandle(hApplicationPageEvent);
902 break;
904 case WM_COMMAND:
906 /* Handle the button clicks */
907 switch (LOWORD(wParam))
909 case IDC_ENDTASK:
910 ApplicationPage_OnEndTask();
911 break;
912 case IDC_SWITCHTO:
913 ApplicationPage_OnSwitchTo();
914 break;
915 case IDC_NEWTASK:
916 SendMessageW(hMainWnd, WM_COMMAND, MAKEWPARAM(ID_FILE_NEW, 0), 0);
917 break;
920 break;
922 case WM_SIZE:
923 if (wParam == SIZE_MINIMIZED)
924 return 0;
926 cx = LOWORD(lParam);
927 cy = HIWORD(lParam);
928 nXDifference = cx - nApplicationPageWidth;
929 nYDifference = cy - nApplicationPageHeight;
930 nApplicationPageWidth = cx;
931 nApplicationPageHeight = cy;
933 /* Reposition the application page's controls */
934 GetWindowRect(hApplicationPageListCtrl, &rc);
935 cx = (rc.right - rc.left) + nXDifference;
936 cy = (rc.bottom - rc.top) + nYDifference;
937 SetWindowPos(hApplicationPageListCtrl, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
938 InvalidateRect(hApplicationPageListCtrl, NULL, TRUE);
940 GetClientRect(hApplicationPageEndTaskButton, &rc);
941 MapWindowPoints(hApplicationPageEndTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
942 cx = rc.left + nXDifference;
943 cy = rc.top + nYDifference;
944 SetWindowPos(hApplicationPageEndTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
945 InvalidateRect(hApplicationPageEndTaskButton, NULL, TRUE);
947 GetClientRect(hApplicationPageSwitchToButton, &rc);
948 MapWindowPoints(hApplicationPageSwitchToButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
949 cx = rc.left + nXDifference;
950 cy = rc.top + nYDifference;
951 SetWindowPos(hApplicationPageSwitchToButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
952 InvalidateRect(hApplicationPageSwitchToButton, NULL, TRUE);
954 GetClientRect(hApplicationPageNewTaskButton, &rc);
955 MapWindowPoints(hApplicationPageNewTaskButton, hDlg, (LPPOINT)(&rc), (sizeof(RECT)/sizeof(POINT)) );
956 cx = rc.left + nXDifference;
957 cy = rc.top + nYDifference;
958 SetWindowPos(hApplicationPageNewTaskButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
959 InvalidateRect(hApplicationPageNewTaskButton, NULL, TRUE);
961 break;
963 case WM_NOTIFY:
964 ApplicationPageOnNotify(wParam, lParam);
965 break;
969 return 0;