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

📄 trayntfy.c

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

            case TCWM_GETMINIMUMSIZE:
            {
                This->IsHorizontal = (BOOL)wParam;

                Ret = (LRESULT)TrayClockWnd_GetMinimumSize(This,
                                                           (BOOL)wParam,
                                                           (PSIZE)lParam) != 0;
                break;
            }

            case TCWM_UPDATETIME:
            {
                Ret = (LRESULT)TrayClockWnd_ResetTime(This);
                break;
            }

            case WM_NCCREATE:
            {
                LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
                This = (PTRAY_CLOCK_WND_DATA)CreateStruct->lpCreateParams;
                This->hWnd = hwnd;
                This->hWndNotify = CreateStruct->hwndParent;

                SetWindowLongPtr(hwnd,
                                 0,
                                 (LONG_PTR)This);

                return TRUE;
            }

            case WM_SETFONT:
            {
                TrayClockWnd_SetFont(This,
                                     (HFONT)wParam,
                                     (BOOL)LOWORD(lParam));
                break;
            }

            case WM_CREATE:
                TrayClockWnd_ResetTime(This);
                break;

            case WM_NCDESTROY:
                TrayClockWnd_NCDestroy(This);
                break;

            case WM_SIZE:
            {
                SIZE szClient;

                szClient.cx = LOWORD(lParam);
                szClient.cy = HIWORD(lParam);
                This->VisibleLines = TrayClockWnd_GetMinimumSize(This,
                                                                 This->IsHorizontal,
                                                                 &szClient);
                This->CurrentSize = szClient;

                InvalidateRect(This->hWnd,
                               NULL,
                               TRUE);
                break;
            }

            default:
                Ret = DefWindowProc(hwnd,
                                    uMsg,
                                    wParam,
                                    lParam);
                break;
        }
    }

    return Ret;
}

static HWND
CreateTrayClockWnd(IN HWND hWndParent,
                   IN BOOL bVisible)
{
    PTRAY_CLOCK_WND_DATA TcData;
    DWORD dwStyle;
    HWND hWnd = NULL;

    TcData = HeapAlloc(hProcessHeap,
                       0,
                       sizeof(*TcData));
    if (TcData != NULL)
    {
        ZeroMemory(TcData,
                   sizeof(*TcData));

        TcData->IsHorizontal = TRUE;
        /* Create the window. The tray window is going to move it to the correct
           position and resize it as needed. */
        dwStyle = WS_CHILD | WS_CLIPSIBLINGS;
        if (bVisible)
            dwStyle |= WS_VISIBLE;

        hWnd = CreateWindowEx(0,
                              szTrayClockWndClass,
                              NULL,
                              dwStyle,
                              0,
                              0,
                              0,
                              0,
                              hWndParent,
                              NULL,
                              hExplorerInstance,
                              (LPVOID)TcData);

        if (hWnd == NULL)
        {
            HeapFree(hProcessHeap,
                     0,
                     TcData);
        }
    }

    return hWnd;

}

static BOOL
RegisterTrayClockWndClass(VOID)
{
    WNDCLASS wcTrayClock;

    wcTrayClock.style = CS_DBLCLKS;
    wcTrayClock.lpfnWndProc = TrayClockWndProc;
    wcTrayClock.cbClsExtra = 0;
    wcTrayClock.cbWndExtra = sizeof(PTRAY_CLOCK_WND_DATA);
    wcTrayClock.hInstance = hExplorerInstance;
    wcTrayClock.hIcon = NULL;
    wcTrayClock.hCursor = LoadCursor(NULL,
                                     IDC_ARROW);
    wcTrayClock.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
    wcTrayClock.lpszMenuName = NULL;
    wcTrayClock.lpszClassName = szTrayClockWndClass;

    return RegisterClass(&wcTrayClock) != 0;
}

static VOID
UnregisterTrayClockWndClass(VOID)
{
    UnregisterClass(szTrayClockWndClass,
                    hExplorerInstance);
}

/*
 * TrayNotifyWnd
 */

static const TCHAR szTrayNotifyWndClass[] = TEXT("TrayNotifyWnd");

#define TRAY_NOTIFY_WND_SPACING_X   2
#define TRAY_NOTIFY_WND_SPACING_Y   2

typedef struct _TRAY_NOTIFY_WND_DATA
{
    HWND hWnd;
    HWND hWndTrayClock;
    HWND hWndNotify;
    SIZE szTrayClockMin;
    SIZE szNonClient;
    ITrayWindow *TrayWindow;
    union
    {
        DWORD dwFlags;
        struct
        {
            DWORD HideClock : 1;
            DWORD IsHorizontal : 1;
        };
    };
} TRAY_NOTIFY_WND_DATA, *PTRAY_NOTIFY_WND_DATA;

