一、实验目的及要求
目的:
通过一周的课程设计,编写一个项目型的功能软件,综合应用专业所学习的多门课程知识,并把本学期所学的网络编程的知识运用到实际编程中,熟练编程规范,训练编程思维,为学生适应毕业后团队合作开发规模稍大项目打下基础。
要求:
利用已有的HTTP控制、HTML解释器和HTML执行器,通过MFC提供的CHtmlView类实现的一个Windows下的多功能的浏览器,其功能包括:WEB站点浏览、本地和网络的文件系统的浏览、历史记录的维护、IE收藏夹功能和设置桌面快捷方式功能等。
二、实验设备(环境)及要求
(1) 使用VC++平台实现该程序
(2) 界面设计合理美观,不要求统一界面
(3) 要求用户操作时,要给出清晰、明确的提示信息
(4) 所有文件、函数、变量的命名应尽量作到”见其名知其意”
(5) 5或6人一小组,明确每个学生在开发小组中扮演的角色及承担的职责(包括选出组长)。可以讨论算法的实现和编程的思路和方法,但每个人必须自己动手编写程序,不得抄袭。
三、实验内容与具体实现步骤
(一)实现WEB站点浏览,初步完成浏览器的模块的建立以及实现工具栏的各个功能(如:前进.后退,刷新,主页,停止以及搜索等功能)。
1.利用MFC AppWizard生成应用程序框架
工程名为myWeb16。第一步,选择工程类型为单文档(SDI),中文语言支持。第二步和第三步使用默认值,不需要数据库,也不提供对于复合对象的支持;第四步选择Internet Explorer ReBars工具栏的风格,这样就有了用来输入网址的文本框;第五步不做任何修改;第六步选择CHtmlView类作为视图类的基类。生成工程框架包含4个类。
(1) 应用程序类:CMyWeb16App,对应myWeb16.h和myWeb16.cpp文件。
(2) 框架类:CMainFrame,对应MainFrm.h和MainFrm.cpp文件。
(3) 文档类:CMyWeb16Doc,对应myWeb16Doc.h和myWeb16Doc.cpp文件。
(4) HtmlView类:CMyWeb16View,对应myWeb16View.h和myWeb16View.cpp文件。
此时编译运行,程序已经具有基本的Web浏览功能,能自动链接到微软公司的网站。
2.修改菜单
在工作区中选择“ResourceView”选项卡,选择Menu,双击菜单控件的名字(IDR_MAINFRAME),右边出现程序的菜单。选择菜单中的“查看”命令,已经有了“工具栏”和“状态栏”两个条目,双击下面的空框,弹出设置菜单条目属性对话框,如图1.1所示,按照表1.2添加6个菜单条目
菜单条目名称(Caption) |
ID号 |
前进 |
ID_FOWARD |
后退 |
ID_BACK |
停止 |
ID_STOP |
刷新 |
ID_UPDATE |
主页 |
ID_HOMEPAGE |
搜索 |
ID_SEARCH |
图1.2 |
3.修改工具栏
在工具栏上增加新的按钮,以便快速执行所需的功能。在工作区中选择“ReaourcecView”选项卡,选择ToolBar,双击工具条控件的名字(IDR_MAINFRAME),右边出现程序的工具条。双击其中的安秀,可以看到他们的属性。其中有一个空的按钮,双击它可以添加新的安秀的属性,如图1.3所示,利用右边的图形绘制工具,可以自己设计新的按钮图样。如图1.4所示。
如图添加6个按钮,他们的ID号与相应的菜单条目相同。拖动按钮,可以改变按钮之间的相对位置。
4.为控件添加时间处理函数
当用户单击菜单条目,或者单击相应的快捷键时,应能引起程序的反映,这就需要给这些控件添加时间处理函数。进入类向导,选择“Message Maps”选项卡。在“Class Name”下拉列表框中选择CMyWeb16View类,然后按照表1.5为前述的六个控件添加事件处理函数。
对象ID |
Messages |
Member Function |
ID_FORWARD |
COMMAND |
OnFoward() |
ID_BACK |
COMMAND |
OnBack() |
ID_STOP |
COMMAND |
OnStop() |
ID_UPDATE |
COMMAND |
OnUpdate() |
ID_HOMEPAGE |
COMMAND |
OnHomepage() |
ID_SEARCH |
COMMAND |
OnSearch() |
图1.5 |
5.添加事件处理函数的代码
在MyWeb16View.cpp实现文件中,添加上述6个时间处理函数的代码。
//前进到下一个网页
void CMyWeb16View::OnFoward() {GoForward();}
//退到下一个网页
void CMyWeb16View::OnBack() {GoBack();}
//停止网页的下载
void CMyWeb16View::OnStop() {Stop();}
//刷新当前的网页
void CMyWeb16View::OnUpdate() {Refresh();}
//回到主页
void CMyWeb16View::OnHomepage() {GoHome();}
//进行搜索
void CMyWeb16View::OnSearch() {GoSearch();}
此时可以再进行编译运行。
6.为应用程序添加URL定位功能
(1)添加网址输入栏控件。在工作区中选择“Resource View”选项卡,选择Dialog,双击对话框控件的名字(IDR_MAINFRAME),右边出现对话框条。在上面添加一个“地址”的静态文本,再添加一个文本编辑框控件,ID号时IDC_ADDR,作为地址栏,提供给用户输入要浏览的网站地址。如图1.6所示。
(2)添加控制代码。当用户输入网址后按回车时,就有一个IDOK的消息发送到主框架类,添加处理这个消息的控制函数,在该函数中,用指定的网址调用Navigate()和Navigate2()函数 ,就可以实现对该网页的浏览。
①在MainFrm.h文件中,添加消息处理函数的声明。
public:
void OnNew();
②在MainFrm.cpp文件中,添加该函数的实现代码。
void CMainFrame::OnNew()
{
CString pp; //获得用户在地址栏中输入的URL
m_wndDlgBar.GetDlgItem(IDC_ADDR)->GetWindowText(pp); //浏览指定的网页
((CMyWeb16View*)GetActiveView())->Navigate(pp);
}
③建立事件处理函数与消息的映射
在MainFrm.cpp的文件中,在消息映射(MESSAGE_MAP)段中添加自己的消息映射宏。用ON_COMMAND命令建立IDOK消息和处理函数OnNew的映射关系。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_COMMAND(IDOK,OnNew) //自己的消息映射宏
END_MESSAGE_MAP()
④在myWeb16View.h文件的类定义前面添加包含语句
#include"myWeb16Doc.h"
7.解决单击超级链接时地址栏的同步问题
利用CHtmlView类的事件处理函数,当网页下载完成,会触发OnDocumentComplete()函数,该函数的参数就是所下载网页的URL,可以利用此函数对地址栏进行设置,添加以下代码。
① 在MainFrm.h文件中,添加处理函数的声明。
public:
void SetPage(LPCTSTR lpazURL);
②在MainFrm.cpp文件中,添加该函数的实现代码。
void CMainFrame::SetPage(LPCTSTR lpszURL)
{
m_wndDlgBar.GetDlgItem(IDC_ADDR)->SetWindowText(lpszURL);
}
③使用类向导添加事件处理函数。用类向导为应用程序的CMyWeb16View类添加OnDocumentComplete()事件处理函数,并在myWeb16View.cpp文件中添加它的实现代码。
void CMyWeb16View::OnDocumentComplete(LPCTSTR lpszURL)
{
((CMainFrame*)GetParentFrame())->SetPage(lpszURL);
}
④添加包含语句。在MainFrm.cpp文件前面添加包含语句。 #include"myWeb16View.h"
在myWeb16View.cpp文件前面添加包含语句。 #include"MainFrm.h"
8.修改首页地址,以及主页地址和搜索页面。
①在myWeb16View.cpp的文件中,找到OnInitialUpdate()函数,修改首页地址。
Navigate2(_T("http://www.baidu.com"),NULL,NULL);
②在开始菜单的运行中输入regedit,回车。在目录菜单下:HKEY_CURRENT_USER/Software/Microsoft/Internet Explorer/Main找到Start Page(主页)和Search Page(搜索页),并修改其数值数据。
Start Page(主页):www.baidu.com Search Page(搜索页):www.google.com.hk
(二)加入删除IE相关历史记录的功能(包括删除文档历史纪录,清除cookies,清除Internet临时文件,清除地址栏中的历史任务,清除密码历史纪录和清除收藏夹)。
1.添加“删除”菜单
(1)修改菜单,在工作区中选择“ResourceView”选项卡,选择Menu,双击菜单控件的名字(IDR_MAINFRAME),右边出现程序的菜单。在菜单中加入“删除”栏,分别添加“删除文档历史记录”、“清除Cookies”、“清除Internet临时文件”、“清除地址栏中的历史地址”、“清除密码历史记录”和“清除收藏夹”6个菜单条目及其属性。如图2.1、2.2、2.3示。
菜单条目名称(Caption) |
ID号 |
删除文档历史记录 |
ID_DelHistory |
清除Cookie |
ID_DelCookies |
清除Internet临时文件 |
ID_DelIntenetTempFile |
清除地址栏中历史地址 |
ID_DelHistoryAddress |
清除密码历史记录 |
ID_DelHistoryPassword |
图2.2 |
2.为控件添加事件处理函数
进入类向导,选择“Message Maps”选项卡。在“Class Name”下拉列表框中选择CMyWeb16View类,然后按照表2.4为上述删除的六个控件添加事件处理函数。
对象ID |
Messages |
Member Function |
ID_DelHistory |
COMMAND |
OnDelHistory() |
ID_DelCookies |
COMMAND |
OnDelCookies() |
ID_DelIntenetTempFile |
COMMAND |
OnDelIntenetTempFile() |
ID_DelHistoryAddress |
COMMAND |
OnDelHistoryAddress() |
ID_DelHistoryPassword |
COMMAND |
OnDelHistoryPassword() |
图2.4 |
3.添加事件处理函数的代码
在myWeb16View.cpp中,添加如下代码。
(1)实现文档历史记录的清除
void CMyWeb16View::OnDelHistory() //清除文档历史记录
{
TCHAR szPath[MAX_PATH];
if(SHGetSpecialFolderPath(NULL,szPath,CSIDL_RECENT,FALSE))
{
EmptyDirectory(szPath);
}
SHDeleteKey(HKEY_CURRENT_USER,_T("Software\\Microsoft\\CurrentVersion\\Explorer\\RecentDocs"));
}
(2)清除Cookie
void CMyWeb16View::OnDelCookies() //清除Cookies
{
TCHAR szPath[MAX_PATH];
DeleteUrlCache(Cookie); //删除URL的Cache
if (SHGetSpecialFolderPath(NULL,szPath,CSIDL_COOKIES,FALSE))
{
EmptyDirectory(szPath);
}
}
(3) 清除Internet的临时文件
void CMyWeb16View::OnDelIntenetTempFile() //清空Internet临时文件
{
TCHAR szPath[MAX_PATH];
DeleteUrlCache(File); //删除URL的Cache
if (SHGetSpecialFolderPath(NULL,szPath,CSIDL_INTERNET_CACHE,FALSE))
{ //得到临时目录并清空它
EmptyDirectory(szPath);
}
}
(4)清除地址栏中的历史任务
void CMyWeb16View::OnDelHistoryAddress()
{ //浏览器地址栏历史记录的清除
SHDeleteKey(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Internet Explorer\\TypedURLs"));
}
(5)清除密码历史纪录
void CMyWeb16View::OnDelHistoryPassword()
{ //清除密码历史记录
SHDeleteKey(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Internet Explorer\\IntelliForms"));
}
(6)实现目录的删除
在OnDelIntenetTempFile、OnDelCookies和OnDelHistory这三个函数中都用到了函数EmptyDirectory()。删除目录是一个基本操作,因为有些历史记录是以文件形式保存在某个特定目录下的而且目录下还可能有子目录,所以可以采用递归方法删除整个目录。
EmptyDirectory函数负责清空整个目录。
①在myWeb16View.cpp文件的类定义前面添加包含语句。
#include "shlwapi.h"
在StdAfc.h文件的类定义前面添加包含语句。
#include "atlbase.h"
② 在myWeb16View.h的文件中,添加处理函数的声明。
public:
BOOL EmptyDirectory(LPCTSTR szPath, BOOL bDeleteDesktopIni = FALSE, BOOL bWipeIndexDat = FALSE);//清空一个目录
③在myWeb16View.cpp的文件中,添加该函数的实现代码。
BOOL CMyWeb16View::EmptyDirectory(LPCTSTR szPath,BOOL bDeleteDesktopIni,BOOL bWipeIndexDat)
{
WIN32_FIND_DATA wfd;
HANDLE hFind; //文件句柄
CString sFullPath;
CString sFindFilter;
DWORD dwAttributes = 0;
sFindFilter = szPath; //路径名
sFindFilter +=_T("\\*.*"); //表示所有文件都要删除
//找到第一个文件
if((hFind=FindFirstFile(sFindFilter,&wfd))==INVALID_HANDLE_VALUE)
{
return FALSE;
}
do
{
if(_tcscmp(wfd.cFileName,_T("."))==0||
_tcscmp(wfd.cFileName,_T(".."))==0||
(bDeleteDesktopIni==FALSE&&_tcscmp(wfd.cFileName,_T("desktop.ini"))==0))
{
continue;
}
sFullPath=szPath;
sFullPath+=_T('\\');
sFullPath+=wfd.cFileName; //文件完整的路径和名称
//如果文件含有只读属性,那么应该去掉该属性再删除
dwAttributes=GetFileAttributes(sFullPath); //得到文件属性
if (dwAttributes&FILE_ATTRIBUTE_READONLY) //判断是否只读
{
dwAttributes&=~FILE_ATTRIBUTE_READONLY; //删除只读属性
SetFileAttributes(sFullPath,dwAttributes); //重新删除
}
//判断该文件是否是一个目录,如果是目录则递归调用清空子目录
if (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
EmptyDirectory(sFullPath,bDeleteDesktopIni,bWipeIndexDat);
RemoveDirectory(sFullPath);
}
else //这是一个文件
{
DeleteFile(sFullPath); //删除该文件
}
}
while(FindNextFile(hFind,&wfd)); //查找下一个文件
FindClose(hFind); //关闭文件句柄
return TRUE;
}
(7)关于Cache
在OnDelCookies函数和OnDelIntenetTempFile()函数中都用到了函数DeleteUrlCache()。在实际的网络中,任何从网络上流入的数据都会在本地的硬盘上缓存起来,Cookies和Internet临时文件也不例外,所以还需要清除他们的Cache,而不仅仅是文件本身。
① 在myWeb16View.h文件的类定义前面添加包含语句
#include "wininet.h"
#include "UrlHist.h"
#define SWEEP_BUFFER_SIZE 10000
② 在myWeb16View.h中添加如下枚举类型,以及处理函数的声明。
public:
enum DEL_CACHE_TYPE
{
File, //表示Internet临时文件
Cookie //表示Cookie
};
BOOL DeleteUrlCache(DEL_CACHE_TYPE type);
③ 在myWeb16View.cpp的文件中添加如下代码。
BOOL CMyWeb16View::DeleteUrlCache(DEL_CACHE_TYPE type)
{
BOOL bRet=FALSE;
HANDLE hEntry;
LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry=NULL; //Cache入口指针
DWORD dwEntrySize;
dwEntrySize=0;
hEntry=FindFirstUrlCacheEntry(NULL,NULL,&dwEntrySize); //找到第一个URL Cache入口
lpCacheEntry=(LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize];//分配空间
hEntry=FindFirstUrlCacheEntry(NULL,lpCacheEntry,&dwEntrySize);
if (!hEntry)
{
goto cleanup;
}
do
{
if (type==File&&!(lpCacheEntry->CacheEntryType&COOKIE_CACHE_ENTRY))
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
}
else if(type==Cookie&&(lpCacheEntry->CacheEntryType&COOKIE_CACHE_ENTRY))
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
}
dwEntrySize=0;
FindNextUrlCacheEntry(hEntry,NULL,&dwEntrySize);
delete [] lpCacheEntry;
lpCacheEntry=(LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize];
}
while (FindNextUrlCacheEntry(hEntry,lpCacheEntry,&dwEntrySize));
bRet=TRUE;
cleanup:
if (lpCacheEntry)
{
delete [] lpCacheEntry;
}
return bRet;
}
(三)加入IE收藏夹功能和设置桌面快捷方式功能。
1. IE收藏夹功能
(1)添加菜单“收藏夹功能”
修改菜单,在菜单中加入“收藏夹”栏,分别添加 “添加到收藏夹”和“浏览收藏夹”2个菜单条目及其属性。新建一个对话框,用于存放用户收藏的网页,当用户点击浏览收藏夹时,便弹出该对话框,如图3.1.、3.2示。
菜单条目名称(Caption) |
ID号 |
添加到收藏夹 |
ID_ADD |
浏览收藏夹 |
ID_LOOK |
对话框条目名称(Caption) |
ID号 |
树状控件 |
IDC_TREE_FAV |
编辑框 |
IDC_EDIT_URL |
按钮“清空收藏夹” |
ID_DelFavoritesMenu |
按钮“OPEN” |
IDC_GOURL |
对象ID |
Messages |
Member Function |
ID_DelFavoritesMenu |
COMMAND |
OnDelFavoritesMenu() |
IDC_GOURL |
COMMAND |
OnGourl() |
(2)删除收藏夹内容
①在CFavoritesTryDlg.cpp的文件中,添加以下代码:
void CFavoritesTryDlg::OnDelFavoritesMenu()
{
//清收藏夹中的内容
TCHAR szPath[MAX_PATH];
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_FAVORITES, FALSE))
{ //得到目录,并清空
EmptyDirectory(szPath);
}
EndDialog(IDOK);
}
(CFavoritesTryDlg.cpp文件中引用到的函数EmptyDirectory()与功能(二)中函数一样。)
②在CFavoritesTryDlg.h文件中,声明EmptyDirectory函数。
public:
BOOL EmptyDirectory(LPCTSTR szPath,BOOL bDeleteDesktopIni=false,BOOL bWipeIndexDat=false);
(3)添加收藏夹
void CMyWeb16View::OnAdd()
{
#define ID_IE_ID_ADDFAV 2261
HWND oleHwnd = ::FindWindowEx(m_wndBrowser.m_hWnd, NULL, _T("Shell DocObject View"), NULL);
HWND ieHwnd=::FindWindowEx(oleHwnd, NULL, _T("Internet Explorer_Server"), NULL);
::SendMessage(ieHwnd , WM_COMMAND,
MAKEWPARAM(LOWORD(ID_IE_ID_ADDFAV), 0x0), 0 );
}
(4)浏览收藏夹网页
1. 菜单中“浏览收藏夹”的消息响应函数:
void CMainFrame::OnLook()
{
CFavoritesTryDlg* pDlg=new CFavoritesTryDlg();
pDlg->Create(IDD_FAVORITESTRY_DIALOG,this);
pDlg->ShowWindow(SW_SHOW);
pDlg->CenterWindow();
}
2. 在FavoritesTryDlg.h中添加代码如下:
public:
CEdit m_EDIT_URL;
CTreeCtrl m_TREE_FAV;
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
HICON m_hIcon;
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnSelchangingTreeFav(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDblclkTreeFav(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelchangedTreeFav(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDelFavoritesMenu();
3. 在FavoritesTryDlg.cpp中添加代码如下:
①设置全局变量:
LPBYTE favpath = new BYTE[80];
CString StrPath;
CString url;
CFileFind finder;
BOOL bWorking;
②DDX_Control(pDX, IDC_EDIT_URL, m_EDIT_URL);
DDX_Control(pDX, IDC_TREE_FAV, m_TREE_FAV);
③ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY(TVN_SELCHANGING, IDC_TREE_FAV, OnSelchangingTreeFav)
ON_NOTIFY(NM_DBLCLK, IDC_TREE_FAV, OnDblclkTreeFav)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_FAV, OnSelchangedTreeFav)
ON_BN_CLICKED(IDC_GOURL, OnGourl)
ON_BN_CLICKED(ID_DelFavoritesMenu, OnDelFavoritesMenu)
ON_WM_SYSCOMMAND()
④BOOL CFavoritesTryDlg::OnInitDialog()
{ ……
// 从注册表获取收藏夹所在位置
HKEY hKEY;
DWORD type=REG_SZ;
LPCTSTR path="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
DWORD cbData=80;
::RegOpenKeyEx(HKEY_CURRENT_USER,path,0,KEY_READ,&hKEY);
::RegQueryValueEx(hKEY,"Favorites",NULL,&type,favpath,&cbData);
::RegCloseKey(hKEY);
OnLoad();
return TRUE;
}
⑤void CFavoritesTryDlg::OnLoad()
{
StrPath = (CString)favpath + "\\*.*";
bWorking = finder.FindFile(StrPath);
while(bWorking)
{
bWorking = finder.FindNextFile();
if (!finder.IsDots() && finder.IsDirectory())
{
HandleDirectory();
}
}
StrPath = (CString)favpath + "\\*.url";
HandleFile(StrPath);
finder.Close();
}
⑥void CFavoritesTryDlg::HandleDirectory()
{
HTREEITEM hTreeItem = m_TREE_FAV.InsertItem(finder.GetFileName(), 0, 1, TVI_ROOT, TVI_LAST);
CString msg;
msg = (CString)favpath + "\\" + finder.GetFileName() + "\\*.url";
CFileFind finder2;
BOOL bWorking2 = finder2.FindFile(msg);
while(bWorking2)
{
bWorking2 = finder2.FindNextFile();
m_TREE_FAV.InsertItem(finder2.GetFileName(), 0, 1, hTreeItem, TVI_LAST);
}
}
void CFavoritesTryDlg::HandleFile(CString FilePath)
{
bWorking = finder.FindFile(FilePath);
while(bWorking)
{
bWorking = finder.FindNextFile();
m_TREE_FAV.InsertItem(finder.GetFileName(), 0, 1, TVI_ROOT, TVI_LAST);
}
}
⑦void CFavoritesTryDlg::OnDblclkTreeFav(NMHDR* pNMHDR, LRESULT* pResult)
{
OnGourl();
*pResult = 0;
}
void CFavoritesTryDlg::OnGourl()
{
HTREEITEM hSel=m_TREE_FAV.GetSelectedItem();
if(!m_TREE_FAV.ItemHasChildren(hSel)) // 没有子树
{
HKEY hKEY;
DWORD type=REG_SZ;
DWORD cbData=80;
LPBYTE IEpath = new BYTE[80];
::RegOpenKeyEx(HKEY_CLASSES_ROOT,"htmlfile\\shell\\open\\command",0,KEY_READ,&hKEY);
::RegQueryValueEx(hKEY,NULL,NULL,&type,IEpath,&cbData);
::RegCloseKey(hKEY);
char ShellChar[256];
strcpy(ShellChar,(char *)IEpath);
strcat(ShellChar,url);
WinExec(ShellChar,SW_SHOW);
}
}
2. 设置桌面快捷方式功能
①添加按钮“创建快捷方式”
修改对话框控件(IDR_MAINFRAME),添加按钮“创建快捷方式”与编辑框,如下图所示。
对话框条目名称(Caption) |
ID号 |
创建快捷方式 |
IDC_SHORTCUT |
编辑框 |
IDC_shortcutname |
对象ID |
Messages |
Member Function |
IDC_SHORTCUT |
COMMAND |
OnShortcut() |
②添加代码如下:
void CMainFrame::OnShortcut()
{
CString pp; //获得用户在地址栏中输入的URL
m_wndDlgBar.GetDlgItem(IDC_ADDR)->GetWindowText(pp);
CString pp1; //获得用户在地址栏中输入的URL
m_wndDlgBar.GetDlgItem(IDC_shortcutname)->GetWindowText(pp1);
IShellLink *MyLink;//IShellLink 接口指针
IPersistFile *ppf; //另一个接口指针
char DesktopLocate[MAX_PATH];//存储快捷方式在桌面保存的位置
//桌面的位置
SHGetSpecialFolderPath(NULL,DesktopLocate,CSIDL_DESKTOP,0);
//以下设定快捷方式在桌面保存位置
strcat(DesktopLocate,"\\");
strcat(DesktopLocate,pp1);
strcat(DesktopLocate,".LNK");
CoInitialize(NULL);//初始化COM
int re=CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_ALL, IID_IShellLink,(void **)&MyLink);
if(re<0)
{
AfxMessageBox("创建COM对象失败!");
return;
}
MyLink->SetPath(pp); //设置快捷方式实际文件位置
MyLink->SetDescription(pp1);//设置快捷方式描述(即名称)
re=MyLink->QueryInterface(IID_IPersistFile, (void **)&ppf);
if(re<0)
{
AfxMessageBox("无法创建快捷方式!");
MyLink->Release();
return;
}
WCHAR wsz[MAX_PATH];
MultiByteToWideChar( CP_ACP,0,DesktopLocate,-1,wsz,MAX_PATH);//转换为unicode
ppf->Save(wsz,true);//在桌面创建快捷方式
ppf->Release();
MyLink->Release();
AfxMessageBox("快捷方式创建成功.");
}
(四)显示浏览器当前访问站点的标题(附加功能)
实现此项功能需要重载CHtmlView::OnTitleChange,添加代码如下:
void CMyWeb16View::OnTitleChange(LPCTSTR lpszText)
{
CHtmlView::OnTitleChange(lpszText);
AfxGetMainWnd ()->SetWindowText (lpszText);
}
四、实验结果与数据处理
①起始页:
②“删除”功能
打开注册表,查找主键HKEY_CURRENT_USER下的键值“Software\\Microsoft\\Internet Explorer\\TypedURLs”,最初如下:
删除后:Internet Explorer\\TypedURLs文件夹为空
③ 收藏夹功能
添加网页至收藏夹:
浏览收藏夹内容:
清空收藏夹内容:
④ 快捷方式创建
五、分析与讨论
项目已实现功能:
1、WEB站点浏览,初步完成浏览器的模块的建立以及实现工具栏的各个功能(包括前进,后退,刷新,主页,停止以及搜索功能)
2、加入删除IE相关历史记录的功能(包括删除文档历史纪录,清除cookies,清除Internet临时文件,清除地址栏中的历史任务,清除密码历史纪录)
3、IE收藏夹功能(包括添加网页至收藏夹,浏览收藏夹内容以及清空收藏夹)
4、设置桌面快捷方式功能
5、显示浏览器当前访问站点的标题(附加功能)
项目未实现功能:
1、设置桌面快捷方式时,无法动态获取网页的标题
2、收藏夹中的网页,浏览时自动调用IE浏览,无法运用本浏览器浏览
六、参考文献
[1]汪翔,袁辉.Visual C++实践与提高—网络编程篇 [M].北京:中国铁道出版社,2001.318-322
[2]陈坚,陈伟等. Visual C++网络高级编程 [M].北京:人民邮电出版社,2001.254-272
[3]汪晓平,刘韬. Visual C++6.0开发网络典型应用实例导航[M]. 北京:人民邮电出版社,2005.234-299
[4]黄维通,姚瑞霞. Visual C++程序设计教程[M]. 北京:机械工业出版社,2001.7
[5]胡志坤. Visual C++通信编程工程实例精解[M]. 北京:机械工业出版社,2007.68-69
[6]四维科技,曹衍龙,刘海英. VC++网络通信编程实用案例精选. 人民邮电出版社,2006.5
[7]叶树华.《网络编程实用教程》第2版.北京人民邮电出版社.2010
[8]曹衍龙 刘海英.《Visual C++网络通信编程实用案例精选》.北京人民邮电出版社.2006