二、实现收藏菜单
一般IE的用户都有个习惯,那就是将自己喜欢的网址保存起来,以方便今后快速的登陆,为了使我们的浏览器能够显示IE收藏过的网址,程序中设置了一个"Favorites"菜单,通过RegOpenKey()、RegQueryValueEx()等函数操作Windows的注册表中的HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders项,将收藏的网址显示到菜单上。为此,笔者定义了两个函数,实现代码如下所示:
TCHAR GetDir( ) //得到存放用户收藏网址的目录;
{
TCHAR sz[MAX_PATH];
TCHAR szPath[MAX_PATH];
HKEY hKey;
DWORD dwSize;
CMenu* pMenu;
// 得到"Favorites"菜单,并删除空白的子菜单项;
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);
Return szPath
}
int CMainFrame::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;
if(strPath[strPath.GetLength() - 1] != _T('\\'))
strPath += _T('\\');
strPath2 = strPath;
strPath += "*.*";
// 扫描当前目录,首先搜索*.URL文件,然后是可能含有*.URL文件的子目录;
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"))
{/*URL文件和INI文件格式类似,所以我们可以使用 GetPrivateProfileString() 来得到我们所需要的信息。*/
::GetPrivateProfileString(_T("InternetShortcut"), T("URL"),
_T(""),buf,INTERNET_MAX_PATH_LENGTH,
strPath2 + str);
str = str.Left(str.GetLength() - 4);
// 判断是否已经重复;
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);
// 将找到的项目添加到菜单中;
for(nPos = nStartPos ; nPos < nEndPos ; ++nPos)
{
pMenu->AppendMenu(MF_STRING | MF_ENABLED, 0xe00 + nPos, astrFavorites[nPos]);
}
// 搜索子目录
nLastDir = 0;
h = FindFirstFile(strPath, &wfd);
ASSERT(h != INVALID_HANDLE_VALUE);
do
{
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{ //对目录进行搜索;
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)
{
// 插入子菜单;
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;
}
三、显示超文本
微软ChtmView类的Navigate2函数可以实现超文本文件的显示,GoBack()、GoForward()等函数可以分别实现网页浏览的回退和前进操作。以响应"Favorite"菜单项为例,需要在程序的CmainFrame类中添加消息映射ON_COMMAND_RANGE(0xe00, 0xfff, OnFavorite)和消息响应函数OnFavorite,来响应ID为0xe00-0xfff范围内的菜单单击处理,具体实现代码如下:
void CMainFrame::OnFavorite(UINT nID)
{
((CMYIEView*)GetActiveView())->Navigate2(m_astrFavoriteURLs[nID-0xe00], 0, NULL);
}
四、小结
上面的代码相对较多,对某些函数的使用不清楚的话,请参考MSDN,它包含了高级界面处理、注册表的操作等内容,也许刚开始看起来可能感到有些困难,但是如果读者朋友细细品味的话,一定可以学到一些东西,对今后程序的界面开发有所帮助。