static VOID
TrayNotifyWnd_UpdateStyle(IN OUT PTRAY_NOTIFY_WND_DATA This)
{
    RECT rcClient = {0};

    if (AdjustWindowRectEx(&rcClient,
                           GetWindowLong(This->hWnd,
                                         GWL_STYLE),
                           FALSE,
                           GetWindowLong(This->hWnd,
                                         GWL_EXSTYLE)))
    {
        This->szNonClient.cx = rcClient.right - rcClient.left;
        This->szNonClient.cy = rcClient.bottom - rcClient.top;
    }
    else
        This->szNonClient.cx = This->szNonClient.cy = 0;
}

static VOID
TrayNotifyWnd_Create(IN OUT PTRAY_NOTIFY_WND_DATA This)
{
    This->hWndTrayClock = CreateTrayClockWnd(This->hWnd,
                                             !This->HideClock);

    TrayNotifyWnd_UpdateStyle(This);
}

static VOID
TrayNotifyWnd_NCDestroy(IN OUT PTRAY_NOTIFY_WND_DATA This)
{
    SetWindowLongPtr(This->hWnd,
                     0,
                     0);
    HeapFree(hProcessHeap,
             0,
             This);
}

static BOOL
TrayNotifyWnd_GetMinimumSize(IN OUT PTRAY_NOTIFY_WND_DATA This,
                             IN BOOL Horizontal,
                             IN OUT PSIZE pSize)
{
    This->IsHorizontal = Horizontal;

    if (!This->HideClock)
    {
        SIZE szClock = {0};

        if (Horizontal)
        {
            szClock.cy = pSize->cy - This->szNonClient.cy - (2 * TRAY_NOTIFY_WND_SPACING_Y);
            if (szClock.cy <= 0)
                goto NoClock;
        }
        else
        {
            szClock.cx = pSize->cx - This->szNonClient.cx - (2 * TRAY_NOTIFY_WND_SPACING_X);
            if (szClock.cx <= 0)
                goto NoClock;
        }

        SendMessage(This->hWndTrayClock,
                    TCWM_GETMINIMUMSIZE,
                    (WPARAM)Horizontal,
                    (LPARAM)&szClock);

        This->szTrayClockMin = szClock;
    }
    else
NoClock:
        This->szTrayClockMin = This->szNonClient;

    if (Horizontal)
    {
        pSize->cx = This->szNonClient.cx + (2 * TRAY_NOTIFY_WND_SPACING_X);

        if (!This->HideClock)
            pSize->cx += TRAY_NOTIFY_WND_SPACING_X + This->szTrayClockMin.cx;
    }
    else
    {
        pSize->cy = This->szNonClient.cy + (2 * TRAY_NOTIFY_WND_SPACING_Y);

        if (!This->HideClock)
            pSize->cy += TRAY_NOTIFY_WND_SPACING_Y + This->szTrayClockMin.cy;
    }

    return TRUE;
}

static VOID
TrayNotifyWnd_Size(IN OUT PTRAY_NOTIFY_WND_DATA This,
                   IN const SIZE *pszClient)
{
    if (!This->HideClock)
    {
        POINT ptClock;
        SIZE szClock;

        if (This->IsHorizontal)
        {
            ptClock.x = pszClient->cx - TRAY_NOTIFY_WND_SPACING_X - This->szTrayClockMin.cx;
            ptClock.y = TRAY_NOTIFY_WND_SPACING_Y;
            szClock.cx = This->szTrayClockMin.cx;
            szClock.cy = pszClient->cy - (2 * TRAY_NOTIFY_WND_SPACING_Y);
        }
        else
        {
            ptClock.x = TRAY_NOTIFY_WND_SPACING_X;
            ptClock.y = pszClient->cy - TRAY_NOTIFY_WND_SPACING_Y - This->szTrayClockMin.cy;
            szClock.cx = pszClient->cx - (2 * TRAY_NOTIFY_WND_SPACING_X);
            szClock.cy = This->szTrayClockMin.cy;
        }

        SetWindowPos(This->hWndTrayClock,
                     NULL,
                     ptClock.x,
                     ptClock.y,
                     szClock.cx,
                     szClock.cy,
                     SWP_NOZORDER);
    }
}

