zoukankan      html  css  js  c++  java
  • C/C++ 如何来自动优雅的涮别银家的贴子

      被涮屏涮烦了,就分享一下如何用低调的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 };
    View Code

    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来搞的话! 也许也未可知!

    以后有时间再来做这方面的 探讨吧!!   希望这些分享,能带给大家一点点的帮助!!

     ---------------------------------------分割线-----------------------------

    这篇文章过去太久了,久得连MFC已经没落的不成样子,隔了这么久,贴一下剩余的几个功能代码.

     补充: 如何使用MFC调用JS来模拟鼠标点击网页

    这里只是针对C++,ATL编写客户端时,调用微软API时常用的问题的解决方案:

    1. 使用com组件调用js来模内点击网页按钮,避免使用复杂的dom树:

    比如有这么一段html页面:

    <input type="submit" id="su" value="百度一下" class="bg s_btn">

    也就是百度首页:

    首先在截图:

    在console中输入:

    document.getElementById("su").click()

    会看到这:截图:

     

    这说明这个js是生效的,然后我们再使用com组件调用这条js代码即可:

    复制代码
     1 std::string strScript ="document.getElementById("su").click()";
     2     // 获取 IHTMLDocument2 接口
     3     IHTMLDocument2 *spDoc = NULL;
     4     if (!webclient.get_Busy() && webclient.get_Document() != NULL)
     5         webclient.get_Document()->QueryInterface(
     6         ::IID_IHTMLDocument2, reinterpret_cast<void **>(&spDoc));
     7     else
     8     {
     9         ::MessageBox(this->GetSafeHwnd(),L"IHTMLDocument2 接口获取失败",
    10             L"Error", MB_OK | MB_ICONERROR);
    11         return;
    12     }
    13 
    14     bool bSucceed(false);
    15     if (spDoc)
    16     {
    17         // 获取 IHTMLWindow2 接口
    18         IHTMLWindow2 *spWin;
    19         VARIANT vRet;
    20         HRESULT hr=spDoc->get_parentWindow(&spWin);
    21         if (spWin)
    22         {
    23             CComBSTR bstrjs = (strScript.c_str());  
    24             CComBSTR bstrlan = SysAllocString(L"javascript");  
    25             long lRet = spWin->execScript(bstrjs, bstrlan, &vRet);
    26             bSucceed = lRet == 0;
    27             spWin->Release();
    28         }
    29         spDoc->Release();
    30     }
    复制代码

    第二个问题,那就是发帖子需要登陆,然后你还要获取到网站cookie才可以,所以下面我又补上获取cookie的代码.

    2. 如何得到webbrower中的cookie值:

    复制代码
     1 HRESULT hr;  
     2     IDispatch* lpDispatch;  
     3     lpDispatch = webclient.GetDocument();  
     4     IHTMLDocument2* lpDocument2;  
     5     hr = lpDispatch->QueryInterface(IID_IHTMLDocument2, (PVOID*)&lpDocument2);  
     6     if ( hr == S_OK )  
     7     {  
     8         BSTR bstrCookie;
     9         hr = lpDocument2->get_cookie(&bstrCookie);  
    10         if ( hr == S_OK )  
    11         {  
    12             webCookie(bstrCookie); 
    13         }  
    14         lpDocument2->put_cookie(NULL);  
    15         pBody->Release();  
    16         lpDocument2->Release();  
    17     }  
    18     lpDispatch->Release();  
    复制代码

      至此,你就可以大胆的去制作刷广告机啦~~

  • 相关阅读:
    java中传值与传引用
    microsofr visual studio编写c语言
    openfile学习笔记
    在 Windows 和 Linux(Gnome) 环境下 从命令界面打开网页的方式
    使用vsphere client 克隆虚拟机
    route命令
    linux rpm问题:怎样查看rpm安装包的安装路径
    【leetcode】415. 字符串相加
    【leetcode】面试题 17.01. 不用加号的加法
    【leetcode】989. 数组形式的整数加法
  • 原文地址:https://www.cnblogs.com/gongxijun/p/4782654.html
Copyright © 2011-2022 走看看