被涮屏涮烦了,就分享一下如何用低调的c/c++来涮别人家的屏吧! 此处埋下三颗雷! 这不是啥新知识,也不是什么浅显的代码。下面,来淘淘这份经验,呼呼
我们要了解Web browser 这个控件,因为到目前为止,很少有浏览器能够被调用内核API,而Web browser 提供了IE的内核内容,就是我们可以用Ie提供的内核来自己设计一个简单的浏览器 当然,我们这儿并不是扯这个蛋。 但是为了后面说起来比较合理些 ,就只能翻山越岭的开始介绍了!
首先创建一个dlg,然后点击Acx control ,如果看见了mscro(简称) Web browser ,就双击两下,如果没看见,那就再去看看,很定是可以看得见的! 这些搞定之后,你就会看到下面这个黑乎乎的东西:
因为,前面说了这个界面不是分享到重点,所以就轻微的飘过。之后将这个dlg写成下面这般模样!!!
WebMFCDlg.h : 头文件
1 // WebMFCDlg.h : 头文件 2 // 3 4 #pragma once 5 #include "explorer1.h" 6 7 8 // CWebMFCDlg 对话框 9 class CWebMFCDlg : public CDialogEx 10 { 11 // 构造 12 DECLARE_DYNAMIC(CWebMFCDlg) 13 public: 14 CWebMFCDlg(CWnd* pParent = NULL); // 标准构造函数 15 16 // 对话框数据 17 enum { IDD = IDD_WEBMFC_DIALOG }; 18 19 protected: 20 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 21 22 23 // 实现 24 protected: 25 HICON m_hIcon; 26 27 // 生成的消息映射函数 28 virtual BOOL OnInitDialog(); 29 afx_msg void OnSysCommand(UINT nID, LPARAM lParam); 30 afx_msg void OnPaint(); 31 afx_msg HCURSOR OnQueryDragIcon(); 32 DECLARE_MESSAGE_MAP() 33 public: 34 CExplorer1 m_explo; 35 afx_msg void OnBnClickedOk(); 36 DECLARE_EVENTSINK_MAP() 37 void OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl); 38 39 };
WebMFCDlg.cpp: 头文件
1 // WebMFCDlg.cpp : 实现文件 2 // 3 4 #include "stdafx.h" 5 #include "WebMFC.h" 6 #include "WebMFCDlg.h" 7 #include "afxdialogex.h" 8 #include <MsHTML.h> 9 #ifdef _DEBUG 10 #define new DEBUG_NEW 11 #endif 12 13 14 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 15 16 17 class CAboutDlg : public CDialogEx 18 { 19 public: 20 CAboutDlg(); 21 22 // 对话框数据 23 enum { IDD = IDD_ABOUTBOX }; 24 25 protected: 26 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 27 28 // 实现 29 protected: 30 DECLARE_MESSAGE_MAP() 31 }; 32 33 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) 34 { 35 } 36 37 void CAboutDlg::DoDataExchange(CDataExchange* pDX) 38 { 39 CDialogEx::DoDataExchange(pDX); 40 } 41 42 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) 43 END_MESSAGE_MAP() 44 45 46 // CWebMFCDlg 对话框 47 48 IMPLEMENT_DYNAMIC(CWebMFCDlg, CDialogEx) 49 50 CWebMFCDlg::CWebMFCDlg(CWnd* pParent /*=NULL*/) 51 : CDialogEx(CWebMFCDlg::IDD, pParent) 52 { 53 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 54 } 55 56 void CWebMFCDlg::DoDataExchange(CDataExchange* pDX) 57 { 58 CDialogEx::DoDataExchange(pDX); 59 DDX_Control(pDX, IDC_EXPLORER1, m_explo); 60 } 61 62 BEGIN_MESSAGE_MAP(CWebMFCDlg, CDialogEx) 63 ON_WM_SYSCOMMAND() 64 ON_WM_PAINT() 65 ON_WM_QUERYDRAGICON() 66 ON_BN_CLICKED(IDOK, &CWebMFCDlg::OnBnClickedOk) 67 END_MESSAGE_MAP() 68 69 70 // CWebMFCDlg 消息处理程序 71 72 BOOL CWebMFCDlg::OnInitDialog() 73 { 74 CDialogEx::OnInitDialog(); 75 76 // 将“关于...”菜单项添加到系统菜单中。 77 78 // IDM_ABOUTBOX 必须在系统命令范围内。 79 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 80 ASSERT(IDM_ABOUTBOX < 0xF000); 81 82 CMenu* pSysMenu = GetSystemMenu(FALSE); 83 if (pSysMenu != NULL) 84 { 85 BOOL bNameValid; 86 CString strAboutMenu; 87 bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); 88 ASSERT(bNameValid); 89 if (!strAboutMenu.IsEmpty()) 90 { 91 pSysMenu->AppendMenu(MF_SEPARATOR); 92 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 93 } 94 } 95 96 // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 97 // 执行此操作 98 SetIcon(m_hIcon, TRUE); // 设置大图标 99 SetIcon(m_hIcon, FALSE); // 设置小图标 100 101 // TODO: 在此添加额外的初始化代码 102 //com组件的变量 103 104 CComVariant vtUrl("http://hust.myubbs.com/forum.php?mod=forumdisplay&fid=11"); 105 CComVariant vtEmpty; //NULL 106 m_explo.Navigate2(&vtUrl, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);//打开指定的网页 107 m_explo.put_Silent(VARIANT_TRUE); //禁止脚本错误提示 108 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE 109 } 110 111 void CWebMFCDlg::OnSysCommand(UINT nID, LPARAM lParam) 112 { 113 if ((nID & 0xFFF0) == IDM_ABOUTBOX) 114 { 115 CAboutDlg dlgAbout; 116 dlgAbout.DoModal(); 117 } 118 else 119 { 120 CDialogEx::OnSysCommand(nID, lParam); 121 } 122 } 123 124 // 如果向对话框添加最小化按钮,则需要下面的代码 125 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, 126 // 这将由框架自动完成。 127 128 void CWebMFCDlg::OnPaint() 129 { 130 if (IsIconic()) 131 { 132 CPaintDC dc(this); // 用于绘制的设备上下文 133 134 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); 135 136 // 使图标在工作区矩形中居中 137 int cxIcon = GetSystemMetrics(SM_CXICON); 138 int cyIcon = GetSystemMetrics(SM_CYICON); 139 CRect rect; 140 GetClientRect(&rect); 141 int x = (rect.Width() - cxIcon + 1) / 2; 142 int y = (rect.Height() - cyIcon + 1) / 2; 143 144 // 绘制图标 145 dc.DrawIcon(x, y, m_hIcon); 146 } 147 else 148 { 149 CDialogEx::OnPaint(); 150 } 151 } 152 153 //当用户拖动最小化窗口时系统调用此函数取得光标 154 //显示。 155 HCURSOR CWebMFCDlg::OnQueryDragIcon() 156 { 157 return static_cast<HCURSOR>(m_hIcon); 158 } 159 160 BEGIN_EVENTSINK_MAP(CWebMFCDlg, CDialogEx) 161 ON_EVENT(CWebMFCDlg, IDC_EXPLORER1, 273, CWebMFCDlg::OnNewwindow3Explorer1, VTS_PDISPATCH VTS_PBOOL VTS_UI4 VTS_BSTR VTS_BSTR) 162 END_EVENTSINK_MAP() 163 164 //放置调用IE 165 void CWebMFCDlg::OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl) 166 { 167 // TODO: Add your message handler code here 168 // TODO: 在此处添加消息处理程序代码 169 170 // 只在一个对话框中操作网页 171 *Cancel = TRUE; 172 CComVariant strUrl; 173 strUrl = bstrUrl; 174 CComVariant vInfo; 175 this->m_explo.Navigate2(&strUrl, &vInfo, &vInfo, &vInfo, &vInfo); 176 this->ShowWindow(SW_SHOW); 177 } 178 void CWebMFCDlg::OnBnClickedOk() 179 { 180 //开始不断的注入数据,哇哈哈哈,好开心! 181 while (1){ 182 183 CComPtr < IDispatch > spDispDoc; //从com组件中分离 184 spDispDoc = m_explo.get_Document(); //得到文档 185 CComQIPtr< IHTMLDocument2 > spDocument2 = spDispDoc; //将其转化为document页面 186 CComQIPtr< IHTMLElementCollection > spElementCollection; //声明一个页面容器 187 if (SUCCEEDED(spDocument2->get_all(&spElementCollection))) //如果得到页面容器成功 188 { 189 CComPtr<IDispatch> spDisp1, spDisp2, spDisp; //com中封住的抽象的对象 190 HRESULT hr1, hr2,hr; 191 //取一个标题 192 hr1 = spElementCollection->item(CComVariant("subject"), CComVariant("0"), &spDisp1); //将热键获取赋予对象 193 // 194 hr2 = spElementCollection->item(CComVariant("message"), CComVariant("0"), &spDisp2); 195 196 hr = spElementCollection->item(CComVariant("topicsubmit"), CComVariant("0"), &spDisp); 197 if (SUCCEEDED(hr1) && SUCCEEDED(hr2)){ 198 CComQIPtr<IHTMLInputElement> spElem1 = spDisp1; //装换为元素 199 CComQIPtr<IHTMLInputElement> spElem2 = spDisp2; 200 spElem1->put_value(CComBSTR("it‘s a test!")); //注入内容 201 202 spElem2->put_value(CComBSTR("这是一份来自电脑的重复输入,测试!it‘s a test !")); 203 if (SUCCEEDED(hr)){ 204 CComQIPtr<IHTMLFormElement> spForm = spDisp; 205 spForm->submit(); 206 } 207 } 208 } 209 m_explo.GoBack(); 210 } 211 // TODO: 在此添加控件通知处理程序代码 212 //CDialogEx::OnOK(); 213 }
下面说说如何去涮别人家的屏, 对于要刷别银家的屏,首先你得有个不错的浏览器。怎么才能说不错的浏览器呢? 第一滴: 你得始终不依靠别人家的浏览器。也就是说,无论点击啥网页,你都只能子在自己的浏览器里去跳转,A网站调到B页面,为啥? 因为我们不能让cookie莫名的中断了! 就如你登录再本地浏览器,出去跑了一圈回来,信息难免会损失。 第二点:不要出现脚本错误,你不能访问一个页面,然后就抬出N多这样的脚本错误!
一般的话都需要加上这句话在你的OnInitDialog()中;
1 m_explo.put_Silent(VARIANT_TRUE); //禁止脚本错误提示
然后要想一直留在自己的浏览器中: 首先得加上一个事件响应函数
在对话框.cpp中,需要实现
1 // CWebMFCDlg 对话框 2 3 IMPLEMENT_DYNAMIC(CWebMFCDlg, CDialogEx) //需要补充这句 4 5 CWebMFCDlg::CWebMFCDlg(CWnd* pParent /*=NULL*/) 6 : CDialogEx(CWebMFCDlg::IDD, pParent) 7 { 8 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 9 }
并且:
还需要不上这些
1 BEGIN_EVENTSINK_MAP(CWebMFCDlg, CDialogEx) 2 ON_EVENT(CWebMFCDlg, IDC_EXPLORER1, 273, CWebMFCDlg::OnNewwindow3Explorer1, VTS_PDISPATCH VTS_PBOOL VTS_UI4 VTS_BSTR VTS_BSTR) 3 END_EVENTSINK_MAP() 4 5 //放置调用IE 6 void CWebMFCDlg::OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl) 7 { 8 // TODO: Add your message handler code here 9 // TODO: 在此处添加消息处理程序代码 10 11 // 只在一个对话框中操作网页 12 *Cancel = TRUE; 13 CComVariant strUrl; 14 strUrl = bstrUrl; 15 CComVariant vInfo; 16 this->m_explo.Navigate2(&strUrl, &vInfo, &vInfo, &vInfo, &vInfo); 17 this->ShowWindow(SW_SHOW); 18 }
在对话框.h中:
1 // CWebMFCDlg 对话框 2 class CWebMFCDlg : public CDialogEx 3 { 4 // 构造 5 DECLARE_DYNAMIC(CWebMFCDlg) //需要添加上这句 6 public: 7 CWebMFCDlg(CWnd* pParent = NULL); // 标准构造函数
并且:
1 public: 2 CExplorer1 m_explo; 3 afx_msg void OnBnClickedOk(); 4 DECLARE_EVENTSINK_MAP() //补充这句 5 void OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl); //和这句
实现了这些,然后只需要在对话框初始化函数中 添加如下:
1 CComVariant vtUrl("http://tieba.baidu.com/f?kw=%BA%FE%B1%B1%B9%A4%D2%B5%B4%F3%D1%A7&fr=ala0&tpl=5"); 2 CComVariant vtEmpty; //NULL 3 m_explo.Navigate2(&vtUrl, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);//打开指定的网页
然后运行就可以去看到这个了:
当然扯了这么多,并没什么鸟用。不过铺垫讲完了,到重点了? 如何才能将我们事先写好的数据,输入到html页面去呢? 而且还是用c++
恩! 这个问题,首先分析,用主流的五大浏览器,是很定搞不定的! 因为我们并不能去调用tm的API,所以我们只能想前面鲁的一大串一样! 去自己写一个浏览器
然后来实现这些调用IE公用的内核API!!!!
那么如何调用呢? 我们再来看看这图片:
这是浏览器原理里面的一部分内容! 偷偷的盗了一张好图,这里道声谢!
我们要将Ccomvarite 转化为document,然后在转化出HTMLHtmlElement元素即可!!!
首先我们需要引入: 头文件 #include<MsHTML.h>
1 CComPtr < IDispatch > sDDc; //从com组件中分离 2 sDDc = m_explo.get_Document(); //得到文档 3 CComQIPtr< IHTMLDocument2 > sDoc= sDDc; //将其转化为document页面 4 CComQIPtr< IHTMLElementCollection > spECn; //声明一个页面容器 5 if (SUCCEEDED(sDoc->get_all(&spECn))) //如果得到页面容器成功 6 { 7 CComPtr<IDispatch> spD1, spD2, spD; //com中封住的抽象的对象 8 HRESULT hr1, hr2,hr; 9 //取一个标题 10 hr1 = spECn->item(CComVariant("subject"), CComVariant("0"), &spD1); //将热键获取赋予对象 11 // 12 hr2 = spECn->item(CComVariant("message"), CComVariant("0"), &spD2); 13 14 hr = spECn->item(CComVariant("topicsubmit"), CComVariant("0"), &spD); 15 if (SUCCEEDED(hr1) && SUCCEEDED(hr2)){ 16 CComQIPtr<IHTMLInputElement> spElem1 = spD1; //装换为元素 17 CComQIPtr<IHTMLInputElement> spElem2 = spD2; 18 spElem1->put_value(CComBSTR("it‘s a test!")); //注入内容 19 20 spElem2->put_value(CComBSTR("这是一份来自电脑的重复输入,测试!it‘s a test !")); 21 if (SUCCEEDED(hr)){ 22 CComQIPtr<IHTMLFormElement> spForm = spD; 23 spForm->submit(); 24 } 25 } 26 }
对于上面的这部分代码: 包含了数据的填写和提交,请结合上面的这张图,来理解!!!!
效果:
然后拉倒华科的考研论坛区测试了下:第一个框中自动填充成功,但是第二,由于对方用js,写了预防注入的程序代码,就是必须输入前鼠标点击一下,不然输入不进去。所以这样单纯的填充,对于这种设置还是比较棘手!!! 当然如果c++,这边调用js来搞的话! 也许也未可知!
以后有时间再来做这方面的 探讨吧!! 希望这些分享,能带给大家一点点的帮助!!