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

📄 taskswnd.c

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

        TaskItem++;
    }

    return NULL;
}

static PTASK_ITEM
TaskSwitchWnd_AllocTaskItem(IN OUT PTASK_SWITCH_WND This)
{
    if (This->TaskItemCount >= MAX_TASKS_COUNT)
    {
        /* We need the most significant bit in 16 bit command IDs to indicate whether it
           is a task group or task item. WM_COMMAND limits command IDs to 16 bits! */
        return NULL;
    }

    if (This->AllocatedTaskItems <= This->TaskItemCount)
    {
        if (This->TaskItemCount != 0)
        {
            PTASK_ITEM NewArray;
            WORD NewArrayLength;

            NewArrayLength = This->AllocatedTaskItems + TASK_ITEM_ARRAY_ALLOC;

            NewArray = HeapReAlloc(hProcessHeap,
                                   0,
                                   This->TaskItems,
                                   NewArrayLength * sizeof(*This->TaskItems));
            if (NewArray != NULL)
            {
                This->AllocatedTaskItems = NewArrayLength;
                This->TaskItems = NewArray;
            }
            else
                return NULL;
        }
        else
        {
            This->TaskItems = HeapAlloc(hProcessHeap,
                                        0,
                                        TASK_ITEM_ARRAY_ALLOC * sizeof(*This->TaskItems));
            if (This->TaskItems != NULL)
            {
                This->AllocatedTaskItems = TASK_ITEM_ARRAY_ALLOC;
            }
            else
                return NULL;
        }
    }

    return This->TaskItems + This->TaskItemCount++;
}

static VOID
TaskSwitchWnd_FreeTaskItem(IN OUT PTASK_SWITCH_WND This,
                           IN OUT PTASK_ITEM TaskItem)
{
    WORD wIndex;

    if (TaskItem == This->ActiveTaskItem)
        This->ActiveTaskItem = NULL;

    wIndex = (WORD)(TaskItem - This->TaskItems);
    if (wIndex + 1 < This->TaskItemCount)
    {
        MoveMemory(TaskItem,
                   TaskItem + 1,
                   (This->TaskItemCount - wIndex - 1) * sizeof(*TaskItem));
    }

    This->TaskItemCount--;
}

static VOID
TaskSwitchWnd_DeleteTaskItem(IN OUT PTASK_SWITCH_WND This,
                             IN OUT PTASK_ITEM TaskItem)
{
    if (!This->IsDestroying)
    {
        /* Delete the task button from the toolbar */
        TaskSwitchWnd_DeleteTaskItemButton(This,
                                           TaskItem);
    }

    /* Remove the task from it's group */
    TaskSwitchWnd_RemoveTaskFromTaskGroup(This,
                                          TaskItem);

    /* Free the task item */
    TaskSwitchWnd_FreeTaskItem(This,
                               TaskItem);
}

static VOID
TaskSwitchWnd_CheckActivateTaskItem(IN OUT PTASK_SWITCH_WND This,
                                    IN OUT PTASK_ITEM TaskItem)
{
    PTASK_ITEM ActiveTaskItem;
    PTASK_GROUP TaskGroup = NULL;

    ActiveTaskItem = This->ActiveTaskItem;

    if (TaskItem != NULL)
        TaskGroup = TaskItem->Group;

    if (This->IsGroupingEnabled && TaskGroup != NULL)
    {
        if (TaskGroup->IsCollapsed)
        {
            /* FIXME */
        }
        else
            goto ChangeTaskItemButton;
    }
    else
    {
ChangeTaskItemButton:
        if (ActiveTaskItem != NULL)
        {
            PTASK_GROUP ActiveTaskGroup;

            if (ActiveTaskItem == TaskItem)
                return;

            ActiveTaskGroup = ActiveTaskItem->Group;

            if (This->IsGroupingEnabled && ActiveTaskGroup != NULL)
            {
                if (ActiveTaskGroup->IsCollapsed)
                {
                    if (ActiveTaskGroup == TaskGroup)
                        return;

                    /* FIXME */
                }
                else
                    goto ChangeActiveTaskItemButton;
            }
            else
            {
ChangeActiveTaskItemButton:
                This->ActiveTaskItem = NULL;
                if (ActiveTaskItem->Index >= 0)
                {
                    TaskSwitchWnd_UpdateTaskItemButton(This,
                                                       ActiveTaskItem);
                }
            }
        }

        This->ActiveTaskItem = TaskItem;

        if (TaskItem != NULL && TaskItem->Index >= 0)
        {
            TaskSwitchWnd_UpdateTaskItemButton(This,
                                               TaskItem);
        }
    }
}

