Link to home
Start Free TrialLog in
Avatar of cheapstr
cheapstr

asked on

CHTML View : Add Favorites Menu

I am using the microsoft sample "mfcie" from the samples download at the msdn site to go by on this. When trying to fill the 'favorites' menu, I keep getting a debug assertation failure. I can get this funtion to work fine using a SDI app, but it crashes if I try to use it in a MDI app. I'm trying to make a MDI web browser (just for fun and to learn from) to have several browsers open in the same frame. Here is the code:

int CWebView::setup()
{
// set up Favorites menu
      TCHAR           sz[MAX_PATH];
      TCHAR           szPath[MAX_PATH];
      HKEY            hKey;
      DWORD           dwSize;
      CMenu*          pMenu;

      // first get rid of bogus submenu items.
      pMenu = GetMenu()->GetSubMenu(3);
      while(pMenu->DeleteMenu(0, MF_BYPOSITION));

      // find out from the registry where the favorites are located.
      if(RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"), &hKey) != ERROR_SUCCESS)
      {
            TRACE0("Favorites folder not found\n");
            return 0;
      }
      dwSize = sizeof(sz);
      RegQueryValueEx(hKey, _T("Favorites"), NULL, NULL, (LPBYTE)sz, &dwSize);
      ExpandEnvironmentStrings(sz, szPath, MAX_PATH);
      RegCloseKey(hKey);

      BuildFavoritesMenu(szPath, 0, pMenu);
      return 0;
}
 int CWebView::BuildFavoritesMenu(LPCTSTR pszPath, int nStartPos, CMenu* pMenu)
{
      CString         strPath(pszPath);
      CString         strPath2;
      CString         str;
      WIN32_FIND_DATA wfd;
      HANDLE          h;
      int             nPos;
      int             nEndPos;
      int             nNewEndPos;
      int             nLastDir;
      TCHAR           buf[INTERNET_MAX_PATH_LENGTH];
      CStringArray    astrFavorites;
      CStringArray    astrDirs;
      CMenu*          pSubMenu;

      // make sure there's a trailing backslash
      if(strPath[strPath.GetLength() - 1] != _T('\\'))
            strPath += _T('\\');
      strPath2 = strPath;
      strPath += "*.*";

      // now scan the directory, first for .URL files and then for subdirectories
      // that may also contain .URL files
      h = FindFirstFile(strPath, &wfd);
      if(h != INVALID_HANDLE_VALUE)
      {
            nEndPos = nStartPos;
            do
            {
                  if((wfd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))==0)
                  {
                        str = wfd.cFileName;
                        if(str.Right(4) == _T(".url"))
                        {
                              // an .URL file is formatted just like an .INI file, so we can
                              // use GetPrivateProfileString() to get the information we want
                              ::GetPrivateProfileString(_T("InternetShortcut"), _T("URL"),
                                                                    _T(""), buf, INTERNET_MAX_PATH_LENGTH,
                                                                    strPath2 + str);
                              str = str.Left(str.GetLength() - 4);

                              // scan through the array and perform an insertion sort
                              // to make sure the menu ends up in alphabetic order
                              for(nPos = nStartPos ; nPos < nEndPos ; ++nPos)
                              {
                                    if(str.CompareNoCase(astrFavorites[nPos]) < 0)
                                          break;
                              }
                              astrFavorites.InsertAt(nPos, str);
                              m_astrFavoriteURLs.InsertAt(nPos, buf);
                              ++nEndPos;
                        }
                  }
            } while(FindNextFile(h, &wfd));
            FindClose(h);
            // Now add these items to the menu
            for(nPos = nStartPos ; nPos < nEndPos ; ++nPos)
            {
                  pMenu->AppendMenu(MF_STRING | MF_ENABLED, 0xe00 + nPos, astrFavorites[nPos]);
            }


            // now that we've got all the .URL files, check the subdirectories for more
            nLastDir = 0;
            h = FindFirstFile(strPath, &wfd);
            ASSERT(h != INVALID_HANDLE_VALUE);
            do
            {
                  if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                  {
                        // ignore the current and parent directory entries
                        if(lstrcmp(wfd.cFileName, _T(".")) == 0 || lstrcmp(wfd.cFileName, _T("..")) == 0)
                              continue;

                        for(nPos = 0 ; nPos < nLastDir ; ++nPos)
                        {
                              if(astrDirs[nPos].CompareNoCase(wfd.cFileName) > 0)
                                    break;
                        }
                        pSubMenu = new CMenu;
                        pSubMenu->CreatePopupMenu();

                        // call this function recursively.
                        nNewEndPos = BuildFavoritesMenu(strPath2 + wfd.cFileName, nEndPos, pSubMenu);
                        if(nNewEndPos != nEndPos)
                        {
                              // only intert a submenu if there are in fact .URL files in the subdirectory
                              nEndPos = nNewEndPos;
                              pMenu->InsertMenu(nPos, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)pSubMenu->m_hMenu, wfd.cFileName);
                              pSubMenu->Detach();
                              astrDirs.InsertAt(nPos, wfd.cFileName);
                              ++nLastDir;
                        }
                        delete pSubMenu;
                  }
            } while(FindNextFile(h, &wfd));
            FindClose(h);
      }
      return nEndPos;
}
Does anyone know why this crashes when using in a MDI app and how can I get this to work?
Avatar of AlexFM
AlexFM

What assertion and where does it happen?
Avatar of cheapstr

ASKER

One thing I forgot to mention about the preceeding question: This MDI app uses 2 different document types, htmlview and richeditview, so of course uses different menu resources, IDR_MAINFRAME(when no documents), IDR_TEXT(when using richeditview), and IDR_WEB(when using browser). I'm thinking that this is the reason for crashing because the favorites menu is under IDR_WEB.  But I am fairly new to this and I'm not sure where or how to specify which menu resource to use in the  setup() and BuildFavoritesMenu() code.
It happens as soon as setup(); is called. It says:

Debug Assertation Failed
project directory path...
f:\vs70builds\9466\vc\MFCATL\ship\atlmfc\include\afxwin1.inl
Line 875
ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks, I've been racking my brain on that for almost a week. worked perfectly!