static LRESULT CALLBACK
TrayNotifyWndProc(IN HWND hwnd,
                  IN UINT uMsg,
                  IN WPARAM wParam,
                  IN LPARAM lParam)
{
    PTRAY_NOTIFY_WND_DATA This = NULL;
    LRESULT Ret = FALSE;

    if (uMsg != WM_NCCREATE)
    {
        This = (PTRAY_NOTIFY_WND_DATA)GetWindowLongPtr(hwnd,
                                                       0);
    }

    if (This != NULL || uMsg == WM_NCCREATE)
    {
        switch (uMsg)
        {
            case TNWM_GETMINIMUMSIZE:
            {
                Ret = (LRESULT)TrayNotifyWnd_GetMinimumSize(This,
                                                            (BOOL)wParam,
                                                            (PSIZE)lParam);
                break;
            }

            case TNWM_UPDATETIME:
            {
                if (This->hWndTrayClock != NULL)
                {
                    /* Forward the message to the tray clock window procedure */
                    Ret = TrayClockWndProc(This->hWndTrayClock,
                                           TCWM_UPDATETIME,
                                           wParam,
                                           lParam);
                }
                break;
            }

            case WM_SIZE:
            {
                SIZE szClient;

                szClient.cx = LOWORD(lParam);
                szClient.cy = HIWORD(lParam);

                TrayNotifyWnd_Size(This,
                                   &szClient);
                break;
            }

            case WM_NCHITTEST:
                /* We want the user to be able to drag the task bar when clicking the
                   tray notification window */
                Ret = HTTRANSPARENT;
                break;

            case TNWM_SHOWCLOCK:
            {
                BOOL PrevHidden = This->HideClock;
                This->HideClock = (wParam == 0);

                if (This->hWndTrayClock != NULL && PrevHidden != This->HideClock)
                {
                    ShowWindow(This->hWndTrayClock,
                               This->HideClock ? SW_HIDE : SW_SHOW);
                }

                Ret = (LRESULT)(!PrevHidden);
                break;
            }

            case WM_NOTIFY:
            {
                const NMHDR *nmh = (const NMHDR *)lParam;

                if (nmh->hwndFrom == This->hWndTrayClock)
                {
                    /* Pass down notifications */
                    Ret = SendMessage(This->hWndNotify,
                                      WM_NOTIFY,
                                      wParam,
                                      lParam);
                }
                break;
            }

            case WM_SETFONT:
            {
                if (This->hWndTrayClock != NULL)
                {
                    SendMessage(This->hWndTrayClock,
                                WM_SETFONT,
                                wParam,
                                lParam);
                }
                goto HandleDefaultMessage;
            }

            case WM_NCCREATE:
            {
                LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
                This = (PTRAY_NOTIFY_WND_DATA)CreateStruct->lpCreateParams;
                This->hWnd = hwnd;
                This->hWndNotify = CreateStruct->hwndParent;

                SetWindowLongPtr(hwnd,
                                 0,
                                 (LONG_PTR)This);

                return TRUE;
            }

            case WM_CREATE:
                TrayNotifyWnd_Create(This);
                break;

            case WM_NCDESTROY:
                TrayNotifyWnd_NCDestroy(This);
                break;

            default:
HandleDefaultMessage:
                Ret = DefWindowProc(hwnd,
                                    uMsg,
                                    wParam,
                                    lParam);
                break;
        }
    }

    return Ret;
}

HWND
CreateTrayNotifyWnd(IN OUT ITrayWindow *TrayWindow,
                    IN BOOL bHideClock)
{
    PTRAY_NOTIFY_WND_DATA TnData;
    HWND hWndTrayWindow;
    HWND hWnd = NULL;

    hWndTrayWindow = ITrayWindow_GetHWND(TrayWindow);
    if (hWndTrayWindow == NULL)
        return NULL;

    TnData = HeapAlloc(hProcessHeap,
                       0,
                       sizeof(*TnData));
    if (TnData != NULL)
    {
        ZeroMemory(TnData,
                   sizeof(*TnData));

        TnData->TrayWindow = TrayWindow;
        TnData->HideClock = bHideClock;

        /* Create the window. The tray window is going to move it to the correct
           position and resize it as needed. */
        hWnd = CreateWindowEx(WS_EX_STATICEDGE,
                              szTrayNotifyWndClass,
                              NULL,
                              WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                              0,
                              0,
                              0,
                              0,
                              hWndTrayWindow,
                              NULL,
                              hExplorerInstance,
                              (LPVOID)TnData);

        if (hWnd == NULL)
        {
            HeapFree(hProcessHeap,
                     0,
                     TnData);
        }
    }

    return hWnd;
}

BOOL
RegisterTrayNotifyWndClass(VOID)
{
    WNDCLASS wcTrayWnd;
    BOOL Ret;

    wcTrayWnd.style = CS_DBLCLKS;
    wcTrayWnd.lpfnWndProc = TrayNotifyWndProc;
    wcTrayWnd.cbClsExtra = 0;
    wcTrayWnd.cbWndExtra = sizeof(PTRAY_NOTIFY_WND_DATA);
    wcTrayWnd.hInstance = hExplorerInstance;
    wcTrayWnd.hIcon = NULL;
    wcTrayWnd.hCursor = LoadCursor(NULL,
                                   IDC_ARROW);
    wcTrayWnd.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
    wcTrayWnd.lpszMenuName = NULL;
    wcTrayWnd.lpszClassName = szTrayNotifyWndClass;

    Ret = RegisterClass(&wcTrayWnd) != 0;

    if (Ret)
    {
        Ret = RegisterTrayClockWndClass();
        if (!Ret)
        {
            UnregisterClass(szTrayNotifyWndClass,
                            hExplorerInstance);
        }
    }

    return Ret;
}

VOID
UnregisterTrayNotifyWndClass(VOID)
{
    UnregisterTrayClockWndClass();

    UnregisterClass(szTrayNotifyWndClass,
                    hExplorerInstance);
}

⌨️ 快捷键说明

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