static BOOL
TaskSwitchWnd_AddTask(IN OUT PTASK_SWITCH_WND This,
                      IN HWND hWnd)
{
    PTASK_ITEM TaskItem;

    TaskItem = TaskSwitchWnd_FindTaskItem(This,
                                          hWnd);
    if (TaskItem == NULL)
    {
        DbgPrint("Add window 0x%p\n", hWnd);
        TaskItem = TaskSwitchWnd_AllocTaskItem(This);
        if (TaskItem != NULL)
        {
            ZeroMemory(TaskItem,
                       sizeof(*TaskItem));
            TaskItem->hWnd = hWnd;
            TaskItem->Index = -1;
            TaskItem->Group = TaskSwitchWnd_AddToTaskGroup(This,
                                                           hWnd);

            if (!This->IsDestroying)
            {
                TaskSwitchWnd_AddTaskItemButton(This,
                                                TaskItem);
            }
        }
    }

    return TaskItem != NULL;
}

static BOOL
TaskSwitchWnd_ActivateTask(IN OUT PTASK_SWITCH_WND This,
                           IN HWND hWnd)
{
    PTASK_ITEM TaskItem;

    TaskItem = TaskSwitchWnd_FindTaskItem(This,
                                          hWnd);
    if (TaskItem == NULL)
    {
        TaskItem = TaskSwitchWnd_FindOtherTaskItem(This,
                                                   hWnd);
    }

    if (TaskItem != NULL)
    {
        DbgPrint("Activate window 0x%p on button %d\n", hWnd, TaskItem->Index);
    }
    else
    {
        DbgPrint("Activate window 0x%p, could not find task\n", hWnd);
    }

    TaskSwitchWnd_CheckActivateTaskItem(This,
                                        TaskItem);

    return FALSE;
}

static BOOL
TaskSwitchWnd_DeleteTask(IN OUT PTASK_SWITCH_WND This,
                         IN HWND hWnd)
{
    PTASK_ITEM TaskItem;

    TaskItem = TaskSwitchWnd_FindTaskItem(This,
                                          hWnd);
    if (TaskItem != NULL)
    {
        DbgPrint("Delete window 0x%p on button %d\n", hWnd, TaskItem->Index);
        TaskSwitchWnd_DeleteTaskItem(This,
                                     TaskItem);
        return TRUE;
    }
    //else
        //DbgPrint("Failed to delete window 0x%p\n", hWnd);

    return FALSE;
}

static VOID
TaskSwitchWnd_DeleteAllTasks(IN OUT PTASK_SWITCH_WND This)
{
    PTASK_ITEM CurrentTask;

    if (This->TaskItemCount > 0)
    {
        CurrentTask = This->TaskItems + This->TaskItemCount;
        do
        {
            TaskSwitchWnd_DeleteTaskItem(This,
                                         --CurrentTask);
        } while (CurrentTask != This->TaskItems);
    }
}

static VOID
TaskSwitchWnd_FlashTaskItem(IN OUT PTASK_SWITCH_WND This,
                            IN OUT PTASK_ITEM TaskItem)
{
    /* FIXME: Implement */
}

static BOOL
TaskSwitchWnd_FlashTask(IN OUT PTASK_SWITCH_WND This,
                        IN HWND hWnd)
{
    PTASK_ITEM TaskItem;

    TaskItem = TaskSwitchWnd_FindTaskItem(This,
                                          hWnd);
    if (TaskItem != NULL)
    {
        DbgPrint("Flashing window 0x%p on button %d\n", hWnd, TaskItem->Index);
        TaskSwitchWnd_FlashTaskItem(This,
                                    TaskItem);
        return TRUE;
    }

    return FALSE;
}

