ReactOS  0.4.15-dev-1207-g698a8e6
taskswnd.cpp
Go to the documentation of this file.
1 /*
2  * ReactOS Explorer
3  *
4  * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "precomp.h"
22 #include <commoncontrols.h>
23 
24 /* Set DUMP_TASKS to 1 to enable a dump of the tasks and task groups every
25  5 seconds */
26 #define DUMP_TASKS 0
27 #define DEBUG_SHELL_HOOK 0
28 
29 #define MAX_TASKS_COUNT (0x7FFF)
30 #define TASK_ITEM_ARRAY_ALLOC 64
31 
32 const WCHAR szTaskSwitchWndClass[] = L"MSTaskSwWClass";
33 const WCHAR szRunningApps[] = L"Running Applications";
34 
35 #if DEBUG_SHELL_HOOK
36 const struct {
37  INT msg;
38  LPCWSTR msg_name;
39 } hshell_msg [] = {
40  { HSHELL_WINDOWCREATED, L"HSHELL_WINDOWCREATED" },
41  { HSHELL_WINDOWDESTROYED, L"HSHELL_WINDOWDESTROYED" },
42  { HSHELL_ACTIVATESHELLWINDOW, L"HSHELL_ACTIVATESHELLWINDOW" },
43  { HSHELL_WINDOWACTIVATED, L"HSHELL_WINDOWACTIVATED" },
44  { HSHELL_GETMINRECT, L"HSHELL_GETMINRECT" },
45  { HSHELL_REDRAW, L"HSHELL_REDRAW" },
46  { HSHELL_TASKMAN, L"HSHELL_TASKMAN" },
47  { HSHELL_LANGUAGE, L"HSHELL_LANGUAGE" },
48  { HSHELL_SYSMENU, L"HSHELL_SYSMENU" },
49  { HSHELL_ENDTASK, L"HSHELL_ENDTASK" },
50  { HSHELL_ACCESSIBILITYSTATE, L"HSHELL_ACCESSIBILITYSTATE" },
51  { HSHELL_APPCOMMAND, L"HSHELL_APPCOMMAND" },
52  { HSHELL_WINDOWREPLACED, L"HSHELL_WINDOWREPLACED" },
53  { HSHELL_WINDOWREPLACING, L"HSHELL_WINDOWREPLACING" },
54  { HSHELL_RUDEAPPACTIVATED, L"HSHELL_RUDEAPPACTIVATED" },
55 };
56 #endif
57 
58 typedef struct _TASK_GROUP
59 {
60  /* We have to use a linked list instead of an array so we don't have to
61  update all pointers to groups in the task item array when removing
62  groups. */
63  struct _TASK_GROUP *Next;
64 
68  union
69  {
71  struct
72  {
73 
75  };
76  };
78 
79 typedef struct _TASK_ITEM
80 {
85 
86  union
87  {
89  struct
90  {
91 
92  /* IsFlashing is TRUE when the task bar item should be flashing. */
94 
95  /* RenderFlashed is only TRUE if the task bar item should be
96  drawn with a flash. */
98  };
99  };
101 
102 
104 {
112 public:
113 
115  m_ThreadId(0),
116  m_hThread(NULL),
118  m_Status(NULL),
119  m_dwType(NULL)
120  {
121  }
122 
124  {
125  if (m_bThreadRunning)
126  {
127  /* Try to unstuck Show */
130  if (ret == WAIT_TIMEOUT)
133  }
134  }
135 
137  {
138  HRESULT hr;
139  CComPtr<IUserNotification> pnotification;
140 
141  hr = OleInitialize(NULL);
142  if (FAILED_UNEXPECTEDLY(hr))
143  return hr;
144 
145  hr = CoCreateInstance(CLSID_UserNotification,
146  NULL,
147  CLSCTX_INPROC_SERVER,
148  IID_PPV_ARG(IUserNotification, &pnotification));
149  if (FAILED_UNEXPECTEDLY(hr))
150  return hr;
151 
152  hr = pnotification->SetBalloonInfo(m_Title, m_Text, NIIF_WARNING);
153  if (FAILED_UNEXPECTEDLY(hr))
154  return hr;
155 
156  hr = pnotification->SetIconInfo(NULL, NULL);
157  if (FAILED_UNEXPECTEDLY(hr))
158  return hr;
159 
160  /* Show will block until the balloon closes */
161  hr = pnotification->Show(NULL, 0);
162  if (FAILED_UNEXPECTEDLY(hr))
163  return hr;
164 
165  return S_OK;
166  }
167 
169  {
170  CHardErrorThread* pThis = reinterpret_cast<CHardErrorThread*>(lpParameter);
171  pThis->ThreadProc();
172  CloseHandle(pThis->m_hThread);
173  OleUninitialize();
175  return 0;
176  }
177 
179  {
181 
182  /* Ignore the new message if we are already showing one */
183  if (bIsRunning)
184  return;
185 
186  m_Status = pData->Status;
187  m_dwType = pData->dwType;
188  m_Title = (PWCHAR)((ULONG_PTR)pData + pData->TitleOffset);
189  m_Text = (PWCHAR)((ULONG_PTR)pData + pData->MessageOffset);
191  if (!m_hThread)
192  {
195  }
196  }
197 };
198 
200  public CWindowImplBaseT< CToolbar<TASK_ITEM>, CControlWinTraits >
201 {
202 public:
203  INT UpdateTbButtonSpacing(IN BOOL bHorizontal, IN BOOL bThemed, IN UINT uiRows = 0, IN UINT uiBtnsPerLine = 0)
204  {
205  TBMETRICS tbm;
206 
207  tbm.cbSize = sizeof(tbm);
209 
210  tbm.cxBarPad = tbm.cyBarPad = 0;
211 
212  if (bThemed)
213  {
214  tbm.cxButtonSpacing = 0;
215  tbm.cyButtonSpacing = 0;
216  }
217  else
218  {
219  if (bHorizontal || uiBtnsPerLine > 1)
220  tbm.cxButtonSpacing = (3 * GetSystemMetrics(SM_CXEDGE) / 2);
221  else
222  tbm.cxButtonSpacing = 0;
223 
224  if (!bHorizontal || uiRows > 1)
225  tbm.cyButtonSpacing = (3 * GetSystemMetrics(SM_CYEDGE) / 2);
226  else
227  tbm.cyButtonSpacing = 0;
228  }
229 
230  SetMetrics(&tbm);
231 
232  return tbm.cxButtonSpacing;
233  }
234 
236  {
237  SetRedraw(FALSE);
238  }
239 
241  {
244  }
245 
246  BOOL SetButtonCommandId(IN INT iButtonIndex, IN INT iCommandId)
247  {
248  TBBUTTONINFO tbbi;
249 
250  tbbi.cbSize = sizeof(tbbi);
251  tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
252  tbbi.idCommand = iCommandId;
253 
254  return SetButtonInfo(iButtonIndex, &tbbi) != 0;
255  }
256 
258  {
259  POINT pt;
260 
261  /* See if the mouse is on a button */
262  pt.x = GET_X_LPARAM(lParam);
263  pt.y = GET_Y_LPARAM(lParam);
264  ScreenToClient(&pt);
265 
266  INT index = HitTest(&pt);
267  if (index < 0)
268  {
269  /* Make the control appear to be transparent outside of any buttons */
270  return HTTRANSPARENT;
271  }
272 
273  bHandled = FALSE;
274  return 0;
275  }
276 
277 public:
280  END_MSG_MAP()
281 
283  {
287 
288  HWND toolbar = CToolbar::Create(hWndParent, styles);
290  return SubclassWindow(toolbar);
291  }
292 };
293 
295  public CComCoClass<CTaskSwitchWnd>,
296  public CComObjectRootEx<CComMultiThreadModelNoCS>,
297  public CWindowImpl < CTaskSwitchWnd, CWindow, CControlWinTraits >,
298  public IOleWindow
299 {
301 
303 
305 
308 
312 
316 
318 
321 
323 
326 
327 public:
330  m_TaskItemCount(0),
333  m_TaskItems(NULL),
335  m_Theme(NULL),
336  m_ButtonsPerLine(0),
337  m_ButtonCount(0),
338  m_ImageList(NULL),
341  {
344  }
345  virtual ~CTaskSwitchWnd() { }
346 
348  {
349  /* Get the window text without sending a message so we don't hang if an
350  application isn't responding! */
351  return InternalGetWindowText(TaskItem->hWnd, szBuf, cchBuf);
352  }
353 
354 
355 #if DUMP_TASKS != 0
356  VOID DumpTasks()
357  {
358  PTASK_GROUP CurrentGroup;
359  PTASK_ITEM CurrentTaskItem, LastTaskItem;
360 
361  TRACE("Tasks dump:\n");
363  {
364  CurrentGroup = m_TaskGroups;
365  while (CurrentGroup != NULL)
366  {
367  TRACE("- Group PID: 0x%p Tasks: %d Index: %d\n", CurrentGroup->dwProcessId, CurrentGroup->dwTaskCount, CurrentGroup->Index);
368 
369  CurrentTaskItem = m_TaskItems;
370  LastTaskItem = CurrentTaskItem + m_TaskItemCount;
371  while (CurrentTaskItem != LastTaskItem)
372  {
373  if (CurrentTaskItem->Group == CurrentGroup)
374  {
375  TRACE(" + Task hwnd: 0x%p Index: %d\n", CurrentTaskItem->hWnd, CurrentTaskItem->Index);
376  }
377  CurrentTaskItem++;
378  }
379 
380  CurrentGroup = CurrentGroup->Next;
381  }
382 
383  CurrentTaskItem = m_TaskItems;
384  LastTaskItem = CurrentTaskItem + m_TaskItemCount;
385  while (CurrentTaskItem != LastTaskItem)
386  {
387  if (CurrentTaskItem->Group == NULL)
388  {
389  TRACE("- Task hwnd: 0x%p Index: %d\n", CurrentTaskItem->hWnd, CurrentTaskItem->Index);
390  }
391  CurrentTaskItem++;
392  }
393  }
394  else
395  {
396  CurrentTaskItem = m_TaskItems;
397  LastTaskItem = CurrentTaskItem + m_TaskItemCount;
398  while (CurrentTaskItem != LastTaskItem)
399  {
400  TRACE("- Task hwnd: 0x%p Index: %d\n", CurrentTaskItem->hWnd, CurrentTaskItem->Index);
401  CurrentTaskItem++;
402  }
403  }
404  }
405 #endif
406 
407  VOID UpdateIndexesAfter(IN INT iIndex, BOOL bInserted)
408  {
409  PTASK_GROUP CurrentGroup;
410  PTASK_ITEM CurrentTaskItem, LastTaskItem;
411  INT NewIndex;
412 
413  int offset = bInserted ? +1 : -1;
414 
416  {
417  /* Update all affected groups */
418  CurrentGroup = m_TaskGroups;
419  while (CurrentGroup != NULL)
420  {
421  if (CurrentGroup->IsCollapsed &&
422  CurrentGroup->Index >= iIndex)
423  {
424  /* Update the toolbar buttons */
425  NewIndex = CurrentGroup->Index + offset;
426  if (m_TaskBar.SetButtonCommandId(CurrentGroup->Index + offset, NewIndex))
427  {
428  CurrentGroup->Index = NewIndex;
429  }
430  else
431  CurrentGroup->Index = -1;
432  }
433 
434  CurrentGroup = CurrentGroup->Next;
435  }
436  }
437 
438  /* Update all affected task items */
439  CurrentTaskItem = m_TaskItems;
440  LastTaskItem = CurrentTaskItem + m_TaskItemCount;
441  while (CurrentTaskItem != LastTaskItem)
442  {
443  CurrentGroup = CurrentTaskItem->Group;
444  if (CurrentGroup != NULL)
445  {
446  if (!CurrentGroup->IsCollapsed &&
447  CurrentTaskItem->Index >= iIndex)
448  {
449  goto UpdateTaskItemBtn;
450  }
451  }
452  else if (CurrentTaskItem->Index >= iIndex)
453  {
454  UpdateTaskItemBtn:
455  /* Update the toolbar buttons */
456  NewIndex = CurrentTaskItem->Index + offset;
457  if (m_TaskBar.SetButtonCommandId(CurrentTaskItem->Index + offset, NewIndex))
458  {
459  CurrentTaskItem->Index = NewIndex;
460  }
461  else
462  CurrentTaskItem->Index = -1;
463  }
464 
465  CurrentTaskItem++;
466  }
467  }
468 
469 
471  {
472  ASSERT(TaskGroup->Index >= 0);
473 
474  /* FIXME: Implement */
475 
476  return TaskGroup->Index;
477  }
478 
480  {
481  ASSERT(TaskGroup->dwTaskCount > 0);
482  ASSERT(TaskGroup->IsCollapsed);
483  ASSERT(TaskGroup->Index >= 0);
484 
485  /* FIXME: Implement */
486  }
487 
489  {
490  HICON hIcon = 0;
491 
492  SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL2, 0, SMTO_ABORTIFHUNG, 1000, (PDWORD_PTR) &hIcon);
493  if (hIcon)
494  return hIcon;
495 
497  if (hIcon)
498  return hIcon;
499 
500  SendMessageTimeout(hwnd, WM_GETICON, ICON_BIG, 0, SMTO_ABORTIFHUNG, 1000, (PDWORD_PTR) &hIcon);
501  if (hIcon)
502  return hIcon;
503 
505  if (hIcon)
506  return hIcon;
507 
509 
510  return hIcon;
511  }
512 
514  {
515  TBBUTTONINFO tbbi = { 0 };
516  HICON icon;
517  WCHAR windowText[255];
518 
519  ASSERT(TaskItem->Index >= 0);
520 
521  tbbi.cbSize = sizeof(tbbi);
522  tbbi.dwMask = TBIF_BYINDEX | TBIF_STATE | TBIF_TEXT | TBIF_IMAGE;
523  tbbi.fsState = TBSTATE_ENABLED;
524  if (m_ActiveTaskItem == TaskItem)
525  tbbi.fsState |= TBSTATE_CHECKED;
526 
527  if (TaskItem->RenderFlashed)
528  tbbi.fsState |= TBSTATE_MARKED;
529 
530  /* Check if we're updating a button that is the last one in the
531  line. If so, we need to set the TBSTATE_WRAP flag! */
532  if (!m_Tray->IsHorizontal() || (m_ButtonsPerLine != 0 &&
533  (TaskItem->Index + 1) % m_ButtonsPerLine == 0))
534  {
535  tbbi.fsState |= TBSTATE_WRAP;
536  }
537 
539  {
540  tbbi.pszText = windowText;
541  }
542 
543  icon = GetWndIcon(TaskItem->hWnd);
544  if (!icon)
545  icon = static_cast<HICON>(LoadImageW(NULL, MAKEINTRESOURCEW(OIC_SAMPLE), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
546  TaskItem->IconIndex = ImageList_ReplaceIcon(m_ImageList, TaskItem->IconIndex, icon);
547  tbbi.iImage = TaskItem->IconIndex;
548 
549  if (!m_TaskBar.SetButtonInfo(TaskItem->Index, &tbbi))
550  {
551  TaskItem->Index = -1;
552  return -1;
553  }
554 
555  TRACE("Updated button %d for hwnd 0x%p\n", TaskItem->Index, TaskItem->hWnd);
556  return TaskItem->Index;
557  }
558 
560  {
561  TBBUTTONINFO tbbi;
562  PTASK_ITEM currentTaskItem, LastItem;
563 
564  if (TaskItem->IconIndex == -1)
565  return;
566 
567  tbbi.cbSize = sizeof(tbbi);
568  tbbi.dwMask = TBIF_IMAGE;
569 
570  currentTaskItem = m_TaskItems;
571  LastItem = currentTaskItem + m_TaskItemCount;
572  while (currentTaskItem != LastItem)
573  {
574  if (currentTaskItem->IconIndex > TaskItem->IconIndex)
575  {
576  currentTaskItem->IconIndex--;
577  tbbi.iImage = currentTaskItem->IconIndex;
578 
579  m_TaskBar.SetButtonInfo(currentTaskItem->Index, &tbbi);
580  }
581  currentTaskItem++;
582  }
583 
584  ImageList_Remove(m_ImageList, TaskItem->IconIndex);
585  }
586 
588  IN PTASK_GROUP TaskGroup OPTIONAL,
589  IN PTASK_ITEM NewTaskItem OPTIONAL)
590  {
591  PTASK_ITEM TaskItem, LastTaskItem, FoundTaskItem = NULL;
592  DWORD dwTaskCount;
593 
595 
596  TaskItem = m_TaskItems;
597  LastTaskItem = TaskItem + m_TaskItemCount;
598 
599  dwTaskCount = (TaskGroup != NULL ? TaskGroup->dwTaskCount : MAX_TASKS_COUNT);
600 
601  ASSERT(dwTaskCount > 0);
602 
603  while (TaskItem != LastTaskItem)
604  {
605  if (TaskItem->Group == TaskGroup)
606  {
607  if ((NewTaskItem != NULL && TaskItem != NewTaskItem) || NewTaskItem == NULL)
608  {
609  FoundTaskItem = TaskItem;
610  }
611 
612  if (--dwTaskCount == 0)
613  {
614  /* We found the last task item in the group! */
615  break;
616  }
617  }
618 
619  TaskItem++;
620  }
621 
622  return FoundTaskItem;
623  }
624 
626  {
627  PTASK_GROUP TaskGroup;
628  PTASK_ITEM LastTaskItem;
629 
630  /* NOTE: This routine assumes that the group is *not* collapsed! */
631 
632  TaskGroup = TaskItem->Group;
634  {
635  if (TaskGroup != NULL)
636  {
637  ASSERT(TaskGroup->Index < 0);
638  ASSERT(!TaskGroup->IsCollapsed);
639 
640  if (TaskGroup->dwTaskCount > 1)
641  {
642  LastTaskItem = FindLastTaskItemOfGroup(TaskGroup, TaskItem);
643  if (LastTaskItem != NULL)
644  {
645  /* Since the group is expanded the task items must have an index */
646  ASSERT(LastTaskItem->Index >= 0);
647 
648  return LastTaskItem->Index + 1;
649  }
650  }
651  }
652  else
653  {
654  /* Find the last NULL group button. NULL groups are added at the end of the
655  task item list when grouping is enabled */
656  LastTaskItem = FindLastTaskItemOfGroup(NULL, TaskItem);
657  if (LastTaskItem != NULL)
658  {
659  ASSERT(LastTaskItem->Index >= 0);
660 
661  return LastTaskItem->Index + 1;
662  }
663  }
664  }
665 
666  return m_ButtonCount;
667  }
668 
670  {
671  WCHAR windowText[255];
672  TBBUTTON tbBtn = { 0 };
673  INT iIndex;
674  HICON icon;
675 
676  if (TaskItem->Index >= 0)
677  {
678  return UpdateTaskItemButton(TaskItem);
679  }
680 
681  if (TaskItem->Group != NULL &&
682  TaskItem->Group->IsCollapsed)
683  {
684  /* The task group is collapsed, we only need to update the group button */
685  return UpdateTaskGroupButton(TaskItem->Group);
686  }
687 
688  icon = GetWndIcon(TaskItem->hWnd);
689  if (!icon)
690  icon = static_cast<HICON>(LoadImageW(NULL, MAKEINTRESOURCEW(OIC_SAMPLE), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
691  TaskItem->IconIndex = ImageList_ReplaceIcon(m_ImageList, -1, icon);
692 
693  tbBtn.iBitmap = TaskItem->IconIndex;
696  tbBtn.dwData = TaskItem->Index;
697 
699  {
700  tbBtn.iString = (DWORD_PTR) windowText;
701  }
702 
703  /* Find out where to insert the new button */
704  iIndex = CalculateTaskItemNewButtonIndex(TaskItem);
705  ASSERT(iIndex >= 0);
706  tbBtn.idCommand = iIndex;
707 
709 
710  if (m_TaskBar.InsertButton(iIndex, &tbBtn))
711  {
712  UpdateIndexesAfter(iIndex, TRUE);
713 
714  TRACE("Added button %d for hwnd 0x%p\n", iIndex, TaskItem->hWnd);
715 
716  TaskItem->Index = iIndex;
717  m_ButtonCount++;
718 
719  /* Update button sizes and fix the button wrapping */
721  return iIndex;
722  }
723 
725 
726  return -1;
727  }
728 
730  {
731  PTASK_GROUP TaskGroup;
732  INT iIndex;
733 
734  TaskGroup = TaskItem->Group;
735 
736  if (TaskItem->Index >= 0)
737  {
738  if ((TaskGroup != NULL && !TaskGroup->IsCollapsed) ||
739  TaskGroup == NULL)
740  {
742 
743  RemoveIcon(TaskItem);
744  iIndex = TaskItem->Index;
745  if (m_TaskBar.DeleteButton(iIndex))
746  {
747  TaskItem->Index = -1;
748  m_ButtonCount--;
749 
750  UpdateIndexesAfter(iIndex, FALSE);
751 
752  /* Update button sizes and fix the button wrapping */
754  return TRUE;
755  }
756 
758  }
759  }
760 
761  return FALSE;
762  }
763 
765  {
766  DWORD dwProcessId;
767  PTASK_GROUP TaskGroup, *PrevLink;
768 
770  &dwProcessId))
771  {
772  TRACE("Cannot get process id of hwnd 0x%p\n", hWnd);
773  return NULL;
774  }
775 
776  /* Try to find an existing task group */
777  TaskGroup = m_TaskGroups;
778  PrevLink = &m_TaskGroups;
779  while (TaskGroup != NULL)
780  {
781  if (TaskGroup->dwProcessId == dwProcessId)
782  {
783  TaskGroup->dwTaskCount++;
784  return TaskGroup;
785  }
786 
787  PrevLink = &TaskGroup->Next;
788  TaskGroup = TaskGroup->Next;
789  }
790 
791  /* Allocate a new task group */
792  TaskGroup = (PTASK_GROUP) HeapAlloc(hProcessHeap,
794  sizeof(*TaskGroup));
795  if (TaskGroup != NULL)
796  {
797  TaskGroup->dwTaskCount = 1;
798  TaskGroup->dwProcessId = dwProcessId;
799  TaskGroup->Index = -1;
800 
801  /* Add the task group to the list */
802  *PrevLink = TaskGroup;
803  }
804 
805  return TaskGroup;
806  }
807 
809  {
810  PTASK_GROUP TaskGroup, CurrentGroup, *PrevLink;
811 
812  TaskGroup = TaskItem->Group;
813  if (TaskGroup != NULL)
814  {
815  DWORD dwNewTaskCount = --TaskGroup->dwTaskCount;
816  if (dwNewTaskCount == 0)
817  {
818  /* Find the previous pointer in the chain */
819  CurrentGroup = m_TaskGroups;
820  PrevLink = &m_TaskGroups;
821  while (CurrentGroup != TaskGroup)
822  {
823  PrevLink = &CurrentGroup->Next;
824  CurrentGroup = CurrentGroup->Next;
825  }
826 
827  /* Remove the group from the list */
828  ASSERT(TaskGroup == CurrentGroup);
829  *PrevLink = TaskGroup->Next;
830 
831  /* Free the task group */
833  0,
834  TaskGroup);
835  }
836  else if (TaskGroup->IsCollapsed &&
837  TaskGroup->Index >= 0)
838  {
839  if (dwNewTaskCount > 1)
840  {
841  /* FIXME: Check if we should expand the group */
842  /* Update the task group button */
843  UpdateTaskGroupButton(TaskGroup);
844  }
845  else
846  {
847  /* Expand the group of one task button to a task button */
848  ExpandTaskGroup(TaskGroup);
849  }
850  }
851  }
852  }
853 
855  {
856  PTASK_ITEM TaskItem, LastItem;
857 
858  TaskItem = m_TaskItems;
859  LastItem = TaskItem + m_TaskItemCount;
860  while (TaskItem != LastItem)
861  {
862  if (TaskItem->hWnd == hWnd)
863  return TaskItem;
864 
865  TaskItem++;
866  }
867 
868  return NULL;
869  }
870 
872  {
873  PTASK_ITEM LastItem, TaskItem;
874  PTASK_GROUP TaskGroup;
875  DWORD dwProcessId;
876 
877  if (!GetWindowThreadProcessId(hWnd, &dwProcessId))
878  {
879  return NULL;
880  }
881 
882  /* Try to find another task that belongs to the same
883  process as the given window */
884  TaskItem = m_TaskItems;
885  LastItem = TaskItem + m_TaskItemCount;
886  while (TaskItem != LastItem)
887  {
888  TaskGroup = TaskItem->Group;
889  if (TaskGroup != NULL)
890  {
891  if (TaskGroup->dwProcessId == dwProcessId)
892  return TaskItem;
893  }
894  else
895  {
896  DWORD dwProcessIdTask;
897 
898  if (GetWindowThreadProcessId(TaskItem->hWnd,
899  &dwProcessIdTask) &&
900  dwProcessIdTask == dwProcessId)
901  {
902  return TaskItem;
903  }
904  }
905 
906  TaskItem++;
907  }
908 
909  return NULL;
910  }
911 
913  {
915  {
916  /* We need the most significant bit in 16 bit command IDs to indicate whether it
917  is a task group or task item. WM_COMMAND limits command IDs to 16 bits! */
918  return NULL;
919  }
920 
922 
923  if (m_TaskItemCount == 0)
924  {
926  0,
928  if (m_TaskItems != NULL)
929  {
931  }
932  else
933  return NULL;
934  }
936  {
937  PTASK_ITEM NewArray;
938  SIZE_T NewArrayLength, ActiveTaskItemIndex;
939 
940  NewArrayLength = m_AllocatedTaskItems + TASK_ITEM_ARRAY_ALLOC;
941 
942  NewArray = (PTASK_ITEM) HeapReAlloc(hProcessHeap,
943  0,
944  m_TaskItems,
945  NewArrayLength * sizeof(*m_TaskItems));
946  if (NewArray != NULL)
947  {
948  if (m_ActiveTaskItem != NULL)
949  {
950  /* Fixup the ActiveTaskItem pointer */
951  ActiveTaskItemIndex = m_ActiveTaskItem - m_TaskItems;
952  m_ActiveTaskItem = NewArray + ActiveTaskItemIndex;
953  }
954  m_AllocatedTaskItems = (WORD) NewArrayLength;
955  m_TaskItems = NewArray;
956  }
957  else
958  return NULL;
959  }
960 
961  return m_TaskItems + m_TaskItemCount++;
962  }
963 
965  {
966  WORD wIndex;
967 
968  if (TaskItem == m_ActiveTaskItem)
970 
971  wIndex = (WORD) (TaskItem - m_TaskItems);
972  if (wIndex + 1 < m_TaskItemCount)
973  {
974  MoveMemory(TaskItem,
975  TaskItem + 1,
976  (m_TaskItemCount - wIndex - 1) * sizeof(*TaskItem));
977  }
978 
979  m_TaskItemCount--;
980  }
981 
983  {
984  if (!m_IsDestroying)
985  {
986  /* Delete the task button from the toolbar */
987  DeleteTaskItemButton(TaskItem);
988  }
989 
990  /* Remove the task from it's group */
991  RemoveTaskFromTaskGroup(TaskItem);
992 
993  /* Free the task item */
994  FreeTaskItem(TaskItem);
995  }
996 
998  {
999  PTASK_ITEM CurrentTaskItem;
1000  PTASK_GROUP TaskGroup = NULL;
1001 
1002  CurrentTaskItem = m_ActiveTaskItem;
1003 
1004  if (TaskItem != NULL)
1005  TaskGroup = TaskItem->Group;
1006 
1007  if (m_IsGroupingEnabled &&
1008  TaskGroup != NULL &&
1009  TaskGroup->IsCollapsed)
1010  {
1011  /* FIXME */
1012  return;
1013  }
1014 
1015  if (CurrentTaskItem != NULL)
1016  {
1017  PTASK_GROUP CurrentTaskGroup;
1018 
1019  if (CurrentTaskItem == TaskItem)
1020  return;
1021 
1022  CurrentTaskGroup = CurrentTaskItem->Group;
1023 
1024  if (m_IsGroupingEnabled &&
1025  CurrentTaskGroup != NULL &&
1026  CurrentTaskGroup->IsCollapsed)
1027  {
1028  if (CurrentTaskGroup == TaskGroup)
1029  return;
1030 
1031  /* FIXME */
1032  }
1033  else
1034  {
1036  if (CurrentTaskItem->Index >= 0)
1037  {
1038  UpdateTaskItemButton(CurrentTaskItem);
1039  }
1040  }
1041  }
1042 
1043  m_ActiveTaskItem = TaskItem;
1044 
1045  if (TaskItem != NULL && TaskItem->Index >= 0)
1046  {
1047  UpdateTaskItemButton(TaskItem);
1048  }
1049  else if (TaskItem == NULL)
1050  {
1051  TRACE("Active TaskItem now NULL\n");
1052  }
1053  }
1054 
1056  {
1057  PTASK_ITEM TaskItem, LastItem;
1058 
1059  TaskItem = m_TaskItems;
1060  LastItem = TaskItem + m_TaskItemCount;
1061  while (TaskItem != LastItem)
1062  {
1063  if (TaskItem->Index == Index)
1064  return TaskItem;
1065 
1066  TaskItem++;
1067  }
1068 
1069  return NULL;
1070  }
1071 
1073  {
1074  PTASK_GROUP CurrentGroup;
1075 
1076  CurrentGroup = m_TaskGroups;
1077  while (CurrentGroup != NULL)
1078  {
1079  if (CurrentGroup->Index == Index)
1080  break;
1081 
1082  CurrentGroup = CurrentGroup->Next;
1083  }
1084 
1085  return CurrentGroup;
1086  }
1087 
1089  {
1090  PTASK_ITEM TaskItem;
1091 
1092  if (!::IsWindow(hWnd) || m_Tray->IsSpecialHWND(hWnd))
1093  return FALSE;
1094 
1095  TaskItem = FindTaskItem(hWnd);
1096  if (TaskItem == NULL)
1097  {
1098  TRACE("Add window 0x%p\n", hWnd);
1099  TaskItem = AllocTaskItem();
1100  if (TaskItem != NULL)
1101  {
1102  ZeroMemory(TaskItem, sizeof(*TaskItem));
1103  TaskItem->hWnd = hWnd;
1104  TaskItem->Index = -1;
1105  TaskItem->Group = AddToTaskGroup(hWnd);
1106 
1107  if (!m_IsDestroying)
1108  {
1109  AddTaskItemButton(TaskItem);
1110  }
1111  }
1112  }
1113 
1114  return TaskItem != NULL;
1115  }
1116 
1118  {
1119  if (TaskItem != NULL)
1120  {
1121  TRACE("Activate window 0x%p on button %d\n", TaskItem->hWnd, TaskItem->Index);
1122  }
1123 
1124  CheckActivateTaskItem(TaskItem);
1125 
1126  return FALSE;
1127  }
1128 
1130  {
1131  PTASK_ITEM TaskItem;
1132 
1133  if (!hWnd)
1134  {
1135  return ActivateTaskItem(NULL);
1136  }
1137 
1138  TaskItem = FindTaskItem(hWnd);
1139  if (TaskItem == NULL)
1140  {
1141  TaskItem = FindOtherTaskItem(hWnd);
1142  }
1143 
1144  if (TaskItem == NULL)
1145  {
1146  WARN("Activate window 0x%p, could not find task\n", hWnd);
1148  }
1149 
1150  return ActivateTaskItem(TaskItem);
1151  }
1152 
1154  {
1155  PTASK_ITEM TaskItem;
1156 
1157  TaskItem = FindTaskItem(hWnd);
1158  if (TaskItem != NULL)
1159  {
1160  TRACE("Delete window 0x%p on button %d\n", hWnd, TaskItem->Index);
1161  DeleteTaskItem(TaskItem);
1162  return TRUE;
1163  }
1164  //else
1165  //TRACE("Failed to delete window 0x%p\n", hWnd);
1166 
1167  return FALSE;
1168  }
1169 
1171  {
1172  PTASK_ITEM CurrentTask;
1173 
1174  if (m_TaskItemCount > 0)
1175  {
1176  CurrentTask = m_TaskItems + m_TaskItemCount;
1177  do
1178  {
1179  DeleteTaskItem(--CurrentTask);
1180  } while (CurrentTask != m_TaskItems);
1181  }
1182  }
1183 
1185  {
1186  TaskItem->RenderFlashed = 1;
1187  UpdateTaskItemButton(TaskItem);
1188  }
1189 
1191  {
1192  PTASK_ITEM TaskItem;
1193 
1194  TaskItem = FindTaskItem(hWnd);
1195  if (TaskItem != NULL)
1196  {
1197  TRACE("Flashing window 0x%p on button %d\n", hWnd, TaskItem->Index);
1198  FlashTaskItem(TaskItem);
1199  return TRUE;
1200  }
1201 
1202  return FALSE;
1203  }
1204 
1206  {
1207  PTASK_GROUP TaskGroup;
1208 
1209  TaskGroup = TaskItem->Group;
1210  if (m_IsGroupingEnabled && TaskGroup != NULL)
1211  {
1212  if (TaskGroup->IsCollapsed && TaskGroup->Index >= 0)
1213  {
1214  UpdateTaskGroupButton(TaskGroup);
1215  }
1216  else if (TaskItem->Index >= 0)
1217  {
1218  goto UpdateTaskItem;
1219  }
1220  }
1221  else if (TaskItem->Index >= 0)
1222  {
1223  UpdateTaskItem:
1224  TaskItem->RenderFlashed = 0;
1225  UpdateTaskItemButton(TaskItem);
1226  }
1227  }
1228 
1229 
1231  {
1232  PTASK_ITEM TaskItem;
1233 
1234  TaskItem = FindTaskItem(hWnd);
1235  if (TaskItem != NULL)
1236  {
1237  RedrawTaskItem(TaskItem);
1238  return TRUE;
1239  }
1240 
1241  return FALSE;
1242  }
1243 
1244  VOID UpdateButtonsSize(IN BOOL bRedrawDisabled)
1245  {
1246  RECT rcClient;
1247  UINT uiRows, uiMax, uiMin, uiBtnsPerLine, ui;
1248  LONG NewBtnSize;
1249  BOOL Horizontal;
1250 
1251  /* Update the size of the image list if needed */
1252  int cx, cy;
1255  {
1257 
1258  /* SetIconSize removes all icons so we have to reinsert them */
1259  PTASK_ITEM TaskItem = m_TaskItems;
1260  PTASK_ITEM LastTaskItem = m_TaskItems + m_TaskItemCount;
1261  while (TaskItem != LastTaskItem)
1262  {
1263  TaskItem->IconIndex = -1;
1264  UpdateTaskItemButton(TaskItem);
1265 
1266  TaskItem++;
1267  }
1269  }
1270 
1271  if (GetClientRect(&rcClient) && !IsRectEmpty(&rcClient))
1272  {
1273  if (m_ButtonCount > 0)
1274  {
1275  Horizontal = m_Tray->IsHorizontal();
1276 
1277  if (Horizontal)
1278  {
1279  TBMETRICS tbm = { 0 };
1280  tbm.cbSize = sizeof(tbm);
1281  tbm.dwMask = TBMF_BUTTONSPACING;
1282  m_TaskBar.GetMetrics(&tbm);
1283 
1284  if (m_ButtonSize.cy + tbm.cyButtonSpacing != 0)
1285  uiRows = (rcClient.bottom + tbm.cyButtonSpacing) / (m_ButtonSize.cy + tbm.cyButtonSpacing);
1286  else
1287  uiRows = 1;
1288 
1289  if (uiRows == 0)
1290  uiRows = 1;
1291 
1292  uiBtnsPerLine = (m_ButtonCount + uiRows - 1) / uiRows;
1293  }
1294  else
1295  {
1296  uiBtnsPerLine = 1;
1297  uiRows = m_ButtonCount;
1298  }
1299 
1300  if (!bRedrawDisabled)
1302 
1303  /* We might need to update the button spacing */
1304  int cxButtonSpacing = m_TaskBar.UpdateTbButtonSpacing(
1305  Horizontal, m_Theme != NULL,
1306  uiRows, uiBtnsPerLine);
1307 
1308  /* Determine the minimum and maximum width of a button */
1310  if (Horizontal)
1311  {
1313 
1314  /* Calculate the ideal width and make sure it's within the allowed range */
1315  NewBtnSize = (rcClient.right - (uiBtnsPerLine * cxButtonSpacing)) / uiBtnsPerLine;
1316 
1317  if (NewBtnSize < (LONG) uiMin)
1318  NewBtnSize = uiMin;
1319  if (NewBtnSize >(LONG)uiMax)
1320  NewBtnSize = uiMax;
1321 
1322  /* Recalculate how many buttons actually fit into one line */
1323  uiBtnsPerLine = rcClient.right / (NewBtnSize + cxButtonSpacing);
1324  if (uiBtnsPerLine == 0)
1325  uiBtnsPerLine++;
1326  }
1327  else
1328  {
1329  NewBtnSize = uiMax = rcClient.right;
1330  }
1331 
1332  m_ButtonSize.cx = NewBtnSize;
1333 
1334  m_ButtonsPerLine = uiBtnsPerLine;
1335 
1336  for (ui = 0; ui != m_ButtonCount; ui++)
1337  {
1338  TBBUTTONINFOW tbbi = { 0 };
1339  tbbi.cbSize = sizeof(tbbi);
1341  tbbi.cx = (INT) NewBtnSize;
1342  tbbi.fsState = TBSTATE_ENABLED;
1343 
1344  /* Check if we're updating a button that is the last one in the
1345  line. If so, we need to set the TBSTATE_WRAP flag! */
1346  if (Horizontal)
1347  {
1348  if ((ui + 1) % uiBtnsPerLine == 0)
1349  tbbi.fsState |= TBSTATE_WRAP;
1350  }
1351  else
1352  {
1353  tbbi.fsState |= TBSTATE_WRAP;
1354  }
1355 
1356  if (m_ActiveTaskItem != NULL &&
1358  {
1359  tbbi.fsState |= TBSTATE_CHECKED;
1360  }
1361 
1362  m_TaskBar.SetButtonInfo(ui, &tbbi);
1363  }
1364  }
1365  else
1366  {
1367  m_ButtonsPerLine = 0;
1368  m_ButtonSize.cx = 0;
1369  }
1370  }
1371 
1372  // FIXME: This seems to be enabling redraws prematurely, but moving it to its right place doesn't work!
1373  m_TaskBar.EndUpdate();
1374  }
1375 
1377  {
1378  /* Only show windows that still exist and are visible and none of explorer's
1379  special windows (such as the desktop or the tray window) */
1380  if (::IsWindow(hWnd) && ::IsWindowVisible(hWnd) &&
1381  !m_Tray->IsSpecialHWND(hWnd))
1382  {
1383  DWORD exStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
1384  /* Don't list popup windows and also no tool windows */
1385  if ((::GetWindow(hWnd, GW_OWNER) == NULL || exStyle & WS_EX_APPWINDOW) &&
1386  !(exStyle & WS_EX_TOOLWINDOW))
1387  {
1388  TRACE("Adding task for %p...\n", hWnd);
1389  AddTask(hWnd);
1390  }
1391 
1392  }
1393 
1394  return TRUE;
1395  }
1396 
1398  {
1400 
1401  return This->EnumWindowsProc(hWnd);
1402  }
1403 
1405  {
1406  TRACE("Refreshing window list...\n");
1407  /* Add all windows to the toolbar */
1408  return EnumWindows(s_EnumWindowsProc, (LPARAM)this);
1409  }
1410 
1412  {
1413  TRACE("OmThemeChanged\n");
1414 
1415  if (m_Theme)
1417 
1418  if (IsThemeActive())
1419  m_Theme = OpenThemeData(m_hWnd, L"TaskBand");
1420  else
1421  m_Theme = NULL;
1422 
1423  return TRUE;
1424  }
1425 
1427  {
1428  if (!m_TaskBar.Initialize(m_hWnd))
1429  return FALSE;
1430 
1431  SetWindowTheme(m_TaskBar.m_hWnd, L"TaskBand", NULL);
1432 
1435 
1436  /* Set proper spacing between buttons */
1437  m_TaskBar.UpdateTbButtonSpacing(m_Tray->IsHorizontal(), m_Theme != NULL);
1438 
1439  /* Register the shell hook */
1440  m_ShellHookMsg = RegisterWindowMessageW(L"SHELLHOOK");
1441 
1442  TRACE("ShellHookMsg got assigned number %d\n", m_ShellHookMsg);
1443 
1444  RegisterShellHook(m_hWnd, 3); /* 1 if no NT! We're targeting NT so we don't care! */
1445 
1447 
1448  /* Recalculate the button size */
1450 
1451 #if DUMP_TASKS != 0
1452  SetTimer(hwnd, 1, 5000, NULL);
1453 #endif
1454  return TRUE;
1455  }
1456 
1458  {
1459  m_IsDestroying = TRUE;
1460 
1461  /* Unregister the shell hook */
1463 
1465  DeleteAllTasks();
1466  return TRUE;
1467  }
1468 
1470  {
1471  BOOL Ret = FALSE;
1472 
1473  switch (GET_APPCOMMAND_LPARAM(lParam))
1474  {
1475  case APPCOMMAND_BROWSER_SEARCH:
1476  Ret = SHFindFiles(NULL,
1477  NULL);
1478  break;
1479 
1480  case APPCOMMAND_BROWSER_HOME:
1481  case APPCOMMAND_LAUNCH_MAIL:
1482  default:
1483  TRACE("Shell app command %d unhandled!\n", (INT) GET_APPCOMMAND_LPARAM(lParam));
1484  break;
1485  }
1486 
1487  return Ret;
1488  }
1489 
1491  {
1492  BOOL Ret = FALSE;
1493 
1494  /* In case the shell hook wasn't registered properly, ignore WM_NULLs*/
1495  if (uMsg == 0)
1496  {
1497  bHandled = FALSE;
1498  return 0;
1499  }
1500 
1501  TRACE("Received shell hook message: wParam=%08lx, lParam=%08lx\n", wParam, lParam);
1502 
1503  switch ((INT) wParam)
1504  {
1505  case HSHELL_APPCOMMAND:
1506  Ret = HandleAppCommand(wParam, lParam);
1507  break;
1508 
1509  case HSHELL_WINDOWCREATED:
1510  AddTask((HWND) lParam);
1511  break;
1512 
1514  /* The window still exists! Delay destroying it a bit */
1515  DeleteTask((HWND) lParam);
1516  break;
1517 
1519  case HSHELL_WINDOWACTIVATED:
1521  break;
1522 
1523  case HSHELL_FLASH:
1524  FlashTask((HWND) lParam);
1525  break;
1526 
1527  case HSHELL_REDRAW:
1528  RedrawTask((HWND) lParam);
1529  break;
1530 
1531  case HSHELL_TASKMAN:
1532  ::PostMessage(m_Tray->GetHWND(), TWM_OPENSTARTMENU, 0, 0);
1533  break;
1534 
1536  ::SwitchToThisWindow(m_Tray->GetHWND(), TRUE);
1537  ::SetForegroundWindow(m_Tray->GetHWND());
1538  break;
1539 
1540  case HSHELL_LANGUAGE:
1541  case HSHELL_SYSMENU:
1542  case HSHELL_ENDTASK:
1543  case HSHELL_ACCESSIBILITYSTATE:
1544  case HSHELL_WINDOWREPLACED:
1545  case HSHELL_WINDOWREPLACING:
1546 
1547  case HSHELL_GETMINRECT:
1548  default:
1549  {
1550 #if DEBUG_SHELL_HOOK
1551  int i, found;
1552  for (i = 0, found = 0; i != _countof(hshell_msg); i++)
1553  {
1554  if (hshell_msg[i].msg == (INT) wParam)
1555  {
1556  TRACE("Shell message %ws unhandled (lParam = 0x%p)!\n", hshell_msg[i].msg_name, lParam);
1557  found = 1;
1558  break;
1559  }
1560  }
1561  if (found)
1562  break;
1563 #endif
1564  TRACE("Shell message %d unhandled (lParam = 0x%p)!\n", (INT) wParam, lParam);
1565  break;
1566  }
1567  }
1568 
1569  return Ret;
1570  }
1571 
1573  {
1574  BOOL bIsMinimized;
1575  BOOL bIsActive;
1576 
1577  if (::IsWindow(TaskItem->hWnd))
1578  {
1579  bIsMinimized = ::IsIconic(TaskItem->hWnd);
1580  bIsActive = (TaskItem == m_ActiveTaskItem);
1581 
1582  TRACE("Active TaskItem %p, selected TaskItem %p\n", m_ActiveTaskItem, TaskItem);
1583  if (m_ActiveTaskItem)
1584  TRACE("Active TaskItem hWnd=%p, TaskItem hWnd %p\n", m_ActiveTaskItem->hWnd, TaskItem->hWnd);
1585 
1586  TRACE("Valid button clicked. HWND=%p, IsMinimized=%s, IsActive=%s...\n",
1587  TaskItem->hWnd, bIsMinimized ? "Yes" : "No", bIsActive ? "Yes" : "No");
1588 
1589  if (!bIsMinimized && bIsActive)
1590  {
1591  ::ShowWindowAsync(TaskItem->hWnd, SW_MINIMIZE);
1592  TRACE("Valid button clicked. App window Minimized.\n");
1593  }
1594  else
1595  {
1596  ::SwitchToThisWindow(TaskItem->hWnd, TRUE);
1597  TRACE("Valid button clicked. App window Restored.\n");
1598  }
1599  }
1600  }
1601 
1603  {
1604  /* TODO: Show task group menu */
1605  }
1606 
1608  {
1609  PTASK_ITEM TaskItem;
1610  PTASK_GROUP TaskGroup;
1611 
1612  if (m_IsGroupingEnabled)
1613  {
1614  TaskGroup = FindTaskGroupByIndex((INT) wIndex);
1615  if (TaskGroup != NULL && TaskGroup->IsCollapsed)
1616  {
1617  HandleTaskGroupClick(TaskGroup);
1618  return TRUE;
1619  }
1620  }
1621 
1622  TaskItem = FindTaskItemByIndex((INT) wIndex);
1623  if (TaskItem != NULL)
1624  {
1625  HandleTaskItemClick(TaskItem);
1626  return TRUE;
1627  }
1628 
1629  return FALSE;
1630  }
1631 
1632 
1634  {
1635  POINT pt;
1636  GetCursorPos(&pt);
1637 
1638  SetForegroundWindow(TaskItem->hWnd);
1639 
1640  ActivateTask(TaskItem->hWnd);
1641 
1642  /* Wait up to 2 seconds for the window to process the foreground notification. */
1643  DWORD_PTR resultDummy;
1644  if (!SendMessageTimeout(TaskItem->hWnd, WM_NULL, 0, 0, 0, 2000, &resultDummy))
1645  ERR("HandleTaskItemRightClick detected the window was unresponsive for 2 seconds, or was destroyed\n");
1646  if (GetForegroundWindow() != TaskItem->hWnd)
1647  ERR("HandleTaskItemRightClick detected the window did not become foreground\n");
1648 
1649  ::SendMessageW(TaskItem->hWnd, WM_POPUPSYSTEMMENU, 0, MAKELPARAM(pt.x, pt.y));
1650  }
1651 
1653  {
1654  /* TODO: Show task group right click menu */
1655  }
1656 
1658  {
1659  PTASK_ITEM TaskItem;
1660  PTASK_GROUP TaskGroup;
1661  if (m_IsGroupingEnabled)
1662  {
1663  TaskGroup = FindTaskGroupByIndex((INT) wIndex);
1664  if (TaskGroup != NULL && TaskGroup->IsCollapsed)
1665  {
1666  HandleTaskGroupRightClick(TaskGroup);
1667  return TRUE;
1668  }
1669  }
1670 
1671  TaskItem = FindTaskItemByIndex((INT) wIndex);
1672 
1673  if (TaskItem != NULL)
1674  {
1675  HandleTaskItemRightClick(TaskItem);
1676  return TRUE;
1677  }
1678 
1679  return FALSE;
1680  }
1681 
1682 
1684  {
1685  LRESULT Ret = CDRF_DODEFAULT;
1686  PTASK_GROUP TaskGroup;
1687  PTASK_ITEM TaskItem;
1688 
1689  TaskItem = FindTaskItemByIndex((INT) nmtbcd->nmcd.dwItemSpec);
1690  TaskGroup = FindTaskGroupByIndex((INT) nmtbcd->nmcd.dwItemSpec);
1691  if (TaskGroup == NULL && TaskItem != NULL)
1692  {
1693  ASSERT(TaskItem != NULL);
1694 
1695  if (TaskItem != NULL && ::IsWindow(TaskItem->hWnd))
1696  {
1697  /* Make the entire button flashing if necessary */
1698  if (nmtbcd->nmcd.uItemState & CDIS_MARKED)
1699  {
1700  Ret = TBCDRF_NOBACKGROUND;
1701  if (!m_Theme)
1702  {
1703  SelectObject(nmtbcd->nmcd.hdc, GetSysColorBrush(COLOR_HIGHLIGHT));
1704  Rectangle(nmtbcd->nmcd.hdc,
1705  nmtbcd->nmcd.rc.left,
1706  nmtbcd->nmcd.rc.top,
1707  nmtbcd->nmcd.rc.right,
1708  nmtbcd->nmcd.rc.bottom);
1709  }
1710  else
1711  {
1712  DrawThemeBackground(m_Theme, nmtbcd->nmcd.hdc, TDP_FLASHBUTTON, 0, &nmtbcd->nmcd.rc, 0);
1713  }
1714  nmtbcd->clrText = GetSysColor(COLOR_HIGHLIGHTTEXT);
1715  return Ret;
1716  }
1717  }
1718  }
1719  else if (TaskGroup != NULL)
1720  {
1721  /* FIXME: Implement painting for task groups */
1722  }
1723  return Ret;
1724  }
1725 
1727  {
1728  LRESULT Ret = 0;
1729 
1730  switch (nmh->code)
1731  {
1732  case NM_CUSTOMDRAW:
1733  {
1734  LPNMTBCUSTOMDRAW nmtbcd = (LPNMTBCUSTOMDRAW) nmh;
1735 
1736  switch (nmtbcd->nmcd.dwDrawStage)
1737  {
1738 
1739  case CDDS_ITEMPREPAINT:
1740  Ret = HandleItemPaint(nmtbcd);
1741  break;
1742 
1743  case CDDS_PREPAINT:
1744  Ret = CDRF_NOTIFYITEMDRAW;
1745  break;
1746 
1747  default:
1748  Ret = CDRF_DODEFAULT;
1749  break;
1750  }
1751  break;
1752  }
1753  }
1754 
1755  return Ret;
1756  }
1757 
1759  {
1760  HDC hdc = (HDC) wParam;
1761 
1762  if (!IsAppThemed())
1763  {
1764  bHandled = FALSE;
1765  return 0;
1766  }
1767 
1768  RECT rect;
1769  GetClientRect(&rect);
1771 
1772  return TRUE;
1773  }
1774 
1776  {
1777  SIZE szClient;
1778 
1779  szClient.cx = LOWORD(lParam);
1780  szClient.cy = HIWORD(lParam);
1781  if (m_TaskBar.m_hWnd != NULL)
1782  {
1783  m_TaskBar.SetWindowPos(NULL, 0, 0, szClient.cx, szClient.cy, SWP_NOZORDER);
1784 
1786  }
1787  return TRUE;
1788  }
1789 
1791  {
1792  LRESULT Ret = TRUE;
1793  /* We want the tray window to be draggable everywhere, so make the control
1794  appear transparent */
1795  Ret = DefWindowProc(uMsg, wParam, lParam);
1796  if (Ret != HTVSCROLL && Ret != HTHSCROLL)
1797  Ret = HTTRANSPARENT;
1798  return Ret;
1799  }
1800 
1802  {
1803  LRESULT Ret = TRUE;
1804  if (lParam != 0 && (HWND) lParam == m_TaskBar.m_hWnd)
1805  {
1807  }
1808  return Ret;
1809  }
1810 
1812  {
1813  LRESULT Ret = TRUE;
1814  const NMHDR *nmh = (const NMHDR *) lParam;
1815 
1816  if (nmh->hwndFrom == m_TaskBar.m_hWnd)
1817  {
1818  Ret = HandleToolbarNotification(nmh);
1819  }
1820  return Ret;
1821  }
1822 
1824  {
1825  /* Update the button spacing */
1826  m_TaskBar.UpdateTbButtonSpacing(m_Tray->IsHorizontal(), m_Theme != NULL);
1827  return TRUE;
1828  }
1829 
1831  {
1832  TaskbarSettings* newSettings = (TaskbarSettings*)lParam;
1833  if (newSettings->bGroupButtons != g_TaskbarSettings.bGroupButtons)
1834  {
1837 
1838  /* Collapse or expand groups if necessary */
1841  }
1842 
1843  return 0;
1844  }
1845 
1847  {
1848  LRESULT Ret = 0;
1849  INT_PTR iBtn = -1;
1850 
1851  if (m_TaskBar.m_hWnd != NULL)
1852  {
1853  POINT pt;
1854 
1855  pt.x = GET_X_LPARAM(lParam);
1856  pt.y = GET_Y_LPARAM(lParam);
1857 
1858  ::ScreenToClient(m_TaskBar.m_hWnd, &pt);
1859 
1860  iBtn = m_TaskBar.HitTest(&pt);
1861  if (iBtn >= 0)
1862  {
1863  HandleButtonRightClick(iBtn);
1864  }
1865  }
1866  if (iBtn < 0)
1867  {
1868  /* Not on a taskbar button, so forward message to tray */
1869  Ret = SendMessage(m_Tray->GetHWND(), uMsg, wParam, lParam);
1870  }
1871  return Ret;
1872  }
1873 
1875  {
1876  PTASK_ITEM TaskItem = FindTaskItem((HWND) wParam);
1877  if (TaskItem)
1878  {
1879  RECT* prcMinRect = (RECT*) lParam;
1880  RECT rcItem, rcToolbar;
1881  m_TaskBar.GetItemRect(TaskItem->Index, &rcItem);
1882  m_TaskBar.GetWindowRect(&rcToolbar);
1883 
1884  OffsetRect(&rcItem, rcToolbar.left, rcToolbar.top);
1885 
1886  *prcMinRect = rcItem;
1887  return TRUE;
1888  }
1889  return FALSE;
1890  }
1891 
1893  {
1894  return MA_NOACTIVATE;
1895  }
1896 
1898  {
1899 #if DUMP_TASKS != 0
1900  switch (wParam)
1901  {
1902  case 1:
1903  DumpTasks();
1904  break;
1905  }
1906 #endif
1907  return TRUE;
1908  }
1909 
1911  {
1912  return m_TaskBar.SendMessageW(uMsg, wParam, lParam);
1913  }
1914 
1916  {
1917  if (wParam == SPI_SETNONCLIENTMETRICS)
1918  {
1919  /* Don't update the font, this will be done when we get a WM_SETFONT from our parent */
1921  }
1922 
1923  return 0;
1924  }
1925 
1927  {
1929  if (cpData->dwData == m_uHardErrorMsg)
1930  {
1931  /* A hard error balloon message */
1933  ERR("Got balloon data 0x%x, 0x%x, '%S', '%S'\n", pData->Status, pData->dwType, (WCHAR*)((ULONG_PTR)pData + pData->TitleOffset), (WCHAR*)((ULONG_PTR)pData + pData->MessageOffset));
1934  if (pData->cbHeaderSize == sizeof(BALLOON_HARD_ERROR_DATA))
1936  return TRUE;
1937  }
1938 
1939  return FALSE;
1940  }
1941 
1942  HRESULT Initialize(IN HWND hWndParent, IN OUT ITrayWindow *tray)
1943  {
1944  m_Tray = tray;
1947  if (!m_hWnd)
1948  return E_FAIL;
1949  return S_OK;
1950  }
1951 
1953  {
1954  if (!phwnd)
1955  return E_INVALIDARG;
1956  *phwnd = m_hWnd;
1957  return S_OK;
1958  }
1959 
1961  {
1962  return E_NOTIMPL;
1963  }
1964 
1966 
1968  MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
1986  END_MSG_MAP()
1987 
1989 
1993  END_COM_MAP()
1994 };
1995 
1997 {
1998  return ShellObjectCreatorInit<CTaskSwitchWnd>(hWndParent, Tray, riid, ppv);
1999 }
WORD m_AllocatedTaskItems
Definition: taskswnd.cpp:307
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
LRESULT OnKludgeItemRect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1874
#define TBIF_COMMAND
Definition: commctrl.h:1220
#define WM_NULL
Definition: winuser.h:1589
HWND Create(HWND hWndParent, DWORD dwStyles=0, DWORD dwExStyles=0)
Definition: rosctrls.h:254
VOID HandleTaskGroupRightClick(IN OUT PTASK_GROUP TaskGroup)
Definition: taskswnd.cpp:1652
VOID DeleteTaskItem(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:982
INT WINAPI ImageList_ReplaceIcon(HIMAGELIST himl, INT nIndex, HICON hIcon)
Definition: imagelist.c:2779
#define BTNS_NOPREFIX
Definition: commctrl.h:1001
LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1892
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define IN
Definition: typedefs.h:39
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1801
static HICON
Definition: imagelist.c:84
#define HTHSCROLL
Definition: winuser.h:2456
BOOL WINAPI RegisterShellHook(HWND hWnd, DWORD dwType)
Definition: shellord.c:311
VOID HandleTaskItemClick(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:1572
#define HTTRANSPARENT
Definition: winuser.h:2448
DWORD SetRedraw(BOOL bEnable)
Definition: rosctrls.h:406
#define REFIID
Definition: guiddef.h:118
HRESULT Initialize(IN HWND hWndParent, IN OUT ITrayWindow *tray)
Definition: taskswnd.cpp:1942
#define CloseHandle
Definition: compat.h:598
#define COLOR_HIGHLIGHT
Definition: winuser.h:916
#define LR_SHARED
Definition: winuser.h:1090
#define IMAGE_ICON
Definition: winuser.h:212
#define WM_CONTEXTMENU
Definition: richedit.h:64
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:586
#define DWORD_PTR
Definition: treelist.c:76
HRESULT hr
Definition: shlfolder.c:183
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
WORD m_TaskItemCount
Definition: taskswnd.cpp:306
#define GCL_HICONSM
Definition: winuser.h:662
LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1790
PTASK_GROUP FindTaskGroupByIndex(IN INT Index)
Definition: taskswnd.cpp:1072
INT HitTest(PPOINT ppt)
Definition: rosctrls.h:428
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define TRUE
Definition: types.h:120
#define pt(x, y)
Definition: drawing.c:79
#define SM_CXMINIMIZED
Definition: winuser.h:1010
REFIID riid
Definition: precomp.h:44
BOOL ShowWindowAsync(int nCmdShow)
Definition: atlwin.h:1271
#define TBIF_BYINDEX
Definition: commctrl.h:1222
#define TBSTYLE_TRANSPARENT
Definition: commctrl.h:992
HWND Create(HWND hWndParent, _U_RECT rect=NULL, LPCTSTR szWindowName=NULL, DWORD dwStyle=0, DWORD dwExStyle=0, _U_MENUorID MenuOrID=0U, LPVOID lpCreateParam=NULL)
Definition: atlwin.h:1637
#define MAX_TASKS_COUNT
Definition: taskswnd.cpp:29
PTASK_ITEM m_ActiveTaskItem
Definition: taskswnd.cpp:311
BOOL Initialize(HWND hWndParent)
Definition: taskswnd.cpp:282
#define WM_KLUDGEMINRECT
Definition: undocuser.h:39
#define WARN(fmt,...)
Definition: debug.h:112
HRESULT WINAPI GetWindow(HWND *phwnd)
Definition: taskswnd.cpp:1952
#define MAKELPARAM(l, h)
Definition: winuser.h:3983
#define HSHELL_FLASH
Definition: winuser.h:1262
UINT ui
Definition: oleauto.h:49
BOOL m_IsGroupingEnabled
Definition: taskswnd.cpp:319
#define INT
Definition: polytest.cpp:20
DWORD dwMask
Definition: commctrl.h:1239
static HDC
Definition: imagelist.c:92
GLintptr offset
Definition: glext.h:5920
#define CALLBACK
Definition: compat.h:35
#define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd)
Definition: atlwin.h:1886
#define WM_SETREDRAW
Definition: winuser.h:1598
BOOL IsWindow() const
Definition: atlwin.h:879
CStringW m_Title
Definition: taskswnd.cpp:110
LRESULT OnShellHook(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1490
HWND hWnd
Definition: settings.c:17
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define WM_QUIT
Definition: winuser.h:1605
LONG top
Definition: windef.h:307
#define HSHELL_WINDOWCREATED
Definition: winuser.h:1240
BOOL HandleAppCommand(IN WPARAM wParam, IN LPARAM lParam)
Definition: taskswnd.cpp:1469
#define GET_X_LPARAM(lp)
Definition: windowsx.h:274
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1499
DWORD dwFlags
Definition: taskswnd.cpp:70
#define CDDS_ITEMPREPAINT
Definition: commctrl.h:281
static HTHEME(WINAPI *pOpenThemeDataEx)(HWND
#define ZeroMemory
Definition: winbase.h:1648
DWORD DeleteButton(int index)
Definition: rosctrls.h:345
#define GWL_EXSTYLE
Definition: winuser.h:845
#define SM_CXEDGE
Definition: winuser.h:998
#define DECLARE_NOT_AGGREGATABLE(x)
Definition: atlcom.h:611
#define SM_CYSMICON
Definition: winuser.h:1003
DWORD dwFlags
Definition: taskswnd.cpp:88
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1457
#define WM_NCHITTEST
Definition: winuser.h:1668
BOOL CALLBACK EnumWindowsProc(IN HWND hWnd)
Definition: taskswnd.cpp:1376
VOID RedrawTaskItem(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:1205
UINT_PTR WPARAM
Definition: windef.h:207
BOOL FlashTask(IN HWND hWnd)
Definition: taskswnd.cpp:1190
LRESULT OnSetFont(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1910
#define WS_CHILD
Definition: pedump.c:617
uint16_t * PWCHAR
Definition: typedefs.h:56
LONG left
Definition: windef.h:306
#define SWP_NOZORDER
Definition: winuser.h:1232
BOOL DeleteTaskItemButton(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:729
int32_t INT_PTR
Definition: typedefs.h:64
#define MoveMemory
Definition: winbase.h:1645
VOID RemoveIcon(IN PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:559
BYTE fsStyle
Definition: commctrl.h:948
LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1915
#define WS_CLIPCHILDREN
Definition: pedump.c:619
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2635
struct _TASK_GROUP * PTASK_GROUP
LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1846
LONG right
Definition: windef.h:308
#define DT_NOPREFIX
Definition: winuser.h:537
void StartThread(PBALLOON_HARD_ERROR_DATA pData)
Definition: taskswnd.cpp:178
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
#define TASK_ITEM_ARRAY_ALLOC
Definition: taskswnd.cpp:30
HRESULT WINAPI DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
Definition: draw.c:128
#define WS_EX_TOOLWINDOW
Definition: winuser.h:404
PTASK_ITEM FindTaskItem(IN HWND hWnd)
Definition: taskswnd.cpp:854
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetSysColor(_In_ int)
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: atlwin.h:1522
#define TBIF_IMAGE
Definition: commctrl.h:1215
struct _TASK_ITEM TASK_ITEM
PTASK_ITEM AllocTaskItem()
Definition: taskswnd.cpp:912
#define SMTO_ABORTIFHUNG
Definition: winuser.h:1209
#define WM_SETTINGCHANGE
Definition: winuser.h:1611
BOOL HandleButtonClick(IN WORD wIndex)
Definition: taskswnd.cpp:1607
LRESULT OnNcHitTestToolbar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:257
INT UpdateTaskItemButton(IN PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:513
#define ICON_SMALL
Definition: tnclass.cpp:48
#define ILC_COLOR32
Definition: commctrl.h:354
uint32_t ULONG_PTR
Definition: typedefs.h:65
PTASK_ITEM m_TaskItems
Definition: taskswnd.cpp:310
#define CDIS_MARKED
Definition: commctrl.h:294
VOID CheckActivateTaskItem(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:997
LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1758
struct _TASK_ITEM * PTASK_ITEM
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL ActivateTask(IN HWND hWnd)
Definition: taskswnd.cpp:1129
#define CCS_NODIVIDER
Definition: commctrl.h:2244
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG_PTR dwData
Definition: winuser.h:2976
WORD m_ButtonCount
Definition: taskswnd.cpp:315
BOOL ActivateTaskItem(IN OUT PTASK_ITEM TaskItem OPTIONAL)
Definition: taskswnd.cpp:1117
#define COLOR_3DFACE
Definition: winuser.h:919
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:804
#define FALSE
Definition: types.h:117
struct _BALLOON_HARD_ERROR_DATA * PBALLOON_HARD_ERROR_DATA
VOID UpdateIndexesAfter(IN INT iIndex, BOOL bInserted)
Definition: taskswnd.cpp:407
#define TWM_SETTINGSCHANGED
Definition: precomp.h:132
BOOL HandleButtonRightClick(IN WORD wIndex)
Definition: taskswnd.cpp:1657
unsigned int BOOL
Definition: ntddk_ex.h:94
#define WM_POPUPSYSTEMMENU
Definition: undocuser.h:59
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2172
long LONG
Definition: pedump.c:60
BOOL WINAPI IsAppThemed(void)
Definition: system.c:596
BOOL RedrawTask(IN HWND hWnd)
Definition: taskswnd.cpp:1230
UINT m_ButtonsPerLine
Definition: taskswnd.cpp:314
struct _TASK_GROUP * Next
Definition: taskswnd.cpp:63
VOID DeleteAllTasks()
Definition: taskswnd.cpp:1170
UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse, void(CALLBACK *lpfnTimer)(HWND, UINT, UINT_PTR, DWORD)=NULL)
Definition: atlwin.h:1190
#define BTNS_CHECK
Definition: commctrl.h:996
PTASK_GROUP Group
Definition: taskswnd.cpp:82
BOOL GetClientRect(LPRECT lpRect) const
Definition: atlwin.h:507
HRESULT WINAPI SetWindowTheme(_In_ HWND hwnd, _In_ LPCWSTR pszSubAppName, _In_ LPCWSTR pszSubIdList)
Definition: uxthemesupp.c:69
#define TBMF_BUTTONSPACING
Definition: commctrl.h:1285
BOOL WINAPI SHFindFiles(PCIDLIST_ABSOLUTE pidlFolder, PCIDLIST_ABSOLUTE pidlSaveFile)
Definition: shellord.c:2234
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
VOID HandleTaskGroupClick(IN OUT PTASK_GROUP TaskGroup)
Definition: taskswnd.cpp:1602
DWORD GetMetrics(TBMETRICS *tbm)
Definition: rosctrls.h:391
DWORD WINAPI GetWindowThreadProcessId(HWND, PDWORD)
DWORD RenderFlashed
Definition: taskswnd.cpp:97
#define E_INVALIDARG
Definition: ddrawi.h:101
virtual ~CTaskSwitchWnd()
Definition: taskswnd.cpp:345
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
smooth NULL
Definition: ftsmooth.c:416
TaskbarSettings g_TaskbarSettings
Definition: settings.cpp:23
LONG cx
Definition: windef.h:334
LONG_PTR LPARAM
Definition: windef.h:208
#define CCS_TOP
Definition: commctrl.h:2238
#define SM_CYEDGE
Definition: winuser.h:999
#define TWM_OPENSTARTMENU
Definition: precomp.h:131
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1775
#define BTNS_SHOWTEXT
Definition: commctrl.h:1002
#define CDRF_NOTIFYITEMDRAW
Definition: commctrl.h:271
PTASK_ITEM FindLastTaskItemOfGroup(IN PTASK_GROUP TaskGroup OPTIONAL, IN PTASK_ITEM NewTaskItem OPTIONAL)
Definition: taskswnd.cpp:587
#define WM_MOUSEACTIVATE
Definition: winuser.h:1619
GLuint index
Definition: glext.h:6031
DWORD dwTaskCount
Definition: taskswnd.cpp:65
HIMAGELIST SetImageList(HIMAGELIST himl)
Definition: rosctrls.h:422
INT_PTR iString
Definition: commctrl.h:955
HTHEME m_Theme
Definition: taskswnd.cpp:313
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:917
VOID RemoveTaskFromTaskGroup(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:808
DWORD GetItemRect(int index, LPRECT prcItem)
Definition: rosctrls.h:401
DWORD_PTR dwData
Definition: commctrl.h:954
#define WM_DESTROY
Definition: winuser.h:1591
int iBitmap
Definition: commctrl.h:945
INT IconIndex
Definition: taskswnd.cpp:84
BOOL RefreshWindowList()
Definition: taskswnd.cpp:1404
DWORD IsFlashing
Definition: taskswnd.cpp:93
static DWORD CALLBACK s_HardErrorThreadProc(IN OUT LPVOID lpParameter)
Definition: taskswnd.cpp:168
HRESULT WINAPI DrawThemeParentBackground(HWND hwnd, HDC hdc, RECT *prc)
Definition: draw.c:72
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:541
BOOL DeleteTask(IN HWND hWnd)
Definition: taskswnd.cpp:1153
#define TBIF_STATE
Definition: commctrl.h:1217
#define WM_COPYDATA
Definition: winuser.h:1646
int cyButtonSpacing
Definition: commctrl.h:1295
#define TRACE(s)
Definition: solgame.cpp:4
NMCUSTOMDRAW nmcd
Definition: commctrl.h:1013
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define LR_DEFAULTSIZE
Definition: winuser.h:1084
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WM_SIZE
Definition: winuser.h:1593
LONG HRESULT
Definition: typedefs.h:79
#define SendMessageTimeout
Definition: winuser.h:5820
#define END_MSG_MAP()
Definition: atlwin.h:1799
#define _countof(array)
Definition: sndvol32.h:68
#define WM_TIMER
Definition: winuser.h:1724
UINT m_uHardErrorMsg
Definition: taskswnd.cpp:324
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define PostThreadMessage
Definition: winuser.h:5808
#define WINAPI
Definition: msvc.h:6
HRESULT WINAPI ContextSensitiveHelp(BOOL fEnterMode)
Definition: taskswnd.cpp:1960
BOOL bGroupButtons
Definition: precomp.h:206
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
static const UCHAR Index[8]
Definition: usbohci.c:18
CTaskToolbar m_TaskBar
Definition: taskswnd.cpp:300
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC, _In_ LPARAM)
unsigned short WORD
Definition: ntddk_ex.h:93
HICON GetWndIcon(HWND hwnd)
Definition: taskswnd.cpp:488
int WINAPI GetSystemMetrics(_In_ int)
BOOL SetButtonCommandId(IN INT iButtonIndex, IN INT iCommandId)
Definition: taskswnd.cpp:246
unsigned long DWORD
Definition: ntddk_ex.h:95
LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1811
ULONG_PTR * PDWORD_PTR
Definition: basetsd.h:184
#define TBSTYLE_TOOLTIPS
Definition: commctrl.h:985
#define CDRF_DODEFAULT
Definition: commctrl.h:264
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
Definition: system.c:835
#define SW_MINIMIZE
Definition: winuser.h:770
const WCHAR szRunningApps[]
Definition: taskswnd.cpp:33
DWORD SetMetrics(TBMETRICS *tbm)
Definition: rosctrls.h:396
#define WAIT_TIMEOUT
Definition: dderror.h:14
struct _TASK_GROUP TASK_GROUP
#define SM_CXSMICON
Definition: winuser.h:1002
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define CCS_NORESIZE
Definition: commctrl.h:2241
PTASK_GROUP m_TaskGroups
Definition: taskswnd.cpp:309
int ret
#define NM_CUSTOMDRAW
Definition: commctrl.h:137
BOOL WINAPI ImageList_Remove(HIMAGELIST himl, INT i)
Definition: imagelist.c:2568
#define TBSTATE_MARKED
Definition: commctrl.h:975
#define CDDS_PREPAINT
Definition: commctrl.h:276
BOOL ScreenToClient(LPPOINT lpPoint) const
Definition: atlwin.h:1024
static const WCHAR L[]
Definition: oid.c:1250
PTASK_ITEM FindOtherTaskItem(IN HWND hWnd)
Definition: taskswnd.cpp:871
HDC hdc
Definition: main.c:9
VOID BeginUpdate()
Definition: taskswnd.cpp:235
DWORD SetDrawTextFlags(DWORD useBits, DWORD bitState)
Definition: rosctrls.h:309
struct tagCOPYDATASTRUCT * PCOPYDATASTRUCT
int idCommand
Definition: commctrl.h:946
LPVOID lpParameter
Definition: kernel32.h:241
INT AddTaskItemButton(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:669
#define ILC_MASK
Definition: commctrl.h:347
LRESULT OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1926
LONG GetWindowLong(int nIndex) const
Definition: atlwin.h:738
UINT cbSize
Definition: commctrl.h:1288
LRESULT HandleToolbarNotification(IN const NMHDR *nmh)
Definition: taskswnd.cpp:1726
HWND m_hWnd
Definition: atlwin.h:268
#define CS_DBLCLKS
Definition: winuser.h:646
DWORD dwProcessId
Definition: taskswnd.cpp:66
#define WS_TABSTOP
Definition: pedump.c:634
#define WM_COMMAND
Definition: winuser.h:1722
#define MA_NOACTIVATE
Definition: winuser.h:2478
const WCHAR szTaskSwitchWndClass[]
Definition: taskswnd.cpp:32
HWND hwndFrom
Definition: winuser.h:3132
uint32_t DWORD_PTR
Definition: typedefs.h:65
DWORD IsCollapsed
Definition: taskswnd.cpp:74
BOOL AddTask(IN HWND hWnd)
Definition: taskswnd.cpp:1088
#define GetClassLongPtr
Definition: winuser.h:5757
HIMAGELIST m_ImageList
Definition: taskswnd.cpp:317
#define InterlockedExchange
Definition: armddk.h:54
BOOL IsIconic() const
Definition: atlwin.h:864
#define HSHELL_WINDOWDESTROYED
Definition: winuser.h:1241
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
BOOL m_IsDestroying
Definition: taskswnd.cpp:320
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:169
#define ERR(fmt,...)
Definition: debug.h:110
int cxBarPad
Definition: commctrl.h:1292
ULONG_PTR SIZE_T
Definition: typedefs.h:80
LRESULT OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1830
VOID FreeTaskItem(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:964
#define GCL_HICON
Definition: winuser.h:661
UINT WINAPI RegisterWindowMessageW(_In_ LPCWSTR)
#define TSWM_UPDATETASKBARPOS
Definition: precomp.h:347
#define S_OK
Definition: intsafe.h:51
HRESULT ThreadProc()
Definition: taskswnd.cpp:136
HRESULT CTaskSwitchWnd_CreateInstance(IN HWND hWndParent, IN OUT ITrayWindow *Tray, REFIID riid, void **ppv)
Definition: taskswnd.cpp:1996
#define TBMF_BARPAD
Definition: commctrl.h:1284
struct _NMTBCUSTOMDRAW * LPNMTBCUSTOMDRAW
#define TBSTATE_CHECKED
Definition: commctrl.h:968
INT CalculateTaskItemNewButtonIndex(IN PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:625
BOOL PostMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0)
Definition: atlwin.h:976
VOID HandleTaskItemRightClick(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:1633
INT WINAPI InternalGetWindowText(_In_ HWND hWnd, _Out_writes_to_(cchMaxCount, return+1) LPWSTR pString, _In_ int cchMaxCount)
int cxButtonSpacing
Definition: commctrl.h:1294
HICON hIcon
Definition: msconfig.c:44
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:561
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HeapReAlloc
Definition: compat.h:593
LRESULT HandleItemPaint(IN OUT NMTBCUSTOMDRAW *nmtbcd)
Definition: taskswnd.cpp:1683
DWORD InsertButton(int insertAt, TBBUTTON *btn)
Definition: rosctrls.h:335
INT UpdateTaskGroupButton(IN PTASK_GROUP TaskGroup)
Definition: taskswnd.cpp:470
#define E_NOTIMPL
Definition: ddrawi.h:99
LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1411
#define TBCDRF_NOBACKGROUND
Definition: commctrl.h:1036
#define TBIF_TEXT
Definition: commctrl.h:1216
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1426
UINT m_ShellHookMsg
Definition: taskswnd.cpp:304
unsigned int UINT
Definition: ndis.h:50
#define GW_OWNER
Definition: winuser.h:761
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
INT UpdateTbButtonSpacing(IN BOOL bHorizontal, IN BOOL bThemed, IN UINT uiRows=0, IN UINT uiBtnsPerLine=0)
Definition: taskswnd.cpp:203
PTASK_ITEM FindTaskItemByIndex(IN INT Index)
Definition: taskswnd.cpp:1055
#define WM_SETFONT
Definition: winuser.h:1632
VOID FlashTaskItem(IN OUT PTASK_ITEM TaskItem)
Definition: taskswnd.cpp:1184
#define BEGIN_MSG_MAP(theClass)
Definition: atlwin.h:1780
#define GET_Y_LPARAM(lp)
Definition: windowsx.h:275
CComPtr< ITrayWindow > m_Tray
Definition: taskswnd.cpp:302
#define HTVSCROLL
Definition: winuser.h:2457
#define DECLARE_PROTECT_FINAL_CONSTRUCT()
Definition: atlcom.h:639
WCHAR windowText[1024]
Definition: appswitch.c:49
#define MESSAGE_HANDLER(msg, func)
Definition: atlwin.h:1808
#define HSHELL_RUDEAPPACTIVATED
Definition: winuser.h:1263
#define msg(x)
Definition: auth_time.c:54
_Out_opt_ int * cx
Definition: commctrl.h:581
VOID ExpandTaskGroup(IN PTASK_GROUP TaskGroup)
Definition: taskswnd.cpp:479
#define OUT
Definition: typedefs.h:40
#define TBSTATE_ENABLED
Definition: commctrl.h:970
#define WM_CREATE
Definition: winuser.h:1590
#define SM_CXSIZE
Definition: winuser.h:981
LRESULT OnUpdateTaskbarPos(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1823
BOOL WINAPI ImageList_GetIconSize(HIMAGELIST himl, INT *cx, INT *cy)
Definition: imagelist.c:2037
#define HSHELL_ACTIVATESHELLWINDOW
Definition: winuser.h:1242
const GUID IID_IOleWindow
DWORD dwMask
Definition: commctrl.h:1289
#define TBSTYLE_WRAPABLE
Definition: commctrl.h:986
#define HIWORD(l)
Definition: typedefs.h:247
LRESULT SendMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0)
Definition: atlwin.h:1048
#define TBSTATE_WRAP
Definition: commctrl.h:973
static BOOL CALLBACK s_EnumWindowsProc(IN HWND hWnd, IN LPARAM lParam)
Definition: taskswnd.cpp:1397
BOOL WINAPI IsThemeActive(void)
Definition: system.c:606
DWORD SetButtonInfo(int cmdId, TBBUTTONINFO *info)
Definition: rosctrls.h:355
BOOL WINAPI SetForegroundWindow(_In_ HWND)
LONG bottom
Definition: windef.h:309
#define ULONG_PTR
Definition: config.h:101
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define WS_EX_APPWINDOW
Definition: winuser.h:383
#define END_COM_MAP()
Definition: atlcom.h:552
#define WM_ERASEBKGND
Definition: winuser.h:1607
#define TBIF_SIZE
Definition: commctrl.h:1221
VOID EndUpdate()
Definition: taskswnd.cpp:240
BYTE fsState
Definition: commctrl.h:947
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
LONG_PTR LRESULT
Definition: windef.h:209
BOOL WINAPI ImageList_SetIconSize(HIMAGELIST himl, INT cx, INT cy)
Definition: imagelist.c:3038
int cyBarPad
Definition: commctrl.h:1293
#define OIC_SAMPLE
Definition: winuser.h:1148
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: taskswnd.cpp:1897
#define WS_VISIBLE
Definition: pedump.c:620
HBRUSH WINAPI GetSysColorBrush(_In_ int)
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:230
LONG cy
Definition: windef.h:335
#define TBSTATE_ELLIPSES
Definition: commctrl.h:974
#define TBSTYLE_LIST
Definition: commctrl.h:989
LPARAM lParam
Definition: combotst.c:139
CHardErrorThread m_HardErrorThread
Definition: taskswnd.cpp:325
#define LOWORD(l)
Definition: pedump.c:82
VOID WINAPI SwitchToThisWindow(HWND hwnd, BOOL fAltTab)
Definition: window.c:82
INT GetWndTextFromTaskItem(IN PTASK_ITEM TaskItem, LPWSTR szBuf, DWORD cchBuf)
Definition: taskswnd.cpp:347
#define HeapFree(x, y, z)
Definition: compat.h:594
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
Definition: system.c:950
#define WM_NOTIFY
Definition: richedit.h:61
PTASK_GROUP AddToTaskGroup(IN HWND hWnd)
Definition: taskswnd.cpp:764
VOID UpdateButtonsSize(IN BOOL bRedrawDisabled)
Definition: taskswnd.cpp:1244
BOOL IsWindowVisible() const
Definition: atlwin.h:890
#define TBBUTTONINFO
Definition: commctrl.h:1250
#define ICON_BIG
Definition: tnclass.cpp:51
CStringW m_Text
Definition: taskswnd.cpp:111
HANDLE hProcessHeap
Definition: kbswitch.c:25
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
HWND hWnd
Definition: taskswnd.cpp:81