Bug 166994 - Make our MSAA objects also support IDispatch methods for scripters, r=davidb
authorAlexander Surkov <surkov.alexander@gmail.com>
Fri, 08 Jan 2010 14:50:38 +0800
changeset 36947 1f9ae6f1f9c55e256aa99649a8a91dea1e065df8
parent 36946 b919e8a488903207396e0502bba1051a30f11528
child 36948 6ce98ed11af8a38561d23d132668dd0793408533
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersdavidb
bugs166994
milestone1.9.3a1pre
Bug 166994 - Make our MSAA objects also support IDispatch methods for scripters, r=davidb
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/msaa/nsAccessibleWrap.h
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -80,25 +80,27 @@ static const PRInt32 kIEnumVariantDiscon
 /*
  * Class nsAccessibleWrap
  */
 
 //-----------------------------------------------------
 // construction
 //-----------------------------------------------------
 nsAccessibleWrap::nsAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference *aShell):
-  nsAccessible(aNode, aShell), mEnumVARIANTPosition(0)
+  nsAccessible(aNode, aShell), mEnumVARIANTPosition(0), mTypeInfo(NULL)
 {
 }
 
 //-----------------------------------------------------
 // destruction
 //-----------------------------------------------------
 nsAccessibleWrap::~nsAccessibleWrap()
 {
+  if (mTypeInfo)
+    mTypeInfo->Release();
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsAccessibleWrap, nsAccessible);
 
 //-----------------------------------------------------
 // IUnknown interface methods - see iunknown.h for documentation
 //-----------------------------------------------------
 
@@ -1584,48 +1586,73 @@ nsAccessibleWrap::get_attributes(BSTR *a
     return GetHRESULT(rv);
 
   return ConvertToIA2Attributes(attributes, aAttributes);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
-// For IDispatch support
+////////////////////////////////////////////////////////////////////////////////
+// IDispatch
+
 STDMETHODIMP
-nsAccessibleWrap::GetTypeInfoCount(UINT *p)
+nsAccessibleWrap::GetTypeInfoCount(UINT *pctinfo)
 {
-  *p = 0;
-  return E_NOTIMPL;
-}
-
-// For IDispatch support
-STDMETHODIMP nsAccessibleWrap::GetTypeInfo(UINT i, LCID lcid, ITypeInfo **ppti)
-{
-  *ppti = 0;
-  return E_NOTIMPL;
+  *pctinfo = 1;
+  return S_OK;
 }
 
-// For IDispatch support
+STDMETHODIMP
+nsAccessibleWrap::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+{
+  *ppTInfo = NULL;
+
+  if (iTInfo != 0)
+    return ResultFromScode(DISP_E_BADINDEX);
+
+  ITypeInfo * typeInfo = GetTI(lcid);
+  if (!typeInfo)
+    return E_FAIL;
+
+  typeInfo->AddRef();
+  *ppTInfo = typeInfo;
+
+  return S_OK;
+}
+
 STDMETHODIMP
 nsAccessibleWrap::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames,
-                           UINT cNames, LCID lcid, DISPID *rgDispId)
+                                UINT cNames, LCID lcid, DISPID *rgDispId)
 {
-  return E_NOTIMPL;
+  ITypeInfo *typeInfo = GetTI(lcid);
+  if (!typeInfo)
+    return E_FAIL;
+
+  HRESULT hr = DispGetIDsOfNames(typeInfo, rgszNames, cNames, rgDispId);
+  return hr;
 }
 
-// For IDispatch support
-STDMETHODIMP nsAccessibleWrap::Invoke(DISPID dispIdMember, REFIID riid,
-    LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
-    VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+STDMETHODIMP
+nsAccessibleWrap::Invoke(DISPID dispIdMember, REFIID riid,
+                         LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+                         VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
+                         UINT *puArgErr)
 {
-  return E_NOTIMPL;
+  ITypeInfo *typeInfo = GetTI(lcid);
+  if (!typeInfo)
+    return E_FAIL;
+
+  return typeInfo->Invoke(static_cast<IAccessible*>(this), dispIdMember,
+                          wFlags, pDispParams, pVarResult, pExcepInfo,
+                          puArgErr);
 }
 
 
+// nsIAccessible method
 NS_IMETHODIMP nsAccessibleWrap::GetNativeInterface(void **aOutAccessible)
 {
   *aOutAccessible = static_cast<IAccessible*>(this);
   NS_ADDREF_THIS();
   return NS_OK;
 }
 
 // nsAccessible
@@ -1930,8 +1957,28 @@ void nsAccessibleWrap::UpdateSystemCaret
   if (::CreateCaret(caretWnd, caretBitMap, 1, caretRect.height)) {  // Also destroys the last caret
     ::ShowCaret(caretWnd);
     RECT windowRect;
     ::GetWindowRect(caretWnd, &windowRect);
     ::SetCaretPos(caretRect.x - windowRect.left, caretRect.y - windowRect.top);
     ::DeleteObject(caretBitMap);
   }
 }
