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

📄 startmnu.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
                                        IN BOOL fEnterMode)
{
    DbgPrint("IStartMenuCallback::ContextSensitiveHelp\n");
    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE
IStartMenuSiteImpl_Execute(IN OUT IStartMenuCallback *iface,
                           IN IShellFolder *pShellFolder,
                           IN LPCITEMIDLIST pidl)
{
    IStartMenuSiteImpl *This = IStartMenuSiteImpl_from_IStartMenuCallback(iface);

    DbgPrint("IStartMenuCallback::Execute\n");
    return SHInvokeDefaultCommand(ITrayWindow_GetHWND(This->Tray),
                                  pShellFolder,
                                  pidl);
}

static HRESULT STDMETHODCALLTYPE
IStartMenuSiteImpl_Unknown(IN OUT IStartMenuCallback *iface,
                           IN PVOID Unknown1,
                           IN PVOID Unknown2,
                           IN PVOID Unknown3,
                           IN PVOID Unknown4)
{
    DbgPrint("IStartMenuCallback::Unknown(0x%p,0x%p,0x%p,0x%p)\n", Unknown1, Unknown2, Unknown3, Unknown4);
    return E_NOTIMPL;
}

static BOOL
ShowUndockMenuItem(VOID)
{
    DbgPrint("ShowUndockMenuItem() not implemented!\n");
    /* FIXME: How do we detect this?! */
    return FALSE;
}

static BOOL
ShowSynchronizeMenuItem(VOID)
{
    DbgPrint("ShowSynchronizeMenuItem() not implemented!\n");
    /* FIXME: How do we detect this?! */
    return FALSE;
}

static HRESULT STDMETHODCALLTYPE
IStartMenuSiteImpl_AppendMenu(IN OUT IStartMenuCallback *iface,
                              OUT HMENU* phMenu)
{
    HMENU hMenu, hSettingsMenu;
    DWORD dwLogoff;
    BOOL bWantLogoff;
    UINT uLastItemsCount = 5; /* 5 menu items below the last separator */
    TCHAR szUser[128];

    DbgPrint("IStartMenuCallback::AppendMenu\n");

    hMenu = LoadPopupMenu(hExplorerInstance,
                          MAKEINTRESOURCE(IDM_STARTMENU));
    *phMenu = hMenu;
    if (hMenu == NULL)
        return E_FAIL;

    /* Remove menu items that don't apply */

    dwLogoff = SHRestricted(REST_STARTMENULOGOFF);
    bWantLogoff = (dwLogoff == 2 ||
                   SHRestricted(REST_FORCESTARTMENULOGOFF) ||
                   GetExplorerRegValueSet(HKEY_CURRENT_USER,
                                          TEXT("Advanced"),
                                          TEXT("StartMenuLogoff")));

    /* FIXME: Favorites */

    /* Documents */
    if (SHRestricted(REST_NORECENTDOCSMENU))
    {
        DeleteMenu(hMenu,
                   IDM_DOCUMENTS,
                   MF_BYCOMMAND);
    }

    /* Settings */
    hSettingsMenu = FindSubMenu(hMenu,
                                IDM_SETTINGS,
                                FALSE);
    if (hSettingsMenu != NULL)
    {
        if (SHRestricted(REST_NOSETFOLDERS))
        {
            /* Control Panel */
            if (SHRestricted(REST_NOCONTROLPANEL))
            {
                DeleteMenu(hSettingsMenu,
                           IDM_CONTROLPANEL,
                           MF_BYCOMMAND);

                /* Delete the separator below it */
                DeleteMenu(hSettingsMenu,
                           0,
                           MF_BYPOSITION);
            }

            /* Network Connections */
            if (SHRestricted(REST_NONETWORKCONNECTIONS))
            {
                DeleteMenu(hSettingsMenu,
                           IDM_NETWORKCONNECTIONS,
                           MF_BYCOMMAND);
            }

            /* Printers and Faxes */
            DeleteMenu(hSettingsMenu,
                       IDM_PRINTERSANDFAXES,
                       MF_BYCOMMAND);
        }

        /* Security */
        if (GetSystemMetrics(SM_REMOTECONTROL) == 0 ||
            SHRestricted(REST_NOSECURITY))
        {
            DeleteMenu(hSettingsMenu,
                       IDM_SECURITY,
                       MF_BYCOMMAND);
        }

        if (GetMenuItemCount(hSettingsMenu) == 0)
        {
            DeleteMenu(hMenu,
                       IDM_SETTINGS,
                       MF_BYCOMMAND);
        }
    }

    /* Search */
    if (SHRestricted(REST_NOFIND))
    {
        DeleteMenu(hMenu,
                   IDM_SEARCH,
                   MF_BYCOMMAND);
    }

    /* FIXME: Help */

    /* Run */
    if (SHRestricted(REST_NORUN))
    {
        DeleteMenu(hMenu,
                   IDM_RUN,
                   MF_BYCOMMAND);
    }

    /* Synchronize */
    if (!ShowSynchronizeMenuItem())
    {
        DeleteMenu(hMenu,
                   IDM_SYNCHRONIZE,
                   MF_BYCOMMAND);
        uLastItemsCount--;
    }

    /* Log off */
    if (dwLogoff != 1 && bWantLogoff)
    {
        /* FIXME: We need a more sophisticated way to determine whether to show
                  or hide it, it might be hidden in too many cases!!! */

        /* Update Log Off menu item */
        if (!GetCurrentLoggedOnUserName(szUser,
                                        sizeof(szUser) / sizeof(szUser[0])))
        {
            szUser[0] = _T('\0');
        }

        if (!FormatMenuString(hMenu,
                              IDM_LOGOFF,
                              MF_BYCOMMAND,
                              szUser))
        {
            /* We couldn't update the menu item, delete it... */
            DeleteMenu(hMenu,
                       IDM_LOGOFF,
                       MF_BYCOMMAND);
        }
    }
    else
    {
        DeleteMenu(hMenu,
                   IDM_LOGOFF,
                   MF_BYCOMMAND);
        uLastItemsCount--;
    }


    /* Disconnect */
    if (GetSystemMetrics(SM_REMOTECONTROL) == 0)
    {
        DeleteMenu(hMenu,
                   IDM_DISCONNECT,
                   MF_BYCOMMAND);
        uLastItemsCount--;
    }

    /* Undock computer */
    if (!ShowUndockMenuItem())
    {
        DeleteMenu(hMenu,
                   IDM_UNDOCKCOMPUTER,
                   MF_BYCOMMAND);
        uLastItemsCount--;
    }

    /* Shut down */
    if (SHRestricted(REST_NOCLOSE))
    {
        DeleteMenu(hMenu,
                   IDM_SHUTDOWN,
                   MF_BYCOMMAND);
        uLastItemsCount--;
    }

    if (uLastItemsCount == 0)
    {
        /* Remove the separator at the end of the menu */
        DeleteMenu(hMenu,
                   IDM_LASTSTARTMENU_SEPARATOR,
                   MF_BYCOMMAND);
    }

    return S_OK;
}

static const IStartMenuCallbackVtbl IStartMenuCallbackImpl_Vtbl =
{
    /*** IUnknown methods ***/
    METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IStartMenuCallback, IStartMenuSite),
    METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IStartMenuCallback, IStartMenuSite),
    METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IStartMenuCallback, IStartMenuSite),
    /*** IOleWindow methods ***/
    IStartMenuSiteImpl_GetWindow,
    IStartMenuSiteImpl_ContextSensitiveHelp,
    /*** IStartMenuCallback methods ***/
    IStartMenuSiteImpl_Execute,
    IStartMenuSiteImpl_Unknown,
    IStartMenuSiteImpl_AppendMenu
};

