Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenshlmenu.cpp
Go to the documentation of this file.
00001 /* 00002 * see www.geocities.com/SiliconValley/4942/filemenu.html 00003 * 00004 * Copyright 1999, 2000 Juergen Schmied 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 St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include <precomp.h> 00022 00023 #ifdef FM_SEPARATOR 00024 #undef FM_SEPARATOR 00025 #endif 00026 #define FM_SEPARATOR (LPCWSTR)1 00027 00028 static BOOL FileMenu_AppendItemW(HMENU hMenu, LPCWSTR lpText, UINT uID, int icon, 00029 HMENU hMenuPopup, int nItemHeight); 00030 00031 typedef struct 00032 { 00033 BOOL bInitialized; 00034 BOOL bFixedItems; 00035 /* create */ 00036 COLORREF crBorderColor; 00037 int nBorderWidth; 00038 HBITMAP hBorderBmp; 00039 00040 /* insert using pidl */ 00041 LPITEMIDLIST pidl; 00042 UINT uID; 00043 UINT uFlags; 00044 UINT uEnumFlags; 00045 LPFNFMCALLBACK lpfnCallback; 00046 } FMINFO, *LPFMINFO; 00047 00048 typedef struct 00049 { int cchItemText; 00050 int iIconIndex; 00051 HMENU hMenu; 00052 WCHAR szItemText[1]; 00053 } FMITEM, * LPFMITEM; 00054 00055 static BOOL bAbortInit; 00056 00057 #define CCH_MAXITEMTEXT 256 00058 00059 WINE_DEFAULT_DEBUG_CHANNEL(shell); 00060 00061 static LPFMINFO FM_GetMenuInfo(HMENU hmenu) 00062 { 00063 MENUINFO MenuInfo; 00064 LPFMINFO menudata; 00065 00066 MenuInfo.cbSize = sizeof(MENUINFO); 00067 MenuInfo.fMask = MIM_MENUDATA; 00068 00069 if (! GetMenuInfo(hmenu, &MenuInfo)) 00070 return NULL; 00071 00072 menudata = (LPFMINFO)MenuInfo.dwMenuData; 00073 00074 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO))) 00075 { 00076 ERR("menudata corrupt: %p %u\n", menudata, MenuInfo.cbSize); 00077 return 0; 00078 } 00079 00080 return menudata; 00081 00082 } 00083 /************************************************************************* 00084 * FM_SetMenuParameter [internal] 00085 * 00086 */ 00087 static LPFMINFO FM_SetMenuParameter( 00088 HMENU hmenu, 00089 UINT uID, 00090 LPCITEMIDLIST pidl, 00091 UINT uFlags, 00092 UINT uEnumFlags, 00093 LPFNFMCALLBACK lpfnCallback) 00094 { 00095 LPFMINFO menudata; 00096 00097 TRACE("\n"); 00098 00099 menudata = FM_GetMenuInfo(hmenu); 00100 00101 SHFree(menudata->pidl); 00102 00103 menudata->uID = uID; 00104 menudata->pidl = ILClone(pidl); 00105 menudata->uFlags = uFlags; 00106 menudata->uEnumFlags = uEnumFlags; 00107 menudata->lpfnCallback = lpfnCallback; 00108 00109 return menudata; 00110 } 00111 00112 /************************************************************************* 00113 * FM_InitMenuPopup [internal] 00114 * 00115 */ 00116 static int FM_InitMenuPopup(HMENU hmenu, LPCITEMIDLIST pAlternatePidl) 00117 { IShellFolder *lpsf, *lpsf2; 00118 ULONG ulItemAttr = SFGAO_FOLDER; 00119 UINT uID, uEnumFlags; 00120 LPFNFMCALLBACK lpfnCallback; 00121 LPCITEMIDLIST pidl; 00122 WCHAR sTemp[MAX_PATH]; 00123 int NumberOfItems = 0, iIcon; 00124 MENUINFO MenuInfo; 00125 LPFMINFO menudata; 00126 00127 TRACE("%p %p\n", hmenu, pAlternatePidl); 00128 00129 MenuInfo.cbSize = sizeof(MENUINFO); 00130 MenuInfo.fMask = MIM_MENUDATA; 00131 00132 if (! GetMenuInfo(hmenu, &MenuInfo)) 00133 return FALSE; 00134 00135 menudata = (LPFMINFO)MenuInfo.dwMenuData; 00136 00137 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO))) 00138 { 00139 ERR("menudata corrupt: %p %u\n", menudata, MenuInfo.cbSize); 00140 return 0; 00141 } 00142 00143 if (menudata->bInitialized) 00144 return 0; 00145 00146 pidl = (pAlternatePidl? pAlternatePidl: menudata->pidl); 00147 if (!pidl) 00148 return 0; 00149 00150 uID = menudata->uID; 00151 uEnumFlags = menudata->uEnumFlags; 00152 lpfnCallback = menudata->lpfnCallback; 00153 menudata->bInitialized = FALSE; 00154 00155 SetMenuInfo(hmenu, &MenuInfo); 00156 00157 if (SUCCEEDED (SHGetDesktopFolder(&lpsf))) 00158 { 00159 if (SUCCEEDED(lpsf->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID *)&lpsf2))) 00160 { 00161 IEnumIDList *lpe = NULL; 00162 00163 if (SUCCEEDED (lpsf2->EnumObjects(0, uEnumFlags, &lpe ))) 00164 { 00165 00166 LPITEMIDLIST pidlTemp = NULL; 00167 ULONG ulFetched; 00168 00169 while ((!bAbortInit) && (NOERROR == lpe->Next(1,&pidlTemp,&ulFetched))) 00170 { 00171 if (SUCCEEDED (lpsf->GetAttributesOf(1, (LPCITEMIDLIST*)&pidlTemp, &ulItemAttr))) 00172 { 00173 ILGetDisplayNameExW(NULL, pidlTemp, sTemp, ILGDN_FORPARSING); 00174 if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon))) 00175 iIcon = FM_BLANK_ICON; 00176 if ( SFGAO_FOLDER & ulItemAttr) 00177 { 00178 LPFMINFO lpFmMi; 00179 MENUINFO MenuInfo; 00180 HMENU hMenuPopup = CreatePopupMenu(); 00181 00182 lpFmMi = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO)); 00183 00184 lpFmMi->pidl = ILCombine(pidl, pidlTemp); 00185 lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS; 00186 00187 MenuInfo.cbSize = sizeof(MENUINFO); 00188 MenuInfo.fMask = MIM_MENUDATA; 00189 MenuInfo.dwMenuData = (ULONG_PTR) lpFmMi; 00190 SetMenuInfo (hMenuPopup, &MenuInfo); 00191 00192 FileMenu_AppendItemW (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT); 00193 } 00194 else 00195 { 00196 LPWSTR pExt = PathFindExtensionW(sTemp); 00197 if (pExt) 00198 *pExt = 0; 00199 FileMenu_AppendItemW (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT); 00200 } 00201 } 00202 00203 if (lpfnCallback) 00204 { 00205 TRACE("enter callback\n"); 00206 lpfnCallback ( pidl, pidlTemp); 00207 TRACE("leave callback\n"); 00208 } 00209 00210 NumberOfItems++; 00211 } 00212 lpe->Release(); 00213 } 00214 lpsf2->Release(); 00215 } 00216 lpsf->Release(); 00217 } 00218 00219 if ( GetMenuItemCount (hmenu) == 0 ) 00220 { 00221 static const WCHAR szEmpty[] = { '(','e','m','p','t','y',')',0 }; 00222 FileMenu_AppendItemW (hmenu, szEmpty, uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT); 00223 NumberOfItems++; 00224 } 00225 00226 menudata->bInitialized = TRUE; 00227 SetMenuInfo(hmenu, &MenuInfo); 00228 00229 return NumberOfItems; 00230 } 00231 /************************************************************************* 00232 * FileMenu_Create [SHELL32.114] 00233 * 00234 * NOTES 00235 * for non-root menus values are 00236 * (ffffffff,00000000,00000000,00000000,00000000) 00237 */ 00238 HMENU WINAPI FileMenu_Create ( 00239 COLORREF crBorderColor, 00240 int nBorderWidth, 00241 HBITMAP hBorderBmp, 00242 int nSelHeight, 00243 UINT uFlags) 00244 { 00245 MENUINFO MenuInfo; 00246 LPFMINFO menudata; 00247 00248 HMENU hMenu = CreatePopupMenu(); 00249 00250 TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x hMenu=%p\n", 00251 crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu); 00252 00253 menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO)); 00254 menudata->crBorderColor = crBorderColor; 00255 menudata->nBorderWidth = nBorderWidth; 00256 menudata->hBorderBmp = hBorderBmp; 00257 00258 MenuInfo.cbSize = sizeof(MENUINFO); 00259 MenuInfo.fMask = MIM_MENUDATA; 00260 MenuInfo.dwMenuData = (ULONG_PTR) menudata; 00261 SetMenuInfo (hMenu, &MenuInfo); 00262 00263 return hMenu; 00264 } 00265 00266 /************************************************************************* 00267 * FileMenu_Destroy [SHELL32.118] 00268 * 00269 * NOTES 00270 * exported by name 00271 */ 00272 void WINAPI FileMenu_Destroy (HMENU hmenu) 00273 { 00274 LPFMINFO menudata; 00275 00276 TRACE("%p\n", hmenu); 00277 00278 FileMenu_DeleteAllItems (hmenu); 00279 00280 menudata = FM_GetMenuInfo(hmenu); 00281 00282 SHFree( menudata->pidl); 00283 HeapFree(GetProcessHeap(), 0, menudata); 00284 00285 DestroyMenu (hmenu); 00286 } 00287 00288 /************************************************************************* 00289 * FileMenu_AppendItem [SHELL32.115] 00290 * 00291 */ 00292 static BOOL FileMenu_AppendItemW( 00293 HMENU hMenu, 00294 LPCWSTR lpText, 00295 UINT uID, 00296 int icon, 00297 HMENU hMenuPopup, 00298 int nItemHeight) 00299 { 00300 MENUITEMINFOW mii; 00301 LPFMITEM myItem; 00302 LPFMINFO menudata; 00303 MENUINFO MenuInfo; 00304 00305 00306 TRACE("%p %s 0x%08x 0x%08x %p 0x%08x\n", 00307 hMenu, (lpText!=FM_SEPARATOR) ? debugstr_w(lpText) : NULL, 00308 uID, icon, hMenuPopup, nItemHeight); 00309 00310 ZeroMemory (&mii, sizeof(MENUITEMINFOW)); 00311 00312 mii.cbSize = sizeof(MENUITEMINFOW); 00313 00314 if (lpText != FM_SEPARATOR) 00315 { 00316 int len = strlenW (lpText); 00317 myItem = (LPFMITEM)SHAlloc(sizeof(FMITEM) + len*sizeof(WCHAR)); 00318 wcscpy (myItem->szItemText, lpText); 00319 myItem->cchItemText = len; 00320 myItem->iIconIndex = icon; 00321 myItem->hMenu = hMenu; 00322 mii.fMask = MIIM_DATA; 00323 mii.dwItemData = (ULONG_PTR) myItem; 00324 } 00325 00326 if ( hMenuPopup ) 00327 { /* sub menu */ 00328 mii.fMask |= MIIM_TYPE | MIIM_SUBMENU; 00329 mii.fType = MFT_OWNERDRAW; 00330 mii.hSubMenu = hMenuPopup; 00331 } 00332 else if (lpText == FM_SEPARATOR ) 00333 { mii.fMask |= MIIM_ID | MIIM_TYPE; 00334 mii.fType = MFT_SEPARATOR; 00335 } 00336 else 00337 { /* normal item */ 00338 mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE; 00339 mii.fState = MFS_ENABLED | MFS_DEFAULT; 00340 mii.fType = MFT_OWNERDRAW; 00341 } 00342 mii.wID = uID; 00343 00344 InsertMenuItemW (hMenu, (UINT)-1, TRUE, &mii); 00345 00346 /* set bFixedItems to true */ 00347 MenuInfo.cbSize = sizeof(MENUINFO); 00348 MenuInfo.fMask = MIM_MENUDATA; 00349 00350 if (! GetMenuInfo(hMenu, &MenuInfo)) 00351 return FALSE; 00352 00353 menudata = (LPFMINFO)MenuInfo.dwMenuData; 00354 if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO))) 00355 { 00356 ERR("menudata corrupt: %p %u\n", menudata, MenuInfo.cbSize); 00357 return 0; 00358 } 00359 00360 menudata->bFixedItems = TRUE; 00361 SetMenuInfo(hMenu, &MenuInfo); 00362 00363 return TRUE; 00364 00365 } 00366 00367 /**********************************************************************/ 00368 00369 EXTERN_C BOOL WINAPI FileMenu_AppendItemAW( 00370 HMENU hMenu, 00371 LPCVOID lpText, 00372 UINT uID, 00373 int icon, 00374 HMENU hMenuPopup, 00375 int nItemHeight) 00376 { 00377 BOOL ret; 00378 00379 if (!lpText) return FALSE; 00380 00381 if (SHELL_OsIsUnicode() || lpText == FM_SEPARATOR) 00382 ret = FileMenu_AppendItemW(hMenu, (LPWSTR)lpText, uID, icon, hMenuPopup, nItemHeight); 00383 else 00384 { 00385 DWORD len = MultiByteToWideChar( CP_ACP, 0, (LPSTR)lpText, -1, NULL, 0 ); 00386 LPWSTR lpszText = (LPWSTR)HeapAlloc ( GetProcessHeap(), 0, len*sizeof(WCHAR) ); 00387 if (!lpszText) return FALSE; 00388 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lpText, -1, lpszText, len ); 00389 ret = FileMenu_AppendItemW(hMenu, lpszText, uID, icon, hMenuPopup, nItemHeight); 00390 HeapFree( GetProcessHeap(), 0, lpszText ); 00391 } 00392 00393 return ret; 00394 } 00395 00396 /************************************************************************* 00397 * FileMenu_InsertUsingPidl [SHELL32.110] 00398 * 00399 * NOTES 00400 * uEnumFlags any SHCONTF flag 00401 */ 00402 int WINAPI FileMenu_InsertUsingPidl ( 00403 HMENU hmenu, 00404 UINT uID, 00405 LPCITEMIDLIST pidl, 00406 UINT uFlags, 00407 UINT uEnumFlags, 00408 LPFNFMCALLBACK lpfnCallback) 00409 { 00410 TRACE("%p 0x%08x %p 0x%08x 0x%08x %p\n", 00411 hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback); 00412 00413 pdump (pidl); 00414 00415 bAbortInit = FALSE; 00416 00417 FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback); 00418 00419 return FM_InitMenuPopup(hmenu, NULL); 00420 } 00421 00422 /************************************************************************* 00423 * FileMenu_ReplaceUsingPidl [SHELL32.113] 00424 * 00425 * FIXME: the static items are deleted but won't be refreshed 00426 */ 00427 int WINAPI FileMenu_ReplaceUsingPidl( 00428 HMENU hmenu, 00429 UINT uID, 00430 LPCITEMIDLIST pidl, 00431 UINT uEnumFlags, 00432 LPFNFMCALLBACK lpfnCallback) 00433 { 00434 TRACE("%p 0x%08x %p 0x%08x %p\n", 00435 hmenu, uID, pidl, uEnumFlags, lpfnCallback); 00436 00437 FileMenu_DeleteAllItems (hmenu); 00438 00439 FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback); 00440 00441 return FM_InitMenuPopup(hmenu, NULL); 00442 } 00443 00444 /************************************************************************* 00445 * FileMenu_Invalidate [SHELL32.111] 00446 */ 00447 void WINAPI FileMenu_Invalidate (HMENU hMenu) 00448 { 00449 FIXME("%p\n",hMenu); 00450 } 00451 00452 /************************************************************************* 00453 * FileMenu_FindSubMenuByPidl [SHELL32.106] 00454 */ 00455 HMENU WINAPI FileMenu_FindSubMenuByPidl( 00456 HMENU hMenu, 00457 LPCITEMIDLIST pidl) 00458 { 00459 FIXME("%p %p\n",hMenu, pidl); 00460 return 0; 00461 } 00462 00463 /************************************************************************* 00464 * FileMenu_AppendFilesForPidl [SHELL32.124] 00465 */ 00466 int WINAPI FileMenu_AppendFilesForPidl( 00467 HMENU hmenu, 00468 LPCITEMIDLIST pidl, 00469 BOOL bAddSeparator) 00470 { 00471 LPFMINFO menudata; 00472 00473 menudata = FM_GetMenuInfo(hmenu); 00474 00475 menudata->bInitialized = FALSE; 00476 00477 FM_InitMenuPopup(hmenu, pidl); 00478 00479 if (bAddSeparator) 00480 FileMenu_AppendItemW (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT); 00481 00482 TRACE("%p %p 0x%08x\n",hmenu, pidl,bAddSeparator); 00483 00484 return 0; 00485 } 00486 /************************************************************************* 00487 * FileMenu_AddFilesForPidl [SHELL32.125] 00488 * 00489 * NOTES 00490 * uEnumFlags any SHCONTF flag 00491 */ 00492 int WINAPI FileMenu_AddFilesForPidl ( 00493 HMENU hmenu, 00494 UINT uReserved, 00495 UINT uID, 00496 LPCITEMIDLIST pidl, 00497 UINT uFlags, 00498 UINT uEnumFlags, 00499 LPFNFMCALLBACK lpfnCallback) 00500 { 00501 TRACE("%p 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n", 00502 hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback); 00503 00504 return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback); 00505 00506 } 00507 00508 00509 /************************************************************************* 00510 * FileMenu_TrackPopupMenuEx [SHELL32.116] 00511 */ 00512 BOOL WINAPI FileMenu_TrackPopupMenuEx ( 00513 HMENU hMenu, 00514 UINT uFlags, 00515 int x, 00516 int y, 00517 HWND hWnd, 00518 LPTPMPARAMS lptpm) 00519 { 00520 TRACE("%p 0x%08x 0x%x 0x%x %p %p\n", 00521 hMenu, uFlags, x, y, hWnd, lptpm); 00522 return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm); 00523 } 00524 00525 /************************************************************************* 00526 * FileMenu_GetLastSelectedItemPidls [SHELL32.107] 00527 */ 00528 BOOL WINAPI FileMenu_GetLastSelectedItemPidls( 00529 UINT uReserved, 00530 LPCITEMIDLIST *ppidlFolder, 00531 LPCITEMIDLIST *ppidlItem) 00532 { 00533 FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem); 00534 return 0; 00535 } 00536 00537 #define FM_ICON_SIZE 16 00538 #define FM_Y_SPACE 4 00539 #define FM_SPACE1 4 00540 #define FM_SPACE2 2 00541 #define FM_LEFTBORDER 2 00542 #define FM_RIGHTBORDER 8 00543 /************************************************************************* 00544 * FileMenu_MeasureItem [SHELL32.112] 00545 */ 00546 LRESULT WINAPI FileMenu_MeasureItem( 00547 HWND hWnd, 00548 LPMEASUREITEMSTRUCT lpmis) 00549 { 00550 LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData); 00551 HDC hdc = GetDC(hWnd); 00552 SIZE size; 00553 LPFMINFO menuinfo; 00554 00555 TRACE("%p %p %s\n", hWnd, lpmis, debugstr_w(pMyItem->szItemText)); 00556 00557 GetTextExtentPoint32W(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size); 00558 00559 lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER; 00560 lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE); 00561 00562 /* add the menubitmap */ 00563 menuinfo = FM_GetMenuInfo(pMyItem->hMenu); 00564 if (menuinfo->nBorderWidth) 00565 lpmis->itemWidth += menuinfo->nBorderWidth; 00566 00567 TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight); 00568 ReleaseDC (hWnd, hdc); 00569 return 0; 00570 } 00571 /************************************************************************* 00572 * FileMenu_DrawItem [SHELL32.105] 00573 */ 00574 LRESULT WINAPI FileMenu_DrawItem( 00575 HWND hWnd, 00576 LPDRAWITEMSTRUCT lpdis) 00577 { 00578 LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData); 00579 COLORREF clrPrevText, clrPrevBkgnd; 00580 int xi,yi,xt,yt; 00581 HIMAGELIST hImageList; 00582 RECT TextRect; 00583 LPFMINFO menuinfo; 00584 00585 TRACE("%p %p %s\n", hWnd, lpdis, debugstr_w(pMyItem->szItemText)); 00586 00587 if (lpdis->itemState & ODS_SELECTED) 00588 { 00589 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT)); 00590 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT)); 00591 } 00592 else 00593 { 00594 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT)); 00595 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU)); 00596 } 00597 00598 CopyRect(&TextRect, &(lpdis->rcItem)); 00599 00600 /* add the menubitmap */ 00601 menuinfo = FM_GetMenuInfo(pMyItem->hMenu); 00602 if (menuinfo->nBorderWidth) 00603 TextRect.left += menuinfo->nBorderWidth; 00604 00605 TextRect.left += FM_LEFTBORDER; 00606 xi = TextRect.left + FM_SPACE1; 00607 yi = TextRect.top + FM_Y_SPACE/2; 00608 TextRect.bottom -= FM_Y_SPACE/2; 00609 00610 xt = xi + FM_ICON_SIZE + FM_SPACE2; 00611 yt = yi; 00612 00613 ExtTextOutW (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL); 00614 00615 Shell_GetImageLists(0, &hImageList); 00616 ImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL); 00617 00618 TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom); 00619 00620 SetTextColor(lpdis->hDC, clrPrevText); 00621 SetBkColor(lpdis->hDC, clrPrevBkgnd); 00622 00623 return TRUE; 00624 } 00625 00626 /************************************************************************* 00627 * FileMenu_InitMenuPopup [SHELL32.109] 00628 * 00629 * NOTES 00630 * The filemenu is an ownerdrawn menu. Call this function responding to 00631 * WM_INITPOPUPMENU 00632 * 00633 */ 00634 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu) 00635 { 00636 FM_InitMenuPopup(hmenu, NULL); 00637 return TRUE; 00638 } 00639 00640 /************************************************************************* 00641 * FileMenu_HandleMenuChar [SHELL32.108] 00642 */ 00643 LRESULT WINAPI FileMenu_HandleMenuChar( 00644 HMENU hMenu, 00645 WPARAM wParam) 00646 { 00647 FIXME("%p 0x%08lx\n",hMenu,wParam); 00648 return 0; 00649 } 00650 00651 /************************************************************************* 00652 * FileMenu_DeleteAllItems [SHELL32.104] 00653 * 00654 * NOTES 00655 * exported by name 00656 */ 00657 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu) 00658 { 00659 MENUITEMINFOW mii; 00660 LPFMINFO menudata; 00661 00662 int i; 00663 00664 TRACE("%p\n", hmenu); 00665 00666 ZeroMemory ( &mii, sizeof(MENUITEMINFOW)); 00667 mii.cbSize = sizeof(MENUITEMINFOW); 00668 mii.fMask = MIIM_SUBMENU|MIIM_DATA; 00669 00670 for (i = 0; i < GetMenuItemCount( hmenu ); i++) 00671 { GetMenuItemInfoW(hmenu, i, TRUE, &mii ); 00672 00673 SHFree((LPFMINFO)mii.dwItemData); 00674 00675 if (mii.hSubMenu) 00676 FileMenu_Destroy(mii.hSubMenu); 00677 } 00678 00679 while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){}; 00680 00681 menudata = FM_GetMenuInfo(hmenu); 00682 00683 menudata->bInitialized = FALSE; 00684 00685 return TRUE; 00686 } 00687 00688 /************************************************************************* 00689 * FileMenu_DeleteItemByCmd [SHELL32.117] 00690 * 00691 */ 00692 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID) 00693 { 00694 MENUITEMINFOW mii; 00695 00696 TRACE("%p 0x%08x\n", hMenu, uID); 00697 00698 ZeroMemory ( &mii, sizeof(MENUITEMINFOW)); 00699 mii.cbSize = sizeof(MENUITEMINFOW); 00700 mii.fMask = MIIM_SUBMENU; 00701 00702 GetMenuItemInfoW(hMenu, uID, FALSE, &mii ); 00703 if ( mii.hSubMenu ) 00704 { 00705 /* FIXME: Do what? */ 00706 } 00707 00708 DeleteMenu(hMenu, MF_BYCOMMAND, uID); 00709 return TRUE; 00710 } 00711 00712 /************************************************************************* 00713 * FileMenu_DeleteItemByIndex [SHELL32.140] 00714 */ 00715 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos) 00716 { 00717 MENUITEMINFOW mii; 00718 00719 TRACE("%p 0x%08x\n", hMenu, uPos); 00720 00721 ZeroMemory ( &mii, sizeof(MENUITEMINFOW)); 00722 mii.cbSize = sizeof(MENUITEMINFOW); 00723 mii.fMask = MIIM_SUBMENU; 00724 00725 GetMenuItemInfoW(hMenu, uPos, TRUE, &mii ); 00726 if ( mii.hSubMenu ) 00727 { 00728 /* FIXME: Do what? */ 00729 } 00730 00731 DeleteMenu(hMenu, MF_BYPOSITION, uPos); 00732 return TRUE; 00733 } 00734 00735 /************************************************************************* 00736 * FileMenu_DeleteItemByFirstID [SHELL32.141] 00737 */ 00738 EXTERN_C BOOL WINAPI FileMenu_DeleteItemByFirstID( 00739 HMENU hMenu, 00740 UINT uID) 00741 { 00742 TRACE("%p 0x%08x\n", hMenu, uID); 00743 return 0; 00744 } 00745 00746 /************************************************************************* 00747 * FileMenu_DeleteSeparator [SHELL32.142] 00748 */ 00749 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu) 00750 { 00751 TRACE("%p\n", hMenu); 00752 return 0; 00753 } 00754 00755 /************************************************************************* 00756 * FileMenu_EnableItemByCmd [SHELL32.143] 00757 */ 00758 BOOL WINAPI FileMenu_EnableItemByCmd( 00759 HMENU hMenu, 00760 UINT uID, 00761 BOOL bEnable) 00762 { 00763 TRACE("%p 0x%08x 0x%08x\n", hMenu, uID,bEnable); 00764 return 0; 00765 } 00766 00767 /************************************************************************* 00768 * FileMenu_GetItemExtent [SHELL32.144] 00769 * 00770 * NOTES 00771 * if the menu is too big, entries are getting cut away!! 00772 */ 00773 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos) 00774 { RECT rect; 00775 00776 FIXME("%p 0x%08x\n", hMenu, uPos); 00777 00778 if (GetMenuItemRect(0, hMenu, uPos, &rect)) 00779 { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n", 00780 rect.right, rect.left, rect.top, rect.bottom); 00781 return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom); 00782 } 00783 return 0x00100010; /*FIXME*/ 00784 } 00785 00786 /************************************************************************* 00787 * FileMenu_AbortInitMenu [SHELL32.120] 00788 * 00789 */ 00790 void WINAPI FileMenu_AbortInitMenu (void) 00791 { TRACE("\n"); 00792 bAbortInit = TRUE; 00793 } 00794 00795 /************************************************************************* 00796 * SHFind_InitMenuPopup [SHELL32.149] 00797 * 00798 * Get the IContextMenu instance for the submenu of options displayed 00799 * for the Search entry in the Classic style Start menu. 00800 * 00801 * PARAMETERS 00802 * hMenu [in] handle of menu previously created 00803 * hWndParent [in] parent window 00804 * w [in] no pointer (0x209 over here) perhaps menu IDs ??? 00805 * x [in] no pointer (0x226 over here) 00806 * 00807 * RETURNS 00808 * LPXXXXX pointer to struct containing a func addr at offset 8 00809 * or NULL at failure. 00810 */ 00811 EXTERN_C IContextMenu * WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, UINT w, UINT x) 00812 { 00813 FIXME("hmenu=%p hwnd=%p 0x%08x 0x%08x stub\n", 00814 hMenu,hWndParent,w,x); 00815 return NULL; /* this is supposed to be a pointer */ 00816 } 00817 00818 /************************************************************************* 00819 * _SHIsMenuSeparator (internal) 00820 */ 00821 static BOOL _SHIsMenuSeparator(HMENU hm, int i) 00822 { 00823 MENUITEMINFOW mii; 00824 00825 mii.cbSize = sizeof(MENUITEMINFOW); 00826 mii.fMask = MIIM_TYPE; 00827 mii.cch = 0; /* WARNING: We MUST initialize it to 0*/ 00828 if (!GetMenuItemInfoW(hm, i, TRUE, &mii)) 00829 { 00830 return(FALSE); 00831 } 00832 00833 if (mii.fType & MFT_SEPARATOR) 00834 { 00835 return(TRUE); 00836 } 00837 00838 return(FALSE); 00839 } 00840 00841 /************************************************************************* 00842 * Shell_MergeMenus [SHELL32.67] 00843 */ 00844 UINT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags) 00845 { 00846 int nItem; 00847 HMENU hmSubMenu; 00848 BOOL bAlreadySeparated; 00849 MENUITEMINFOW miiSrc; 00850 WCHAR szName[256]; 00851 UINT uTemp, uIDMax = uIDAdjust; 00852 00853 TRACE("hmenu1=%p hmenu2=%p 0x%04x 0x%04x 0x%04x 0x%04x\n", 00854 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags); 00855 00856 if (!hmDst || !hmSrc) 00857 return uIDMax; 00858 00859 nItem = GetMenuItemCount(hmDst); 00860 00861 if (uInsert >= (UINT)nItem) /* insert position inside menu? */ 00862 { 00863 uInsert = (UINT)nItem; /* append on the end */ 00864 bAlreadySeparated = TRUE; 00865 } 00866 else 00867 { 00868 bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert); 00869 } 00870 00871 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated) 00872 { 00873 /* Add a separator between the menus */ 00874 InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); 00875 bAlreadySeparated = TRUE; 00876 } 00877 00878 00879 /* Go through the menu items and clone them*/ 00880 for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--) 00881 { 00882 miiSrc.cbSize = sizeof(MENUITEMINFOW); 00883 miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA; 00884 00885 /* We need to reset this every time through the loop in case menus DON'T have IDs*/ 00886 miiSrc.fType = MFT_STRING; 00887 miiSrc.dwTypeData = szName; 00888 miiSrc.dwItemData = 0; 00889 miiSrc.cch = sizeof(szName)/sizeof(WCHAR); 00890 00891 if (!GetMenuItemInfoW(hmSrc, nItem, TRUE, &miiSrc)) 00892 { 00893 continue; 00894 } 00895 00896 /* TRACE("found menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmSrc, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu); 00897 */ 00898 if (miiSrc.fType & MFT_SEPARATOR) 00899 { 00900 /* This is a separator; don't put two of them in a row */ 00901 if (bAlreadySeparated) 00902 continue; 00903 bAlreadySeparated = TRUE; 00904 } 00905 else if (miiSrc.hSubMenu) 00906 { 00907 if ((uFlags & MM_SUBMENUSHAVEIDS) != 0 && miiSrc.wID != (UINT)miiSrc.hSubMenu) 00908 { 00909 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */ 00910 00911 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */ 00912 continue; 00913 if (uIDMax <= miiSrc.wID) /* remember the highest ID */ 00914 uIDMax = miiSrc.wID + 1; 00915 } 00916 else 00917 { 00918 miiSrc.fMask &= ~MIIM_ID; /* Don't set IDs for submenus that didn't have them already */ 00919 } 00920 hmSubMenu = miiSrc.hSubMenu; 00921 00922 miiSrc.hSubMenu = CreatePopupMenu(); 00923 00924 if (!miiSrc.hSubMenu) return(uIDMax); 00925 00926 uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS); 00927 00928 if (uIDMax <= uTemp) 00929 uIDMax = uTemp; 00930 00931 bAlreadySeparated = FALSE; 00932 } 00933 else /* normal menu item */ 00934 { 00935 miiSrc.wID += uIDAdjust; /* add uIDAdjust to the ID */ 00936 00937 if (miiSrc.wID > uIDAdjustMax) /* skip ID's higher uIDAdjustMax */{ 00938 continue; 00939 } 00940 if (uIDMax <= miiSrc.wID) /* remember the highest ID */ 00941 uIDMax = miiSrc.wID + 1; 00942 00943 bAlreadySeparated = FALSE; 00944 } 00945 00946 /* TRACE("inserting menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmDst, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu); 00947 */ 00948 if (!InsertMenuItemW(hmDst, uInsert, TRUE, &miiSrc)) 00949 { 00950 return(uIDMax); 00951 } 00952 } 00953 00954 /* Ensure the correct number of separators at the beginning of the 00955 inserted menu items*/ 00956 if (uInsert == 0) 00957 { 00958 if (bAlreadySeparated) 00959 { 00960 DeleteMenu(hmDst, uInsert, MF_BYPOSITION); 00961 } 00962 } 00963 else 00964 { 00965 if (_SHIsMenuSeparator(hmDst, uInsert-1)) 00966 { 00967 if (bAlreadySeparated) 00968 { 00969 DeleteMenu(hmDst, uInsert, MF_BYPOSITION); 00970 } 00971 } 00972 else 00973 { 00974 if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated) 00975 { 00976 /* Add a separator between the menus*/ 00977 InsertMenuW(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); 00978 } 00979 } 00980 } 00981 return(uIDMax); 00982 } Generated on Sun May 27 2012 04:26:28 for ReactOS by
1.7.6.1
|