ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

startmnu.c
Go to the documentation of this file.
00001 /*
00002  * ReactOS Explorer
00003  *
00004  * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <precomp.h>
00022 
00023 /*
00024  * Start menu button context menu
00025  */
00026 
00027 typedef struct _STARTMNU_CTMENU_CTX
00028 {
00029     IContextMenu *pcm;
00030     LPITEMIDLIST pidl;
00031 } STARTMNU_CTMENU_CTX, *PSTARTMNU_CTMENU_CTX;
00032 
00033 static HMENU
00034 CreateStartContextMenu(IN HWND hWndOwner,
00035                        IN PVOID *ppcmContext,
00036                        IN PVOID Context  OPTIONAL);
00037 
00038 static VOID
00039 OnStartContextMenuCommand(IN HWND hWndOwner,
00040                           IN UINT uiCmdId,
00041                           IN PVOID pcmContext  OPTIONAL,
00042                           IN PVOID Context  OPTIONAL);
00043 
00044 const TRAYWINDOW_CTXMENU StartMenuBtnCtxMenu = {
00045     CreateStartContextMenu,
00046     OnStartContextMenuCommand
00047 };
00048 
00049 static HMENU
00050 CreateContextMenuFromShellFolderPidl(IN HWND hWndOwner,
00051                                      IN OUT IShellFolder *psf,
00052                                      IN OUT LPITEMIDLIST pidl,
00053                                      OUT IContextMenu **ppcm)
00054 {
00055     IContextMenu *pcm;
00056     HRESULT hRet;
00057     HMENU hPopup;
00058 
00059     hRet = IShellFolder_GetUIObjectOf(psf,
00060                                       hWndOwner,
00061                                       1,
00062                                       (LPCITEMIDLIST*)&pidl, /* FIXME: shouldn't need a typecast! */
00063                                       &IID_IContextMenu,
00064                                       NULL,
00065                                       (PVOID*)&pcm);
00066     if (SUCCEEDED(hRet))
00067     {
00068         hPopup = CreatePopupMenu();
00069 
00070         if (hPopup != NULL)
00071         {
00072             hRet = IContextMenu_QueryContextMenu(pcm,
00073                                                  hPopup,
00074                                                  0,
00075                                                  ID_SHELL_CMD_FIRST,
00076                                                  ID_SHELL_CMD_LAST,
00077                                                  CMF_VERBSONLY);
00078 
00079             if (SUCCEEDED(hRet))
00080             {
00081                 *ppcm = pcm;
00082                 return hPopup;
00083             }
00084 
00085             IContextMenu_Release(pcm);
00086             DestroyMenu(hPopup);
00087         }
00088     }
00089 
00090     return NULL;
00091 }
00092 
00093 static VOID
00094 OnStartContextMenuCommand(IN HWND hWndOwner,
00095                           IN UINT uiCmdId,
00096                           IN PVOID pcmContext  OPTIONAL,
00097                           IN PVOID Context  OPTIONAL)
00098 {
00099     PSTARTMNU_CTMENU_CTX psmcmc = (PSTARTMNU_CTMENU_CTX)pcmContext;
00100 
00101     if (uiCmdId != 0)
00102     {
00103         if ((uiCmdId >= ID_SHELL_CMD_FIRST) && (uiCmdId <= ID_SHELL_CMD_LAST))
00104         {
00105             CMINVOKECOMMANDINFO cmici = {0};
00106             CHAR szDir[MAX_PATH];
00107 
00108             /* Setup and invoke the shell command */
00109             cmici.cbSize = sizeof(cmici);
00110             cmici.hwnd = hWndOwner;
00111             cmici.lpVerb = (LPCSTR)MAKEINTRESOURCE(uiCmdId - ID_SHELL_CMD_FIRST);
00112             cmici.nShow = SW_NORMAL;
00113 
00114             /* FIXME: Support Unicode!!! */
00115             if (SHGetPathFromIDListA(psmcmc->pidl,
00116                                      szDir))
00117             {
00118                 cmici.lpDirectory = szDir;
00119             }
00120 
00121             IContextMenu_InvokeCommand(psmcmc->pcm,
00122                                        &cmici);
00123         }
00124         else
00125         {
00126             ITrayWindow_ExecContextMenuCmd((ITrayWindow *)Context,
00127                                            uiCmdId);
00128         }
00129     }
00130 
00131     IContextMenu_Release(psmcmc->pcm);
00132 
00133     HeapFree(hProcessHeap,
00134              0,
00135              psmcmc);
00136 }
00137 
00138 static VOID
00139 AddStartContextMenuItems(IN HWND hWndOwner,
00140                          IN HMENU hPopup)
00141 {
00142     TCHAR szBuf[MAX_PATH];
00143     HRESULT hRet;
00144 
00145     /* Add the "Open All Users" menu item */
00146     if (LoadString(hExplorerInstance,
00147                    IDS_PROPERTIES,
00148                    szBuf,
00149                    sizeof(szBuf) / sizeof(szBuf[0])))
00150     {
00151         AppendMenu(hPopup,
00152                    MF_STRING,
00153                    ID_SHELL_CMD_PROPERTIES,
00154                    szBuf);
00155     }
00156 
00157     if (!SHRestricted(REST_NOCOMMONGROUPS))
00158     {
00159         /* Check if we should add menu items for the common start menu */
00160         hRet = SHGetFolderPath(hWndOwner,
00161                                CSIDL_COMMON_STARTMENU,
00162                                NULL,
00163                                SHGFP_TYPE_CURRENT,
00164                                szBuf);
00165         if (SUCCEEDED(hRet) && hRet != S_FALSE)
00166         {
00167             /* The directory exists, but only show the items if the
00168                user can actually make any changes to the common start
00169                menu. This is most likely only the case if the user
00170                has administrative rights! */
00171             if (IsUserAnAdmin())
00172             {
00173                 AppendMenu(hPopup,
00174                            MF_SEPARATOR,
00175                            0,
00176                            NULL);
00177 
00178                 /* Add the "Open All Users" menu item */
00179                 if (LoadString(hExplorerInstance,
00180                                IDS_OPEN_ALL_USERS,
00181                                szBuf,
00182                                sizeof(szBuf) / sizeof(szBuf[0])))
00183                 {
00184                     AppendMenu(hPopup,
00185                                MF_STRING,
00186                                ID_SHELL_CMD_OPEN_ALL_USERS,
00187                                szBuf);
00188                 }
00189 
00190                 /* Add the "Explore All Users" menu item */
00191                 if (LoadString(hExplorerInstance,
00192                                IDS_EXPLORE_ALL_USERS,
00193                                szBuf,
00194                                sizeof(szBuf) / sizeof(szBuf[0])))
00195                 {
00196                     AppendMenu(hPopup,
00197                                MF_STRING,
00198                                ID_SHELL_CMD_EXPLORE_ALL_USERS,
00199                                szBuf);
00200                 }
00201             }
00202         }
00203     }
00204 }
00205 
00206 static HMENU
00207 CreateStartContextMenu(IN HWND hWndOwner,
00208                        IN PVOID *ppcmContext,
00209                        IN PVOID Context  OPTIONAL)
00210 {
00211     LPITEMIDLIST pidlStart, pidlLast;
00212     IShellFolder *psfStart, *psfDesktop;
00213     IContextMenu *pcm;
00214     HRESULT hRet;
00215     HMENU hPopup;
00216 
00217     pidlStart = SHCloneSpecialIDList(hWndOwner,
00218                                      CSIDL_STARTMENU,
00219                                      TRUE);
00220 
00221     if (pidlStart != NULL)
00222     {
00223         pidlLast = ILClone(ILFindLastID(pidlStart));
00224         ILRemoveLastID(pidlStart);
00225 
00226         if (pidlLast != NULL)
00227         {
00228             hRet = SHGetDesktopFolder(&psfDesktop);
00229             if (SUCCEEDED(hRet))
00230             {
00231                 hRet = IShellFolder_BindToObject(psfDesktop,
00232                                                  pidlStart,
00233                                                  NULL,
00234                                                  (REFIID)&IID_IShellFolder, /* FIXME: Shouldn't require a typecast */
00235                                                  (PVOID*)&psfStart);
00236                 if (SUCCEEDED(hRet))
00237                 {
00238                     hPopup = CreateContextMenuFromShellFolderPidl(hWndOwner,
00239                                                                   psfStart,
00240                                                                   pidlLast,
00241                                                                   &pcm);
00242 
00243                     if (hPopup != NULL)
00244                     {
00245                         PSTARTMNU_CTMENU_CTX psmcmc;
00246 
00247                         psmcmc = HeapAlloc(hProcessHeap,
00248                                            0,
00249                                            sizeof(*psmcmc));
00250                         if (psmcmc != NULL)
00251                         {
00252                             psmcmc->pcm = pcm;
00253                             psmcmc->pidl = pidlLast;
00254 
00255                             AddStartContextMenuItems(hWndOwner,
00256                                                      hPopup);
00257 
00258                             *((PSTARTMNU_CTMENU_CTX*)ppcmContext) = psmcmc;
00259                             return hPopup;
00260                         }
00261                         else
00262                         {
00263                             IContextMenu_Release(pcm);
00264 
00265                             DestroyMenu(hPopup);
00266                             hPopup = NULL;
00267                         }
00268                     }
00269 
00270                     IShellFolder_Release(psfStart);
00271                 }
00272 
00273                 IShellFolder_Release(psfDesktop);
00274             }
00275 
00276             ILFree(pidlLast);
00277         }
00278 
00279         ILFree(pidlStart);
00280     }
00281 
00282     return NULL;
00283 }
00284 
00285 /*****************************************************************************
00286  ** IStartMenuSite ***********************************************************
00287  *****************************************************************************/
00288 
00289 static const IStartMenuSiteVtbl IStartMenuSiteImpl_Vtbl;
00290 static const IServiceProviderVtbl IServiceProviderImpl_Vtbl;
00291 static const ITrayPrivVtbl ITrayPrivImpl_Vtbl;
00292 static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl;
00293 
00294 typedef struct
00295 {
00296     const IStartMenuSiteVtbl *lpVtbl;
00297     const IServiceProviderVtbl *lpServiceProviderVtbl;
00298     const ITrayPrivVtbl *lpStartMenuCallbackVtbl;
00299     const IOleCommandTargetVtbl *lpOleCommandTargetVtbl;
00300     LONG Ref;
00301 
00302     ITrayWindow *Tray;
00303 } IStartMenuSiteImpl;
00304 
00305 static IUnknown *
00306 IUnknown_from_IStartMenuSiteImpl(IStartMenuSiteImpl *This)
00307 {
00308     return (IUnknown *)&This->lpVtbl;
00309 }
00310 
00311 IMPL_CASTS(IStartMenuSite, IStartMenuSite, lpVtbl)
00312 IMPL_CASTS(IServiceProvider, IStartMenuSite, lpServiceProviderVtbl)
00313 IMPL_CASTS(ITrayPriv, IStartMenuSite, lpStartMenuCallbackVtbl)
00314 IMPL_CASTS(IOleCommandTarget, IStartMenuSite, lpOleCommandTargetVtbl)
00315 
00316 /*******************************************************************/
00317 
00318 static ULONG STDMETHODCALLTYPE
00319 IStartMenuSiteImpl_AddRef(IN OUT IStartMenuSite *iface)
00320 {
00321     IStartMenuSiteImpl *This = IStartMenuSiteImpl_from_IStartMenuSite(iface);
00322 
00323     return InterlockedIncrement(&This->Ref);
00324 }
00325 
00326 static VOID
00327 IStartMenuSiteImpl_Free(IN OUT IStartMenuSiteImpl *This)
00328 {
00329     HeapFree(hProcessHeap,
00330              0,
00331              This);
00332 }
00333 
00334 static ULONG STDMETHODCALLTYPE
00335 IStartMenuSiteImpl_Release(IN OUT IStartMenuSite *iface)
00336 {
00337     IStartMenuSiteImpl *This = IStartMenuSiteImpl_from_IStartMenuSite(iface);
00338     ULONG Ret;
00339 
00340     Ret = InterlockedDecrement(&This->Ref);
00341 
00342     if (Ret == 0)
00343         IStartMenuSiteImpl_Free(This);
00344 
00345     return Ret;
00346 }
00347 
00348 static HRESULT STDMETHODCALLTYPE
00349 IStartMenuSiteImpl_QueryInterface(IN OUT IStartMenuSite *iface,
00350                                   IN REFIID riid,
00351                                   OUT LPVOID *ppvObj)
00352 {
00353     IStartMenuSiteImpl *This;
00354 
00355     if (ppvObj == NULL)
00356         return E_POINTER;
00357 
00358     This = IStartMenuSiteImpl_from_IStartMenuSite(iface);
00359 
00360     if (IsEqualIID(riid,
00361                    &IID_IUnknown))
00362     {
00363         *ppvObj = IUnknown_from_IStartMenuSiteImpl(This);
00364     }
00365     else if (IsEqualIID(riid,
00366                         &IID_IServiceProvider))
00367     {
00368         *ppvObj = IServiceProvider_from_IStartMenuSiteImpl(This);
00369     }
00370     else if (IsEqualIID(riid,
00371                         &IID_ITrayPriv) ||
00372              IsEqualIID(riid,
00373                         &IID_IOleWindow))
00374     {
00375         *ppvObj = ITrayPriv_from_IStartMenuSiteImpl(This);
00376     }
00377     else if (IsEqualIID(riid,
00378                         &IID_IOleCommandTarget))
00379     {
00380         *ppvObj = IOleCommandTarget_from_IStartMenuSiteImpl(This);
00381     }
00382     else
00383     {
00384         DbgPrint("IStartMenuSite::QueryInterface queried unsupported interface: "
00385                  "{0x%8x,0x%4x,0x%4x,{0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x}}\n",
00386                  riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], riid->Data4[1],
00387                  riid->Data4[2], riid->Data4[3], riid->Data4[4], riid->Data4[5],
00388                  riid->Data4[6], riid->Data4[7]);
00389         *ppvObj = NULL;
00390         return E_NOINTERFACE;
00391     }
00392 
00393     IStartMenuSiteImpl_AddRef(iface);
00394     return S_OK;
00395 }
00396 
00397 static const IStartMenuSiteVtbl IStartMenuSiteImpl_Vtbl =
00398 {
00399     /*** IUnknown methods ***/
00400     IStartMenuSiteImpl_QueryInterface,
00401     IStartMenuSiteImpl_AddRef,
00402     IStartMenuSiteImpl_Release,
00403     /*** IStartMenuSite methods ***/
00404 };
00405 
00406 /*******************************************************************/
00407 
00408 METHOD_IUNKNOWN_INHERITED_ADDREF(IServiceProvider, IStartMenuSite)
00409 METHOD_IUNKNOWN_INHERITED_RELEASE(IServiceProvider, IStartMenuSite)
00410 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IServiceProvider, IStartMenuSite)
00411 
00412 static HRESULT STDMETHODCALLTYPE
00413 IStartMenuSiteImpl_QueryService(IN OUT IServiceProvider *iface,
00414                                 IN REFGUID guidService,
00415                                 IN REFIID riid,
00416                                 OUT PVOID *ppvObject)
00417 {
00418     IStartMenuSiteImpl *This = IStartMenuSiteImpl_from_IServiceProvider(iface);
00419 
00420     if (IsEqualGUID(guidService,
00421                     &SID_SMenuPopup))
00422     {
00423         return IStartMenuSiteImpl_QueryInterface(IStartMenuSite_from_IStartMenuSiteImpl(This),
00424                                                  riid,
00425                                                  ppvObject);
00426     }
00427 
00428     return E_NOINTERFACE;
00429 }
00430 
00431 static const IServiceProviderVtbl IServiceProviderImpl_Vtbl =
00432 {
00433     /*** IUnknown methods ***/
00434     METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IServiceProvider, IStartMenuSite),
00435     METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IServiceProvider, IStartMenuSite),
00436     METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IServiceProvider, IStartMenuSite),
00437     /*** IServiceProvider methods ***/
00438     IStartMenuSiteImpl_QueryService
00439 };
00440 
00441 /*******************************************************************/
00442 
00443 METHOD_IUNKNOWN_INHERITED_ADDREF(ITrayPriv, IStartMenuSite)
00444 METHOD_IUNKNOWN_INHERITED_RELEASE(ITrayPriv, IStartMenuSite)
00445 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(ITrayPriv, IStartMenuSite)
00446 
00447 static HRESULT STDMETHODCALLTYPE
00448 IStartMenuSiteImpl_GetWindow(IN OUT ITrayPriv *iface,
00449                              OUT HWND *phwnd)
00450 {
00451     IStartMenuSiteImpl *This = IStartMenuSiteImpl_from_ITrayPriv(iface);
00452     DbgPrint("ITrayPriv::GetWindow\n");
00453 
00454     *phwnd = ITrayWindow_GetHWND(This->Tray);
00455     if (*phwnd != NULL)
00456         return S_OK;
00457 
00458     return E_FAIL;
00459 }
00460 
00461 static HRESULT STDMETHODCALLTYPE
00462 IStartMenuSiteImpl_ContextSensitiveHelp(IN OUT ITrayPriv *iface,
00463                                         IN BOOL fEnterMode)
00464 {
00465     DbgPrint("ITrayPriv::ContextSensitiveHelp\n");
00466     return E_NOTIMPL;
00467 }
00468 
00469 static HRESULT STDMETHODCALLTYPE
00470 IStartMenuSiteImpl_Execute(IN OUT ITrayPriv *iface,
00471                            IN IShellFolder *pShellFolder,
00472                            IN LPCITEMIDLIST pidl)
00473 {
00474     HMODULE hShlwapi;
00475     HRESULT ret = S_FALSE;
00476 
00477     IStartMenuSiteImpl *This = IStartMenuSiteImpl_from_ITrayPriv(iface);
00478 
00479     DbgPrint("ITrayPriv::Execute\n");
00480 
00481     hShlwapi = GetModuleHandle(TEXT("SHLWAPI.DLL"));
00482     if (hShlwapi != NULL)
00483     {
00484         SHINVDEFCMD SHInvokeDefCmd;
00485 
00486         /* SHInvokeDefaultCommand */
00487         SHInvokeDefCmd = (SHINVDEFCMD)GetProcAddress(hShlwapi,
00488                                                      (LPCSTR)((LONG)279));
00489         if (SHInvokeDefCmd != NULL)
00490         {
00491             ret = SHInvokeDefCmd(ITrayWindow_GetHWND(This->Tray),
00492                                  pShellFolder,
00493                                  pidl);
00494         }
00495     }
00496 
00497     return ret;
00498 }
00499 
00500 static HRESULT STDMETHODCALLTYPE
00501 IStartMenuSiteImpl_Unknown(IN OUT ITrayPriv *iface,
00502                            IN PVOID Unknown1,
00503                            IN PVOID Unknown2,
00504                            IN PVOID Unknown3,
00505                            IN PVOID Unknown4)
00506 {
00507     DbgPrint("ITrayPriv::Unknown(0x%p,0x%p,0x%p,0x%p)\n", Unknown1, Unknown2, Unknown3, Unknown4);
00508     return E_NOTIMPL;
00509 }
00510 
00511 static BOOL
00512 ShowUndockMenuItem(VOID)
00513 {
00514     DbgPrint("ShowUndockMenuItem() not implemented!\n");
00515     /* FIXME: How do we detect this?! */
00516     return FALSE;
00517 }
00518 
00519 static BOOL
00520 ShowSynchronizeMenuItem(VOID)
00521 {
00522     DbgPrint("ShowSynchronizeMenuItem() not implemented!\n");
00523     /* FIXME: How do we detect this?! */
00524     return FALSE;
00525 }
00526 
00527 static HRESULT STDMETHODCALLTYPE
00528 IStartMenuSiteImpl_AppendMenu(IN OUT ITrayPriv *iface,
00529                               OUT HMENU* phMenu)
00530 {
00531     HMENU hMenu, hSettingsMenu;
00532     DWORD dwLogoff;
00533     BOOL bWantLogoff;
00534     UINT uLastItemsCount = 5; /* 5 menu items below the last separator */
00535     TCHAR szUser[128];
00536 
00537     DbgPrint("ITrayPriv::AppendMenu\n");
00538 
00539     hMenu = LoadPopupMenu(hExplorerInstance,
00540                           MAKEINTRESOURCE(IDM_STARTMENU));
00541     *phMenu = hMenu;
00542     if (hMenu == NULL)
00543         return E_FAIL;
00544 
00545     /* Remove menu items that don't apply */
00546 
00547     dwLogoff = SHRestricted(REST_STARTMENULOGOFF);
00548     bWantLogoff = (dwLogoff == 2 ||
00549                    SHRestricted(REST_FORCESTARTMENULOGOFF) ||
00550                    GetExplorerRegValueSet(HKEY_CURRENT_USER,
00551                                           TEXT("Advanced"),
00552                                           TEXT("StartMenuLogoff")));
00553 
00554     /* FIXME: Favorites */
00555 
00556     /* Documents */
00557     if (SHRestricted(REST_NORECENTDOCSMENU))
00558     {
00559         DeleteMenu(hMenu,
00560                    IDM_DOCUMENTS,
00561                    MF_BYCOMMAND);
00562     }
00563 
00564     /* Settings */
00565     hSettingsMenu = FindSubMenu(hMenu,
00566                                 IDM_SETTINGS,
00567                                 FALSE);
00568     if (hSettingsMenu != NULL)
00569     {
00570         if (SHRestricted(REST_NOSETFOLDERS))
00571         {
00572             /* Control Panel */
00573             if (SHRestricted(REST_NOCONTROLPANEL))
00574             {
00575                 DeleteMenu(hSettingsMenu,
00576                            IDM_CONTROLPANEL,
00577                            MF_BYCOMMAND);
00578 
00579                 /* Delete the separator below it */
00580                 DeleteMenu(hSettingsMenu,
00581                            0,
00582                            MF_BYPOSITION);
00583             }
00584 
00585             /* Network Connections */
00586             if (SHRestricted(REST_NONETWORKCONNECTIONS))
00587             {
00588                 DeleteMenu(hSettingsMenu,
00589                            IDM_NETWORKCONNECTIONS,
00590                            MF_BYCOMMAND);
00591             }
00592 
00593             /* Printers and Faxes */
00594             DeleteMenu(hSettingsMenu,
00595                        IDM_PRINTERSANDFAXES,
00596                        MF_BYCOMMAND);
00597         }
00598 
00599         /* Security */
00600         if (GetSystemMetrics(SM_REMOTECONTROL) == 0 ||
00601             SHRestricted(REST_NOSECURITY))
00602         {
00603             DeleteMenu(hSettingsMenu,
00604                        IDM_SECURITY,
00605                        MF_BYCOMMAND);
00606         }
00607 
00608         if (GetMenuItemCount(hSettingsMenu) == 0)
00609         {
00610             DeleteMenu(hMenu,
00611                        IDM_SETTINGS,
00612                        MF_BYCOMMAND);
00613         }
00614     }
00615 
00616     /* Search */
00617     if (SHRestricted(REST_NOFIND))
00618     {
00619         DeleteMenu(hMenu,
00620                    IDM_SEARCH,
00621                    MF_BYCOMMAND);
00622     }
00623 
00624     /* FIXME: Help */
00625 
00626     /* Run */
00627     if (SHRestricted(REST_NORUN))
00628     {
00629         DeleteMenu(hMenu,
00630                    IDM_RUN,
00631                    MF_BYCOMMAND);
00632     }
00633 
00634     /* Synchronize */
00635     if (!ShowSynchronizeMenuItem())
00636     {
00637         DeleteMenu(hMenu,
00638                    IDM_SYNCHRONIZE,
00639                    MF_BYCOMMAND);
00640         uLastItemsCount--;
00641     }
00642 
00643     /* Log off */
00644     if (dwLogoff != 1 && bWantLogoff)
00645     {
00646         /* FIXME: We need a more sophisticated way to determine whether to show
00647                   or hide it, it might be hidden in too many cases!!! */
00648 
00649         /* Update Log Off menu item */
00650         if (!GetCurrentLoggedOnUserName(szUser,
00651                                         sizeof(szUser) / sizeof(szUser[0])))
00652         {
00653             szUser[0] = _T('\0');
00654         }
00655 
00656         if (!FormatMenuString(hMenu,
00657                               IDM_LOGOFF,
00658                               MF_BYCOMMAND,
00659                               szUser))
00660         {
00661             /* We couldn't update the menu item, delete it... */
00662             DeleteMenu(hMenu,
00663                        IDM_LOGOFF,
00664                        MF_BYCOMMAND);
00665         }
00666     }
00667     else
00668     {
00669         DeleteMenu(hMenu,
00670                    IDM_LOGOFF,
00671                    MF_BYCOMMAND);
00672         uLastItemsCount--;
00673     }
00674 
00675 
00676     /* Disconnect */
00677     if (GetSystemMetrics(SM_REMOTECONTROL) == 0)
00678     {
00679         DeleteMenu(hMenu,
00680                    IDM_DISCONNECT,
00681                    MF_BYCOMMAND);
00682         uLastItemsCount--;
00683     }
00684 
00685     /* Undock computer */
00686     if (!ShowUndockMenuItem())
00687     {
00688         DeleteMenu(hMenu,
00689                    IDM_UNDOCKCOMPUTER,
00690                    MF_BYCOMMAND);
00691         uLastItemsCount--;
00692     }
00693 
00694     /* Shut down */
00695     if (SHRestricted(REST_NOCLOSE))
00696     {
00697         DeleteMenu(hMenu,
00698                    IDM_SHUTDOWN,
00699                    MF_BYCOMMAND);
00700         uLastItemsCount--;
00701     }
00702 
00703     if (uLastItemsCount == 0)
00704     {
00705         /* Remove the separator at the end of the menu */
00706         DeleteMenu(hMenu,
00707                    IDM_LASTSTARTMENU_SEPARATOR,
00708                    MF_BYCOMMAND);
00709     }
00710 
00711     return S_OK;
00712 }
00713 
00714 static const ITrayPrivVtbl ITrayPrivImpl_Vtbl =
00715 {
00716     /*** IUnknown methods ***/
00717     METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(ITrayPriv, IStartMenuSite),
00718     METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(ITrayPriv, IStartMenuSite),
00719     METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(ITrayPriv, IStartMenuSite),
00720     /*** IOleWindow methods ***/
00721     IStartMenuSiteImpl_GetWindow,
00722     IStartMenuSiteImpl_ContextSensitiveHelp,
00723     /*** ITrayPriv methods ***/
00724     IStartMenuSiteImpl_Execute,
00725     IStartMenuSiteImpl_Unknown,
00726     IStartMenuSiteImpl_AppendMenu
00727 };
00728 
00729 /*******************************************************************/
00730 
00731 METHOD_IUNKNOWN_INHERITED_ADDREF(IOleCommandTarget, IStartMenuSite)
00732 METHOD_IUNKNOWN_INHERITED_RELEASE(IOleCommandTarget, IStartMenuSite)
00733 METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IOleCommandTarget, IStartMenuSite)
00734 
00735 static HRESULT STDMETHODCALLTYPE
00736 IStartMenuSiteImpl_QueryStatus(IN OUT IOleCommandTarget *iface,
00737                                IN const GUID *pguidCmdGroup  OPTIONAL,
00738                                IN ULONG cCmds,
00739                                IN OUT OLECMD *prgCmds,
00740                                IN OUT OLECMDTEXT *pCmdText  OPTIONAL)
00741 {
00742     return E_NOTIMPL;
00743 }
00744 
00745 static HRESULT STDMETHODCALLTYPE
00746 IStartMenuSiteImpl_Exec(IN OUT IOleCommandTarget *iface,
00747                         IN const GUID *pguidCmdGroup  OPTIONAL,
00748                         IN DWORD nCmdID,
00749                         IN DWORD nCmdExecOpt,
00750                         IN VARIANTARG *pvaIn  OPTIONAL,
00751                         IN VARIANTARG *pvaOut  OPTIONAL)
00752 {
00753     return E_NOTIMPL;
00754 }
00755 
00756 static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl =
00757 {
00758     /*** IUnknown methods ***/
00759     METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IOleCommandTarget, IStartMenuSite),
00760     METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IOleCommandTarget, IStartMenuSite),
00761     METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IOleCommandTarget, IStartMenuSite),
00762     /*** IOleCommandTarget ***/
00763     IStartMenuSiteImpl_QueryStatus,
00764     IStartMenuSiteImpl_Exec
00765 };
00766 
00767 /*******************************************************************/
00768 
00769 static IStartMenuSiteImpl*
00770 IStartMenuSiteImpl_Construct(IN ITrayWindow *Tray)
00771 {
00772     IStartMenuSiteImpl *This;
00773 
00774     This = HeapAlloc(hProcessHeap,
00775                      0,
00776                      sizeof(*This));
00777     if (This == NULL)
00778         return NULL;
00779 
00780     ZeroMemory(This,
00781                sizeof(*This));
00782 
00783     This->lpVtbl = &IStartMenuSiteImpl_Vtbl;
00784     This->lpServiceProviderVtbl = &IServiceProviderImpl_Vtbl;
00785     This->lpStartMenuCallbackVtbl = &ITrayPrivImpl_Vtbl;
00786     This->lpOleCommandTargetVtbl = &IOleCommandTargetImpl_Vtbl;
00787     This->Ref = 1;
00788 
00789     This->Tray = Tray;
00790 
00791     return This;
00792 }
00793 
00794 static IStartMenuSite*
00795 CreateStartMenuSite(IN ITrayWindow *Tray)
00796 {
00797     IStartMenuSiteImpl *This;
00798 
00799     This = IStartMenuSiteImpl_Construct(Tray);
00800     if (This != NULL)
00801     {
00802         return IStartMenuSite_from_IStartMenuSiteImpl(This);
00803     }
00804 
00805     return NULL;
00806 }
00807 
00808 HRESULT
00809 UpdateStartMenu(IN OUT IMenuPopup *pMenuPopup,
00810                 IN HBITMAP hbmBanner  OPTIONAL,
00811                 IN BOOL bSmallIcons)
00812 {
00813     IBanneredBar *pbb;
00814     HRESULT hRet;
00815 
00816     hRet = IMenuPopup_QueryInterface(pMenuPopup,
00817                                      &IID_IBanneredBar,
00818                                      (PVOID)&pbb);
00819     if (SUCCEEDED(hRet))
00820     {
00821         hRet = IBanneredBar_SetBitmap(pbb, hbmBanner);
00822 
00823 
00824         /* Update the icon size */
00825         hRet = IBanneredBar_SetIconSize(pbb,
00826                                         bSmallIcons ? BMICON_SMALL : BMICON_LARGE);
00827 
00828         IBanneredBar_Release(pbb);
00829     }
00830 
00831     return hRet;
00832 }
00833 
00834 IMenuPopup*
00835 CreateStartMenu(IN ITrayWindow *Tray,
00836                 OUT IMenuBand **ppMenuBand,
00837                 IN HBITMAP hbmBanner  OPTIONAL,
00838                 IN BOOL bSmallIcons)
00839 {
00840     HRESULT hr;
00841     IObjectWithSite *pOws = NULL;
00842     IMenuPopup *pMp = NULL;
00843     IStartMenuSite *pSms = NULL;
00844     IMenuBand *pMb = NULL;
00845     IInitializeObject *pIo;
00846     IUnknown *pUnk = NULL;
00847     IBandSite *pBs = NULL;
00848     DWORD dwBandId = 0;
00849 
00850     pSms = CreateStartMenuSite(Tray);
00851     if (pSms == NULL)
00852         return NULL;
00853 
00854     hr = CoCreateInstance(&CLSID_StartMenu,
00855                           NULL,
00856                           CLSCTX_INPROC_SERVER,
00857                           &IID_IMenuPopup,
00858                           (PVOID*)&pMp);
00859     if (FAILED(hr))
00860     {
00861         DbgPrint("CoCreateInstance failed: %x\n", hr);
00862         goto cleanup;
00863     }
00864 
00865     hr = IMenuPopup_QueryInterface(pMp,
00866                                    &IID_IObjectWithSite,
00867                                    (PVOID*)&pOws);
00868     if (FAILED(hr))
00869     {
00870         DbgPrint("IMenuPopup_QueryInterface failed: %x\n", hr);
00871         goto cleanup;
00872     }
00873 
00874     /* Set the menu site so we can handle messages */
00875     hr = IObjectWithSite_SetSite(pOws, (IUnknown*)pSms);
00876     if (FAILED(hr))
00877     {
00878         DbgPrint("IObjectWithSite_SetSite failed: %x\n", hr);
00879         goto cleanup;
00880     }
00881 
00882     /* Initialize the menu object */
00883     hr = IMenuPopup_QueryInterface(pMp, &IID_IInitializeObject, (PVOID*)&pIo);
00884     if (SUCCEEDED(hr))
00885     {
00886         hr = IInitializeObject_Initialize(pIo);
00887         IInitializeObject_Release(pIo);
00888     }
00889     else
00890         hr = S_OK;
00891 
00892     /* Everything is initialized now. Let's get the IMenuBand interface. */
00893     if (FAILED(hr))
00894     {
00895         DbgPrint("IMenuPopup_QueryInterface failed: %x\n", hr);
00896         goto cleanup;
00897     }
00898 
00899     hr = IMenuPopup_GetClient(pMp, &pUnk);
00900     if (FAILED(hr))
00901     {
00902         DbgPrint("IMenuPopup_GetClient failed: %x\n", hr);
00903         goto cleanup;
00904     }
00905 
00906     hr = IUnknown_QueryInterface(pUnk, &IID_IBandSite, (PVOID*)&pBs);
00907     if (FAILED(hr))
00908     {
00909         DbgPrint("IUnknown_QueryInterface pBs failed: %x\n", hr);
00910         goto cleanup;
00911     }
00912 
00913     /* Finally we have the IBandSite interface, there's only one
00914        band in it that apparently provides the IMenuBand interface */
00915     hr = IBandSite_EnumBands(pBs, 0, &dwBandId);
00916     if (FAILED(hr))
00917     {
00918         DbgPrint("IBandSite_EnumBands failed: %x\n", hr);
00919         goto cleanup;
00920     }
00921 
00922     hr = IBandSite_GetBandObject(pBs, dwBandId, &IID_IMenuBand, (PVOID*)&pMb);
00923     if (FAILED(hr))
00924     {
00925         DbgPrint("IBandSite_GetBandObject failed: %x\n", hr);
00926         goto cleanup;
00927     }
00928 
00929     UpdateStartMenu(pMp,
00930                     hbmBanner,
00931                     bSmallIcons);
00932 
00933 cleanup:
00934     if (SUCCEEDED(hr))
00935         *ppMenuBand = pMb;
00936     else if (pMb != NULL)
00937         IMenuBand_Release(pMb);
00938 
00939     if (pBs != NULL)
00940         IBandSite_Release(pBs);
00941     if (pUnk != NULL)
00942         IUnknown_Release(pUnk);
00943     if (pOws != NULL)
00944         IObjectWithSite_Release(pOws);
00945     if (pMp != NULL)
00946         IMenuPopup_Release(pMp);
00947     if (pSms != NULL)
00948         IStartMenuSite_Release(pSms);
00949 
00950     if (FAILED(hr))
00951         return NULL;
00952     return pMp;
00953 }

Generated on Sun May 27 2012 04:18:27 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.