Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstartmnu.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
1.7.6.1
|