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\\W indows\\Cu rrentVersi on\\Explor er\\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(s z, szPath, MAX_PATH);
RegCloseKey(hKey);
BuildFavoritesMenu(szPath, 0, pMenu);
return 0;
}
int CWebView::BuildFavoritesMe nu(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_LENG TH];
CStringArray astrFavorites;
CStringArray astrDirs;
CMenu* pSubMenu;
// make sure there's a trailing backslash
if(strPath[strPath.GetLeng th() - 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_ATTRI BUTE_HIDDE N|FILE_ATT RIBUTE_SYS TEM))==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("Intern etShortcut "), _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(astrF avorites[n Pos]) < 0)
break;
}
astrFavorites.InsertAt(nPo s, str);
m_astrFavoriteURLs.InsertA t(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_STRIN G | 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].CompareN oCase(wfd. cFileName) > 0)
break;
}
pSubMenu = new CMenu;
pSubMenu->CreatePopupMenu( );
// call this function recursively.
nNewEndPos = BuildFavoritesMenu(strPath 2 + 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?
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,
// find out from the registry where the favorites are located.
if(RegOpenKey(HKEY_CURRENT
{
TRACE0("Favorites folder not found\n");
return 0;
}
dwSize = sizeof(sz);
RegQueryValueEx(hKey, _T("Favorites"), NULL, NULL, (LPBYTE)sz, &dwSize);
ExpandEnvironmentStrings(s
RegCloseKey(hKey);
BuildFavoritesMenu(szPath,
return 0;
}
int CWebView::BuildFavoritesMe
{
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_LENG
CStringArray astrFavorites;
CStringArray astrDirs;
CMenu* pSubMenu;
// make sure there's a trailing backslash
if(strPath[strPath.GetLeng
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|
{
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(""), 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(astrF
break;
}
astrFavorites.InsertAt(nPo
m_astrFavoriteURLs.InsertA
++nEndPos;
}
}
} while(FindNextFile(h, &wfd));
FindClose(h);
// Now add these items to the menu
for(nPos = nStartPos ; nPos < nEndPos ; ++nPos)
{
pMenu->AppendMenu(MF_STRIN
}
// 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].CompareN
break;
}
pSubMenu = new CMenu;
pSubMenu->CreatePopupMenu(
// call this function recursively.
nNewEndPos = BuildFavoritesMenu(strPath
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?
What assertion and where does it happen?
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.
ASKER
It happens as soon as setup(); is called. It says:
Debug Assertation Failed
project directory path...
f:\vs70builds\9466\vc\MFCA TL\ship\at lmfc\inclu de\afxwin1 .inl
Line 875
Debug Assertation Failed
project directory path...
f:\vs70builds\9466\vc\MFCA
Line 875
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks, I've been racking my brain on that for almost a week. worked perfectly!