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

shlmenu.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 doxygen 1.7.6.1

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