Logo Search packages:      
Sourcecode: xulrunner version File versions  Download package

STDMETHODIMP nsAccessibleWrap::get_accSelection ( VARIANT __RPC_FAR *  pvarChildren  )  [virtual, inherited]

This method is called when a client wants to know which children of a node are selected. Currently we only handle this for HTML selects, which are the only nsIAccessible objects to implement nsIAccessibleSelectable.

The VARIANT return value arguement is expected to either contain a single IAccessible or an IEnumVARIANT of IAccessibles. We return the IEnumVARIANT regardless of the number of options selected, unless there are none selected in which case we return an empty VARIANT.

The typedefs at the beginning set up the structure that will contain an array of the IAccessibles. It implements the IEnumVARIANT interface, allowing us to use it to return the IAccessibles in the VARIANT.

We get the selected options from the select's accessible object and then put create IAccessible objects for them and put those in the CComObject<EnumeratorType> object. Then we put the CComObject<EnumeratorType> object in the VARIANT and return.

returns a VT_EMPTY VARIANT if:

  • there are no options in the select
  • none of the options are selected
  • there is an error QIing to IEnumVARIANT
  • The object is not the type that can have children selected

Definition at line 596 of file nsAccessibleWrap.cpp.

{
  typedef VARIANT                      ItemType;              /* type of the object to be stored in container */
  typedef ItemType                     EnumeratorExposedType; /* the type of the item exposed by the enumerator interface */
  typedef IEnumVARIANT                 EnumeratorInterface;   /* a COM enumerator ( IEnumXXXXX ) interface */
  typedef _Copy<EnumeratorExposedType> EnumeratorCopyPolicy;  /* Copy policy class */
  typedef CComEnum<EnumeratorInterface,
                   &__uuidof(EnumeratorInterface),
                   EnumeratorExposedType,
                   EnumeratorCopyPolicy > EnumeratorType;

  IEnumVARIANT* pUnk = NULL;
  CComObject<EnumeratorType>* pEnum = NULL;
  VariantInit(pvarChildren);
  pvarChildren->vt = VT_EMPTY;

  nsCOMPtr<nsIAccessibleSelectable> select;
  nsAccessNode::QueryInterface(NS_GET_IID(nsIAccessibleSelectable), getter_AddRefs(select));

  if (select) {  // do we have an nsIAccessibleSelectable?
    // we have an accessible that can have children selected
    nsCOMPtr<nsIArray> selectedOptions;
    // gets the selected options as nsIAccessibles.
    select->GetSelectedChildren(getter_AddRefs(selectedOptions));
    if (selectedOptions) { // false if the select has no children or none are selected
      PRUint32 length;
      selectedOptions->GetLength(&length);
      CComVariant* optionArray = new CComVariant[length]; // needs to be a CComVariant to go into the EnumeratorType object

      // 1) Populate an array to store in the enumeration
      for (PRUint32 i = 0 ; i < length ; i++) {
        nsCOMPtr<nsIAccessible> tempAccess;
        selectedOptions->QueryElementAt(i, NS_GET_IID(nsIAccessible), 
                                        getter_AddRefs(tempAccess));
        if (tempAccess) {
          optionArray[i] = NativeAccessible(tempAccess);
        }
      }

      // 2) Create and initialize the enumeration
      HRESULT hr = CComObject<EnumeratorType>::CreateInstance(&pEnum);
      pEnum->Init(&optionArray[0], &optionArray[length], NULL, AtlFlagCopy);
      pEnum->QueryInterface(IID_IEnumVARIANT, reinterpret_cast<void**>(&pUnk));
      delete [] optionArray; // clean up, the Init call copies the data (AtlFlagCopy)

      // 3) Put the enumerator in the VARIANT
      if (!pUnk)
        return NS_ERROR_FAILURE;
      pvarChildren->vt = VT_UNKNOWN;    // this must be VT_UNKNOWN for an IEnumVARIANT
      pvarChildren->punkVal = pUnk;
    }
  }
  return S_OK;
}


Generated by  Doxygen 1.6.0   Back to index