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

📄 traywnd.c

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

    SelectObject(hDC,
                 hFontOld);
    if (!Ret)
        goto Cleanup;

    /* Make sure the height is at least the size of a caption icon. */
    if (hIconStart != NULL)
        Size.cx += SmallIcon.cx + 4;
    Size.cy = max(Size.cy,
                  SmallIcon.cy);

    /* Create the bitmap */
    hbmp = CreateCompatibleBitmap(hDCScreen,
                                  Size.cx,
                                  Size.cy);
    if (hbmp == NULL)
        goto Cleanup;

    /* Caluclate the button rect */
    rcButton.left = 0;
    rcButton.top = 0;
    rcButton.right = Size.cx;
    rcButton.bottom = Size.cy;

    /* Draw the button */
    hbmpOld = SelectObject(hDC,
                           hbmp);

    Flags = DC_TEXT | DC_INBUTTON;
    if (hIconStart != NULL)
        Flags |= DC_ICON;

    Ret = DrawCaptionTemp(NULL,
                          hDC,
                          &rcButton,
                          This->hStartBtnFont,
                          hIconStart,
                          szStartCaption,
                          Flags);

    SelectObject(hDC,
                 hbmpOld);

    if (!Ret)
        goto Cleanup;

    /* We successfully created the bitmap! */
    hBitmap = hbmp;
    hbmp = NULL;

Cleanup:
    if (hDCScreen != NULL)
    {
        ReleaseDC(NULL,
            hDCScreen);
    }

    if (hbmp != NULL)
        DeleteObject(hbmp);

    if (hDC != NULL)
        DeleteDC(hDC);

    return hBitmap;
}

