⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 taskswnd.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * 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 + -