程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 如何獲取網頁密碼框中的密碼

如何獲取網頁密碼框中的密碼

編輯:關於VC++

前言

本人是在家中上網,經常有一些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)//右鍵點擊網頁中除上以外的地方顯示該項

現在我們寫一段腳本程序以獲取密碼框的值.

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()

然後在注冊表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 pElement;
	HRESULT hr=pDoc2->elementFromPoint(pt.x,pt.y,&pElement);//取得鼠標所在的元素
	if(SUCCEEDED(hr)){
		CComPtr 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();
}

使用這種方法要注意:

如果程序在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中已經有了,所以不用);

這種方法只適用用於Internet Explorer (Programming) versions 4.0, 4.01, 4.01 SP1, 4.01 SP2, 5;

使用這種方法前要調用CoInitialize(NULL);然後應該相應地調用CoUninitialize();

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,
					//取得Webbrowser控件的IAccessible接口
					IID_IAccessible,(void**) &spAccess);
				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;
}

具體的例程可見本文提供的源代碼(在WINDOWS ME,IE 5.5,VC6.0調試通過)

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved