ActiveX asynchronous callback Javascript

Source: Internet
Author: User

 

Copyright Notice

Respect Original Works. Reprinted, please maintain the integrity of the article, and in the form of a hyperlink to indicate the original author "tingsking18" and the main site address, so that other friends can ask and correct.

ActiveX asynchronous callback Javascript

Development Environment: vc6.0.

Background: COM/ActiveX/JavaScript/mfc/thread

Those who have used Ajax know about XMLHTTP. By setting the onreadystatechange attribute, we can specify the callback function for changing the state. When the state changes, the ActiveX Control calls the callback function developed through the onreadystatechange attribute. As a result, Ajax brings us a wonderful experience. We will not discuss Ajax technology here. Our goal is to implement OCX controls with asynchronous callback JavaScript Functions like XMLHTTP.

Let's go!

1. Establish MFC ActiveX Control (method omitted)

2. Add the callbackfunction attribute in classwizard and generate get and set methods for this attribute. We will enable the thread in the ActiveX control. After the thread is executed, the JavaScript function executed through this attribute will be called. In this instance, the JavaScript function specified through the callbackfunction attribute must return void and contain a short type parameter.

3. We need a method to trigger the callback function. The add method invoke contains a short type parameter Param. In this function, a thread is enabled for computation and the computation result is returned. And call JavaScript Functions in the form of callback functions.

4. Enable the thread in the invoke method. . The thread synchronization method uses postmessage to customize messages. This is very important. Otherwise, the interface controls in our thread are incorrect. (I just forgot to perform thread synchronization before taking many detours)

# Define wm_threadfireevent wm_user+ 101

Void F (void * r)

{

Cthirdctrl * P = (cthirdctrl *) R;

Sleep (5000 );

P-> m_param + = 10;

Postmessage (p-> m_hwnd, wm_threadfireevent, (wparam) null, (lparam) null );

Return;

}

Void cthirdctrl: invoke (short PARAM)

{

M_param = Param;

_ Beginthread (F, 0, (void *) (this ));

}

5. added the message ing function for the threadfireevent message:

On_message (wm_threadfireevent, onfireeventforthread)

6. Implement the onfireeventforthread function:

Lresult cthirdctrl: onfireeventforthread (wparam, lparam)

{

// Firelengthyprocessdone ();

Invokescript ();

Return true;

}

7. Before invokescript is implemented, let's talk about an important thing, that is, onsetclientsite, which is a virtual method of colecontrol, the parent class of cthirdctrl. We need to rewrite it to get the iwebbrowser2 pointer. With iwebbrowser2, we can do whatever we want. For example, get the document object, get Elements in HTML, set their attributes, and call the method. You can also execute JavaScript Functions on the page.

