获取password框的文本; ch:=SendMessage(h1,EM_GETPASSWORDCHAR,0,0); 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 ----Windows虽然是一个功能强大的操作系统,但其存在的一些先天性不足,给黑客留下了许多可乘之机,著名的BO程序就是利用Windows的这些漏洞来危害计算机的安全。笔者最近发现了一个很流行的专门获取Edit框Password的工具,甚至其源代码已在某报纸发表,这无疑是对Edit的Password功能的完全否定。本文将首先分析非法获取Password的原理,然后给出用VisualC++来实现保护Edit框中的Password不被非法获取的对策。----(一)非法获取Password的原理----Edit是Windows的一个标准控件,当把其Password属性设为True时,就会将输入的内容屏蔽为星号(*),从而达到保护的目的。而Edit框中的内容可通过发WM_GETTEXT,EM_GETLINE消息来获取。黑客程序就是利用Edit的这个特性,首先枚举当前程序的所有子窗口,当发现枚举的窗口是EDIT并且具有ES_PASSWORD属性时,则通过SendMessage向此窗口发送WM_GETTEXT或EM_GETLINE消息,这样Edit框中的内容就一目了然了。----(二)对Password进行保护----由上述分析可看出,Edit的漏洞在于没有检查发送WM_GETTEXT或EM_GETLINE消息者的身份,只要找到Edit窗口句柄,任何进程都可获取其内容。这里给出一种简单的方法来验证发送消息者的身份是否合法。----1)创建新CEdit类----从CEdit继承一个子类CPasswordEdit,申明全局变量g_bAuthorIdentity表明消息发送者的身份:BOOLg_bAuthorIdentity;----然后响应CWnd的虚函数DefWindowProc,在这个回调函数中进行身份验证:LRESULTCPasswordEdit::DefWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam){//对Edit的内容获取必须通过以下两个消息之一if((message==WM_GETTEXT)||(message==EM_GETLINE)){//检查是否为合法if(!g_bAuthorIdentity){//非法获取,显示信息AfxMessageBox(_T("我的密码,可不能让你看哦!"));//return0;}//合法获取g_bAuthorIdentity=FALSE;}returnCEdit::DefWindowProc(message,wParam,lParam);}----2)在数据输入对话框中做处理----在对话框中申明一个类成员m_edtPassword:CPasswordEditm_edtPassword;----然后在对话框的OnInitDialog()中加入下列代码:m_edtPassword.SubclassDlgItem(IDC_EDIT_PASSWORD,this);----其目的是将控制与新类做关联。----之后在对话框的数据交换中将身份设为合法:voidCDlgInput::DoDataExchange(CDataExchange*pDX){//如果获取数据//注意:对于CPropertyPage类这里不需要if(pDX->m_bSaveAndValidate)条件if(pDX->m_bSaveAndValidate){g_bAuthorIdentity=TRUE;}CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CDlgInput)DDX_Text(pDX,IDC_EDIT_PASSWORD,m_sPassword);//}}AFX_DATA_MAP}----这样,Password输入框就会受到保护。----(三)需要注意的问题----以上的方法仅针对VC程序,对于VB程序,需要借助VC做一个Password的ActiveX控件,实现方法与上类似。同时以上程序在VisualC++6.0上通过,并且用黑客程序PWBTool测试通过。 如何获取网页密码框中的密码作者:Sjx前言本人是在家中上网,经常有一些BBS的密码懒得记了,就用IE的自动密码保存功能,这样一来是方便了,但却有一个麻烦,一旦机子不行了,想要重装操作系统了,这些密码却也取不出了,还得重新申请,好麻烦!因此我就写了一个工具,可以取得网页密码框的密码.因为网页密码框不是一般的EDIT控件,因此不能取得网页密码框的句柄.要实现这个功能,只好通过WebBrowser控件的有关COM接口了.因此取得这些接口是整个程序的关键.有两种方法可以取得WebBrowser控件的接口,接下来我们会逐一介绍,并提供示例源代码供大家参考。下载源代码 大小:24K 示例程序运行效果图第一种方法:使用脚本语言和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 ifend subcall 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接口)(http://support.microsoft.com/default.aspx?scid=kb;EN-US;q249232).它的实现机理是向Webbrowser控件(窗口类名是"Internet Explorer_Server")发一个WM_HTML_GETOBJECT,然后把返回值传给Microsoft Active Accessibility (MSAA) 函数ObjectFromLresult,这样你会取得一个已经编排(Marshaling)过的COM接口.如下函数所示:IHTMLDocument2* GetDocInterface(HWND hWnd) { // 我们需要显示地装载OLEACC.DLL,这样我们才知道有没有安装MSAA HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") ); IHTMLDocument2* pDoc2=NULL; if ( hInst != NULL ){ if ( hWnd != NULL ){ CComPtr spDoc=NULL; LRESULT lRes; /*由于WM_HTML_GETOBJECT非Windows标准消息,所以需要RegisterWindowMessage*/ UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") ); ::SendMessageTimeout( hWnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes ); /*取得ObjectFromLresult函数的地址*/ LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") ); if ( pfObjectFromLresult != NULL ){ HRESULT hr; hr=pfObjectFromLresult(lRes,IID_IHTMLDocument,0,(void**)&spDoc); if ( SUCCEEDED(hr) ){ CComPtr spDisp; CComQIPtr spWin; spDoc->get_Script( &spDisp ); spWin = spDisp; spWin->get_document( &pDoc2 ); } } } ::FreeLibrary(hInst); } else{//如果没有安装MSAA AfxMessageBox(_T("请您安装Microsoft Active Accessibility")); } return pDoc2;} 这样,我们就取得了IHTMLDocument2*接口了,要取得密码框的密码还得一番周折,首先得构造一个基于对话框的MFC程序,增加一个按钮,在主对话框类增加一个成员变量m_bCapture,在构造函数中初始化为FALSE.然后处理该按钮的Click事件: void CXXXXDlg::OnGetHtmlClick(){ SetCapture();//跟踪鼠标 m_bCapture=TRUE;}接着应该处理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, 53.使用这种方法前要调用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;} procedure TForm1.Button1Click(Sender: TObject);varh1:HWND;beginh1:=Edit1.Handle;SendMessage(h1,EM_SETPASSWORDCHAR,0,0);SendMessage(h1,EM_SETSEL,0,-1);SendMessage(h1,WM_COPY,0,0);Edit2.PasteFromClipboard;end; WM_GETTEXT和WM_GETLINE消息怎么实现获取,能写的详细点吗?谢谢 另外,你可以在SendMessage(h1,EM_SETPASSWORDCHAR,0,0);之前用x:=SendMessage(h1,EM_GETPASSWORDCHAR,0,0);然后再在SendMessage(h1,WM_COPY,0,0);之后用SendMessage(h1,EM_SETPASSWORDCHAR,x,0);进行恢复 unsigned谢谢你,我明白了,给你分 关于字体变大问题 如何获取未使用键盘、鼠标的时间? 又一个排序问题:如何能排序后仍能修改记录内容,或者能改变数据库表中记录的实际位置呢? InsertObject(Index, S, nil)用法? udp问题,在线等待 我是FOXNT, 请小班主们注意一下. idftp的返回消息怎么屏蔽掉?在线等待,给分 一个大家都可以拿分的问题 **************让PC喇叭发音是用MessageBeep(0);吗?怎么不响啊?*************** 如何把已有的几个网址替换到IE的地址栏中 關于DBGRID列的問題 CoolSlob、softwing(无人喝彩) 谢谢你们! 再次发分
许多可乘之机,著名的BO程序就是利用Windows的这些漏洞来危害计算机的安全。笔者
最近发现了一个很流行的专门获取Edit框Password的工具,甚至其源代码已在某报纸发表,
这无疑是对Edit的Password功能的完全否定。本文将首先分析非法获取Password的原理,
然后给出用VisualC++来实现保护Edit框中的Password不被非法获取的对策。----(一)非法获取Password的原理----Edit是Windows的一个标准控件,当把其Password属性设为True时,就会将输入的内容
屏蔽为星号(*),从而达到保护的目的。
而Edit框中的内容可通过发WM_GETTEXT,EM_GETLINE消息来获取。黑客程序就是利
用Edit的这个特性,首先枚举当前程序的所有子窗口,当发现枚举的窗口是EDIT并且具
有ES_PASSWORD属性时,则通过SendMessage向此窗口发送WM_GETTEXT或
EM_GETLINE消息,这样Edit框中的内容就一目了然了。----(二)对Password进行保护----由上述分析可看出,Edit的漏洞在于没有检查发送WM_GETTEXT或EM_GETLINE消
息者的身份,只要找到Edit窗口句柄,任何进程都可获取其内容。这里给出一种简单的方
法来验证发送消息者的身份是否合法。----1)创建新CEdit类----从CEdit继承一个子类CPasswordEdit,申明全局变量g_bAuthorIdentity表明消息发送者的身份:BOOLg_bAuthorIdentity;
----然后响应CWnd的虚函数DefWindowProc,在这个回调函数中进行身份验证:LRESULTCPasswordEdit::DefWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)
{//对Edit的内容获取必须通过以下两个消息之一
if((message==WM_GETTEXT)||
(message==EM_GETLINE))
{//检查是否为合法
if(!g_bAuthorIdentity)
{//非法获取,显示信息
AfxMessageBox(_T("我的密码,可不能让你看哦!"));
//
return0;
}
//合法获取
g_bAuthorIdentity=FALSE;
}
returnCEdit::DefWindowProc(message,wParam,lParam);
}----2)在数据输入对话框中做处理----在对话框中申明一个类成员m_edtPassword:
CPasswordEditm_edtPassword;
----然后在对话框的OnInitDialog()中加入下列代码:
m_edtPassword.SubclassDlgItem(IDC_EDIT_PASSWORD,this);
----其目的是将控制与新类做关联。
----之后在对话框的数据交换中将身份设为合法:
voidCDlgInput::DoDataExchange(CDataExchange*pDX)
{//如果获取数据
//注意:对于CPropertyPage类这里不需要
if(pDX->m_bSaveAndValidate)条件
if(pDX->m_bSaveAndValidate)
{
g_bAuthorIdentity=TRUE;
}
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgInput)
DDX_Text(pDX,IDC_EDIT_PASSWORD,m_sPassword);
//}}AFX_DATA_MAP
}----这样,Password输入框就会受到保护。
----(三)需要注意的问题
----以上的方法仅针对VC程序,对于VB程序,需要借助VC做一个Password的ActiveX
控件,实现方法与上类似。同时以上程序在VisualC++6.0上通过,并且用黑客程序PWBTool
测试通过。
作者:Sjx
前言本人是在家中上网,经常有一些BBS的密码懒得记了,就用IE的自动密码保存功能,这样一来是方便了,但却有一个麻烦,一旦机子不行了,想要重装操作系统了,这些密码却也取不出了,还得重新申请,好麻烦!因此我就写了一个工具,可以取得网页密码框的密码.
因为网页密码框不是一般的EDIT控件,因此不能取得网页密码框的句柄.要实现这个功能,只好通过WebBrowser控件的有关COM接口了.因此取得这些接口是整个程序的关键.有两种方法可以取得WebBrowser控件的接口,接下来我们会逐一介绍,并提供示例源代码供大家参考。下载源代码 大小:24K 示例程序运行效果图第一种方法:使用脚本语言和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 subcall 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接口)(http://support.microsoft.com/default.aspx?scid=kb;EN-US;q249232).它的实现机理是向Webbrowser控件(窗口类名是"Internet Explorer_Server")发一个WM_HTML_GETOBJECT,然后把返回值传给Microsoft Active Accessibility (MSAA) 函数ObjectFromLresult,这样你会取得一个已经编排(Marshaling)过的COM接口.如下函数所示:IHTMLDocument2* GetDocInterface(HWND hWnd)
{
// 我们需要显示地装载OLEACC.DLL,这样我们才知道有没有安装MSAA
HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
IHTMLDocument2* pDoc2=NULL;
if ( hInst != NULL ){
if ( hWnd != NULL ){
CComPtr spDoc=NULL;
LRESULT lRes;
/*由于WM_HTML_GETOBJECT非Windows标准消息,所以需要RegisterWindowMessage*/
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
::SendMessageTimeout( hWnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes ); /*取得ObjectFromLresult函数的地址*/
LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") );
if ( pfObjectFromLresult != NULL ){
HRESULT hr;
hr=pfObjectFromLresult(lRes,IID_IHTMLDocument,0,(void**)&spDoc);
if ( SUCCEEDED(hr) ){
CComPtr spDisp;
CComQIPtr spWin;
spDoc->get_Script( &spDisp );
spWin = spDisp;
spWin->get_document( &pDoc2 );
}
}
}
::FreeLibrary(hInst);
}
else{//如果没有安装MSAA
AfxMessageBox(_T("请您安装Microsoft Active Accessibility"));
}
return pDoc2;
}
这样,我们就取得了IHTMLDocument2*接口了,要取得密码框的密码还得一番周折,首先得构造一个基于对话框的MFC程序,增加一个按钮,在主对话框类增加一个成员变量m_bCapture,在构造函数中初始化为FALSE.
然后处理该按钮的Click事件: void CXXXXDlg::OnGetHtmlClick()
{
SetCapture();//跟踪鼠标
m_bCapture=TRUE;
}
接着应该处理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;
}
var
h1:HWND;
begin
h1:=Edit1.Handle;
SendMessage(h1,EM_SETPASSWORDCHAR,0,0);
SendMessage(h1,EM_SETSEL,0,-1);
SendMessage(h1,WM_COPY,0,0);
Edit2.PasteFromClipboard;
end;
SendMessage(h1,EM_SETPASSWORDCHAR,0,0);
之前用
x:=SendMessage(h1,EM_GETPASSWORDCHAR,0,0);
然后再在
SendMessage(h1,WM_COPY,0,0);
之后用
SendMessage(h1,EM_SETPASSWORDCHAR,x,0);
进行恢复