前言
本人是在家中上网,经常有一些BBS的密码懒得记了,就用IE的自动密码保存功能,这样一来是方便了,但却有一个麻烦,一旦机子不行了,想要重装操作系统了,这些密码却也取不出了,还得重新申请,好麻烦!因此我就写了一个工具,可以取得网页密码框的密码.
因为网页密码框不是一般的EDIT控件,因此不能取得网页密码框的句柄.要实现这个功能,只好通过WebBrowser控件的有关COM接口了.因此取得这些接口是整个程序的关键.有两种方法可以取得WebBrowser控件的接口,接下来我们会逐一介绍。
示例程序运行效果图
第一种方法:使用脚本语言和IE右键菜单
我们可以使用注册表来控制IE右键菜单.当你装了FlashGet(网际快车)时,你会发现IE右键菜单多了两项:"使用网际快车下载"和"使用网际快车下载全部链接",而这时你打开注册表,在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\下有这两个主键.这两个主键下都有两个值,一个是默认的串值,指定了选择了这个菜单命令要打开的URL,IE在一个隐藏的窗口打开它,并这个隐藏窗口的external.menuArguments值设为当前窗口对象,执行完URL对话网页包含的脚本程序该窗口自动关闭.另一个名称是contexts是DWORD值,指定了在什么情况下需要显示这个菜单项.具体的值见下.
(0x1 << CONTEXT_MENU_DEFAULT) (等于 0x1) //缺省时显示 (0x1 << CONTEXT_MENU_IMAGE) (等于 0x2) //右键点击图像时显示该项 (0x1 << CONTEXT_MENU_CONTROL) (等于 0x4) //右键点击表单元素时显示该项 (0x1 << CONTEXT_MENU_TABLE) (等于 0x8) //右键点击表格时显示该项 (0x1 << CONTEXT_MENU_TEXTSELECT) (等于 0x10) //右键点击高亮选择的文本时显示该项 (0x1 << CONTEXT_MENU_ANCHOR) (等于 0x20) //右键点击链接时显示该项 (0x1 << CONTEXT_MENU_UNKNOWN) (等于 0x40)//右键点击网页中除上以外的地方显示该项
现在我们写一段脚本程序以获取密码框的值. <!--getpassword.htm-> <script language="VBScript"> Sub GetPassword() set srcEvent = external.menuArguments.event Set doc=external.menuArguments.document set ele=doc.elementFromPoint( srcEvent.clientX, srcEvent.clientY ) if ele.type ="password" then if ele.value="" then Alert("密码为空") else Alert("密码为:"+ele.value) end if end if end sub call GetPassword() </script>
然后在注册表HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\下新建一下主键,键名为"取得密码",缺省值设为该htm文件的路径,在该主键下另增一个DWORD值,值为4,表示只在右击表单元素时显示该项.关闭注册表,重新启动IE窗口,点击一下密码框,就会出现该项,点击该项,弹出一个对话框,告诉你的密码.
接着应该处理WM_LBUTTONUP消息:
1.如果程序在Windows95,98和NT 4.0 Service With Pack 4 or 5下运行必须要把Microsoft Active Accessibility (MSAA)运行时组件(RDK)与程序一起发布(Windows2000及Windows NT 4.0 Service With Pack 6中已经有了,所以不用).
2.这种方法只适用用于Internet Explorer (Programming) versions 4.0, 4.01, 4.01 SP1, 4.01 SP2, 5
3.使用这种方法前要调用CoInitialize(NULL);然后应该相应地调用CoUninitialize();
4.Microsoft Active Accessibility (MSAA)可从 http://www.microsoft.com/enable/msaa/download.htm下载
附:
我们也可以使用Active Accessibility(MSAA)获取IHTMLDocument2*接口,见下程序:
/*函数名:GetDocInterfaceByMSAA 参数:hwnd,WebBrowser控件的窗口句柄 功能:取得hwnd对应的Webbrowser控件的IHTMLDocument2*接口. */ IHTMLDocument2* GetDocInterfaceByMSAA(HWND hwnd) { HRESULT hr; HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") ); IHTMLDocument2* pDoc2=NULL; if ( hInst != NULL ){ if ( hwnd != NULL ){ //取得AccessibleObjectFromWindow函数 LPFNACCESSIBLEOBJECTFROMWINDOW pfAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)::GetProcAddress(hInst,_T("AccessibleObjectFromWindow")); if(pfAccessibleObjectFromWindow != NULL){ CComPtr spAccess; hr=pfAccessibleObjectFromWindow(hwnd,0, IID_IAccessible,(void**) &spAccess);//取得Webbrowser控件的IAccessible接口 if ( SUCCEEDED(hr) ){ CComPtr spServiceProv; hr=spAccess->QueryInterface(IID_IServiceProvider,(void**)&spServiceProv); if(hr==S_OK){ CComPtr spWin; hr=spServiceProv->QueryService(IID_IHTMLWindow2,IID_IHTMLWindow2, (void**)&spWin); /* 注意:并不是每次都能取得IHTMLWindow2接口,如果调用失败,可以尝试取得IHTMLElement接口: CComPtr spElement; hr=spServiceProv->QueryService(IID_IHTMLElement,IID_IHTMLElement,(void**)&spElement); */ if(hr==S_OK) spWin->get_document(&pDoc2); } } } } ::FreeLibrary(hInst); } else{ AfxMessageBox(_T("请您安装Microsoft Active Accessibility")); } return pDoc2; }
本人是在家中上网,经常有一些BBS的密码懒得记了,就用IE的自动密码保存功能,这样一来是方便了,但却有一个麻烦,一旦机子不行了,想要重装操作系统了,这些密码却也取不出了,还得重新申请,好麻烦!因此我就写了一个工具,可以取得网页密码框的密码.
因为网页密码框不是一般的EDIT控件,因此不能取得网页密码框的句柄.要实现这个功能,只好通过WebBrowser控件的有关COM接口了.因此取得这些接口是整个程序的关键.有两种方法可以取得WebBrowser控件的接口,接下来我们会逐一介绍。
示例程序运行效果图
第一种方法:使用脚本语言和IE右键菜单
我们可以使用注册表来控制IE右键菜单.当你装了FlashGet(网际快车)时,你会发现IE右键菜单多了两项:"使用网际快车下载"和"使用网际快车下载全部链接",而这时你打开注册表,在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\下有这两个主键.这两个主键下都有两个值,一个是默认的串值,指定了选择了这个菜单命令要打开的URL,IE在一个隐藏的窗口打开它,并这个隐藏窗口的external.menuArguments值设为当前窗口对象,执行完URL对话网页包含的脚本程序该窗口自动关闭.另一个名称是contexts是DWORD值,指定了在什么情况下需要显示这个菜单项.具体的值见下.
(0x1 << CONTEXT_MENU_DEFAULT) (等于 0x1) //缺省时显示 (0x1 << CONTEXT_MENU_IMAGE) (等于 0x2) //右键点击图像时显示该项 (0x1 << CONTEXT_MENU_CONTROL) (等于 0x4) //右键点击表单元素时显示该项 (0x1 << CONTEXT_MENU_TABLE) (等于 0x8) //右键点击表格时显示该项 (0x1 << CONTEXT_MENU_TEXTSELECT) (等于 0x10) //右键点击高亮选择的文本时显示该项 (0x1 << CONTEXT_MENU_ANCHOR) (等于 0x20) //右键点击链接时显示该项 (0x1 << CONTEXT_MENU_UNKNOWN) (等于 0x40)//右键点击网页中除上以外的地方显示该项
现在我们写一段脚本程序以获取密码框的值. <!--getpassword.htm-> <script language="VBScript"> Sub GetPassword() set srcEvent = external.menuArguments.event Set doc=external.menuArguments.document set ele=doc.elementFromPoint( srcEvent.clientX, srcEvent.clientY ) if ele.type ="password" then if ele.value="" then Alert("密码为空") else Alert("密码为:"+ele.value) end if end if end sub call GetPassword() </script>
然后在注册表HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\下新建一下主键,键名为"取得密码",缺省值设为该htm文件的路径,在该主键下另增一个DWORD值,值为4,表示只在右击表单元素时显示该项.关闭注册表,重新启动IE窗口,点击一下密码框,就会出现该项,点击该项,弹出一个对话框,告诉你的密码.
第二种方法:使用VC来实现
由于VC知识库是一个关于C++以及Visual C++的网站,与脚本语言没什么关系。所以我们要用另一种稍微复杂一点的方法来实现相同的事情,那就是用C++来做。在不同的进程中取得IE的Webbrowser控件的IHTMLDocument2接口,请参阅MSDN上的一篇文章,标题是:HOWTO: Get IHTMLDocument2 from a HWND(根据HWND取得IHTMLDocument2接口)它的实现机理是向Webbrowser控件(窗口类名是"Internet Explorer_Server")发一个WM_HTML_GETOBJECT,然后把返回值传给Microsoft Active Accessibility (MSAA) 函数ObjectFromLresult,这样你会取得一个已经编排(Marshaling)过的COM接口.如下函数所示:
接着应该处理WM_LBUTTONUP消息:
void CXXXXDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_bCapture){
m_bCapture=FALSE;
ReleaseCapture();//释放鼠标
static TCHAR buf[100];
POINT pt;
GetCursorPos(&pt);
HWND hwnd=::WindowFromPoint(pt);
if(hwnd!=NULL){
::GetClassName( hwnd, (LPTSTR)&buf, 100 );
if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 ){
POINT iept=pt;
::ScreenToClient(hwnd,&iept);
GetPassword(GetDocInterface(hwnd),iept);
}
}
}
CDialog::OnLButtonUp(nFlags, point);
}
GetPassword函数是这样实现的,基本可以模仿VBScript的调用,但要复杂一些:
void GetPassword(IHTMLDocument2* pDoc2,POINT pt)
{
if(pDoc2==NULL)return;
CComPtr<IHTMLElement> pElement;
HRESULT hr=pDoc2->elementFromPoint(pt.x,pt.y,&pElement);//取得鼠标所在的元素
if(SUCCEEDED(hr)){
CComPtr<IHTMLInputTextElement> pPwdElement;
hr=pElement->QueryInterface(IID_IHTMLInputTextElement,
(void**)&pPwdElement);//是否有表单输入元素
if(SUCCEEDED(hr)){
CComBSTR type;
hr=pPwdElement->get_type(&type);
if(SUCCEEDED(hr)){
if(type==_T("password")){//是密码框吗?
CComBSTR pwd;
hr=pPwdElement->get_value(&pwd);
if(SUCCEEDED(hr)){
if(pwd.Length()!=0){//有密码则显示
CComBSTR msg=_T("密码是:");
msg+=pwd;
CString str(msg);
AfxMessageBox(str);
}
else{
AfxMessageBox(_T("密码为空!"));
}
}
}
}
}
}
pDoc2->Release();
}
使用这种方法要注意:
1.如果程序在Windows95,98和NT 4.0 Service With Pack 4 or 5下运行必须要把Microsoft Active Accessibility (MSAA)运行时组件(RDK)与程序一起发布(Windows2000及Windows NT 4.0 Service With Pack 6中已经有了,所以不用).
2.这种方法只适用用于Internet Explorer (Programming) versions 4.0, 4.01, 4.01 SP1, 4.01 SP2, 5
3.使用这种方法前要调用CoInitialize(NULL);然后应该相应地调用CoUninitialize();
4.Microsoft Active Accessibility (MSAA)可从 http://www.microsoft.com/enable/msaa/download.htm下载
附:
我们也可以使用Active Accessibility(MSAA)获取IHTMLDocument2*接口,见下程序:
/*函数名:GetDocInterfaceByMSAA 参数:hwnd,WebBrowser控件的窗口句柄 功能:取得hwnd对应的Webbrowser控件的IHTMLDocument2*接口. */ IHTMLDocument2* GetDocInterfaceByMSAA(HWND hwnd) { HRESULT hr; HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") ); IHTMLDocument2* pDoc2=NULL; if ( hInst != NULL ){ if ( hwnd != NULL ){ //取得AccessibleObjectFromWindow函数 LPFNACCESSIBLEOBJECTFROMWINDOW pfAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)::GetProcAddress(hInst,_T("AccessibleObjectFromWindow")); if(pfAccessibleObjectFromWindow != NULL){ CComPtr spAccess; hr=pfAccessibleObjectFromWindow(hwnd,0, IID_IAccessible,(void**) &spAccess);//取得Webbrowser控件的IAccessible接口 if ( SUCCEEDED(hr) ){ CComPtr spServiceProv; hr=spAccess->QueryInterface(IID_IServiceProvider,(void**)&spServiceProv); if(hr==S_OK){ CComPtr spWin; hr=spServiceProv->QueryService(IID_IHTMLWindow2,IID_IHTMLWindow2, (void**)&spWin); /* 注意:并不是每次都能取得IHTMLWindow2接口,如果调用失败,可以尝试取得IHTMLElement接口: CComPtr spElement; hr=spServiceProv->QueryService(IID_IHTMLElement,IID_IHTMLElement,(void**)&spElement); */ if(hr==S_OK) spWin->get_document(&pDoc2); } } } } ::FreeLibrary(hInst); } else{ AfxMessageBox(_T("请您安装Microsoft Active Accessibility")); } return pDoc2; }
本文介绍两种方法来获取网页上的密码框内容:一是利用脚本语言和IE右键菜单;二是使用VC++通过WebBrowser控件的COM接口实现。
2万+

被折叠的 条评论
为什么被折叠?