To obtain the top-level iwebbrowser2 reference, obtain the iserviceprovider interface from the customer site and execute a queryservice operation to obtain the iid_iserviceprovider service: sid_stoplevelbrowser (this is in shlguid. for the second iserviceprovider, execute a queryservice to obtain the iid_iwebbrowser2 service: sid_swebbrowserapp.

Code:

Void cthirdctrl: onsetclientsite ()

{

Ioleclientsite * pclientsite = getclientsite ();

Hresult hR = s_ OK;

Iserviceprovider * ISP, * isp2 = NULL; // used to navigate the DHTML Object hierarchy and provide services

If (! Pclientsite)

{

If (browser! = NULL)

{

Browser-> release ();

Browser = NULL;

}

Return ;//! S_ OK;

}

Else

{

HR = pclientsite-> QueryInterface (iid_iserviceprovider, reinterpret_cast <void **> (& ISP ));

If (failed (HR ))

{

HR = s_ OK;

Goto cleanup;

}

HR = ISP-> queryservice (sid_stoplevelbrowser, iid_iserviceprovider, reinterpret_cast <void **> (& isp2 ));

If (failed (HR ))

{

HR = s_ OK;

Goto cleanup;

}

// Obtain the browser

HR = ISP-> queryservice (sid_swebbrowserapp, iid_iwebbrowser2, reinterpret_cast <void **> (& browser ));

If (failed (HR ))

{

HR = s_ OK;

Goto cleanup;

}

Cleanup:

// Free resources.

If (ISP! = NULL)

{

ISP-> release ();

ISP = NULL;

}

If (isp2! = NULL)

{

Isp2-> release ();

Isp2 = NULL;

}

Return; // hr;

}

Return; // hr;

}

In the same way, if we are using ActiveX, We need to rewrite it.

Stdmethodimp cthirdctrl: setclientsite ()

This method.

8. the following is the implementation of the most critical invokescript function. Here we use the iwebbrowser2 pointer obtained above to obtain the document object and then obtain the script object of the idispatch interface, then, call the invoke method of the idispatch interface. You can call JavaScript. The idispatch interface is really powerful.

To put it bluntly, go to the Code:

Void cthirdctrl: invokescript ()

{

If (! Browser)

{

If (browser! = NULL)

{

Browser-> release ();

Browser = NULL;

}

Return;

}

Ccomptr <ihtmldocument2> m_spdoc;

Hresult hR = browser-> get_document (idispatch **) & m_spdoc );

If (failed (HR ))

Throw ("");

Ccomptr <idispatch> pscript;

HR = m_spdoc-> get_script (& pscript );

If (failed (HR ))

Throw ("");

Ccombstr bstrmember (m_callbackfunction );

Dispid;

HR = pscript-> getidsofnames (iid_null, & bstrmember, 1, locale_system_default, & dispid );

// Set function parameters

Dispparams;

Memset (& dispparams, 0, sizeof (dispparams ));

Dispparams. cargs = 1; // indicates the parameter count.

Dispparams. rgvarg = new variant [dispparams. cargs]; // indicates a reference to the parameter array.

For (INT I = 0; I <1; I ++)

{

// Ccombstr BSTR = "111"; // back reading

// BSTR. copyto (& dispparams. rgvarg [I]. bstrval );

Dispparams. rgvarg [I]. ival = m_param;

Dispparams. rgvarg [I]. Vt = vt_i2;

}

Dispparams. cnamedargs = 0; // indicates the name parameter count.

Raise info raise Info;

Memset (& cmdinfo, 0, sizeof (cmdinfo ));

Ccomvariant varesult;

Uint nargerr = (uint)-1; // initialize to invalid ARG

HR = pscript-> invoke (dispid, iid_null, 0, dispatch_method, & dispparams, & varesult, & excepinfo, & nargerr );

}

In this way, the ActiveX control is complete.

9. Compile the HTML page code. Open Microsoft ActiveX control pad and insert the control. Then write JavaScript code.

<HTML>

<Head>

<Title> new page </title>

</Head>

<Body>

<Script language = "JavaScript">

Function invoke ()

{

Third1.callbackfunction = "Callback ";

Third1.invoke (2 );

Alert ("begin invoke ");

}

Function callback (PARAM)

{

Alert (PARAM );

}

</SCRIPT>

<Object ID = "third1" width = 100 Height = 51

Classid = "CLSID: E9D38528-0F4E-468B-858D-69905F16942F">

<Param name = "_ version" value = "65536">

<Param name = "_ extentx" value = "2646">

<Param name = "_ extenty" value = "1323">

<Param name = "_ stockprops" value = "0">

</Object>

<Input type = "button" value = "test" onclick = "INVOKE ();"/>

</Body>

</Html>

10. Test: Open the browser and open the test.html page. Click the "test" button. The begin invoke dialog box is displayed first, and then 12 is displayed in five seconds.

11. debugging method: We can directly debug the browser. The browser loads the control, and then calls the control method. This will automatically trigger the breakpoint we set in the project. In

Project --- settings --- debug --- executable for debug sessions sets the path of the EXE file in the browser. I used the window of the world browser. Therefore, the value is set to c: \ Program Files \ theworld \ theworld.exe.

If you use IE, you can set it to: C: \ Program Files \ Internet Explorer \ ipolice.exe

Note:

1. The difference between the above control and XMLHTTP is that callbackfunction is a string while XMLHTTP is a JavaScript function pointer.

2. The thread model in COM is not covered in this article. There are also browser security issues and the issue of packaging the cab is not covered in this article.

Refer:

Http://vcfaq.mvps.org/com/1.htm

Http://vcfaq.mvps.org/com/11.htm

Http://support.microsoft.com/kb/q157437/

Related Article

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.