static VOID
TaskSwitchWnd_RedrawTaskItem(IN OUT PTASK_SWITCH_WND This,
                             IN OUT PTASK_ITEM TaskItem)
{
    PTASK_GROUP TaskGroup;

    TaskGroup = TaskItem->Group;
    if (This->IsGroupingEnabled && TaskGroup != NULL)
    {
        if (TaskGroup->IsCollapsed && TaskGroup->Index >= 0)
        {
            TaskSwitchWnd_UpdateTaskGroupButton(This,
                                                TaskGroup);
        }
        else if (TaskItem->Index >= 0)
        {
            goto UpdateTaskItem;
        }
    }
    else if (TaskItem->Index >= 0)
    {
UpdateTaskItem:
        TaskSwitchWnd_UpdateTaskItemButton(This,
                                           TaskItem);
    }
}


static BOOL
TaskSwitchWnd_RedrawTask(IN OUT PTASK_SWITCH_WND This,
                         IN HWND hWnd)
{
    PTASK_ITEM TaskItem;

    TaskItem = TaskSwitchWnd_FindTaskItem(This,
                                          hWnd);
    if (TaskItem != NULL)
    {
        TaskSwitchWnd_RedrawTaskItem(This,
                                     TaskItem);
        return TRUE;
    }

    return FALSE;
}

static INT
TaskSwitchWnd_UpdateTbButtonSpacing(IN OUT PTASK_SWITCH_WND This,
                                    IN BOOL bHorizontal,
                                    IN UINT uiBtnsPerLine)
{
    TBMETRICS tbm;

    tbm.cbSize = sizeof(tbm);
    tbm.dwMask = TBMF_BUTTONSPACING;

    if (bHorizontal || uiBtnsPerLine > 1)
        tbm.cxButtonSpacing = (3 * GetSystemMetrics(SM_CXEDGE) / 2);
    else
        tbm.cxButtonSpacing = 0;

    tbm.cyButtonSpacing = (3 * GetSystemMetrics(SM_CYEDGE) / 2);

    SendMessage(This->hWndToolbar,
                TB_SETMETRICS,
                0,
                (LPARAM)&tbm);

    return tbm.cxButtonSpacing;
}


static VOID
TaskSwitchWnd_UpdateButtonsSize(IN OUT PTASK_SWITCH_WND This,
                                IN BOOL bRedrawDisabled)
{
    RECT rcClient;
    UINT uiRows, uiMax, uiMin, uiBtnsPerLine, ui;
    LONG NewBtnSize;
    BOOL Horizontal;
    TBBUTTONINFO tbbi;
    TBMETRICS tbm;

    if (GetClientRect(This->hWnd,
                      &rcClient) &&
        !IsRectEmpty(&rcClient))
    {
        if (This->ToolbarBtnCount > 0)
        {
            tbm.cbSize = sizeof(tbm);
            tbm.dwMask = TBMF_PAD | TBMF_BUTTONSPACING;
            SendMessage(This->hWndToolbar,
                        TB_GETMETRICS,
                        0,
                        (LPARAM)&tbm);

            uiRows = (rcClient.bottom + tbm.cyButtonSpacing) / (This->ButtonSize.cy + tbm.cyButtonSpacing);
            if (uiRows == 0)
                uiRows = 1;

            uiBtnsPerLine = (This->ToolbarBtnCount + uiRows - 1) / uiRows;

            Horizontal = ITrayWindow_IsHorizontal(This->Tray);

            if (!bRedrawDisabled)
                TaskSwitchWnd_BeginUpdate(This);

            /* We might need to update the button spacing */
            tbm.cxButtonSpacing = TaskSwitchWnd_UpdateTbButtonSpacing(This,
                                                                      Horizontal,
                                                                      uiBtnsPerLine);

            /* Calculate the ideal width and make sure it's within the allowed range */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -