Google Desktop
 Google Desktop Actions API Developer Guide

For Users
  Download Plug-ins
  Desktop Search Forum

For Developers
  Plug-in Development
  Download SDK
  Developer Guide
    Index API
    Query API
    Display API
      Script API
      Communication API
      Plug-in Design Guidelines
      Plug-in Tutorials
        Using Wizard
        Using Helper Framework
        Using ActiveX
    Action API
    Event API
    Plug-in Installer
  Submit Software
  Developer Forum
  Desktop Blog

Contents

Overview

Custom Actions Developer API

GoogleDesktopActionAPI.idl


Overview

Getting Started

Google Desktop Custom Actions allow plug-in developers to override the default actions when a user clicks on a specific UI item.

To implement Custom Actions and integrate your application with Google Desktop you will need, in addition to the information in this document:

  • Sufficient access to write a plug-in for your application and an installer for it.
  • Programming knowledge of the Microsoft Windows Component Object Model (COM).

Development Process Overview

To develop a GD Custom Action, start by downloading the SDK, in particular the GoogleDesktopActionAPI.idl file. We recommend developing your application with Microsoft Visual Studio.

You will then need to write code to:

  • Register your application with the GD (required).
  • Implement the required Custom Actions interfaces.
  • Unregister your application with GD when your application uninstalls.

We recommend that you look over the sample code provided with the SDK. Please note that the sample code examples have their GUIDs hardcoded, so if you choose to reuse code from there you must change the interfaceIDs, classIDs, and libIDs to ones valid for your application.

Back to top
Custom Action Developer API

Registering Custom Action Components

GD will not accept unregistered components. Custom Action component registration is a one-time process done using the IGoogleDesktopRegistrar interface, and should be done during component installation. As part of the registration process, the component must provide its GUID as well as information about itself.

As part of its own uninstallation process, a component should unregister itself with GD.

Component Registration Interface Summary

The following summarizes the interface and its methods. All method return values are of type HRESULT.

interface IGoogleDesktopRegistrar: IDispatch
  • Note: Components are required to to call this interface to register themselves with Google Desktop before they can interact with any APIs or other provided services.
  • Note: The registration process consists of a call to StartComponentRegistration followed by individual registrations for various services obtained through GetRegistrationInterface and finished by a call to FinishComponentRegistration. For action components, the registration progid is "GoogleDesktop.ActionRegistration" and the interface is IGoogleDesktopRegisterCustomAction.
  • StartComponentRegistration: Must be invoked by any component to initiate the registration process.
    • Arguments:
      • BSTR component_guid_or_progid: The component's GUID or ProgID.
      • VARIANT component_description: A SAFEARRAY of pairs, where the first element is a descriptive parameter name and the second element is that parameter's value. The method expects only the following three required parameters, which should be given in this order.
        • "Title": Component title that will be displayed on the GD preferences page.
        • "Description": Component description that will be displayed on the GD preferences page.
        • "Icon": A string pointing to an ICON resource, of the form "c:\program files\boo\comp.dll,23". This icon may be used to indicate the component and its results on various GD pages.
    • Returns:
      • S_OK if successful.
      • E_COMPONENT_ALREADY_REGISTERED if this component has already been registered with GD.
      • Appropriate error on failure, such as an unregistered component classID or appID, component prohibited by policy, etc.

  • GetRegistrationInterface: Provides the requested type of registration interface.
    • Arguments:
      • BSTR registration_type: a stringified CLSID or a progid to the type of registration required.
      • [out, retval] IUnknown **registration_interface: provides the requested registration mechanism.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.

  • FinishComponentRegistration: Must be invoked to finish the registration process.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure, such as an unregistered component classID or appID, component prohibited by policy, etc.

  • UnregisterComponent
    • Arguments:
      • BSTR component_guid_or_progid: the same GUID used when registering the component.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
Component Registration Code Template

The following template demonstrates how a component can register to handle the "Reply" action for emails. Note that this registration should only be done once, not every time the plug-in starts.

