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

📄 tooldock.c

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

static const TCHAR szToolDockWndClass[] = TEXT("ImageSoftToolDockWndClass");

typedef struct _TOOLDOCKWND_INIT
{
    PTOOLBAR_DOCKS TbDocks;
    PDOCKBAR_ITEM Item;
} TOOLDOCKWND_INIT, *PTOOLDOCKWND_INIT;

static UINT
TbdCalculateInsertIndex(PTOOLBAR_DOCKS TbDocks,
                        DOCK_POSITION Position,
                        POINT pt)
{
    RECT rcRebar;
    UINT Ret = 0;

    GetWindowRect(TbDocks->hRebar[Position],
                  &rcRebar);

    switch (Position)
    {
        case TOP_DOCK:
        case BOTTOM_DOCK:
            if (pt.y > rcRebar.top + ((rcRebar.bottom - rcRebar.top) / 2))
                Ret = (UINT)-1;
            break;

        case LEFT_DOCK:
        case RIGHT_DOCK:
            if (pt.x > rcRebar.left + ((rcRebar.right - rcRebar.left) / 2))
                Ret = (UINT)-1;
            break;

        default:
            break;
    }

    return Ret;
}

INT
TbdAdjustUpdateClientRect(PTOOLBAR_DOCKS TbDocks,
                          PRECT rcClient)
{
    INT i, DocksVisible = 0;

    for (i = 0; i < DOCKS_COUNT; i++)
    {
        if (TbDocks->hRebar[i] != NULL)
        {
            DocksVisible++;
        }
    }

    if (DocksVisible != 0)
    {
        rcClient->top += TbDocks->rcRebar[TOP_DOCK].bottom;
        rcClient->left += TbDocks->rcRebar[LEFT_DOCK].right;
        rcClient->right -= TbDocks->rcRebar[RIGHT_DOCK].right;
        rcClient->bottom -= TbDocks->rcRebar[BOTTOM_DOCK].bottom;
    }

    TbDocks->rcClient = *rcClient;

    return DocksVisible;
}

HDWP
TbdDeferDocks(HDWP hWinPosInfo,
              PTOOLBAR_DOCKS TbDocks)
{
    LONG cx, cy;
    HDWP hRet = hWinPosInfo;

    cx = TbDocks->rcClient.right - TbDocks->rcClient.left;
    cy = TbDocks->rcClient.bottom - TbDocks->rcClient.top;

    /* Top dock */
    if (TbDocks->hRebar[TOP_DOCK] != NULL)
    {
        hRet = DeferWindowPos(hRet,
                              TbDocks->hRebar[TOP_DOCK],
                              NULL,
                              TbDocks->rcClient.left - TbDocks->rcRebar[LEFT_DOCK].right,
                              TbDocks->rcClient.top - TbDocks->rcRebar[TOP_DOCK].bottom,
                              cx + TbDocks->rcRebar[LEFT_DOCK].right + TbDocks->rcRebar[RIGHT_DOCK].right,
                              TbDocks->rcRebar[TOP_DOCK].bottom,
                              SWP_NOZORDER);
        if (hRet == NULL)
            return NULL;
    }

    /* Left dock */
    if (TbDocks->hRebar[LEFT_DOCK] != NULL)
    {
        hRet = DeferWindowPos(hRet,
                              TbDocks->hRebar[LEFT_DOCK],
                              NULL,
                              TbDocks->rcClient.left - TbDocks->rcRebar[LEFT_DOCK].right,
                              TbDocks->rcClient.top,
                              TbDocks->rcRebar[LEFT_DOCK].right,
                              cy,
                              SWP_NOZORDER);
        if (hRet == NULL)
            return NULL;
    }

    /* Right dock */
    if (TbDocks->hRebar[RIGHT_DOCK] != NULL)
    {
        hRet = DeferWindowPos(hRet,
                              TbDocks->hRebar[RIGHT_DOCK],
                              NULL,
                              TbDocks->rcClient.right,
                              TbDocks->rcClient.top,
                              TbDocks->rcRebar[RIGHT_DOCK].right,
                              cy,
                              SWP_NOZORDER);
        if (hRet == NULL)
            return NULL;
    }

    /* Bottom dock */
    if (TbDocks->hRebar[BOTTOM_DOCK] != NULL)
    {
        hRet = DeferWindowPos(hRet,
                              TbDocks->hRebar[BOTTOM_DOCK],
                              NULL,
                              TbDocks->rcClient.left - TbDocks->rcRebar[LEFT_DOCK].right,
                              TbDocks->rcClient.bottom,
                              cx + TbDocks->rcRebar[LEFT_DOCK].right + TbDocks->rcRebar[RIGHT_DOCK].right,
                              TbDocks->rcRebar[BOTTOM_DOCK].bottom,
                              SWP_NOZORDER);
        if (hRet == NULL)
            return NULL;
    }

    return hRet;
}

static PDOCKBAR_ITEM
TbnDockbarItemFromBandId(PTOOLBAR_DOCKS TbDocks,
                         DOCK_POSITION Position,
                         UINT uBand)
{
    REBARBANDINFO rbi = {0};

    rbi.cbSize = sizeof(rbi);
    rbi.fMask = RBBIM_LPARAM;

    if (SendMessage(TbDocks->hRebar[Position],
                    RB_GETBANDINFO,
                    (WPARAM)uBand,
                    (LPARAM)&rbi))
    {
        return (PDOCKBAR_ITEM)rbi.lParam;
    }

    return NULL;
}

