开源小工具一:获取客户端内嵌IE控件(Internet Explorer_Server)的URL
2015-11-26 20:31
232 查看
前言:
做客户端开发的很多时候,我们需要查看别人的客户端里面嵌入的网页,查看里面的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_WND WM_USER+100 #define WM_HOTKEY_BASE 100 inline 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 screen CenterWindow(); // set icons HICON 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++的调用在这里不做介绍,前面的文章说过了:/article/7721133.html
360的IE空间捕获不到,应该是那个老流氓做了处理。
相关文章推荐
- <13> go collection-func
- PHP中正则表达式的用法
- 修改redhat/centos 的网络配置为静态IP
- Androidのspinner控件使用
- 链表保存学生信息
- [ectouch 调试必备] 显示出错误信息
- 如何在网页中打开一个本地桌面程序
- python对ini配置文件处理
- Leveldb源码分析--10
- C++指针与引用(一):函数传参,是该传对象,还是传指针,抑或是引用
- [CodeChef FEB15]Payton numbers(CUSTPRIM)解题报告
- <12> go panic
- 一些API平台
- 时间计算
- Leveldb源码分析--9
- Android之NDK开发 环境配置
- Java 中的 static 使用之静态变量,静态方法和静态初始化块
- Cassandra总结1
- hiho刷题日记——第二十二天更为复杂的买卖房屋姿势
- C++设计模式[十九]状态模式