二、实现收藏菜单
一般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,它包含了高级界面处理、注册表的操作等内容,也许刚开始看起来可能感到有些困难,但是如果读者朋友细细品味的话,一定可以学到一些东西,对今后程序的界面开发有所帮助。
|