Ignore:
Timestamp:
Sep 5, 2001, 3:54:53 PM (24 years ago)
Author:
bird
Message:

Added $Id:$ keyword.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shell32/shlmenu.c

    r5618 r6650  
     1/* $Id: shlmenu.c,v 1.3 2001-09-05 13:46:59 bird Exp $ */
    12/*
    23 * see www.geocities.com/SiliconValley/4942/filemenu.html
     
    2223typedef struct
    2324{
    24         BOOL            bInitialized;
    25         BOOL            bFixedItems;
    26         /* create */
    27         COLORREF        crBorderColor;
    28         int             nBorderWidth;
    29         HBITMAP         hBorderBmp;
    30 
    31         /* insert using pidl */
    32         LPITEMIDLIST    pidl;
    33         UINT            uID;
    34         UINT            uFlags;
    35         UINT            uEnumFlags;
    36         LPFNFMCALLBACK lpfnCallback;
     25    BOOL        bInitialized;
     26    BOOL        bFixedItems;
     27    /* create */
     28    COLORREF    crBorderColor;
     29    int     nBorderWidth;
     30    HBITMAP     hBorderBmp;
     31
     32    /* insert using pidl */
     33    LPITEMIDLIST    pidl;
     34    UINT        uID;
     35    UINT        uFlags;
     36    UINT        uEnumFlags;
     37    LPFNFMCALLBACK lpfnCallback;
    3738} FMINFO, *LPFMINFO;
    3839
    3940typedef struct
    40 {       int     cchItemText;
    41         int     iIconIndex;
    42         HMENU   hMenu;
    43         char    szItemText[1];
     41{   int cchItemText;
     42    int iIconIndex;
     43    HMENU   hMenu;
     44    char    szItemText[1];
    4445} FMITEM, * LPFMITEM;
    4546
    4647static BOOL bAbortInit;
    4748
    48 #define CCH_MAXITEMTEXT 256
     49#define CCH_MAXITEMTEXT 256
    4950
    5051DEFAULT_DEBUG_CHANNEL(shell);
    5152
    5253LPFMINFO FM_GetMenuInfo(HMENU hmenu)
    53 {       MENUINFO        MenuInfo;
    54         LPFMINFO        menudata;
    55 
    56         MenuInfo.cbSize = sizeof(MENUINFO);
    57         MenuInfo.fMask = MIM_MENUDATA;
    58 
    59         if (! GetMenuInfo(hmenu, &MenuInfo))
    60           return NULL;
    61 
    62         menudata = (LPFMINFO)MenuInfo.dwMenuData;
    63 
    64         if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
    65         {
    66           ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
    67           return 0;
    68         }
    69        
    70         return menudata;
    71 
    72 }
    73 /*************************************************************************
    74  * FM_SetMenuParameter                          [internal]
     54{   MENUINFO    MenuInfo;
     55    LPFMINFO    menudata;
     56
     57    MenuInfo.cbSize = sizeof(MENUINFO);
     58    MenuInfo.fMask = MIM_MENUDATA;
     59
     60    if (! GetMenuInfo(hmenu, &MenuInfo))
     61      return NULL;
     62
     63    menudata = (LPFMINFO)MenuInfo.dwMenuData;
     64
     65    if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
     66    {
     67      ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
     68      return 0;
     69    }
     70
     71    return menudata;
     72
     73}
     74/*************************************************************************
     75 * FM_SetMenuParameter              [internal]
    7576 *
    7677 */
    7778static LPFMINFO FM_SetMenuParameter(
    78         HMENU hmenu,
    79         UINT uID,
    80         LPCITEMIDLIST pidl,
    81         UINT uFlags,
    82         UINT uEnumFlags,
    83         LPFNFMCALLBACK lpfnCallback)
    84 {
    85         LPFMINFO        menudata;
    86 
    87         TRACE("\n");
    88        
    89         menudata = FM_GetMenuInfo(hmenu);
    90        
    91         if ( menudata->pidl)
    92         { SHFree(menudata->pidl);
    93         }
    94        
    95         menudata->uID = uID;
    96         menudata->pidl = ILClone(pidl);
    97         menudata->uFlags = uFlags;
    98         menudata->uEnumFlags = uEnumFlags;
    99         menudata->lpfnCallback = lpfnCallback;
    100 
    101         return menudata;
    102 }
    103 
    104 /*************************************************************************
    105  * FM_InitMenuPopup                             [internal]
     79    HMENU hmenu,
     80    UINT uID,
     81    LPCITEMIDLIST pidl,
     82    UINT uFlags,
     83    UINT uEnumFlags,
     84    LPFNFMCALLBACK lpfnCallback)
     85{
     86    LPFMINFO    menudata;
     87
     88    TRACE("\n");
     89
     90    menudata = FM_GetMenuInfo(hmenu);
     91
     92    if ( menudata->pidl)
     93    { SHFree(menudata->pidl);
     94    }
     95
     96    menudata->uID = uID;
     97    menudata->pidl = ILClone(pidl);
     98    menudata->uFlags = uFlags;
     99    menudata->uEnumFlags = uEnumFlags;
     100    menudata->lpfnCallback = lpfnCallback;
     101
     102    return menudata;
     103}
     104
     105/*************************************************************************
     106 * FM_InitMenuPopup             [internal]
    106107 *
    107108 */
    108109static int FM_InitMenuPopup(HMENU hmenu, LPITEMIDLIST pAlternatePidl)
    109 {       IShellFolder    *lpsf, *lpsf2;
    110         ULONG           ulItemAttr = SFGAO_FOLDER;
    111         UINT            uID, uFlags, uEnumFlags;
    112         LPFNFMCALLBACK  lpfnCallback;
    113         LPITEMIDLIST    pidl;
    114         char            sTemp[MAX_PATH];
    115         int             NumberOfItems = 0, iIcon;
    116         MENUINFO        MenuInfo;
    117         LPFMINFO        menudata;
    118 
    119         TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
    120 
    121         MenuInfo.cbSize = sizeof(MENUINFO);
    122         MenuInfo.fMask = MIM_MENUDATA;
    123 
    124         if (! GetMenuInfo(hmenu, &MenuInfo))
    125           return FALSE;
    126 
    127         menudata = (LPFMINFO)MenuInfo.dwMenuData;
    128        
    129         if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
    130         {
    131           ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
    132           return 0;
    133         }
    134        
    135         if (menudata->bInitialized)
    136           return 0;
    137        
    138         pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
    139         if (!pidl)
    140           return 0;
    141 
    142         uID = menudata->uID;
    143         uFlags = menudata->uFlags;
    144         uEnumFlags = menudata->uEnumFlags;
    145         lpfnCallback = menudata->lpfnCallback;
    146         menudata->bInitialized = FALSE;
    147 
    148         SetMenuInfo(hmenu, &MenuInfo);
    149        
    150         if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
    151         {
    152           if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
    153           {
    154             IEnumIDList *lpe = NULL;
    155 
    156             if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
    157             {
    158 
    159               LPITEMIDLIST pidlTemp = NULL;
    160               ULONG ulFetched;
    161 
    162               while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
    163               {
    164                 if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
    165                 {
    166                   ILGetDisplayName( pidlTemp, sTemp);
    167                   if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon)))
    168                     iIcon = FM_BLANK_ICON;
    169                   if ( SFGAO_FOLDER & ulItemAttr)
    170                   {
    171                     LPFMINFO lpFmMi;
    172                     MENUINFO MenuInfo;
    173                     HMENU hMenuPopup = CreatePopupMenu();
    174        
    175                     lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
    176 
    177                     lpFmMi->pidl = ILCombine(pidl, pidlTemp);
    178                     lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
    179 
    180                     MenuInfo.cbSize = sizeof(MENUINFO);
    181                     MenuInfo.fMask = MIM_MENUDATA;
    182                     MenuInfo.dwMenuData = (DWORD) lpFmMi;
    183                     SetMenuInfo (hMenuPopup, &MenuInfo);
    184 
    185                     FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
    186                   }
    187                   else
    188                   {
    189                     ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
    190                     FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
    191                   }
    192                 }
    193 
    194                 if (lpfnCallback)
    195                 {
    196                   TRACE("enter callback\n");
    197                   lpfnCallback ( pidl, pidlTemp);
    198                   TRACE("leave callback\n");
    199                 }
    200 
    201                 NumberOfItems++;
    202               }
    203               IEnumIDList_Release (lpe);
    204             }
    205             IShellFolder_Release(lpsf2);
    206           }
    207           IShellFolder_Release(lpsf);
    208         }
    209 
    210         if ( GetMenuItemCount (hmenu) == 0 )
    211         { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
    212           NumberOfItems++;
    213         }
    214 
    215         menudata->bInitialized = TRUE;
    216         SetMenuInfo(hmenu, &MenuInfo);
    217 
    218         return NumberOfItems;
    219 }
    220 /*************************************************************************
    221  * FileMenu_Create                              [SHELL32.114]
     110{   IShellFolder    *lpsf, *lpsf2;
     111    ULONG       ulItemAttr = SFGAO_FOLDER;
     112    UINT        uID, uFlags, uEnumFlags;
     113    LPFNFMCALLBACK  lpfnCallback;
     114    LPITEMIDLIST    pidl;
     115    char        sTemp[MAX_PATH];
     116    int     NumberOfItems = 0, iIcon;
     117    MENUINFO    MenuInfo;
     118    LPFMINFO    menudata;
     119
     120    TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
     121
     122    MenuInfo.cbSize = sizeof(MENUINFO);
     123    MenuInfo.fMask = MIM_MENUDATA;
     124
     125    if (! GetMenuInfo(hmenu, &MenuInfo))
     126      return FALSE;
     127
     128    menudata = (LPFMINFO)MenuInfo.dwMenuData;
     129
     130    if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
     131    {
     132      ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
     133      return 0;
     134    }
     135
     136    if (menudata->bInitialized)
     137      return 0;
     138
     139    pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
     140    if (!pidl)
     141      return 0;
     142
     143    uID = menudata->uID;
     144    uFlags = menudata->uFlags;
     145    uEnumFlags = menudata->uEnumFlags;
     146    lpfnCallback = menudata->lpfnCallback;
     147    menudata->bInitialized = FALSE;
     148
     149    SetMenuInfo(hmenu, &MenuInfo);
     150
     151    if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
     152    {
     153      if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
     154      {
     155        IEnumIDList *lpe = NULL;
     156
     157        if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
     158        {
     159
     160          LPITEMIDLIST pidlTemp = NULL;
     161          ULONG ulFetched;
     162
     163          while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
     164          {
     165        if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
     166        {
     167          ILGetDisplayName( pidlTemp, sTemp);
     168          if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon)))
     169            iIcon = FM_BLANK_ICON;
     170          if ( SFGAO_FOLDER & ulItemAttr)
     171          {
     172            LPFMINFO lpFmMi;
     173            MENUINFO MenuInfo;
     174            HMENU hMenuPopup = CreatePopupMenu();
     175
     176            lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
     177
     178            lpFmMi->pidl = ILCombine(pidl, pidlTemp);
     179            lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
     180
     181            MenuInfo.cbSize = sizeof(MENUINFO);
     182            MenuInfo.fMask = MIM_MENUDATA;
     183            MenuInfo.dwMenuData = (DWORD) lpFmMi;
     184            SetMenuInfo (hMenuPopup, &MenuInfo);
     185
     186            FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
     187          }
     188          else
     189          {
     190            ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
     191            FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
     192          }
     193        }
     194
     195        if (lpfnCallback)
     196        {
     197          TRACE("enter callback\n");
     198          lpfnCallback ( pidl, pidlTemp);
     199          TRACE("leave callback\n");
     200        }
     201
     202        NumberOfItems++;
     203          }
     204          IEnumIDList_Release (lpe);
     205        }
     206        IShellFolder_Release(lpsf2);
     207      }
     208      IShellFolder_Release(lpsf);
     209    }
     210
     211    if ( GetMenuItemCount (hmenu) == 0 )
     212    { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
     213      NumberOfItems++;
     214    }
     215
     216    menudata->bInitialized = TRUE;
     217    SetMenuInfo(hmenu, &MenuInfo);
     218
     219    return NumberOfItems;
     220}
     221/*************************************************************************
     222 * FileMenu_Create              [SHELL32.114]
    222223 *
    223224 * NOTES
    224225 *  for non-root menus values are
    225  *  (ffffffff,00000000,00000000,00000000,00000000) 
     226 *  (ffffffff,00000000,00000000,00000000,00000000)
    226227 */
    227228HMENU WINAPI FileMenu_Create (
    228         COLORREF crBorderColor,
    229         int nBorderWidth,
    230         HBITMAP hBorderBmp,
    231         int nSelHeight,
    232         UINT uFlags)
    233 {
    234         MENUINFO        MenuInfo;
    235         LPFMINFO        menudata;
    236 
    237         HMENU hMenu = CreatePopupMenu();
    238 
    239         TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x  hMenu=0x%08x\n",
    240         crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
    241 
    242         menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
    243         menudata->crBorderColor = crBorderColor;
    244         menudata->nBorderWidth = nBorderWidth;
    245         menudata->hBorderBmp = hBorderBmp;
    246 
    247         MenuInfo.cbSize = sizeof(MENUINFO);
    248         MenuInfo.fMask = MIM_MENUDATA;
    249         MenuInfo.dwMenuData = (DWORD) menudata;
    250         SetMenuInfo (hMenu, &MenuInfo);
    251 
    252         return hMenu;
    253 }
    254 
    255 /*************************************************************************
    256  * FileMenu_Destroy                             [SHELL32.118]
     229    COLORREF crBorderColor,
     230    int nBorderWidth,
     231    HBITMAP hBorderBmp,
     232    int nSelHeight,
     233    UINT uFlags)
     234{
     235    MENUINFO    MenuInfo;
     236    LPFMINFO    menudata;
     237
     238    HMENU hMenu = CreatePopupMenu();
     239
     240    TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x  hMenu=0x%08x\n",
     241    crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
     242
     243    menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
     244    menudata->crBorderColor = crBorderColor;
     245    menudata->nBorderWidth = nBorderWidth;
     246    menudata->hBorderBmp = hBorderBmp;
     247
     248    MenuInfo.cbSize = sizeof(MENUINFO);
     249    MenuInfo.fMask = MIM_MENUDATA;
     250    MenuInfo.dwMenuData = (DWORD) menudata;
     251    SetMenuInfo (hMenu, &MenuInfo);
     252
     253    return hMenu;
     254}
     255
     256/*************************************************************************
     257 * FileMenu_Destroy             [SHELL32.118]
    257258 *
    258259 * NOTES
     
    261262void WINAPI FileMenu_Destroy (HMENU hmenu)
    262263{
    263         LPFMINFO        menudata;
    264 
    265         TRACE("0x%08x\n", hmenu);
    266 
    267         FileMenu_DeleteAllItems (hmenu);
    268        
    269         menudata = FM_GetMenuInfo(hmenu);
    270 
    271         if ( menudata->pidl)
    272         { SHFree( menudata->pidl);
    273         }
    274         HeapFree(GetProcessHeap(), 0, menudata);
    275 
    276         DestroyMenu (hmenu);
    277 }
    278 
    279 /*************************************************************************
    280  * FileMenu_AppendItemAW                        [SHELL32.115]
     264    LPFMINFO    menudata;
     265
     266    TRACE("0x%08x\n", hmenu);
     267
     268    FileMenu_DeleteAllItems (hmenu);
     269
     270    menudata = FM_GetMenuInfo(hmenu);
     271
     272    if ( menudata->pidl)
     273    { SHFree( menudata->pidl);
     274    }
     275    HeapFree(GetProcessHeap(), 0, menudata);
     276
     277    DestroyMenu (hmenu);
     278}
     279
     280/*************************************************************************
     281 * FileMenu_AppendItemAW            [SHELL32.115]
    281282 *
    282283 */
    283284BOOL WINAPI FileMenu_AppendItemA(
    284         HMENU hMenu,
    285         LPCSTR lpText,
    286         UINT uID,
    287         int icon,
    288         HMENU hMenuPopup,
    289         int nItemHeight)
    290 {
    291         LPSTR lpszText = (LPSTR)lpText;
    292         MENUITEMINFOA   mii;
    293         LPFMITEM        myItem;
    294         LPFMINFO        menudata;
    295         MENUINFO        MenuInfo;
    296 
    297 
    298         TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
    299         hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
    300         uID, icon, hMenuPopup, nItemHeight);
    301        
    302         ZeroMemory (&mii, sizeof(MENUITEMINFOA));
    303        
    304         mii.cbSize = sizeof(MENUITEMINFOA);
    305 
    306         if (lpText != FM_SEPARATOR)
    307         { int len = strlen (lpText);
    308           myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
    309           strcpy (myItem->szItemText, lpText);
    310           myItem->cchItemText = len;
    311           myItem->iIconIndex = icon;
    312           myItem->hMenu = hMenu;
    313           mii.fMask = MIIM_DATA;
    314           mii.dwItemData = (DWORD) myItem;
    315         }
    316        
    317         if ( hMenuPopup )
    318         { /* sub menu */
    319           mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
    320           mii.fType = MFT_OWNERDRAW;
    321           mii.hSubMenu = hMenuPopup;
    322         }
    323         else if (lpText == FM_SEPARATOR )
    324         { mii.fMask |= MIIM_ID | MIIM_TYPE;
    325           mii.fType = MFT_SEPARATOR;
    326         }
    327         else
    328         { /* normal item */
    329           mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
    330           mii.fState = MFS_ENABLED | MFS_DEFAULT;
    331           mii.fType = MFT_OWNERDRAW;
    332         }
    333         mii.wID = uID;
    334 
    335         InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
    336 
    337         /* set bFixedItems to true */
    338         MenuInfo.cbSize = sizeof(MENUINFO);
    339         MenuInfo.fMask = MIM_MENUDATA;
    340 
    341         if (! GetMenuInfo(hMenu, &MenuInfo))
    342           return FALSE;
    343 
    344         menudata = (LPFMINFO)MenuInfo.dwMenuData;
    345         if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
    346         {
    347           ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
    348           return 0;
    349         }
    350 
    351         menudata->bFixedItems = TRUE;
    352         SetMenuInfo(hMenu, &MenuInfo);
    353 
    354         return TRUE;
     285    HMENU hMenu,
     286    LPCSTR lpText,
     287    UINT uID,
     288    int icon,
     289    HMENU hMenuPopup,
     290    int nItemHeight)
     291{
     292    LPSTR lpszText = (LPSTR)lpText;
     293    MENUITEMINFOA   mii;
     294    LPFMITEM    myItem;
     295    LPFMINFO    menudata;
     296    MENUINFO        MenuInfo;
     297
     298
     299    TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
     300    hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
     301    uID, icon, hMenuPopup, nItemHeight);
     302
     303    ZeroMemory (&mii, sizeof(MENUITEMINFOA));
     304
     305    mii.cbSize = sizeof(MENUITEMINFOA);
     306
     307    if (lpText != FM_SEPARATOR)
     308    { int len = strlen (lpText);
     309      myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
     310      strcpy (myItem->szItemText, lpText);
     311      myItem->cchItemText = len;
     312      myItem->iIconIndex = icon;
     313      myItem->hMenu = hMenu;
     314      mii.fMask = MIIM_DATA;
     315      mii.dwItemData = (DWORD) myItem;
     316    }
     317
     318    if ( hMenuPopup )
     319    { /* sub menu */
     320      mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
     321      mii.fType = MFT_OWNERDRAW;
     322      mii.hSubMenu = hMenuPopup;
     323    }
     324    else if (lpText == FM_SEPARATOR )
     325    { mii.fMask |= MIIM_ID | MIIM_TYPE;
     326      mii.fType = MFT_SEPARATOR;
     327    }
     328    else
     329    { /* normal item */
     330      mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
     331      mii.fState = MFS_ENABLED | MFS_DEFAULT;
     332      mii.fType = MFT_OWNERDRAW;
     333    }
     334    mii.wID = uID;
     335
     336    InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
     337
     338    /* set bFixedItems to true */
     339    MenuInfo.cbSize = sizeof(MENUINFO);
     340    MenuInfo.fMask = MIM_MENUDATA;
     341
     342    if (! GetMenuInfo(hMenu, &MenuInfo))
     343      return FALSE;
     344
     345    menudata = (LPFMINFO)MenuInfo.dwMenuData;
     346    if ((menudata == 0) || (MenuInfo.cbSize != sizeof(MENUINFO)))
     347    {
     348      ERR("menudata corrupt: %p %lu\n", menudata, MenuInfo.cbSize);
     349      return 0;
     350    }
     351
     352    menudata->bFixedItems = TRUE;
     353    SetMenuInfo(hMenu, &MenuInfo);
     354
     355    return TRUE;
    355356
    356357}
     
    359360
    360361BOOL WINAPI FileMenu_AppendItemAW(
    361         HMENU hMenu,
    362         LPCVOID lpText,
    363         UINT uID,
    364         int icon,
    365         HMENU hMenuPopup,
    366         int nItemHeight)
    367 {
    368         BOOL ret;
    369         LPSTR lpszText=NULL;
    370 
    371         if (SHELL_OsIsUnicode() && (lpText!=FM_SEPARATOR))
    372           lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
    373 
    374         ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
    375 
    376         if (lpszText)
    377           HeapFree( GetProcessHeap(), 0, lpszText );
    378 
    379         return ret;
    380 }
    381 /*************************************************************************
    382  * FileMenu_InsertUsingPidl                     [SHELL32.110]
     362    HMENU hMenu,
     363    LPCVOID lpText,
     364    UINT uID,
     365    int icon,
     366    HMENU hMenuPopup,
     367    int nItemHeight)
     368{
     369    BOOL ret;
     370    LPSTR lpszText=NULL;
     371
     372    if (SHELL_OsIsUnicode() && (lpText!=FM_SEPARATOR))
     373      lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
     374
     375    ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
     376
     377    if (lpszText)
     378      HeapFree( GetProcessHeap(), 0, lpszText );
     379
     380    return ret;
     381}
     382/*************************************************************************
     383 * FileMenu_InsertUsingPidl         [SHELL32.110]
    383384 *
    384385 * NOTES
    385  *      uEnumFlags      any SHCONTF flag
     386 *  uEnumFlags  any SHCONTF flag
    386387 */
    387388int WINAPI FileMenu_InsertUsingPidl (
    388         HMENU hmenu,
    389         UINT uID,
    390         LPCITEMIDLIST pidl,
    391         UINT uFlags,
    392         UINT uEnumFlags,
    393         LPFNFMCALLBACK lpfnCallback)
    394 {       
    395         TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
    396         hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
    397 
    398         pdump (pidl);
    399 
    400         bAbortInit = FALSE;
    401 
    402         FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);       
    403 
    404         return FM_InitMenuPopup(hmenu, NULL);
    405 }
    406 
    407 /*************************************************************************
    408  * FileMenu_ReplaceUsingPidl                    [SHELL32.113]
     389    HMENU hmenu,
     390    UINT uID,
     391    LPCITEMIDLIST pidl,
     392    UINT uFlags,
     393    UINT uEnumFlags,
     394    LPFNFMCALLBACK lpfnCallback)
     395{
     396    TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
     397    hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
     398
     399    pdump (pidl);
     400
     401    bAbortInit = FALSE;
     402
     403    FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
     404
     405    return FM_InitMenuPopup(hmenu, NULL);
     406}
     407
     408/*************************************************************************
     409 * FileMenu_ReplaceUsingPidl            [SHELL32.113]
    409410 *
    410411 * FIXME: the static items are deleted but wont be refreshed
    411412 */
    412413int WINAPI FileMenu_ReplaceUsingPidl(
    413         HMENU   hmenu,
    414         UINT    uID,
    415         LPCITEMIDLIST   pidl,
    416         UINT    uEnumFlags,
    417         LPFNFMCALLBACK lpfnCallback)
    418 {
    419         TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
    420         hmenu, uID, pidl, uEnumFlags, lpfnCallback);
    421        
    422         FileMenu_DeleteAllItems (hmenu);
    423 
    424         FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);     
    425 
    426         return FM_InitMenuPopup(hmenu, NULL);
    427 }
    428 
    429 /*************************************************************************
    430  * FileMenu_Invalidate                  [SHELL32.111]
     414    HMENU   hmenu,
     415    UINT    uID,
     416    LPCITEMIDLIST   pidl,
     417    UINT    uEnumFlags,
     418    LPFNFMCALLBACK lpfnCallback)
     419{
     420    TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
     421    hmenu, uID, pidl, uEnumFlags, lpfnCallback);
     422
     423    FileMenu_DeleteAllItems (hmenu);
     424
     425    FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
     426
     427    return FM_InitMenuPopup(hmenu, NULL);
     428}
     429
     430/*************************************************************************
     431 * FileMenu_Invalidate          [SHELL32.111]
    431432 */
    432433void WINAPI FileMenu_Invalidate (HMENU hMenu)
    433434{
    434         FIXME("0x%08x\n",hMenu);       
    435 }
    436 
    437 /*************************************************************************
    438  * FileMenu_FindSubMenuByPidl                   [SHELL32.106]
     435    FIXME("0x%08x\n",hMenu);
     436}
     437
     438/*************************************************************************
     439 * FileMenu_FindSubMenuByPidl           [SHELL32.106]
    439440 */
    440441HMENU WINAPI FileMenu_FindSubMenuByPidl(
    441         HMENU   hMenu,
    442         LPCITEMIDLIST   pidl)
    443 {
    444         FIXME("0x%08x %p\n",hMenu, pidl);       
    445         return 0;
    446 }
    447 
    448 /*************************************************************************
    449  * FileMenu_AppendFilesForPidl                  [SHELL32.124]
     442    HMENU   hMenu,
     443    LPCITEMIDLIST   pidl)
     444{
     445    FIXME("0x%08x %p\n",hMenu, pidl);
     446    return 0;
     447}
     448
     449/*************************************************************************
     450 * FileMenu_AppendFilesForPidl          [SHELL32.124]
    450451 */
    451452int WINAPI FileMenu_AppendFilesForPidl(
    452         HMENU   hmenu,
    453         LPCITEMIDLIST   pidl,
    454         BOOL    bAddSeperator)
    455 {
    456         LPFMINFO        menudata;
    457 
    458         menudata = FM_GetMenuInfo(hmenu);
    459        
    460         menudata->bInitialized = FALSE;
    461        
    462         FM_InitMenuPopup(hmenu, pidl);
    463 
    464         if (bAddSeperator)
    465           FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
    466 
    467         TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator); 
    468 
    469         return 0;
    470 }
    471 /*************************************************************************
    472  * FileMenu_AddFilesForPidl                     [SHELL32.125]
     453    HMENU   hmenu,
     454    LPCITEMIDLIST   pidl,
     455    BOOL    bAddSeperator)
     456{
     457    LPFMINFO    menudata;
     458
     459    menudata = FM_GetMenuInfo(hmenu);
     460
     461    menudata->bInitialized = FALSE;
     462
     463    FM_InitMenuPopup(hmenu, pidl);
     464
     465    if (bAddSeperator)
     466      FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
     467
     468    TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
     469
     470    return 0;
     471}
     472/*************************************************************************
     473 * FileMenu_AddFilesForPidl         [SHELL32.125]
    473474 *
    474475 * NOTES
    475  *      uEnumFlags      any SHCONTF flag
     476 *  uEnumFlags  any SHCONTF flag
    476477 */
    477478int WINAPI FileMenu_AddFilesForPidl (
    478         HMENU   hmenu,
    479         UINT    uReserved,
    480         UINT    uID,
    481         LPCITEMIDLIST   pidl,
    482         UINT    uFlags,
    483         UINT    uEnumFlags,
    484         LPFNFMCALLBACK  lpfnCallback)
    485 {
    486         TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
    487         hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
    488 
    489         return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
    490 
    491 }
    492 
    493 
    494 /*************************************************************************
    495  * FileMenu_TrackPopupMenuEx                    [SHELL32.116]
     479    HMENU   hmenu,
     480    UINT    uReserved,
     481    UINT    uID,
     482    LPCITEMIDLIST   pidl,
     483    UINT    uFlags,
     484    UINT    uEnumFlags,
     485    LPFNFMCALLBACK  lpfnCallback)
     486{
     487    TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
     488    hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
     489
     490    return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
     491
     492}
     493
     494
     495/*************************************************************************
     496 * FileMenu_TrackPopupMenuEx            [SHELL32.116]
    496497 */
    497498BOOL WINAPI FileMenu_TrackPopupMenuEx (
    498         HMENU hMenu,
    499         UINT uFlags,
    500         int x,
    501         int y,
    502         HWND hWnd,
    503         LPTPMPARAMS lptpm)
    504 {
    505         TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
    506         hMenu, uFlags, x, y, hWnd, lptpm);
    507         return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
    508 }
    509 
    510 /*************************************************************************
    511  * FileMenu_GetLastSelectedItemPidls            [SHELL32.107]
     499    HMENU hMenu,
     500    UINT uFlags,
     501    int x,
     502    int y,
     503    HWND hWnd,
     504    LPTPMPARAMS lptpm)
     505{
     506    TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
     507    hMenu, uFlags, x, y, hWnd, lptpm);
     508    return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
     509}
     510
     511/*************************************************************************
     512 * FileMenu_GetLastSelectedItemPidls        [SHELL32.107]
    512513 */
    513514BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
    514         UINT    uReserved,
    515         LPCITEMIDLIST   *ppidlFolder,
    516         LPCITEMIDLIST   *ppidlItem)
    517 {
    518         FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
    519         return 0;
    520 }
    521 
    522 #define FM_ICON_SIZE    16
    523 #define FM_Y_SPACE      4
    524 #define FM_SPACE1       4
    525 #define FM_SPACE2       2
    526 #define FM_LEFTBORDER   2
    527 #define FM_RIGHTBORDER  8
    528 /*************************************************************************
    529  * FileMenu_MeasureItem                         [SHELL32.112]
     515    UINT    uReserved,
     516    LPCITEMIDLIST   *ppidlFolder,
     517    LPCITEMIDLIST   *ppidlItem)
     518{
     519    FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
     520    return 0;
     521}
     522
     523#define FM_ICON_SIZE    16
     524#define FM_Y_SPACE  4
     525#define FM_SPACE1   4
     526#define FM_SPACE2   2
     527#define FM_LEFTBORDER   2
     528#define FM_RIGHTBORDER  8
     529/*************************************************************************
     530 * FileMenu_MeasureItem             [SHELL32.112]
    530531 */
    531532LRESULT WINAPI FileMenu_MeasureItem(
    532         HWND    hWnd,
    533         LPMEASUREITEMSTRUCT     lpmis)
    534 {
    535         LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
    536         HDC hdc = GetDC(hWnd);
    537         SIZE size;
    538         LPFMINFO menuinfo;
    539                
    540         TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
    541        
    542         GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
    543        
    544         lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
    545         lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
    546 
    547         /* add the menubitmap */
    548         menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
    549         if (menuinfo->nBorderWidth)
    550           lpmis->itemWidth += menuinfo->nBorderWidth;
    551        
    552         TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
    553         ReleaseDC (hWnd, hdc);
    554         return 0;
    555 }
    556 /*************************************************************************
    557  * FileMenu_DrawItem                            [SHELL32.105]
     533    HWND    hWnd,
     534    LPMEASUREITEMSTRUCT lpmis)
     535{
     536    LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
     537    HDC hdc = GetDC(hWnd);
     538    SIZE size;
     539    LPFMINFO menuinfo;
     540
     541    TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
     542
     543    GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
     544
     545    lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
     546    lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
     547
     548    /* add the menubitmap */
     549    menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
     550    if (menuinfo->nBorderWidth)
     551      lpmis->itemWidth += menuinfo->nBorderWidth;
     552
     553    TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
     554    ReleaseDC (hWnd, hdc);
     555    return 0;
     556}
     557/*************************************************************************
     558 * FileMenu_DrawItem                [SHELL32.105]
    558559 */
    559560LRESULT WINAPI FileMenu_DrawItem(
    560         HWND                    hWnd,
    561         LPDRAWITEMSTRUCT        lpdis)
    562 {
    563         LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
    564         COLORREF clrPrevText, clrPrevBkgnd;
    565         int xi,yi,xt,yt;
    566         HIMAGELIST hImageList;
    567         RECT TextRect, BorderRect;
    568         LPFMINFO menuinfo;
    569        
    570         TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
    571        
    572         if (lpdis->itemState & ODS_SELECTED)
    573         {
    574           clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
    575           clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
    576         }
    577         else
    578         {
    579           clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
    580           clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
    581         }
    582        
    583         CopyRect(&TextRect, &(lpdis->rcItem));
    584 
    585         /* add the menubitmap */
    586         menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
    587         if (menuinfo->nBorderWidth)
    588           TextRect.left += menuinfo->nBorderWidth;
    589        
    590         BorderRect.right = menuinfo->nBorderWidth;
    591 /*      FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
     561    HWND            hWnd,
     562    LPDRAWITEMSTRUCT    lpdis)
     563{
     564    LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
     565    COLORREF clrPrevText, clrPrevBkgnd;
     566    int xi,yi,xt,yt;
     567    HIMAGELIST hImageList;
     568    RECT TextRect, BorderRect;
     569    LPFMINFO menuinfo;
     570
     571    TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
     572
     573    if (lpdis->itemState & ODS_SELECTED)
     574    {
     575      clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
     576      clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
     577    }
     578    else
     579    {
     580      clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
     581      clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
     582    }
     583
     584    CopyRect(&TextRect, &(lpdis->rcItem));
     585
     586    /* add the menubitmap */
     587    menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
     588    if (menuinfo->nBorderWidth)
     589      TextRect.left += menuinfo->nBorderWidth;
     590
     591    BorderRect.right = menuinfo->nBorderWidth;
     592/*  FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
    592593*/
    593         TextRect.left += FM_LEFTBORDER;
    594         xi = TextRect.left + FM_SPACE1;
    595         yi = TextRect.top + FM_Y_SPACE/2;
    596         TextRect.bottom -= FM_Y_SPACE/2;
    597 
    598         xt = xi + FM_ICON_SIZE + FM_SPACE2;
    599         yt = yi;
    600 
    601         ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
    602        
    603         Shell_GetImageList(0, &hImageList);
    604         ImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
    605 
    606         TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
    607        
    608         SetTextColor(lpdis->hDC, clrPrevText);
    609         SetBkColor(lpdis->hDC, clrPrevBkgnd);
    610 
    611         return TRUE;
    612 }
    613 
    614 /*************************************************************************
    615  * FileMenu_InitMenuPopup                       [SHELL32.109]
     594    TextRect.left += FM_LEFTBORDER;
     595    xi = TextRect.left + FM_SPACE1;
     596    yi = TextRect.top + FM_Y_SPACE/2;
     597    TextRect.bottom -= FM_Y_SPACE/2;
     598
     599    xt = xi + FM_ICON_SIZE + FM_SPACE2;
     600    yt = yi;
     601
     602    ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
     603
     604    Shell_GetImageList(0, &hImageList);
     605    ImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
     606
     607    TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
     608
     609    SetTextColor(lpdis->hDC, clrPrevText);
     610    SetBkColor(lpdis->hDC, clrPrevBkgnd);
     611
     612    return TRUE;
     613}
     614
     615/*************************************************************************
     616 * FileMenu_InitMenuPopup           [SHELL32.109]
    616617 *
    617618 * NOTES
    618  *  The filemenu is a ownerdrawn menu. Call this function responding to 
     619 *  The filemenu is a ownerdrawn menu. Call this function responding to
    619620 *  WM_INITPOPUPMENU
    620621 *
     
    622623BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
    623624{
    624         FM_InitMenuPopup(hmenu, NULL);
    625         return TRUE;
    626 }
    627 
    628 /*************************************************************************
    629  * FileMenu_HandleMenuChar                      [SHELL32.108]
     625    FM_InitMenuPopup(hmenu, NULL);
     626    return TRUE;
     627}
     628
     629/*************************************************************************
     630 * FileMenu_HandleMenuChar          [SHELL32.108]
    630631 */
    631632LRESULT WINAPI FileMenu_HandleMenuChar(
    632         HMENU   hMenu,
    633         WPARAM  wParam)
    634 {
    635         FIXME("0x%08x 0x%08x\n",hMenu,wParam);
    636         return 0;
    637 }
    638 
    639 /*************************************************************************
    640  * FileMenu_DeleteAllItems                      [SHELL32.104]
     633    HMENU   hMenu,
     634    WPARAM  wParam)
     635{
     636    FIXME("0x%08x 0x%08x\n",hMenu,wParam);
     637    return 0;
     638}
     639
     640/*************************************************************************
     641 * FileMenu_DeleteAllItems          [SHELL32.104]
    641642 *
    642643 * NOTES
     
    644645 */
    645646BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
    646 {       
    647         MENUITEMINFOA   mii;
    648         LPFMINFO        menudata;
    649 
    650         int i;
    651        
    652         TRACE("0x%08x\n", hmenu);
    653        
    654         ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
    655         mii.cbSize = sizeof(MENUITEMINFOA);
    656         mii.fMask = MIIM_SUBMENU|MIIM_DATA;
    657 
    658         for (i = 0; i < GetMenuItemCount( hmenu ); i++)
    659         { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
    660 
    661           if (mii.dwItemData)
    662             SHFree((LPFMINFO)mii.dwItemData);
    663 
    664           if (mii.hSubMenu)
    665             FileMenu_Destroy(mii.hSubMenu);
    666         }
    667        
    668         while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
    669 
    670         menudata = FM_GetMenuInfo(hmenu);
    671        
    672         menudata->bInitialized = FALSE;
    673        
    674         return TRUE;
    675 }
    676 
    677 /*************************************************************************
    678  * FileMenu_DeleteItemByCmd                     [SHELL32.]
     647{
     648    MENUITEMINFOA   mii;
     649    LPFMINFO    menudata;
     650
     651    int i;
     652
     653    TRACE("0x%08x\n", hmenu);
     654
     655    ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
     656    mii.cbSize = sizeof(MENUITEMINFOA);
     657    mii.fMask = MIIM_SUBMENU|MIIM_DATA;
     658
     659    for (i = 0; i < GetMenuItemCount( hmenu ); i++)
     660    { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
     661
     662      if (mii.dwItemData)
     663        SHFree((LPFMINFO)mii.dwItemData);
     664
     665      if (mii.hSubMenu)
     666        FileMenu_Destroy(mii.hSubMenu);
     667    }
     668
     669    while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
     670
     671    menudata = FM_GetMenuInfo(hmenu);
     672
     673    menudata->bInitialized = FALSE;
     674
     675    return TRUE;
     676}
     677
     678/*************************************************************************
     679 * FileMenu_DeleteItemByCmd             [SHELL32.]
    679680 *
    680681 */
    681682BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
    682683{
    683         MENUITEMINFOA mii;
    684 
    685         TRACE("0x%08x 0x%08x\n", hMenu, uID);
    686        
    687         ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
    688         mii.cbSize = sizeof(MENUITEMINFOA);
    689         mii.fMask = MIIM_SUBMENU;
    690 
    691         GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
    692         if ( mii.hSubMenu )
    693         {
    694           /* FIXME: Do what? */
    695         }
    696 
    697         DeleteMenu(hMenu, MF_BYCOMMAND, uID);
    698         return TRUE;
    699 }
    700 
    701 /*************************************************************************
    702  * FileMenu_DeleteItemByIndex                   [SHELL32.140]
     684    MENUITEMINFOA mii;
     685
     686    TRACE("0x%08x 0x%08x\n", hMenu, uID);
     687
     688    ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
     689    mii.cbSize = sizeof(MENUITEMINFOA);
     690    mii.fMask = MIIM_SUBMENU;
     691
     692    GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
     693    if ( mii.hSubMenu )
     694    {
     695      /* FIXME: Do what? */
     696    }
     697
     698    DeleteMenu(hMenu, MF_BYCOMMAND, uID);
     699    return TRUE;
     700}
     701
     702/*************************************************************************
     703 * FileMenu_DeleteItemByIndex           [SHELL32.140]
    703704 */
    704705BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
    705706{
    706         MENUITEMINFOA mii;
    707 
    708         TRACE("0x%08x 0x%08x\n", hMenu, uPos);
    709 
    710         ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
    711         mii.cbSize = sizeof(MENUITEMINFOA);
    712         mii.fMask = MIIM_SUBMENU;
    713 
    714         GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
    715         if ( mii.hSubMenu )
    716         {
    717           /* FIXME: Do what? */
    718         }
    719 
    720         DeleteMenu(hMenu, MF_BYPOSITION, uPos);
    721         return TRUE;
    722 }
    723 
    724 /*************************************************************************
    725  * FileMenu_DeleteItemByFirstID                 [SHELL32.141]
     707    MENUITEMINFOA mii;
     708
     709    TRACE("0x%08x 0x%08x\n", hMenu, uPos);
     710
     711    ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
     712    mii.cbSize = sizeof(MENUITEMINFOA);
     713    mii.fMask = MIIM_SUBMENU;
     714
     715    GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
     716    if ( mii.hSubMenu )
     717    {
     718      /* FIXME: Do what? */
     719    }
     720
     721    DeleteMenu(hMenu, MF_BYPOSITION, uPos);
     722    return TRUE;
     723}
     724
     725/*************************************************************************
     726 * FileMenu_DeleteItemByFirstID         [SHELL32.141]
    726727 */
    727728BOOL WINAPI FileMenu_DeleteItemByFirstID(
    728         HMENU   hMenu,
    729         UINT    uID)
    730 {
    731         TRACE("0x%08x 0x%08x\n", hMenu, uID);
    732         return 0;
    733 }
    734 
    735 /*************************************************************************
    736  * FileMenu_DeleteSeparator                     [SHELL32.142]
     729    HMENU   hMenu,
     730    UINT    uID)
     731{
     732    TRACE("0x%08x 0x%08x\n", hMenu, uID);
     733    return 0;
     734}
     735
     736/*************************************************************************
     737 * FileMenu_DeleteSeparator         [SHELL32.142]
    737738 */
    738739BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
    739740{
    740         TRACE("0x%08x\n", hMenu);
    741         return 0;
    742 }
    743 
    744 /*************************************************************************
    745  * FileMenu_EnableItemByCmd                     [SHELL32.143]
     741    TRACE("0x%08x\n", hMenu);
     742    return 0;
     743}
     744
     745/*************************************************************************
     746 * FileMenu_EnableItemByCmd         [SHELL32.143]
    746747 */
    747748BOOL WINAPI FileMenu_EnableItemByCmd(
    748         HMENU   hMenu,
    749         UINT    uID,
    750         BOOL    bEnable)
    751 {
    752         TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
    753         return 0;
    754 }
    755 
    756 /*************************************************************************
    757  * FileMenu_GetItemExtent                       [SHELL32.144]
    758  * 
     749    HMENU   hMenu,
     750    UINT    uID,
     751    BOOL    bEnable)
     752{
     753    TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
     754    return 0;
     755}
     756
     757/*************************************************************************
     758 * FileMenu_GetItemExtent           [SHELL32.144]
     759 *
    759760 * NOTES
    760761 *  if the menu is to big, entrys are getting cut away!!
    761762 */
    762763DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
    763 {       RECT rect;
    764        
    765         FIXME("0x%08x 0x%08x\n", hMenu, uPos);
    766 
    767         if (GetMenuItemRect(0, hMenu, uPos, &rect))
    768         { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
    769           rect.right, rect.left, rect.top, rect.bottom);
    770           return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
    771         }
    772         return 0x00100010; /*fixme*/
    773 }
    774 
    775 /*************************************************************************
    776  * FileMenu_AbortInitMenu                       [SHELL32.120]
     764{   RECT rect;
     765
     766    FIXME("0x%08x 0x%08x\n", hMenu, uPos);
     767
     768    if (GetMenuItemRect(0, hMenu, uPos, &rect))
     769    { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
     770      rect.right, rect.left, rect.top, rect.bottom);
     771      return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
     772    }
     773    return 0x00100010; /*fixme*/
     774}
     775
     776/*************************************************************************
     777 * FileMenu_AbortInitMenu           [SHELL32.120]
    777778 *
    778779 */
    779780void WINAPI FileMenu_AbortInitMenu (void)
    780 {       TRACE("\n");
    781         bAbortInit = TRUE;
    782 }
    783 
    784 /*************************************************************************
    785  * SHFind_InitMenuPopup                         [SHELL32.149]
     781{   TRACE("\n");
     782    bAbortInit = TRUE;
     783}
     784
     785/*************************************************************************
     786 * SHFind_InitMenuPopup             [SHELL32.149]
    786787 *
    787788 *
    788789 * PARAMETERS
    789  *  hMenu               [in] handle of menu previously created
    790  *  hWndParent  [in] parent window
    791  *  w                   [in] no pointer (0x209 over here) perhaps menu IDs ???
    792  *  x                   [in] no pointer (0x226 over here)
     790 *  hMenu       [in] handle of menu previously created
     791 *  hWndParent  [in] parent window
     792 *  w           [in] no pointer (0x209 over here) perhaps menu IDs ???
     793 *  x           [in] no pointer (0x226 over here)
    793794 *
    794795 * RETURNS
    795  *  LPXXXXX                      pointer to struct containing a func addr at offset 8
    796  *                                      or NULL at failure.
     796 *  LPXXXXX          pointer to struct containing a func addr at offset 8
     797 *                  or NULL at failure.
    797798 */
    798799LPVOID WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
    799 {       FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
    800                 hMenu,hWndParent,w,x);
    801         return NULL; /* this is supposed to be a pointer */
    802 }
    803 
    804 /*************************************************************************
    805  * Shell_MergeMenus                             [SHELL32.67]
     800{   FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
     801        hMenu,hWndParent,w,x);
     802    return NULL; /* this is supposed to be a pointer */
     803}
     804
     805/*************************************************************************
     806 * Shell_MergeMenus             [SHELL32.67]
    806807 *
    807808 */
    808809BOOL _SHIsMenuSeparator(HMENU hm, int i)
    809810{
    810         MENUITEMINFOA mii;
    811 
    812         mii.cbSize = sizeof(MENUITEMINFOA);
    813         mii.fMask = MIIM_TYPE;
    814         mii.cch = 0;    /* WARNING: We MUST initialize it to 0*/
    815         if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
    816         {
    817           return(FALSE);
    818         }
    819 
    820         if (mii.fType & MFT_SEPARATOR)
    821         {
    822           return(TRUE);
    823         }
    824 
    825         return(FALSE);
     811    MENUITEMINFOA mii;
     812
     813    mii.cbSize = sizeof(MENUITEMINFOA);
     814    mii.fMask = MIIM_TYPE;
     815    mii.cch = 0;    /* WARNING: We MUST initialize it to 0*/
     816    if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
     817    {
     818      return(FALSE);
     819    }
     820
     821    if (mii.fType & MFT_SEPARATOR)
     822    {
     823      return(TRUE);
     824    }
     825
     826    return(FALSE);
    826827}
    827828
     
    829830
    830831HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
    831 {       int             nItem;
    832         HMENU           hmSubMenu;
    833         BOOL            bAlreadySeparated;
    834         MENUITEMINFOA   miiSrc;
    835         char            szName[256];
    836         UINT            uTemp, uIDMax = uIDAdjust;
    837 
    838         TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x  0x%04lx\n",
    839                 hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
    840 
    841         if (!hmDst || !hmSrc)
    842         { return uIDMax;
    843         }
    844 
    845         nItem = GetMenuItemCount(hmDst);
    846 
    847         if (uInsert >= (UINT)nItem)     /* insert position inside menu? */
    848         {
    849           uInsert = (UINT)nItem;        /* append on the end */
    850           bAlreadySeparated = TRUE;
    851         }
    852         else
    853         {
    854           bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
    855         }
    856 
    857         if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
    858         {
    859           /* Add a separator between the menus */
    860           InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
    861           bAlreadySeparated = TRUE;
    862         }
    863 
    864 
    865         /* Go through the menu items and clone them*/
    866         for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
    867         {
    868           miiSrc.cbSize = sizeof(MENUITEMINFOA);
    869           miiSrc.fMask =  MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
    870 
    871           /* We need to reset this every time through the loop in case menus DON'T have IDs*/
    872           miiSrc.fType = MFT_STRING;
    873           miiSrc.dwTypeData = szName;
    874           miiSrc.dwItemData = 0;
    875           miiSrc.cch = sizeof(szName);
    876 
    877           if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
    878           {
    879             continue;
    880           }
    881 
    882 /*        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);
     832{   int     nItem;
     833    HMENU       hmSubMenu;
     834    BOOL        bAlreadySeparated;
     835    MENUITEMINFOA   miiSrc;
     836    char        szName[256];
     837    UINT        uTemp, uIDMax = uIDAdjust;
     838
     839    TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x  0x%04lx\n",
     840        hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
     841
     842    if (!hmDst || !hmSrc)
     843    { return uIDMax;
     844    }
     845
     846    nItem = GetMenuItemCount(hmDst);
     847
     848    if (uInsert >= (UINT)nItem) /* insert position inside menu? */
     849    {
     850      uInsert = (UINT)nItem;    /* append on the end */
     851      bAlreadySeparated = TRUE;
     852    }
     853    else
     854    {
     855      bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
     856    }
     857
     858    if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
     859    {
     860      /* Add a separator between the menus */
     861      InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
     862      bAlreadySeparated = TRUE;
     863    }
     864
     865
     866    /* Go through the menu items and clone them*/
     867    for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
     868    {
     869      miiSrc.cbSize = sizeof(MENUITEMINFOA);
     870      miiSrc.fMask =  MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
     871
     872      /* We need to reset this every time through the loop in case menus DON'T have IDs*/
     873      miiSrc.fType = MFT_STRING;
     874      miiSrc.dwTypeData = szName;
     875      miiSrc.dwItemData = 0;
     876      miiSrc.cch = sizeof(szName);
     877
     878      if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
     879      {
     880        continue;
     881      }
     882
     883/*    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);
    883884*/
    884           if (miiSrc.fType & MFT_SEPARATOR)
    885           {
    886             /* This is a separator; don't put two of them in a row */
    887             if (bAlreadySeparated)
    888               continue;
    889 
    890             bAlreadySeparated = TRUE;
    891           }
    892           else if (miiSrc.hSubMenu)
    893           {
    894             if (uFlags & MM_SUBMENUSHAVEIDS)
    895             {
    896               miiSrc.wID += uIDAdjust;                  /* add uIDAdjust to the ID */
    897 
    898               if (miiSrc.wID > uIDAdjustMax)            /* skip ID's higher uIDAdjustMax */
    899                 continue;
    900 
    901               if (uIDMax <= miiSrc.wID)                 /* remember the highest ID */
    902                 uIDMax = miiSrc.wID + 1;
    903             }
    904             else
    905             {
    906               miiSrc.fMask &= ~MIIM_ID;                 /* Don't set IDs for submenus that didn't have them already */
    907             }
    908             hmSubMenu = miiSrc.hSubMenu;
    909 
    910             miiSrc.hSubMenu = CreatePopupMenu();
    911 
    912             if (!miiSrc.hSubMenu) return(uIDMax);
    913 
    914             uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
    915 
    916             if (uIDMax <= uTemp)
    917               uIDMax = uTemp;
    918 
    919             bAlreadySeparated = FALSE;
    920           }
    921           else                                          /* normal menu item */
    922           {
    923             miiSrc.wID += uIDAdjust;                    /* add uIDAdjust to the ID */
    924 
    925             if (miiSrc.wID > uIDAdjustMax)              /* skip ID's higher uIDAdjustMax */
    926               continue;
    927 
    928             if (uIDMax <= miiSrc.wID)                   /* remember the highest ID */
    929               uIDMax = miiSrc.wID + 1;
    930 
    931             bAlreadySeparated = FALSE;
    932           }
    933 
    934 /*        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);
     885      if (miiSrc.fType & MFT_SEPARATOR)
     886      {
     887        /* This is a separator; don't put two of them in a row */
     888        if (bAlreadySeparated)
     889          continue;
     890
     891        bAlreadySeparated = TRUE;
     892      }
     893      else if (miiSrc.hSubMenu)
     894      {
     895        if (uFlags & MM_SUBMENUSHAVEIDS)
     896        {
     897          miiSrc.wID += uIDAdjust;          /* add uIDAdjust to the ID */
     898
     899          if (miiSrc.wID > uIDAdjustMax)        /* skip ID's higher uIDAdjustMax */
     900            continue;
     901
     902          if (uIDMax <= miiSrc.wID)         /* remember the highest ID */
     903            uIDMax = miiSrc.wID + 1;
     904        }
     905        else
     906        {
     907          miiSrc.fMask &= ~MIIM_ID;         /* Don't set IDs for submenus that didn't have them already */
     908        }
     909        hmSubMenu = miiSrc.hSubMenu;
     910
     911        miiSrc.hSubMenu = CreatePopupMenu();
     912
     913        if (!miiSrc.hSubMenu) return(uIDMax);
     914
     915        uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
     916
     917        if (uIDMax <= uTemp)
     918          uIDMax = uTemp;
     919
     920        bAlreadySeparated = FALSE;
     921      }
     922      else                      /* normal menu item */
     923      {
     924        miiSrc.wID += uIDAdjust;            /* add uIDAdjust to the ID */
     925
     926        if (miiSrc.wID > uIDAdjustMax)      /* skip ID's higher uIDAdjustMax */
     927          continue;
     928
     929        if (uIDMax <= miiSrc.wID)           /* remember the highest ID */
     930          uIDMax = miiSrc.wID + 1;
     931
     932        bAlreadySeparated = FALSE;
     933      }
     934
     935/*    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);
    935936*/
    936           if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
    937           {
    938             return(uIDMax);
    939           }
    940         }
    941 
    942         /* Ensure the correct number of separators at the beginning of the
    943         inserted menu items*/
    944         if (uInsert == 0)
    945         {
    946           if (bAlreadySeparated)
    947           {
    948             DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
    949           }
    950         }
    951         else
    952         {
    953           if (_SHIsMenuSeparator(hmDst, uInsert-1))
    954           {
    955             if (bAlreadySeparated)
    956             {
    957               DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
    958             }
    959           }
    960           else
    961           {
    962             if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
    963             {
    964               /* Add a separator between the menus*/
    965               InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
    966             }
    967           }
    968         }
    969         return(uIDMax);
    970 }
    971 
     937      if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
     938      {
     939        return(uIDMax);
     940      }
     941    }
     942
     943    /* Ensure the correct number of separators at the beginning of the
     944    inserted menu items*/
     945    if (uInsert == 0)
     946    {
     947      if (bAlreadySeparated)
     948      {
     949        DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
     950      }
     951    }
     952    else
     953    {
     954      if (_SHIsMenuSeparator(hmDst, uInsert-1))
     955      {
     956        if (bAlreadySeparated)
     957        {
     958          DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
     959        }
     960      }
     961      else
     962      {
     963        if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
     964        {
     965          /* Add a separator between the menus*/
     966          InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
     967        }
     968      }
     969    }
     970    return(uIDMax);
     971}
     972
Note: See TracChangeset for help on using the changeset viewer.