static VOID
TbnRebarChangeSize(PTOOLBAR_DOCKS TbDocks,
                   DOCK_POSITION Position)
{
    LONG cRebar;

    TbDocks->rcRebar[Position].left = 0;
    TbDocks->rcRebar[Position].top = 0;

    cRebar = (LONG)SendMessage(TbDocks->hRebar[Position],
                               RB_GETBARHEIGHT,
                               0,
                               0);

    switch (Position)
    {
        case TOP_DOCK:
        case BOTTOM_DOCK:
            TbDocks->rcRebar[Position].bottom = cRebar;
            break;

        case LEFT_DOCK:
        case RIGHT_DOCK:
            TbDocks->rcRebar[Position].right = cRebar;
            break;

        default:
            break;
    }

    if (TbDocks->ParentResize != NULL)
    {
        RECT rcClient = {0};

        GetClientRect(TbDocks->hParent,
                      &rcClient);

        TbDocks->ParentResize(TbDocks->Context,
                              rcClient.right - rcClient.left,
                              rcClient.bottom - rcClient.top);
    }
}

static VOID
TbnRebarChevronPushed(PTOOLBAR_DOCKS TbDocks,
                      DOCK_POSITION Position,
                      LPNMREBARCHEVRON lpnm)
{
    PDOCKBAR_ITEM Item;

    Item = TbnDockbarItemFromBandId(TbDocks,
                                    Position,
                                    lpnm->uBand);

    if (Item != NULL && Item->Callbacks->ChevronPushed)
    {
        Item->Callbacks->ChevronPushed(TbDocks,
                                       &Item->DockBar,
                                       Item->Context,
                                       Item->hWndClient,
                                       lpnm);
    }
}

static LRESULT
TbnRebarBeginDrag(PTOOLBAR_DOCKS TbDocks,
                  DOCK_POSITION Position,
                  LPNMREBAR lpnmrb)
{
    PDOCKBAR_ITEM Item;

    Item = TbnDockbarItemFromBandId(TbDocks,
                                    Position,
                                    lpnmrb->uBand);

    if (Item != NULL)
    {
        TbDocks->Dragging = Item;
        TbDocks->DraggingBandId = lpnmrb->wID;
        return FALSE;
    }

    return TRUE;
}

static VOID
TbnRebarEndDrag(PTOOLBAR_DOCKS TbDocks,
                DOCK_POSITION Position,
                LPNMREBAR lpnmrb)
{
    PDOCKBAR_ITEM Item;

    Item = TbnDockbarItemFromBandId(TbDocks,
                                    Position,
                                    lpnmrb->uBand);

    if (Item != NULL)
    {
        /* Nothing to do */
    }
}

BOOL
TbdDockBarIdFromClientWindow(PTOOLBAR_DOCKS TbDocks,
                             HWND hWndClient,
                             UINT *Id)
{
    PDOCKBAR_ITEM Item;
    BOOL Ret = FALSE;

    Item = TbDocks->Items;
    while (Item != NULL)
    {
        if (Item->hWndClient == hWndClient)
        {
            *Id = Item->DockBar.BarId;
            Ret = TRUE;
            break;
        }

        Item = Item->Next;
    }

    return Ret;
}

BOOL
TbdHandleNotifications(PTOOLBAR_DOCKS TbDocks,
                       LPNMHDR pnmh,
                       LRESULT *Result)
{
    BOOL Handled = FALSE;

    if (pnmh->hwndFrom != NULL)
    {
        DOCK_POSITION Position;

        for (Position = TOP_DOCK; Position < NO_DOCK; Position++)
        {
            if (pnmh->hwndFrom == TbDocks->hRebar[Position])
            {
                switch (pnmh->code)
                {
                    case RBN_HEIGHTCHANGE:
                    {
                        TbnRebarChangeSize(TbDocks,
                                           Position);
                        break;
                    }

                    case RBN_BEGINDRAG:
                    {
                        *Result = TbnRebarBeginDrag(TbDocks,
                                                    Position,
                                                    (LPNMREBAR)pnmh);
                        break;
                    }

                    case RBN_ENDDRAG:
                    {
                        TbnRebarEndDrag(TbDocks,
                                        Position,
                                        (LPNMREBAR)pnmh);
                        break;
                    }

                    case RBN_CHEVRONPUSHED:
                    {
                        TbnRebarChevronPushed(TbDocks,
                                              Position,
                                              (LPNMREBARCHEVRON)pnmh);
                        break;
                    }
                }

                Handled = TRUE;
                break;
            }
        }
    }

    return Handled;
}

static BOOL
TbdCreateToolbarWnd(PTOOLBAR_DOCKS TbDocks,
                    PDOCKBAR_ITEM Item,
                    DOCK_POSITION PrevPosition,
                    UINT PrevBandIndex,
                    LPREBARBANDINFO rbi,
                    POINT pt,
                    HWND hRebar,
                    UINT uBand,
                    BOOL Drag)
{
    LPCTSTR lpCaption = NULL;
    TOOLDOCKWND_INIT Init;
    HWND hToolbar;

    Init.TbDocks = TbDocks;
    Init.Item = Item;

    if (rbi->fMask & RBBIM_TEXT)
    {
        lpCaption = rbi->lpText;
    }

    Item->Callbacks->DockBand(TbDocks,
                              &Item->DockBar,
                              Item->Context,
                              PrevPosition,
                              NO_DOCK,
                              rbi);

    if (rbi->fMask & RBBIM_CHILD)
        Item->hWndClient = rbi->hwndChild;
    else

⌨️ 快捷键说明

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