+
+ITypeInfo*
+nsAccessibleWrap::GetTI(LCID lcid)
+{
+  if (mTypeInfo)
+    return mTypeInfo;
+
+  ITypeLib *typeLib = NULL;
+  HRESULT hr = LoadRegTypeLib(LIBID_Accessibility, 1, 0, lcid, &typeLib);
+  if (FAILED(hr))
+    return NULL;
+
+  hr = typeLib->GetTypeInfoOfGuid(IID_IAccessible, &mTypeInfo);
+  typeLib->Release();
+
+  if (FAILED(hr))
+    return NULL;
+
+  return mTypeInfo;
+}
--- a/accessible/src/msaa/nsAccessibleWrap.h
+++ b/accessible/src/msaa/nsAccessibleWrap.h
@@ -282,25 +282,34 @@ class nsAccessibleWrap : public nsAccess
         /* [in] */ ULONG celt);
   
     virtual HRESULT STDMETHODCALLTYPE Reset( void);
   
     virtual HRESULT STDMETHODCALLTYPE Clone( 
         /* [out] */ IEnumVARIANT __RPC_FAR *__RPC_FAR *ppEnum);
 
         
-  //   ======  Methods for IDispatch - for VisualBasic bindings (not implemented) ======
+  // IDispatch (support of scripting languages like VB)
+  virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo);
+
+  virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid,
+                                                ITypeInfo **ppTInfo);
 
-  STDMETHODIMP GetTypeInfoCount(UINT *p);
-  STDMETHODIMP GetTypeInfo(UINT i, LCID lcid, ITypeInfo **ppti);
-  STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames,
-                               UINT cNames, LCID lcid, DISPID *rgDispId);
-  STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid,
-        LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
-        VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
+  virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,
+                                                  LPOLESTR *rgszNames,
+                                                  UINT cNames,
+                                                  LCID lcid,
+                                                  DISPID *rgDispId);
+
+  virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid,
+                                           LCID lcid, WORD wFlags,
+                                           DISPPARAMS *pDispParams,
+                                           VARIANT *pVarResult,
+                                           EXCEPINFO *pExcepInfo,
+                                           UINT *puArgErr);
 
   // nsAccessible
   virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aEvent);
 
   // Helper methods
   static PRInt32 GetChildIDFor(nsIAccessible* aAccessible);
   static HWND GetHWNDFor(nsIAccessible *aAccessible);
   static HRESULT ConvertToIA2Attributes(nsIPersistentProperties *aAttributes,
@@ -335,16 +344,24 @@ class nsAccessibleWrap : public nsAccess
 protected:
   virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent);
 
   // mEnumVARIANTPosition not the current accessible's position, but a "cursor" of 
   // where we are in the current list of children, with respect to
   // nsIEnumVariant::Reset(), Skip() and Next().
   PRInt32 mEnumVARIANTPosition;
 
+  /**
+   * Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it.
+   */
+  ITypeInfo *GetTI(LCID lcid);
+
+  ITypeInfo *mTypeInfo;
+
+
   enum navRelations {
     NAVRELATION_CONTROLLED_BY = 0x1000,
     NAVRELATION_CONTROLLER_FOR = 0x1001,
     NAVRELATION_LABEL_FOR = 0x1002,
     NAVRELATION_LABELLED_BY = 0x1003,
     NAVRELATION_MEMBER_OF = 0x1004,
     NAVRELATION_NODE_CHILD_OF = 0x1005,
     NAVRELATION_FLOWS_TO = 0x1006,