The application of the technology discussed in the article is still quite wide, in addition to voting this relatively negative application, but also can be completed such as automatic form, email automatic application, website registration functions.
There are two types of methods available here:
Method 1: Implemented through the COM interface provided by the IE control. This approach is to edit the Web form via the IHTMLDocument2 interface (sometimes modifying the page code) and then triggering an event to submit the page. This method, because of the use of IE control, open the Web page will download a lot of data unrelated to the application, such as pictures (of course, you can in IE in the picture and so on the option to turn off), efficiency is very low, and each vote will have to open an IE control, if your machine is less, waiting to press reset it ~ ~. In addition, this method of coding more, very annoying.
Method 2: Implement the work of form submission through the WinInet API. This method is much better than the previous one, not only the implementation of high efficiency, the cost of less, and the specific implementation of a simpler.
Here are two ways to introduce each:
Method 1: The COM interface provided through the IE control is implemented
1, my program is based on the dialog box, not with the Htmlview, so first in the dialog box to put an IE control (inse!rt ActiveX controls, which has a Microsoft Web browser), give this IE control name, such as M_ Ctrlweb. Also remember to add <mshtml.h> header files, IE COM interface things are in the inside. <comdef.h> and <atlbase.h> if not, add it.
2, with ClassWizard to join the DownloadComplete event response, so that the Web page download is over you can do a form of work. Of course, you can also in the Progresschange and other events such as these operations, but so you have to determine whether the Web page is almost downloaded to the appropriate location, Yaotu easy, directly with DownloadComplete forget.
3, the next step is to use this control to open the target page, when to open your own look at the office, I was opened in the InitDialog, the code is as follows:
COleVariant vaurl= "Http://www.onlytest.net";
M_ctrlweb.navigate2 (&vaurl, &vtmissing, &vtmissing, &vtmissing, &vtmissing);
One of the vtmissing is used as the default parameter.
4, then is the main operation. These operations are placed in the ondownloadcompleteexplorer. For convenience, I have written several functions to perform specific functions, explain these functions first before specifying the operations in Ondownloadcompleteexplorer.
Function: To determine if there are strname specified elements in the Web page
Parameters: Pobjallelement: A collection of all elements in a Web page
StrName: ID or name of an element in a Web page
BOOL Hasitem (IHTMLElementCollection *pobjallelement,cstring strName)
{
ccomptr<idispatch>pdisp;
Pobjallelement->item (COleVariant (StrName), COleVariant ((long) 0), &pdisp);
if (pdisp==null)
return false;
Else
return true;
}
Function: Enter a string in the text box of a Web page
Parameters: Pobjallelement: A collection of all elements in a Web page
StrName: ID or name of the text box to edit
StrText: What to write in the text box
void Putietext (IHTMLElementCollection *pobjallelement,cstring strname,cstring strText)
{
CComPtr pdisp;
Pobjallelement->item (COleVariant (StrName), COleVariant ((long) 0), &pdisp);
CComQIPtr pelement;
if (pdisp==null)
{
AfxMessageBox (StrName + "not found!");
}
Else
{
Pelement=pdisp;
Pelement->put_value (Strtext.allocsysstring ());
}
}
Function: Submit a form to a Web page
Parameters: Pobjallelement: A collection of all elements in a Web page
StrName: ID or name of the button that can submit form (or submit directly to form)
void Submitpage (IHTMLElementCollection *pobjallelement,cstring strName)
{
Ccomptrpdisp;
Pobjallelement->item (COleVariant (StrName), COleVariant ((long) 0), &pdisp);
Ccomqiptrpelement;
if (pdisp==null)
{
AfxMessageBox (StrName + "not found!");
}
Else
{
Pelement=pdisp;
Pelement->click ();
}
}
function: Select a checkbox in the page (actually click)
Parameters: Pobjallelement: A collection of all elements in a Web page
StrName: ID or name of the checkbox to select
void Checkitem (IHTMLElementCollection *pobjallelement,cstring strName)
{
CComPtr pdisp;
Pobjallelement->item (COleVariant (StrName), COleVariant ((long) 0), &pdisp);
Ccomqiptr<ihtmlelement, &IID_IHTMLElement>pElement;
if (pdisp==null)
{
AfxMessageBox (StrName + "not found!");
}
Else
{
Pelement=pdisp;
Pelement->click ();
}
}
You can use these functions to easily perform a polling operation. The code in Ondownloadcompleteexplorer is listed below.
Another assumes that the voting page is http://www.onlytest.com/vote.htm and the data is submitted to http://www.onlytest.com/vote2.asp
void Cvotedlg::ondownloadcompleteexplorer ()
{
Todo:add your control notification handler code here
IHTMLElementCollection *objallelement=null;
IHTMLDocument2 *objdocument=null;
CString strurl,strtemp;
Strurl=m_ctrlweb.getlocationurl ()//Get the URL of the current page
if (Strurl.isempty ())
Return
Objdocument= (IHTMLDocument2 *) m_ctrlweb.getdocument (); The IHTMLDocument2 interface pointer is obtained by the control
Objdocument->get_all (&objallelement); Get a collection of all the elements of a Web page
Since all pages are executed after downloading, the message source page must be judged based on the URL
if (strurl== "http://www.onlytest.com/vote.htm")
{
ccomptr<idispatch>pdisp;
if (Hasitem (objallelement, "Voteform") ==true)//voteform for the form where voting options are located
{
Objallelement->item (COleVariant ("Voteform"), COleVariant ((long) 0), &pdisp);
Ccomqiptr<ihtmlformelement, &iid_ihtmlformelement >pElement;
if (pdisp==null)
{
Interface pointer acquisition failed, end program, no additional processing, reason see after
EndDialog (IDOK);
Return
}
Else
{
If the voting results are open in a new window, you should modify the page code so that the results appear in this control
Pelement=pdisp;
Pelement->put_target (CComBSTR ("_self")); Equivalent to target= "_self"
Pelement->put_action (CComBSTR ("vote2.asp"));//equivalent to action= "vote2.asp"
}
Checkitem (objallelement, "chk2"); Select the checkbox with ID chk2 in form
Submitpage (Objallelement, "vote"); Submit the page, vote as the ID or name of the submit button
}
}
else if (strurl== "http://www.onlytest.com/vote2.asp")
{
EndDialog (IDOK); If the voting processing page has been downloaded, end the program, after the reason.
}
}
Now that the tickets have been voted out, but you may wonder why the vote or the middle of the mistake to end the program with the EndDialog, rather than continue voting. The thing is this, some Web site A session can only vote, and an IE control to create a good connection with the server (with the session), the session key is set (Opinion), so if you continue to use this IE control vote, The server will tell you that you have already voted (and, of course, if the voting procedure is stupid, it's much simpler). This question was originally intended to be dealt with by analyzing the running process of the WinInet API, but it seems to be troublesome, so the use of a very stupid but simple method: Voting program as a program, and then another program to call this voting procedure, vote after the vote after the voting process, the main program again run voting procedures, so repeated. As for the limit of the number of voting procedures, the use of shared memory segments is the simplest (opinion), specifically not discussed here.
Method 2: Implementing the form submission through the WinInet API
This method to achieve a small amount of code, and because there is no need to download too much useless data (such as pictures, etc.), the form is on the page does not need to download, so the efficiency is much higher, the other implementation code is a function, is suitable for use in the thread.
The key to this method is to know what data should be submitted to the server if you look at the Web page file, and then analyze what data should be submitted to the server, the Web page is very simple, if the web is very complex, it is a thankless thing. Now is not the exam, that kind of thing we do not do, now have a simpler way, is to use the Win2000 under the Network Monitor, manually cast a vote to see what data submitted to the server. So we can copy the portion of the data that belongs to the HTTP protocol. The data that is copied directly from the monitor is not available. Because the monitor shows the text of the part of the carriage return line and other characters are replaced with a decimal point, these parts must first change back to the original carriage return, line change (HTTP head part of the can not be used, as long as you can distinguish the boundary can be). Also note that the submission may have content-length this information, if you modify the content of the submitted data, and the data length has changed, the value of the Content-length item must be changed. For example content-length the original value is 100, the data has a data "1", you now changed to "12", then Content-length must be changed to 101, otherwise the server will return an error.
The voting function is listed below:
UINT Vote (LPVOID)
{
CInternetSession session;
theapp.m_nthreads++; Used to record the number of polling threads.
Try
{
chttpconnection* pconnection =session. GetHttpConnection ("Www.onlytest.net"); Web server
chttpfile* pFile = pconnection->openrequest (Chttpconnection::http_verb_post, "vote2.asp"); Submit data directly to the voting processing page
The following adds HTTP headers to the submission data, which can be obtained by Network Monitor
Pfile->addrequestheaders ("Accept:image/gif, Image/x-xbitmap, Image/jpeg, Image/pjpeg, application/ Vnd.ms-powerpoint, Application/vnd.ms-excel, Application/msword, */* ");
Pfile->addrequestheaders ("referer:http://www.onlytest.net/vote.htm");
Pfile->addrequestheaders ("ACCEPT-LANGUAGE:ZH-CN");
Pfile->addrequestheaders ("Content-type:multipart/form-data; boundary=---------------------------7d11dc24268052c ");
Pfile->addrequestheaders ("Accept-encoding:gzip, deflate");
Pfile->addrequestheaders ("user-agent:mozilla/4.0" (compatible; MSIE 5.01; Windows NT 5.0) ");
Pfile->addrequestheaders ("content-length:1351");
Pfile->addrequestheaders ("connection:keep-alive");
Pfile->addrequestheaders ("Cache-control:no-cache");
HTTP headers should be true after the data, the following theapp.m_strformdata is to submit the data, server processing returned information in Pfile
Pfile->sendrequest (Null,0,theapp.m_strformdata.getbuffer (0), theApp.m_strFormData.GetLength ()); Submit all data
In fact, the vote here can be finished, but if you want to see the results, you can return the page analysis and analysis, to get some data
Char szbuffer[11001]; Used to store the return processing page, how much to see the actual situation. Of course, can also be dynamically allocated, not too tired words
int Nlen=pfile->read (szbuffer,11000)//Read the returned content, actually is the HTML code of the voting results page
szbuffer[nlen]=0;
CString Strtemp=szbuffer; CString though some, but use is convenient, hehe ~
Pfile->close (); When the data is read, turn off everything that's closed.
Pconnection->close ();
Delete PFile;
Delete pconnection;
Session. Close ();
The following code is used to parse the HTML code to get the data you're interested in, and it doesn't matter what the vote is, it doesn't explain it in detail.
int npos=strtemp.find ("option A");
int ntemppos=npos;
if (npos==-1)
{
theapp.m_nthreads--;
return 0;
}
Npos=strtemp.find ("Table Width=100><tr><td align=right>", NPOs) +36;
int Nendpos=strtemp.find ("Ticket", NPOs);
M_nournum=atoi (Strtemp.mid (Npos,nendpos-npos));
Npos=strtemp.find ("<tr bgcolor= #DEE6EB ><td align=center width=50>1</td>");
Npos=strtemp.find ("Table Width=100><tr><td align=right>", NPOs) +36;
Nendpos=strtemp.find ("Ticket", NPOs);
M_ndiff=atoi (Strtemp.mid (Npos,nendpos-npos))-m_nournum;
m_nvote++;
}
catch (...)
{
}
theapp.m_nthreads--;
return 0;
}
As you can see, the key code is just a few lines, and if you don't analyze the vote, it's a lot less than 1, and it's not as messy as the way 1 looks. However, this approach also exists in Method 1, the session repetition problem. And as far as I'm trying, the new open thread session is also duplicated. So I estimate that the session key is based on the process ID (Opinion, Welcome to the discussion). However, if you start n threads at the same time, n threads can successfully cast the ticket, rather than say "you have voted." It is estimated that this information is submitted at the same time, the server in processing a message is not aware that the session has actually been voted. Whether this is the reason I am not clear, we can discuss.
The two procedures for voting are written here. My level is really general, so there are mistakes in the article, we must not disdain a say ah, the wrong point out that we discuss together. In addition, the question of the session in the article is also expected to be discussed.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.