开源小工具一:获取客户端内嵌IE控件(Internet Explorer_Server)的URL

来源:互联网 发布:墨守成规淘宝店铺 编辑:程序博客网 时间:2024/05/18 02:37

前言:

做客户端开发的很多时候,我们需要查看别人的客户端里面嵌入的网页,查看里面的JS等等,于是就写了一个简单的工具来获取这些嵌入IE的客户端使用的地址。

原理:

开启一个后台线程,不断获取当前鼠标所在位置的窗口句柄,通过这个句柄判断窗口class是不是IE的Internet Explorer_Server,然后通过COM接口来获取IE对象,通过接口获取其内部链接的URL地址。为了提高效率,使用快捷键来捕获和停止捕获。使用时,Alt+B开启捕获,移动鼠标到IE网页上面后就会获得地址了,然后Alt+S停止捕获,就可以去复制链接的URL了。

<span style="font-family: Arial, Helvetica, sans-serif;">// MainDlg.h : interface of the CMainDlg class</span>
///////////////////////////////////////////////////////////////////////////////#pragma once#include <string>using std::wstring;#define WM_GETNEW_WNDWM_USER+100#define WM_HOTKEY_BASE100inline bool operator != (const RECT& rc1, const RECT& rc2){return ((rc1.left!=rc2.left)|| (rc1.top!=rc2.top)|| (rc1.right!=rc2.right)|| (rc1.bottom!=rc2.bottom));}class CMainDlg : public CDialogImpl<CMainDlg>{public:static bool s_bThreadSwitch;static bool s_bRunning;static HBRUSH s_hFrameBrush;HWND m_hEditWnd;enum { IDD = IDD_MAINDLG };CMainDlg():m_hEditWnd(NULL){}BEGIN_MSG_MAP(CMainDlg)MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)MESSAGE_HANDLER(WM_GETNEW_WND, OnGetNewWindow)MESSAGE_HANDLER(WM_DESTROY, OnDestroy)MESSAGE_HANDLER(WM_HOTKEY, OnHotKey)COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)COMMAND_ID_HANDLER(IDOK, OnOK)COMMAND_ID_HANDLER(IDCANCEL, OnCancel)END_MSG_MAP()// Handler prototypes (uncomment arguments if needed)://LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)//LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)//LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){// center the dialog on the screenCenterWindow();// set iconsHICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));SetIcon(hIcon, TRUE);HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));SetIcon(hIconSmall, FALSE);m_hEditWnd=::GetDlgItem(m_hWnd, IDC_EDIT1);::SetDlgItemText(m_hWnd, IDC_STATUS_BAR, L"窗口捕获未开启,Alt+B立即开启");::RegisterHotKey(m_hWnd, WM_HOTKEY_BASE+0, MOD_ALT, 0x42);::RegisterHotKey(m_hWnd, WM_HOTKEY_BASE+1, MOD_ALT, 0x53);s_hFrameBrush=::CreateSolidBrush(0xff0000);::SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(GWL_EXSTYLE)|WS_EX_TOPMOST);return TRUE;}LRESULT OnGetNewWindow(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled){if ( NULL==m_hEditWnd )return 0;HWND hWnd=(HWND)wParam;if ( hWnd==m_hEditWnd ){::SetWindowText(m_hEditWnd, L"");return 0;}WCHAR szText[MAX_PATH+1]={0};LRESULT lSize=::SendMessage(hWnd, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szText);if ( lSize==0 )wcscpy(szText, L"窗口标题为空");WCHAR szClassName[100]={0};::GetClassName(hWnd, szClassName, 100);CComBSTR url;if ( wcsncmp(szClassName, L"Internet Explorer_Server", 24) == 0 ){//此窗口为内嵌IE控件UINT uMsg=::RegisterWindowMessage(L"WM_HTML_GETOBJECT");DWORD_PTR dwRetPtr;LRESULT lRet=::SendMessageTimeout(hWnd, uMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, &dwRetPtr);CComQIPtr<IHTMLDocument> docPtr;HRESULT hr=::ObjectFromLresult((LRESULT)dwRetPtr, IID_IHTMLDocument, 0, (void**)&docPtr);if ( SUCCEEDED(hr) && docPtr ){CComQIPtr<IDispatch> scriptPtr;hr=docPtr->get_Script(&scriptPtr);if ( SUCCEEDED(hr) && scriptPtr ){CComQIPtr<IHTMLWindow2> htmlwndPtr=scriptPtr;IHTMLDocument2* pDoc2;hr=htmlwndPtr->get_document(&pDoc2);if ( SUCCEEDED(hr) && pDoc2 ){pDoc2->get_URL(&url);pDoc2->Release();}}}}wstring strText(szText);strText.append(L"\r\n");strText.append(szClassName);if ( url.Length()>0 ){strText.append(L"\r\n");strText.append(url);}::SendMessage(m_hEditWnd, WM_SETTEXT, 0, (LPARAM)strText.c_str());bHandled=TRUE;return 0;}LRESULT OnDestroy(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled){if ( s_hFrameBrush ){::DeleteObject(s_hFrameBrush);s_hFrameBrush=NULL;}::UnregisterHotKey(m_hWnd, WM_HOTKEY_BASE+0);::UnregisterHotKey(m_hWnd, WM_HOTKEY_BASE+1);s_bThreadSwitch=false;while( s_bRunning )::Sleep(100);return 0;}LRESULT OnHotKey(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled){switch( wParam ){case WM_HOTKEY_BASE+0: BeginTrackWnd();break;case WM_HOTKEY_BASE+1:StopTrackWnd();break;default:break;}return 0;}LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/){CSimpleDialog<IDD_ABOUTBOX, FALSE> dlg;dlg.DoModal();return 0;}LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/){// TODO: Add validation code EndDialog(wID);return 0;}LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/){EndDialog(wID);return 0;}void BeginTrackWnd(){if ( !s_bRunning ){s_bThreadSwitch=true;HANDLE hThread=::CreateThread(NULL, 0, MouseThread, m_hWnd, 0, NULL);::CloseHandle(hThread);::SetDlgItemText(m_hWnd, IDC_STATUS_BAR, L"窗口捕获已经开启,获得IE链接后,Alt+S结束捕获");}}void StopTrackWnd(){if ( s_bRunning ){s_bThreadSwitch=false;::SetDlgItemText(m_hWnd, IDC_STATUS_BAR, L"窗口捕获未开启,Alt+B立即开启");}}static DWORD __stdcall MouseThread(LPVOID lpParam){s_bRunning=true;POINT ptCur={0,0};HWND hMsgWnd=(HWND)lpParam;HWND hPreWnd=NULL;RECT rcWnd={0,0,0,0}, rcPrev={-1,-1,-1.-1};HWND hDeskWnd=::GetDesktopWindow();while( s_bThreadSwitch ){::GetCursorPos(&ptCur);HWND hWnd=::WindowFromPoint(ptCur);if ( NULL!=hWnd && hPreWnd!=hWnd ){::PostMessage(hMsgWnd, WM_GETNEW_WND, (WPARAM)hWnd, 0);hPreWnd=hWnd;if ( rcPrev!=rcWnd ){::InflateRect(&rcPrev, 10, 10);::InvalidateRect(hDeskWnd, NULL, TRUE);HDC hDC=::GetDC(hDeskWnd);RECT rcWnd;::GetWindowRect(hWnd, &rcWnd);::FrameRect(hDC, &rcWnd, s_hFrameBrush);::ReleaseDC(hDeskWnd, hDC);rcPrev=rcWnd;}}Sleep(100);}s_bRunning=false;return 0;}};bool CMainDlg::s_bThreadSwitch=true;bool CMainDlg::s_bRunning=false;HBRUSH CMainDlg::s_hFrameBrush=NULL;

当时写这份代码的时候用的是WTL,所以一长段代码都在一个头文件里面。注意的是,COM初始化一定要在使用COM组件前:::CoInitialize(NULL);main函数退出前:::CoUninitialize();

实际使用:

获取腾讯电脑管家软件管理里面嵌入的IE控件地址:


腾讯使用的居然是本地静态 页面,file://C:\ProgramData\Application Data\Tencent\QQPCMgr\SoftMgr\index-v3.html?version=11.0.16779.224&guid=642DC05B88DE6E170F23A791DC7623FC&from=0&featurever=3。我们还可以用浏览器打开,查看里面JS的调用,JS与客户端C++的调用在这里不做介绍,前面的文章说过了:http://blog.csdn.net/mfcing/article/details/44540683

360的IE空间捕获不到,应该是那个老流氓做了处理。

0 0