static VOID
ITrayWindowImpl_Create(IN OUT ITrayWindowImpl *This)
{
    TCHAR szStartCaption[32];

    InterlockedIncrement(&TrayWndCount);

    if (!LoadString(hExplorerInstance,
                    IDS_START,
                    szStartCaption,
                    sizeof(szStartCaption) / sizeof(szStartCaption[0])))
    {
        szStartCaption[0] = TEXT('\0');
    }

    if (This->hStartBtnFont == NULL || This->hCaptionFont == NULL)
    {
        NONCLIENTMETRICS ncm;

        /* Get the system fonts, we use the caption font,
           always bold, though. */
        ncm.cbSize = sizeof(ncm);
        if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
                                 sizeof(ncm),
                                 &ncm,
                                 FALSE))
        {
            if (This->hCaptionFont == NULL)
            {
                ncm.lfCaptionFont.lfWeight = FW_NORMAL;
                This->hCaptionFont = CreateFontIndirect(&ncm.lfCaptionFont);
            }

            if (This->hStartBtnFont == NULL)
            {
                ncm.lfCaptionFont.lfWeight = FW_BOLD;
                This->hStartBtnFont = CreateFontIndirect(&ncm.lfCaptionFont);
            }
        }
    }

    /* Create the Start button */
    This->hwndStart = CreateWindowEx(0,
                                     WC_BUTTON,
                                     szStartCaption,
                                     WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
                                         BS_PUSHBUTTON | BS_CENTER | BS_VCENTER | BS_BITMAP,
                                     0,
                                     0,
                                     0,
                                     0,
                                     This->hWnd,
                                     (HMENU)IDC_STARTBTN,
                                     hExplorerInstance,
                                     NULL);
    if (This->hwndStart)
    {
        SendMessage(This->hwndStart,
                    WM_SETFONT,
                    (WPARAM)This->hStartBtnFont,
                    FALSE);

        if (ITrayWindowImpl_CreateStartBtnImageList(This))
        {
            BUTTON_IMAGELIST bil;

            /* Try to set the start button image. This requires the Common
               Controls 6.0 to be present (XP and later) */
            bil.himl = This->himlStartBtn;
            bil.margin.left = bil.margin.right = 1;
            bil.margin.top = bil.margin.bottom = 1;
            bil.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT;

            if (!SendMessage(This->hwndStart,
                             BCM_SETIMAGELIST,
                             0,
                             (LPARAM)&bil))
            {
                /* Fall back to the deprecated method on older systems that don't
                   support Common Controls 6.0 */
                ImageList_Destroy(This->himlStartBtn);
                This->himlStartBtn = NULL;

                goto SetStartBtnImage;
            }

            /* We're using the image list, remove the BS_BITMAP style and
               don't center it horizontally */
            SetWindowStyle(This->hwndStart,
                           BS_BITMAP | BS_RIGHT,
                           0);

            ITrayWindowImpl_UpdateStartButton(This,
                                              NULL);
        }
        else
        {
            HBITMAP hbmStart, hbmOld;

SetStartBtnImage:
            hbmStart = ITrayWindowImpl_CreateStartButtonBitmap(This);
            if (hbmStart != NULL)
            {
                ITrayWindowImpl_UpdateStartButton(This,
                                                  hbmStart);

                hbmOld = (HBITMAP)SendMessage(This->hwndStart,
                                              BM_SETIMAGE,
                                              IMAGE_BITMAP,
                                              (LPARAM)hbmStart);

                if (hbmOld != NULL)
                    DeleteObject(hbmOld);
            }
        }
    }

    /* Load the saved tray window settings */
    ITrayWindowImpl_RegLoadSettings(This);

    /* Create and initialize the start menu */
    This->hbmStartMenu = LoadBitmap(hExplorerInstance,
                                    MAKEINTRESOURCE(IDB_STARTMENU));
    This->StartMenuPopup = CreateStartMenu(ITrayWindow_from_impl(This),
                                           &This->StartMenuBand,
                                           This->hbmStartMenu,
                                           0);

    /* Load the tray band site */
    if (This->TrayBandSite != NULL)
    {
        ITrayBandSite_Release(This->TrayBandSite);
    }

    This->TrayBandSite = CreateTrayBandSite(ITrayWindow_from_impl(This),
                                            &This->hwndRebar,
                                            &This->hwndTaskSwitch);

    /* Create the tray notification window */
    This->hwndTrayNotify = CreateTrayNotifyWnd(ITrayWindow_from_impl(This),
                                               This->HideClock);

    if (ITrayWindowImpl_UpdateNonClientMetrics(This))
    {
        ITrayWindowImpl_SetWindowsFont(This);
    }

    /* Move the tray window to the right position and resize it if neccessary */
    ITrayWindowImpl_CheckTrayWndPosition(This);

    /* Align all controls on the tray window */
    ITrayWindowImpl_AlignControls(This,
                                  NULL);
}

static HRESULT STDMETHODCALLTYPE
ITrayWindowImpl_QueryInterface(IN OUT ITrayWindow *iface,
                               IN REFIID riid,
                               OUT LPVOID *ppvObj)
{
    ITrayWindowImpl *This;

    if (ppvObj == NULL)
        return E_POINTER;

    This = impl_from_ITrayWindow(iface);

    if (IsEqualIID(riid,
                   &IID_IUnknown))
    {
        *ppvObj = IUnknown_from_impl(This);
    }
    else if (IsEqualIID(riid,
                        &IID_IShellDesktopTray))
    {
        *ppvObj = IShellDesktopTray_from_impl(This);
    }
    else
    {
        *ppvObj = NULL;
        return E_NOINTERFACE;
    }

    ITrayWindowImpl_AddRef(iface);
    return S_OK;
}

static ITrayWindowImpl *
ITrayWindowImpl_Construct(VOID)
{
    ITrayWindowImpl *This;

    This = HeapAlloc(hProcessHeap,
                     0,
                     sizeof(*This));
    if (This == NULL)
        return NULL;

    ZeroMemory(This,
               sizeof(*This));
    This->lpVtbl = &ITrayWindowImpl_Vtbl;
    This->lpVtblShellDesktopTray = &IShellDesktopTrayImpl_Vtbl;
    This->Ref = 1;
    This->Position = (DWORD)-1;

    return This;
}

static HRESULT STDMETHODCALLTYPE
ITrayWindowImpl_Open(IN OUT ITrayWindow *iface)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
    HRESULT Ret = S_OK;
    HWND hWnd;
    DWORD dwExStyle;

    /* Check if there's already a window created and try to show it.
       If it was somehow destroyed just create a new tray window. */
    if (This->hWnd != NULL)
    {
        if (IsWindow(This->hWnd))
        {
            if (!IsWindowVisible(This->hWnd))
            {
                ITrayWindowImpl_CheckTrayWndPosition(This);

                ShowWindow(This->hWnd,
                           SW_SHOW);
            }
        }
        else
            goto TryCreateTrayWnd;
    }
    else
    {
        RECT rcWnd;

TryCreateTrayWnd:
        dwExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
        if (This->AlwaysOnTop)
            dwExStyle |= WS_EX_TOPMOST;

        if (This->Position != (DWORD)-1)
            rcWnd = This->rcTrayWnd[This->Position];
        else
        {
            ZeroMemory(&rcWnd,
                       sizeof(rcWnd));
        }

        hWnd = CreateWindowEx(dwExStyle,
                              szTrayWndClass,
                              NULL,
                              WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
                                  WS_BORDER | WS_THICKFRAME,
                              rcWnd.left,
                              rcWnd.top,
                              rcWnd.right - rcWnd.left,
                              rcWnd.bottom - rcWnd.top,
                              NULL,
                              NULL,
                              hExplorerInstance,
                              This);
        if (hWnd == NULL)
            Ret = E_FAIL;
    }

    return Ret;
}

static HRESULT STDMETHODCALLTYPE
ITrayWindowImpl_Close(IN OUT ITrayWindow *iface)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);

    if (This->hWnd != NULL)
    {
        SendMessage(This->hWnd,
                    WM_APP_TRAYDESTROY,
                    0,
                    0);
    }

    return S_OK;
}

static HWND STDMETHODCALLTYPE
ITrayWindowImpl_GetHWND(IN OUT ITrayWindow *iface)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);

    return This->hWnd;
}

static BOOL STDMETHODCALLTYPE
ITrayWindowImpl_IsSpecialHWND(IN OUT ITrayWindow *iface,
                              IN HWND hWnd)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);

    return (hWnd == This->hWnd ||
            (This->hWndDesktop != NULL && hWnd == This->hWndDesktop));
}

static BOOL STDMETHODCALLTYPE
ITrayWindowImpl_IsHorizontal(IN OUT ITrayWindow *iface)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);
    return ITrayWindowImpl_IsPosHorizontal(This);
}

static HFONT STDMETHODCALLTYPE
ITrayWIndowImpl_GetCaptionFonts(IN OUT ITrayWindow *iface,
                                OUT HFONT *phBoldCaption  OPTIONAL)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);

    if (phBoldCaption != NULL)
        *phBoldCaption = This->hStartBtnFont;

    return This->hCaptionFont;
}

static HWND STDMETHODCALLTYPE
ITrayWindowImpl_DisplayProperties(IN OUT ITrayWindow *iface)
{
    ITrayWindowImpl *This = impl_from_ITrayWindow(iface);

    if (This->hWndTrayProperties != NULL)
    {
        BringWindowToTop(This->hWndTrayProperties);
        return This->hWndTrayProperties;
    }

    This->hWndTrayProperties = DisplayTrayProperties(ITrayWindow_from_impl(This));
    return This->hWndTrayProperties;
}

static VOID
OpenCommonStartMenuDirectory(IN HWND hWndOwner,
                             IN LPCTSTR lpOperation)
{
    TCHAR szDir[MAX_PATH];

    if (SHGetSpecialFolderPath(hWndOwner,
                               szDir,
                               CSIDL_COMMON_STARTMENU,
                               FALSE))
    {
        ShellExecute(hWndOwner,
                     lpOperation,
                     NULL,
                     NULL,
                     szDir,

⌨️ 快捷键说明

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