tooldock.c

来自「一个类似windows」· C语言 代码 · 共 1,141 行 · 第 1/3 页

C
1,141
字号
                RECT rc;

                /* Save all rebar band information, don't query RBBIM_HEADERSIZE because it
                   seems to cause problems with toolbars*/
                rbi.cbSize = sizeof(rbi);
                rbi.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS |
                    RBBIM_IDEALSIZE | RBBIM_ID | RBBIM_IMAGE | RBBIM_LPARAM | RBBIM_SIZE |
                    RBBIM_STYLE | RBBIM_TEXT;
                rbi.lpText = TbDocks->szTempText;
                rbi.cch = sizeof(TbDocks->szTempText);

                uBand = (UINT)SendMessage(hWnd,
                                          RB_IDTOINDEX,
                                          (WPARAM)TbDocks->DraggingBandId,
                                          0);

                if (uBand != (UINT)-1 &&
                    SendMessage(hWnd,
                                RB_GETBANDINFO,
                                (WPARAM)uBand,
                                (LPARAM)&rbi))
                {
                    MapWindowPoints(hWnd,
                                    HWND_DESKTOP,
                                    &pt,
                                    1);

                    /* Check if the user is trying to drag it into another dock */
                    for (Position = TOP_DOCK; Position < NO_DOCK; Position++)
                    {
                        if (TbDocks->hRebar[Position] != NULL &&
                            TbDocks->hRebar[Position] != hWnd &&
                            GetWindowRect(TbDocks->hRebar[Position],
                                          &rc))
                        {
                            InflateRect(&rc,
                                        szTearOff.cx,
                                        szTearOff.cy);

                            if (PtInRect(&rc,
                                         pt))
                            {
                                DragTo = Position;
                                break;
                            }
                        }
                    }

                    /* Get the current dock */
                    for (Position = TOP_DOCK; Position < NO_DOCK; Position++)
                    {
                        if (TbDocks->hRebar[Position] == hWnd)
                        {
                            break;
                        }
                    }

                    ReleaseCapture();

                    if (SendMessage(hWnd,
                                    RB_SHOWBAND,
                                    (WPARAM)uBand,
                                    FALSE))
                    {
                        /* Change the parent to the new rebar control */
                        if (TbDocks->Dragging->hWndClient != NULL)
                        {
                            SetWindowPos(TbDocks->Dragging->hWndClient,
                                         NULL,
                                         0,
                                         0,
                                         0,
                                         0,
                                         SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);

                            SetParent(TbDocks->Dragging->hWndClient,
                                      TbDocks->hRebar[DragTo]);

                            SetWindowPos(TbDocks->Dragging->hWndClient,
                                         NULL,
                                         0,
                                         0,
                                         0,
                                         0,
                                         SWP_NOSIZE | SWP_NOZORDER);
                        }

                        if (DragTo == NO_DOCK)
                        {
                            if (!TbdCreateToolbarWnd(TbDocks,
                                                     TbDocks->Dragging,
                                                     Position,
                                                     uBand,
                                                     &rbi,
                                                     pt,
                                                     hWnd,
                                                     uBand,
                                                     TRUE))
                            {
                                goto MoveFailed;
                            }
                        }
                        else
                        {
                            BOOL Moved = FALSE;

                            /* Remove the band from the current rebar control */
                            if (SendMessage(hWnd,
                                            RB_DELETEBAND,
                                            (WPARAM)uBand,
                                            0))
                            {
                                UINT uIndex;

                                /* Calculate where to insert the new bar */
                                uIndex = TbdCalculateInsertIndex(TbDocks,
                                                                 DragTo,
                                                                 pt);

                                SetActiveWindow(TbDocks->hRebar[DragTo]);

                                TbDocks->Dragging->Callbacks->DockBand(TbDocks,
                                                                       &TbDocks->Dragging->DockBar,
                                                                       TbDocks->Dragging->Context,
                                                                       Position,
                                                                       DragTo,
                                                                       &rbi);

                                if (rbi.fMask & RBBIM_CHILD)
                                    TbDocks->Dragging->hWndClient = rbi.hwndChild;
                                else
                                    TbDocks->Dragging->hWndClient = NULL;

                                /* Insert the toolbar into the new rebar */
                                rbi.fMask |= RBBIM_STYLE;
                                rbi.fStyle |= RBBS_HIDDEN;
                                if (SendMessage(TbDocks->hRebar[DragTo],
                                                RB_INSERTBAND,
                                                (WPARAM)uIndex,
                                                (LPARAM)&rbi))
                                {
                                    uBand = (UINT)SendMessage(TbDocks->hRebar[DragTo],
                                                              RB_IDTOINDEX,
                                                              (WPARAM)TbDocks->DraggingBandId,
                                                              0);

                                    SendMessage(TbDocks->hRebar[DragTo],
                                                RB_SHOWBAND,
                                                (WPARAM)uBand,
                                                TRUE);

                                    /* Simulate a mouse click to continue dragging */
                                    if (uBand != (UINT)-1 &&
                                        TbDocks->Dragging->hWndClient != NULL &&
                                        GetWindowRect(TbDocks->Dragging->hWndClient,
                                                      &rc))
                                    {
                                        switch (DragTo)
                                        {
                                            case LEFT_DOCK:
                                            case RIGHT_DOCK:
                                                pt.x = rc.left + ((rc.right - rc.left) / 2);
                                                pt.y = rc.top - 1;
                                                break;

                                            default:
                                                pt.x = rc.left - 1;
                                                pt.y = rc.top + ((rc.bottom - rc.top) / 2);
                                                break;
                                        }

                                        MapWindowPoints(HWND_DESKTOP,
                                                        TbDocks->hRebar[DragTo],
                                                        &pt,
                                                        1);

                                        SetCursor(LoadCursor(NULL,
                                                             MAKEINTRESOURCE(IDC_SIZEALL)));

                                        SendMessage(TbDocks->hRebar[DragTo],
                                                    WM_LBUTTONDOWN,
                                                    wParam,
                                                    MAKELPARAM(pt.x,
                                                               pt.y));

                                        Moved = TRUE;
                                    }
                                }
                            }

                            if (!Moved)
                            {
MoveFailed:
                                TbDocks->Dragging = NULL;

                                SendMessage(hWnd,
                                            RB_SHOWBAND,
                                            (WPARAM)uBand,
                                            TRUE);
                            }
                        }
                    }
                }
            }
        }
    }

    return Ret;
}