/*******************************************************************/

METHOD_IUNKNOWN_INHERITED_ADDREF(IOleCommandTarget, IStartMenuSite)
METHOD_IUNKNOWN_INHERITED_RELEASE(IOleCommandTarget, IStartMenuSite)
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IOleCommandTarget, IStartMenuSite)

static HRESULT STDMETHODCALLTYPE
IStartMenuSiteImpl_QueryStatus(IN OUT IOleCommandTarget *iface,
                               IN const GUID *pguidCmdGroup  OPTIONAL,
                               IN ULONG cCmds,
                               IN OUT OLECMD *prgCmds,
                               IN OUT OLECMDTEXT *pCmdText  OPTIONAL)
{
    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE
IStartMenuSiteImpl_Exec(IN OUT IOleCommandTarget *iface,
                        IN const GUID *pguidCmdGroup  OPTIONAL,
                        IN DWORD nCmdID,
                        IN DWORD nCmdExecOpt,
                        IN VARIANTARG *pvaIn  OPTIONAL,
                        IN VARIANTARG *pvaOut  OPTIONAL)
{
    return E_NOTIMPL;
}

static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl =
{
    /*** IUnknown methods ***/
    METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IOleCommandTarget, IStartMenuSite),
    METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IOleCommandTarget, IStartMenuSite),
    METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IOleCommandTarget, IStartMenuSite),
    /*** IOleCommandTarget ***/
    IStartMenuSiteImpl_QueryStatus,
    IStartMenuSiteImpl_Exec
};

/*******************************************************************/

static IStartMenuSiteImpl*
IStartMenuSiteImpl_Construct(IN ITrayWindow *Tray)
{
    IStartMenuSiteImpl *This;

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

    ZeroMemory(This,
               sizeof(*This));

    This->lpVtbl = &IStartMenuSiteImpl_Vtbl;
    This->lpServiceProviderVtbl = &IServiceProviderImpl_Vtbl;
    This->lpStartMenuCallbackVtbl = &IStartMenuCallbackImpl_Vtbl;
    This->lpOleCommandTargetVtbl = &IOleCommandTargetImpl_Vtbl;
    This->Ref = 1;

    This->Tray = Tray;

    return This;
}

static IStartMenuSite*
CreateStartMenuSite(IN ITrayWindow *Tray)
{
    IStartMenuSiteImpl *This;

    This = IStartMenuSiteImpl_Construct(Tray);
    if (This != NULL)
    {
        return IStartMenuSite_from_IStartMenuSiteImpl(This);
    }

    return NULL;
}

HRESULT
UpdateStartMenu(IN OUT IMenuPopup *pMenuPopup,
                IN HBITMAP hbmBanner  OPTIONAL,
                IN BOOL bSmallIcons)
{
    IBanneredBar *pbb;
    HRESULT hRet;

    hRet = IMenuPopup_QueryInterface(pMenuPopup,
                                     &IID_IBanneredBar,
                                     (PVOID)&pbb);
    if (SUCCEEDED(hRet))
    {
        hRet = IBanneredBar_SetBitmap(pbb,
                                      hbmBanner);


        /* Update the icon size */
        hRet = IBanneredBar_SetIconSize(pbb,
                                        bSmallIcons ? BMICON_SMALL : BMICON_LARGE);

        IBanneredBar_Release(pbb);
    }

    return hRet;
}

IMenuPopup*
CreateStartMenu(IN ITrayWindow *Tray,
                OUT IMenuBand **ppMenuBand,
                IN HBITMAP hbmBanner  OPTIONAL,
                IN BOOL bSmallIcons)
{
    HRESULT hRet;
    IObjectWithSite *pOws = NULL;
    IMenuPopup *pMp = NULL;
    IStartMenuSite *pSms = NULL;
    IMenuBand *pMb = NULL;
    IInitializeObject *pIo;
    IUnknown *pUnk;
    IBandSite *pBs;
    DWORD dwBandId = 0;

    pSms = CreateStartMenuSite(Tray);
    if (pSms == NULL)
        return NULL;

    hRet = CoCreateInstance(&CLSID_StartMenu,
                            NULL,
                            CLSCTX_INPROC_SERVER,
                            &IID_IMenuPopup,
                            (PVOID*)&pMp);
    if (SUCCEEDED(hRet))
    {
        hRet = IMenuPopup_QueryInterface(pMp,
                                         &IID_IObjectWithSite,
                                         (PVOID*)&pOws);
        if (SUCCEEDED(hRet))
        {
            /* Set the menu site so we can handle messages */
            hRet = IObjectWithSite_SetSite(pOws,
                                           (IUnknown*)pSms);
            if (SUCCEEDED(hRet))
            {
                /* Initialize the menu object */
                hRet = IMenuPopup_QueryInterface(pMp,
                                                 &IID_IInitializeObject,
                                                 (PVOID*)&pIo);
                if (SUCCEEDED(hRet))
                {
                    hRet = IInitializeObject_Initialize(pIo);

                    IInitializeObject_Release(pIo);
                }
                else
                    hRet = S_OK;

                /* Everything is initialized now. Let's get the IMenuBand interface. */
                if (SUCCEEDED(hRet))
                {
                    hRet = IMenuPopup_GetClient(pMp,
                                                &pUnk);

                    if (SUCCEEDED(hRet))
                    {
                        hRet = IUnknown_QueryInterface(pUnk,
                                                       &IID_IBandSite,
                                                       (PVOID*)&pBs);

                        if (SUCCEEDED(hRet))
                        {
                            /* Finally we have the IBandSite interface, there's only one
                               band in it that apparently provides the IMenuBand interface */
                            hRet = IBandSite_EnumBands(pBs,
                                                       0,
                                                       &dwBandId);
                            if (SUCCEEDED(hRet))
                            {
                                hRet = IBandSite_GetBandObject(pBs,
                                                               dwBandId,
                                                               &IID_IMenuBand,
                                                               (PVOID*)&pMb);
                            }

                            IBandSite_Release(pBs);
                        }

                        IUnknown_Release(pUnk);
                    }
                }
            }

            IObjectWithSite_Release(pOws);
        }
    }

    IStartMenuSite_Release(pSms);

    if (!SUCCEEDED(hRet))
    {
        DbgPrint("Failed to initialize the start menu: 0x%x!\n", hRet);

        if (pMp != NULL)
            IMenuPopup_Release(pMp);

        if (pMb != NULL)
            IMenuBand_Release(pMb);

        return NULL;
    }

    UpdateStartMenu(pMp,
                    hbmBanner,
                    bSmallIcons);

    *ppMenuBand = pMb;
    return pMp;
}

⌨️ 快捷键说明

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