VC ++ access JavaScript (2)-idispatchex is the foundation of dynamic scripting language

Source: Internet
Author: User

The idispatch interface is mainly used in traditional automated programming, such as Microsoft Visual Basic. The client can call all the attributes and methods of the COM component by obtaining the idispatch interface of the COM component. However, the limitation of idispatch is that it assumes that the COM component is static. That is to say, the attributes and methods of these COM components cannot be changed during runtime. Therefore, to realize the dynamic features of JavaScript and VBScript, a more flexible interface is required.

Therefore, the idispatchex interface customized for the scripting language was born. Idispatchex is derived from idispatch. In addition to the methods specified by idispatch, it also provides a set of extension methods to support dynamic features of the script language. These dynamic features include:

  • Add a member to an object ("expando")-useMarked by fdexnameensureMethodGetdispid.
  • Delete an object Member-usageDeletememberbynameOrDeletememberbydispid.
  • Case sensitivity-UseFdexnamecasesensitive mark orFdexnamecaseinsensitive flag..
  • Search for members by implicit name-UseFdexnameimplicit tag
  • Enumerate all objectsDispid-UseGetnextdispid.
  • Get the member name through dispid-UseGetmembername.
  • Get attributes of object members-UseGetmemberproperties.
  • Call by executing a method with the this pointer-Use MethodInvokeex.
  • Allows a browser that supports the namespace concept to obtain the namespace of an object-usage methodGetnamespaceparent.

 

In fact, the idispatchex interface is more important here, so that we can access and simulate the characteristics of dynamic scripting in VC ++. The following uses JavaScript as an example.

 

Example:
The javascript code in method test () performs the following actions:
Call the object constructor (constructor) to create a new object and save it with the variable obj.
Create a new member ELEM in the object and set the value of ELEM as the pointer of the method cat.
Call the ELEM method and pass in the this pointer. Because ELEM is a member of OBJ, this Pointer Points to OBJ. The code in method cat sets a new member bar for OBJ and assigns the value to 10.
The complete HTML code is as follows:
<HTML>
<Body>
<Script language = "JavaScript">

Function CAT ()
{
// Create a new member and assign a value of 10
This. bar = 10;
}

Function Test ()
{
// Create a new object
OBJ = new object ();

// Create a new member and assign it to cat
OBJ. ELEM = cat;

// Call ELEM ("this" = OBJ)
OBJ. ELEM ();

// Now obj. Bar already exists
}
//
Test ();
</SCRIPT>
</Body>
</Html>

We use a control to encapsulate the code in the test method with VC ++. When a control is placed in a webpage, you can obtain the idispatch interface and idispatchex interface of the script engine in the browser (see the previous article for details ).
<HTML>
<Body>
<Script language = "JavaScript">
Function CAT ()
{
// Create a new member and assign a value of 10

This. bar = 10;
}
</SCRIPT>
<Object ID = "test" <classid = "CLSID: 9425db5d-fa2a-11d0-8cb3-00c04fc2b085">
</Object>
</Body>
</Html>

In the control test, we will perform the following operations:

1. Use getdispid () to obtain the cat pointer.
2. Use getdispid () to get the pointer of the method object.
3. Use invokeex () to call the method object to create a new object.
4. Use getdispid () to create a new member ELEM for the object.
5. Use invokeex () to assign the cat pointer to the member ELEM.
6. Use invokeex () to call ELEM (that is, the method cat) and pass in the object as the this pointer. The cat method creates a new member bar for this pointer (that is, object.
7. Use getnextdispid () to enumerate objects and verify whether the newly created member bar exists.

The code in control test is as follows:

  1. Bool test (idispatchex * pdexscript)
  2. {
  3. Hresult hr;
  4. Variant var;
  5. Dispid, putid;
  6. Bool retval = false;
  7. BSTR bstrname = NULL;
  8. Idispatch * pdispobj = NULL, * pdispcat = NULL;
  9. Idispatchex * pdexobj = NULL;
  10. Dispparams, dispparamsnoargs = {null, null, 0, 0 };
  11. // Get dispatch pointer for "cat"
  12. Bstrname = sysallocstring (olestr ("cat "));
  13. If (bstrname = NULL) goto ldone;
  14. HR = pdexscript-> getdispid (bstrname, 0, & dispid );
  15. If (failed (HR) goto ldone;
  16. Sysfreestring (bstrname );
  17. Bstrname = NULL;
  18. HR = pdexscript-> invokeex (dispid, locale_user_default,
  19. Dispatch_propertyget, & dispparamsnoargs,
  20. & Var, null, null );
  21. If (failed (HR) goto ldone;
  22. Pdispcat = var. pdispval;
  23. // Create object by calling "object" Constructor
  24. Bstrname = sysallocstring (olestr ("object "));
  25. If (null = bstrname) goto ldone;
  26. HR = pdexscript-> getdispid (bstrname, 0, & dispid );
  27. If (failed (HR) goto ldone;
  28. Sysfreestring (bstrname );
  29. Bstrname = NULL;
  30. HR = pdexscript-> invokeex (dispid, locale_user_default,
  31. Dispatch_construct, & dispparamsnoargs,
  32. & Var, null, null );
  33. If (failed (HR) goto ldone;
  34. Pdispobj = var. pdispval;
  35. HR = pdispobj-> QueryInterface (iid_idispatchex, (void **) & pdexobj );
  36. If (failed (HR) goto ldone;
  37. // Create new element in object
  38. Bstrname = sysallocstring (olestr ("ELEM "));
  39. If (null = bstrname) goto ldone;
  40. HR = pdexobj-> getdispid (bstrname, fdexnameensure, & dispid );
  41. If (failed (HR) goto ldone;
  42. Sysfreestring (bstrname );
  43. Bstrname = NULL;
  44. // Assign "cat" dispatch pointer to element
  45. Putid = dispid_propertyput;
  46. Var. Vt = vt_dispatch;
  47. Var. pdispval = pdispcat;
  48. Dispparams. rgvarg = & var;
  49. Dispparams. rgdispidnamedargs = & putid;
  50. Dispparams. cargs = 1;
  51. Dispparams. cnamedargs = 1;
  52. HR = pdexobj-> invokeex (dispid, locale_user_default,
  53. Dispatch_propertyputref, & dispparams,
  54. Null, null, null );
  55. If (failed (HR) goto ldone;
  56. // Invoke method with "this" pointer
  57. Putid = dispid_this;
  58. Var. Vt = vt_dispatch;
  59. Var. pdispval = pdispobj;
  60. Dispparams. rgvarg = & var;
  61. Dispparams. rgdispidnamedargs = & putid;
  62. Dispparams. cargs = 1;
  63. Dispparams. cnamedargs = 1;
  64. HR = pdexobj-> invokeex (dispid, locale_user_default,
  65. Dispatch_method, & dispparams,
  66. Null, null, null );
  67. If (failed (HR) goto ldone;
  68. // Confirm that new element "bar" is in object
  69. HR = pdexobj-> getnextdispid (fdexenumall, dispid_startenum, & dispid );
  70. While (hR = noerror)
  71. {
  72. HR = pdexobj-> getmembername (dispid, & bstrname );
  73. If (failed (HR) goto ldone;
  74. Retval =! Wcscmp (bstrname, olestr ("bar "));
  75. Sysfreestring (bstrname );
  76. Bstrname = NULL;
  77. If (retval) goto ldone;
  78. HR = pdexobj-> getnextdispid (fdexenumall, dispid, & dispid );
  79. }
  80. Ldone:
  81. Sysfreestring (bstrname );
  82. If (pdispcat! = NULL)
  83. Pdispcat-> release ();
  84. If (pdispobj! = NULL)
  85. Pdispobj-> release ();
  86. If (pdexobj! = NULL)
  87. Pdexobj-> release ();
  88. Return retval;
  89. }

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.