To register a component:

  CComPtr<IGoogleDesktopRegistrar> spRegistrar;
  HRESULT hr;
  
  hr = spRegistrar.CoCreateInstance(CLSID_GoogleDesktopRegistrar);
  
  if (SUCCEEDED(hr)) {
    ATLASSERT(spRegistrar != NULL);
    
    // Component description is 6 strings
    CComSafeArray<VARIANT> arr_descr(6);

    arr_descr.SetAt(0, CComVariant(L"Title"));
    arr_descr.SetAt(1, CComVariant(L"A sample action plug-in"));
    arr_descr.SetAt(2, CComVariant(L"Description"));
    arr_descr.SetAt(3, CComVariant(L"Implements sample custom actions"));
    arr_descr.SetAt(4, CComVariant(L"Icon"));
    arr_descr.SetAt(5, CComVariant(L",1"));

    // our CLSID in string format
    CComBSTR our_clsid(clsid);
    
    // Wrap description array in variant
    CComVariant descr(arr_descr.m_psa);

    // and register
    hr = spRegistrar->StartComponentRegistration(our_clsid, descr);
    if (FAILED(hr))
      return hr;

    // success, now register as a action component.
    // This two step registration allows the same plug-in to implement multiple
    // components
    CComPtr<IGoogleDesktopRegisterCustomAction> spRegistration;

    CComBSTR action_registrar_progid("GoogleDesktop.ActionRegistration");
    hr = spRegistrar->GetRegistrationInterface(action_registrar_progid,
      reinterpret_cast<IUnknown**>(&spRegistration));
    ATLASSERT(FAILED(hr) || spRegistration);

    if (SUCCEEDED(hr)) {
      CComVariant var;
      var.Clear();
      hr = spRegistration->RegisterAction(CComBSTR(CLSID_EmailActions), 
                    CComBSTR(ACTION_EMAIL_REPLY), CComVariant());

      if (SUCCEEDED(hr)) {
        hr = spRegistrar->FinishComponentRegistration();
      }
    }

To unregister a component:

  CComPtr<IGoogleDesktopRegistrar> spRegistrar;
  HRESULT hr;
  
  hr = spRegistrar.CoCreateInstance(CLSID_GoogleDesktopRegistrar);
  
  if (SUCCEEDED(hr)) { 
    // our CLSID in string format
    CComBSTR bstrClsid(clsid);
  
    hr = spRegistrar->UnregisterComponent(bstrClsid);
  }

Implementing and Handling Custom Actions

After a successful registration with GD, a component can use the Custom Action APIs to implement and override the default actions for specific user actions.

The Action API consists of a COM interface, which must be exposed by plug-ins wishing to implement custom actions. Whenever a custom action is rendered GD will query registered plug-ins about their interest in the action i.e., whether to change he action title and whether to override or perform the default action. Please note that the custom action plugins will be loaded in a COM multi-threaded apartment.

interface IGoogleDesktopCustomAction: IUnknown
  • QueryInterest: Invoked when an action is being rendered to query for the plug-ins interest in the action.
    • Arguments:
      • ACTION_LOCATION location: The GUID identifier for the location where the action is being rendered (ACTION_LOCATION_ALL is a wildcard and currently the only supported location).
      • ACTION_ID action: The GUID for the action queried (e.g., ACTION_EMAIL_REPLY, ACTION_EMAIL_REPLY, ACTION_EMAIL_FORWARD).
      • BSTR query_string: The query string, if applicable and if allowed by the user's preferences. Note: we will not implement a preference to disallow this parameter in this iteration.
      • IUnknown * item: An interface to the item being rendered, most commonly a IGoogleDesktopNotifyEvent.
      • [in, out] BSTR * action_title: If the action is handled, this string will be displayed as the action title. On input this contains the default title for the current language.
      • [out] BSTR * action_cookie: A string which will be handed back to the object if the action is performed. This could be an item specific property (e.g., "uri", "cookie") or any string combination
      • [out] ActionHandling * handling: Specifies whether and how the action should be handled (e.g., ACTION_HANDLING_DEFAULT, ACTION_HANDLING_QUENCH, ACTION_HANDLING_OVERRIDE).
    • Returns:
      • S_OK in all cases.
      • An error return may result in the removal of the plug-in's registration for this action, or until GD is restarted.
  • HandleAction: Invoked when an action needs to be performed.
    • Arguments:
      • ACTION_LOCATION location: The identifier for the location where the action was rendered.
      • ACTION_ID action: The identifier for the action to perform.
      • BSTR query_string: The query string, if applicable and if allowed by the user's preferences.
      • IUnknown * item: An interface to the item who is rendered, most frequently this is IGoogleDesktopNotifyEvent. May be NULL in cases where it's not feasible to pass back the same instance as in QueryInterest.
      • BSTR action_cookie: The string cookie the plug-in provided in the call from QueryInterest.
    • Returns:
      • S_OK if successful.
      • Appropriate error on failure.
Action Code Template

The following template demonstrates how a component can implement the methods on the IGoogleDesktopCustomAction interface.

When QueryInterest is invoked for an email message the plug-in will override Forward and quench Reply.

  /// IGoogleDesktopCustomAction
  STDMETHOD(QueryInterest)( 
      /* [in] */ ACTION_LOCATION location,
      /* [in] */ ACTION_ID action,
      /* [in] */ BSTR query_string,
      /* [in] */ IUnknown *item,
      /* [out][in] */ BSTR *action_title,
      /* [out] */ BSTR *action_cookie,
      /* [out] */ ActionHandling *handling) {
      ATLASSERT(NULL != query_string);
      ATLASSERT(NULL != action_title && NULL != *action_title);
      ATLASSERT(NULL != action_cookie && NULL == *action_cookie);
      ATLASSERT(NULL != handling);
      
      /// Override Forward always, quench reply always
      if (IsEqualGUID(action, ACTION_EMAIL_FORWARD)) {
        CString title(L"Overridden Forward");
        CString cookie(L"Email Forward");
        
        ATLASSERT(NULL != item);
        
        title.SetSysString(action_title);
        *action_cookie = cookie.AllocSysString();

        *handling = ACTION_HANDLING_OVERRIDE;

      } else if (IsEqualGUID(action, ACTION_EMAIL_REPLY)) {
        *handling = ACTION_HANDLING_QUENCH;
      } else {
        /// unknown 
        ATLASSERT(false && "Unregistered action in QueryInterest");
        *handling = ACTION_HANDLING_DEFAULT;
      }

      return S_OK;
    }		
		

When HandleAction is invoked the plug-in will simply display a message box with the query and action strings.

  /// IGoogleDesktopCustomAction
  STDMETHOD(HandleAction)( 
    /* [in] */ ACTION_LOCATION location,
    /* [in] */ ACTION_ID action,
    /* [in] */ BSTR query_string,
    /* [in] */ IUnknown *item,
    /* [in] */ BSTR action_cookie) {
    /// Action processing displays a message box.
    CString str;
    
    str.Format(_T("Query: %ws, action: %ws"), query_string, action_cookie);
    MessageBox(NULL, str, _T("Action!"), MB_OK | MB_SERVICE_NOTIFICATION);

    return S_OK;
  }