📄 taskswnd.c
字号:
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <precomp.h>
/* By default we don't use DrawCaptionTemp() because it causes some minimal
drawing glitches with the toolbar custom painting code */
#define TASK_USE_DRAWCAPTIONTEMP 1
/* Set DUMP_TASKS to 1 to enable a dump of the tasks and task groups every
5 seconds */
#define DUMP_TASKS 0
static const TCHAR szTaskSwitchWndClass[] = TEXT("MSTaskSwWClass");
static const TCHAR szRunningApps[] = TEXT("Running Applications");
typedef struct _TASK_GROUP
{
/* We have to use a linked list instead of an array so we don't have to
update all pointers to groups in the task item array when removing
groups. */
struct _TASK_GROUP *Next;
DWORD dwTaskCount;
DWORD dwProcessId;
INT Index;
union
{
DWORD dwFlags;
struct
{
#if TASK_USE_DRAWCAPTIONTEMP != 0
/* DisplayTooltip is TRUE when the group button text didn't fit into
the button. */
DWORD DisplayTooltip : 1;
#endif
DWORD IsCollapsed : 1;
};
};
} TASK_GROUP, *PTASK_GROUP;
typedef struct _TASK_ITEM
{
HWND hWnd;
PTASK_GROUP Group;
INT Index;
#if !(TASK_USE_DRAWCAPTIONTEMP != 0)
INT IconIndex;
#endif
union
{
DWORD dwFlags;
struct
{
#if TASK_USE_DRAWCAPTIONTEMP != 0
/* DisplayTooltip is TRUE when the window text didn't fit into the
button. */
DWORD DisplayTooltip : 1;
#endif
/* IsFlashing is TRUE when the task bar item should be flashing. */
DWORD IsFlashing : 1;
/* RenderFlashed is only TRUE if the task bar item should be
drawn with a flash. */
DWORD RenderFlashed : 1;
};
};
} TASK_ITEM, *PTASK_ITEM;
#define TASK_ITEM_ARRAY_ALLOC 64
typedef struct _TASK_SWITCH_WND
{
HWND hWnd;
HWND hWndNotify;
UINT ShellHookMsg;
ITrayWindow *Tray;
PTASK_GROUP TaskGroups;
WORD TaskItemCount;
WORD AllocatedTaskItems;
PTASK_ITEM TaskItems;
PTASK_ITEM ActiveTaskItem;
HWND hWndToolbar;
UINT TbButtonsPerLine;
WORD ToolbarBtnCount;
union
{
DWORD dwFlags;
struct
{
DWORD IsGroupingEnabled : 1;
DWORD IsDestroying : 1;
DWORD IsToolbarSubclassed : 1;
};
};
SIZE ButtonSize;
TCHAR szBuf[255];
} TASK_SWITCH_WND, *PTASK_SWITCH_WND;
#define TSW_TOOLBAR_SUBCLASS_ID 1
#define MAX_TASKS_COUNT (0x7FFF)
#define MAKE_TASKITEM_PTR(ti) ((DWORD_PTR)ti)
#define MAKE_TASKGROUP_PTR(tg) (((DWORD_PTR)tg) | 1)
#define IS_TASKGROUP_PTR(p) ((((DWORD_PTR)p) & 1) != 0)
#define GET_TASKITEM_PTR(lp) ((PTASK_ITEM)(((DWORD_PTR)lp) & ~1))
#define GET_TASKGROUP_PTR(lp) ((PTASK_GROUP)(((DWORD_PTR)lp) & ~1))
#define MAKE_TASKITEM_CMD_ID(id) ((INT)(id))
#define MAKE_TASKGROUP_CMD_ID(id) ((INT)(id) | (1 << 15))
#define IS_TASKGROUP_CMD_ID(id) ((((INT)(id)) & (1 << 15)) != 0)
#define GET_INDEX_FROM_CMD_ID(id) ((INT)(id) & MAX_TASKS_COUNT)
static VOID TaskSwitchWnd_UpdateButtonsSize(IN OUT PTASK_SWITCH_WND This,
IN BOOL bRedrawDisabled);
#if TASK_USE_DRAWCAPTIONTEMP != 0
#define TaskSwitchWnd_GetWndTextFromTaskItem(a,b) NULL
#else /* !TASK_USE_DRAWCAPTIONTEMP */
static LPTSTR
TaskSwitchWnd_GetWndTextFromTaskItem(IN OUT PTASK_SWITCH_WND This,
IN PTASK_ITEM TaskItem)
{
/* Get the window text without sending a message so we don't hang if an
application isn't responding! */
if (InternalGetWindowText(TaskItem->hWnd,
This->szBuf,
sizeof(This->szBuf) / sizeof(This->szBuf[0])) > 0)
{
return This->szBuf;
}
return NULL;
}
#endif
#if DUMP_TASKS != 0
static VOID
TaskSwitchWnd_DumpTasks(IN OUT PTASK_SWITCH_WND This)
{
PTASK_GROUP CurrentGroup;
PTASK_ITEM CurrentTaskItem, LastTaskItem;
DbgPrint("Tasks dump:\n");
if (This->IsGroupingEnabled)
{
CurrentGroup = This->TaskGroups;
while (CurrentGroup != NULL)
{
DbgPrint("- Group PID: 0x%p Tasks: %d Index: %d\n", CurrentGroup->dwProcessId, CurrentGroup->dwTaskCount, CurrentGroup->Index);
CurrentTaskItem = This->TaskItems;
LastTaskItem = CurrentTaskItem + This->TaskItemCount;
while (CurrentTaskItem != LastTaskItem)
{
if (CurrentTaskItem->Group == CurrentGroup)
{
DbgPrint(" + Task hwnd: 0x%p Index: %d\n", CurrentTaskItem->hWnd, CurrentTaskItem->Index);
}
CurrentTaskItem++;
}
CurrentGroup = CurrentGroup->Next;
}
CurrentTaskItem = This->TaskItems;
LastTaskItem = CurrentTaskItem + This->TaskItemCount;
while (CurrentTaskItem != LastTaskItem)
{
if (CurrentTaskItem->Group == NULL)
{
DbgPrint("- Task hwnd: 0x%p Index: %d\n", CurrentTaskItem->hWnd, CurrentTaskItem->Index);
}
CurrentTaskItem++;
}
}
else
{
CurrentTaskItem = This->TaskItems;
LastTaskItem = CurrentTaskItem + This->TaskItemCount;
while (CurrentTaskItem != LastTaskItem)
{
DbgPrint("- Task hwnd: 0x%p Index: %d\n", CurrentTaskItem->hWnd, CurrentTaskItem->Index);
CurrentTaskItem++;
}
}
}
#endif
static VOID
TaskSwitchWnd_BeginUpdate(IN OUT PTASK_SWITCH_WND This)
{
SendMessage(This->hWndToolbar,
WM_SETREDRAW,
FALSE,
0);
}
static VOID
TaskSwitchWnd_EndUpdate(IN OUT PTASK_SWITCH_WND This)
{
SendMessage(This->hWndToolbar,
WM_SETREDRAW,
TRUE,
0);
InvalidateRect(This->hWndToolbar,
NULL,
TRUE);
}
static BOOL
TaskSwitchWnd_SetToolbarButtonCommandId(IN OUT PTASK_SWITCH_WND This,
IN INT iButtonIndex,
IN INT iCommandId)
{
TBBUTTONINFO tbbi;
tbbi.cbSize = sizeof(tbbi);
tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
tbbi.idCommand = iCommandId;
return SendMessage(This->hWndToolbar,
TB_SETBUTTONINFO,
(WPARAM)iButtonIndex,
(LPARAM)&tbbi) != 0;
}
static VOID
TaskSwitchWnd_UpdateIndexesAfterButtonInserted(IN OUT PTASK_SWITCH_WND This,
IN INT iIndex)
{
PTASK_GROUP CurrentGroup;
PTASK_ITEM CurrentTaskItem, LastTaskItem;
INT NewIndex;
if (This->IsGroupingEnabled)
{
/* Update all affected groups */
CurrentGroup = This->TaskGroups;
while (CurrentGroup != NULL)
{
if (CurrentGroup->IsCollapsed &&
CurrentGroup->Index >= iIndex)
{
/* Update the toolbar buttons */
NewIndex = CurrentGroup->Index + 1;
if (TaskSwitchWnd_SetToolbarButtonCommandId(This,
CurrentGroup->Index + 1,
MAKE_TASKGROUP_CMD_ID(NewIndex)))
{
CurrentGroup->Index = NewIndex;
}
else
CurrentGroup->Index = -1;
}
CurrentGroup = CurrentGroup->Next;
}
}
/* Update all affected task items */
CurrentTaskItem = This->TaskItems;
LastTaskItem = CurrentTaskItem + This->TaskItemCount;
while (CurrentTaskItem != LastTaskItem)
{
CurrentGroup = CurrentTaskItem->Group;
if (CurrentGroup != NULL)
{
if (!CurrentGroup->IsCollapsed &&
CurrentTaskItem->Index >= iIndex)
{
goto UpdateTaskItemBtn;
}
}
else if (CurrentTaskItem->Index >= iIndex)
{
UpdateTaskItemBtn:
/* Update the toolbar buttons */
NewIndex = CurrentTaskItem->Index + 1;
if (TaskSwitchWnd_SetToolbarButtonCommandId(This,
CurrentTaskItem->Index + 1,
MAKE_TASKITEM_CMD_ID(NewIndex)))
{
CurrentTaskItem->Index = NewIndex;
}
else
CurrentTaskItem->Index = -1;
}
CurrentTaskItem++;
}
}
static VOID
TaskSwitchWnd_UpdateIndexesAfterButtonDeleted(IN OUT PTASK_SWITCH_WND This,
IN INT iIndex)
{
PTASK_GROUP CurrentGroup;
PTASK_ITEM CurrentTaskItem, LastTaskItem;
INT NewIndex;
if (This->IsGroupingEnabled)
{
/* Update all affected groups */
CurrentGroup = This->TaskGroups;
while (CurrentGroup != NULL)
{
if (CurrentGroup->IsCollapsed &&
CurrentGroup->Index > iIndex)
{
/* Update the toolbar buttons */
NewIndex = CurrentGroup->Index - 1;
if (TaskSwitchWnd_SetToolbarButtonCommandId(This,
CurrentGroup->Index - 1,
MAKE_TASKGROUP_CMD_ID(NewIndex)))
{
CurrentGroup->Index = NewIndex;
}
else
CurrentGroup->Index = -1;
}
CurrentGroup = CurrentGroup->Next;
}
}
/* Update all affected task items */
CurrentTaskItem = This->TaskItems;
LastTaskItem = CurrentTaskItem + This->TaskItemCount;
while (CurrentTaskItem != LastTaskItem)
{
CurrentGroup = CurrentTaskItem->Group;
if (CurrentGroup != NULL)
{
if (!CurrentGroup->IsCollapsed &&
CurrentTaskItem->Index > iIndex)
{
goto UpdateTaskItemBtn;
}
}
else if (CurrentTaskItem->Index > iIndex)
{
UpdateTaskItemBtn:
/* Update the toolbar buttons */
NewIndex = CurrentTaskItem->Index - 1;
if (TaskSwitchWnd_SetToolbarButtonCommandId(This,
CurrentTaskItem->Index - 1,
MAKE_TASKITEM_CMD_ID(NewIndex)))
{
CurrentTaskItem->Index = NewIndex;
}
else
CurrentTaskItem->Index = -1;
}
CurrentTaskItem++;
}
}
static INT
TaskSwitchWnd_UpdateTaskGroupButton(IN OUT PTASK_SWITCH_WND This,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -