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

📄 traywnd.c

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

    return cmdId;
}

static UINT
ITrayWindowImpl_TrackCtxMenu(IN OUT ITrayWindowImpl *This,
                             IN const TRAYWINDOW_CTXMENU *pMenu,
                             IN POINT *ppt  OPTIONAL,
                             IN HWND hwndExclude  OPTIONAL,
                             IN BOOL TrackUp,
                             IN PVOID Context  OPTIONAL)
{
    HMENU hPopup;
    UINT cmdId = 0;
    PVOID pcmContext = NULL;

    hPopup = pMenu->CreateCtxMenu(This->hWnd,
                                  &pcmContext,
                                  Context);
    if (hPopup != NULL)
    {
        cmdId = ITrayWindowImpl_TrackMenu(This,
                                          hPopup,
                                          ppt,
                                          hwndExclude,
                                          TrackUp,
                                          TRUE);

        pMenu->CtxMenuCommand(This->hWnd,
                              cmdId,
                              pcmContext,
                              Context);
    }

    return cmdId;
}

static VOID
ITrayWindowImpl_Free(ITrayWindowImpl *This)
{
    HeapFree(hProcessHeap,
             0,
             This);
}


static ULONG STDMETHODCALLTYPE
ITrayWindowImpl_Release(IN OUT ITrayWindow *iface)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
    ULONG Ret;

    Ret = InterlockedDecrement(&This->Ref);
    if (Ret == 0)
        ITrayWindowImpl_Free(This);

    return Ret;
}

static VOID
ITrayWindowImpl_Destroy(ITrayWindowImpl *This)
{
    (void)InterlockedExchangePointer((PVOID*)&This->hWnd,
                                     NULL);

    if (This->himlStartBtn != NULL)
    {
        ImageList_Destroy(This->himlStartBtn);
        This->himlStartBtn = NULL;
    }

    if (This->hCaptionFont != NULL)
    {
        DeleteObject(This->hCaptionFont);
        This->hCaptionFont = NULL;
    }

    if (This->hStartBtnFont != NULL)
    {
        DeleteObject(This->hStartBtnFont);
        This->hStartBtnFont = NULL;
    }

    if (This->hFont != NULL)
    {
        DeleteObject(This->hFont);
        This->hFont = NULL;
    }

    if (This->StartMenuPopup != NULL)
    {
        IMenuPopup_Release(This->StartMenuPopup);
        This->StartMenuPopup = NULL;
    }

    if (This->hbmStartMenu != NULL)
    {
        DeleteObject(This->hbmStartMenu);
        This->hbmStartMenu = NULL;
    }

    if (This->StartMenuBand != NULL)
    {
        IMenuBand_Release(This->StartMenuBand);
        This->StartMenuBand = NULL;
    }

    if (This->TrayBandSite != NULL)
    {
        /* FIXME: Unload bands */
        ITrayBandSite_Release(This->TrayBandSite);
        This->TrayBandSite = NULL;
    }

    ITrayWindowImpl_Release(ITrayWindow_from_impl(This));

    if (InterlockedDecrement(&TrayWndCount) == 0)
        PostQuitMessage(0);
}

static ULONG STDMETHODCALLTYPE
ITrayWindowImpl_AddRef(IN OUT ITrayWindow *iface)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);

    return InterlockedIncrement(&This->Ref);
}


static BOOL
ITrayWindowImpl_NCCreate(IN OUT ITrayWindowImpl *This)
{
    ITrayWindowImpl_AddRef(ITrayWindow_from_impl(This));

    return TRUE;
}

static VOID
ITrayWindowImpl_UpdateStartButton(IN OUT ITrayWindowImpl *This,
                                  IN HBITMAP hbmStart  OPTIONAL)
{
    SIZE Size = {0};

    if (This->himlStartBtn == NULL ||
        !SendMessage(This->hwndStart,
                     BCM_GETIDEALSIZE,
                     0,
                     (LPARAM)&Size))
    {
        Size.cx = GetSystemMetrics(SM_CXEDGE);
        Size.cy = GetSystemMetrics(SM_CYEDGE);

        if (hbmStart == NULL)
        {
            hbmStart = (HBITMAP)SendMessage(This->hwndStart,
                                            BM_GETIMAGE,
                                            IMAGE_BITMAP,
                                            0);
        }

        if (hbmStart != NULL)
        {
            BITMAP bmp;

            if (GetObject(hbmStart,
                          sizeof(bmp),
                          &bmp) != 0)
            {
                Size.cx += max(bmp.bmWidth,
                               GetSystemMetrics(SM_CXMINIMIZED));
                Size.cy += max(bmp.bmHeight,
                               GetSystemMetrics(SM_CYCAPTION));
            }
            else
            {
                /* Huh?! Shouldn't happen... */
                goto DefSize;
            }
        }
        else
        {
DefSize:
            Size.cx += GetSystemMetrics(SM_CXMINIMIZED);
            Size.cy += GetSystemMetrics(SM_CYCAPTION);
        }
    }

    /* Save the size of the start button */
    This->StartBtnSize = Size;
}

static VOID
ITrayWindowImpl_AlignControls(IN OUT ITrayWindowImpl *This,
                              IN PRECT prcClient  OPTIONAL)
{
    RECT rcClient;
    SIZE TraySize, StartSize;
    POINT ptTrayNotify = {0};
    BOOL Horizontal;
    HDWP dwp;

    if (prcClient != NULL)
    {
        rcClient = *prcClient;
    }
    else
    {
        if (!GetClientRect(This->hWnd,
                           &rcClient))
        {
            return;
        }
    }

    Horizontal = ITrayWindowImpl_IsPosHorizontal(This);

    /* We're about to resize/move the start button, the rebar control and
       the tray notification control */
    dwp = BeginDeferWindowPos(3);
    if (dwp == NULL)
        return;

    /* Limit the Start button width to the client width, if neccessary */
    StartSize = This->StartBtnSize;
    if (StartSize.cx > rcClient.right)
        StartSize.cx = rcClient.right;

    if (This->hwndStart != NULL)
    {
        /* Resize and reposition the button */
        dwp = DeferWindowPos(dwp,
                             This->hwndStart,
                             NULL,
                             0,
                             0,
                             StartSize.cx,
                             StartSize.cy,
                             SWP_NOZORDER | SWP_NOACTIVATE);
        if (dwp == NULL)
            return;
    }

    /* Determine the size that the tray notification window needs */
    if (Horizontal)
    {
        TraySize.cx = 0;
        TraySize.cy = rcClient.bottom;
    }
    else
    {
        TraySize.cx = rcClient.right;
        TraySize.cy = 0;
    }

    if (This->hwndTrayNotify != NULL &&
        SendMessage(This->hwndTrayNotify,
                    TNWM_GETMINIMUMSIZE,
                    (WPARAM)Horizontal,
                    (LPARAM)&TraySize))
    {
        /* Move the tray notification window to the desired location */
        if (Horizontal)
            ptTrayNotify.x = rcClient.right - TraySize.cx;
        else
            ptTrayNotify.y = rcClient.bottom - TraySize.cy;

        dwp = DeferWindowPos(dwp,
                             This->hwndTrayNotify,
                             NULL,
                             ptTrayNotify.x,
                             ptTrayNotify.y,
                             TraySize.cx,
                             TraySize.cy,
                             SWP_NOZORDER | SWP_NOACTIVATE);
        if (dwp == NULL)
            return;
    }

    /* Resize/Move the rebar control */
    if (This->hwndRebar != NULL)
    {
        POINT ptRebar = {0};
        SIZE szRebar;

        SetWindowStyle(This->hwndRebar,
                       CCS_VERT,
                       Horizontal ? 0 : CCS_VERT);

        if (Horizontal)
        {
            ptRebar.x = StartSize.cx + GetSystemMetrics(SM_CXSIZEFRAME);
            szRebar.cx = ptTrayNotify.x - ptRebar.x;
            szRebar.cy = rcClient.bottom;
        }
        else
        {
            ptRebar.y = StartSize.cy + GetSystemMetrics(SM_CYSIZEFRAME);
            szRebar.cx = rcClient.right;
            szRebar.cy = ptTrayNotify.y - ptRebar.y;
        }

        dwp = DeferWindowPos(dwp,
                             This->hwndRebar,
                             NULL,
                             ptRebar.x,
                             ptRebar.y,
                             szRebar.cx,
                             szRebar.cy,
                             SWP_NOZORDER | SWP_NOACTIVATE);
    }

    if (dwp != NULL)
        EndDeferWindowPos(dwp);

    if (This->hwndTaskSwitch != NULL)
    {
        /* Update the task switch window configuration */
        SendMessage(This->hwndTaskSwitch,
                    TSWM_UPDATETASKBARPOS,
                    0,
                    0);
    }
}

static BOOL
ITrayWindowImpl_CreateStartBtnImageList(IN OUT ITrayWindowImpl *This)
{
    HICON hIconStart;
    SIZE IconSize;

    if (This->himlStartBtn != NULL)
        return TRUE;

    IconSize.cx = GetSystemMetrics(SM_CXSMICON);
    IconSize.cy = GetSystemMetrics(SM_CYSMICON);

    /* Load the start button icon and create a image list for it */
    hIconStart = LoadImage(hExplorerInstance,
                           MAKEINTRESOURCE(IDI_START),
                           IMAGE_ICON,
                           IconSize.cx,
                           IconSize.cy,
                           LR_SHARED | LR_DEFAULTCOLOR);

    if (hIconStart != NULL)
    {
        This->himlStartBtn = ImageList_Create(IconSize.cx,
                                              IconSize.cy,
                                              ILC_COLOR32 | ILC_MASK,
                                              1,
                                              1);
        if (This->himlStartBtn != NULL)
        {
            if (ImageList_AddIcon(This->himlStartBtn,
                                  hIconStart) >= 0)
            {
                return TRUE;
            }

            /* Failed to add the icon! */
            ImageList_Destroy(This->himlStartBtn);
            This->himlStartBtn = NULL;
        }
    }

    return FALSE;
}

static HBITMAP
ITrayWindowImpl_CreateStartButtonBitmap(IN OUT ITrayWindowImpl *This)
{
    TCHAR szStartCaption[32];
    HFONT  hFontOld;
    HDC hDC = NULL;
    HDC hDCScreen = NULL;
    SIZE Size, SmallIcon;
    HBITMAP hbmpOld, hbmp = NULL;
    HBITMAP hBitmap = NULL;
    HICON hIconStart;
    BOOL Ret;
    UINT Flags;
    RECT rcButton;

    /* NOTE: This is the backwards compatibility code that is used if the
             Common Controls Version 6.0 are not available! */

    if (!LoadString(hExplorerInstance,
                    IDS_START,
                    szStartCaption,
                    sizeof(szStartCaption) / sizeof(szStartCaption[0])))
    {
        return NULL;
    }

    /* Load the start button icon */
    SmallIcon.cx = GetSystemMetrics(SM_CXSMICON);
    SmallIcon.cy = GetSystemMetrics(SM_CYSMICON);
    hIconStart = LoadImage(hExplorerInstance,
                           MAKEINTRESOURCE(IDI_START),
                           IMAGE_ICON,
                           SmallIcon.cx,
                           SmallIcon.cy,
                           LR_SHARED | LR_DEFAULTCOLOR);

    hDCScreen = GetDC(NULL);
    if (hDCScreen == NULL)
        goto Cleanup;

    hDC = CreateCompatibleDC(hDCScreen);
    if (hDC == NULL)
        goto Cleanup;

    hFontOld = SelectObject(hDC,
                            This->hStartBtnFont);

    Ret = GetTextExtentPoint32(hDC,
                               szStartCaption,
                               _tcslen(szStartCaption),
                               &Size);

⌨️ 快捷键说明

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