VOID
TbdHandleEnabling(PTOOLBAR_DOCKS TbDocks,
                  HWND hWnd,
                  BOOL Enable)
{
    PDOCKBAR_ITEM Item;

    Item = TbDocks->Items;
    while (Item != NULL)
    {
        if (Item->hWndTool != NULL &&
            Item->hWndTool != hWnd)
        {
            EnableWindow(Item->hWndTool,
                         Enable);
        }
        Item = Item->Next;
    }
}

VOID
TbdHandleActivation(PTOOLBAR_DOCKS TbDocks,
                    HWND hWnd,
                    WPARAM *wParam,
                    LPARAM *lParam)
{
    BOOL SynchronizeSiblings = TRUE;
    BOOL KeepActive = *(BOOL*)wParam;
    HWND hWndActivate = *(HWND*)lParam;
    PDOCKBAR_ITEM Item;

    Item = TbDocks->Items;
    while (Item != NULL)
    {
        if (Item->hWndTool != NULL &&
            Item->hWndTool == hWndActivate)
        {
            KeepActive = TRUE;
            SynchronizeSiblings = FALSE;
            break;
        }
        Item = Item->Next;
    }

    if (hWndActivate != (HWND)-1)
    {
        if (SynchronizeSiblings)
        {
            Item = TbDocks->Items;
            while (Item != NULL)
            {
                if (Item->hWndTool != NULL &&
                    Item->hWndTool != hWnd &&
                    Item->hWndTool != hWndActivate)
                {
                    SendMessage(Item->hWndTool,
                                WM_NCACTIVATE,
                                (WPARAM)KeepActive,
                                (LPARAM)-1);
                }
                Item = Item->Next;
            }
        }
    }
    else
        *lParam = 0;

    *wParam = (WPARAM)KeepActive;
}

VOID
TbdShowFloatingToolbars(PTOOLBAR_DOCKS TbDocks,
                        BOOL Show)
{
    PDOCKBAR_ITEM Item;

    Item = TbDocks->Items;
    while (Item != NULL)
    {
        if (Item->hWndTool != NULL)
        {
            if ((Show && !IsWindowVisible(Item->hWndTool)) ||
                (!Show && IsWindowVisible(Item->hWndTool)))
            {
                ShowWindow(Item->hWndTool,
                           (Show ? SW_SHOW : SW_HIDE));
            }
        }
        Item = Item->Next;
    }
}

VOID
TbdInitializeDocks(PTOOLBAR_DOCKS TbDocks,
                   HWND hWndParent,
                   PVOID Context,
                   PDOCKBAR_PARENTRESIZE ParentResizeProc)
{
    DWORD rbStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
                        CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NOMOVEY | CCS_NOMOVEX  |
                        RBS_VARHEIGHT | RBS_AUTOSIZE;

    DOCK_POSITION Position;

    TbDocks->hParent = hWndParent;
    TbDocks->Context = Context;
    TbDocks->ParentResize = ParentResizeProc;

    for (Position = TOP_DOCK; Position < NO_DOCK; Position++)
    {
        switch (Position)
        {
            case LEFT_DOCK:
            case RIGHT_DOCK:
                rbStyle |= CCS_VERT;
                break;
            default:
                rbStyle &= ~CCS_VERT;
                break;
        }

        TbDocks->hRebar[Position] = CreateWindowEx(WS_EX_TOOLWINDOW,
                                                   REBARCLASSNAME,
                                                   NULL,
                                                   rbStyle,
                                                   0,
                                                   0,
                                                   0,
                                                   0,
                                                   TbDocks->hParent,
                                                   NULL,
                                                   hInstance,
                                                   NULL);

        if (TbDocks->hRebar[Position] != NULL)
        {
            SetWindowSubclass(TbDocks->hRebar[Position],
                              RebarSubclassProc,
                              1,
                              (DWORD_PTR)TbDocks);
        }
    }
}

BOOL
TbdInitImpl(VOID)
{
    WNDCLASSEX wc = {0};

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = ToolDockWndProc;
    wc.cbWndExtra = TD_EXTRA_BYTES;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL,
                            IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wc.lpszClassName = szToolDockWndClass;

    return RegisterClassEx(&wc) != (ATOM)0;
}

VOID
TbdUninitImpl(VOID)
{
    UnregisterClass(szToolDockWndClass,
                    hInstance);
}

⌨️ 快捷键说明

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