Lab 6: ActiveX Controls in InfoPath 2003

 

Microsoft Corporation

April 2004

Applies to:
    Microsoft® Office InfoPath™ 2003

Summary: Learn how to write a custom Microsoft ActiveX control that meets all requirements for use in InfoPath and learn how to deploy the control. Also, discover how to add the control to the InfoPath Controls task pane, and how to insert it into a form. (12 printed pages)

Contents

Prerequisites
Scenario
Lab Objective
Setup
Exercises
Conclusion

Download the odc_INF03_Labs.exe sample file.

Prerequisites

  • A basic understanding Microsoft® Visual C++®
  • A familiarity with the Microsoft® Visual Studio® .NET 2003 integrated development environment (IDE)

Scenario

At Contoso Corporation, sales representatives use a series of related InfoPath forms to collect sales information. Many of these forms include a text box that needs to be incremented by one each time a drug is sold. Currently, the text box needs to be updated by clicking into the text box and then typing a number. Sales representatives can save time if they simply clicked on the control to increment it.

As a form designer in the IT department, you can create a custom Microsoft ActiveX® control that would exhibit this custom behavior. Creating and distributing your own custom ActiveX control can save time and efforts for other form designers.

Lab Objective

In this lab, learn how to:

  • Create an Microsoft ActiveX control that can be used in InfoPath
  • Add the ActiveX control to the Controls task pane
  • Insert the ActiveX control into your form
  • Install and register the ActiveX controls on users' computers

Setup

Before beginning this lab, install Microsoft Visual Studio.NET 2003. In addition, you need to obtain a code signing certificate from a trusted certificate authority (CA).

Exercises

Exercise 1: Create an ActiveX Control

Contoso sales representatives have to keep track of the number of drugs sold. Updating a text box by typing can be cumbersome and prone to error, considering that sales representatives have to increment by one many times over. A custom control that self-increments on a mouse click cuts down on time spent and reduce errors.

To create an ActiveX control

  1. Open Microsoft Visual Studio .NET 2003.

  2. To create a project, from the File menu, click New, and then click Project. . ..

  3. After the dialog box appears, select a project type. Select Visual C++ Project as the project type, and ATL Project as the template. Type ActiveX for the name, and select a location to which to save the source.

  4. The ATL Project Wizard starts. Click the Application Settings link. A series of properties of new control are created. Uncheck the Attributed text box. Leave the rest of settings as they are.

    Note   InfoPath ActiveX controls can also be attributed ATL controls, but for this lab, we discuss a non-attributed control.

  5. Visual Studio has created an empty ATL project and we have to add empty ActiveX controls. Right-click the ActiveX project, click Add menu, and then click Add Class. . ..

    Click here for larger image.

    Figure 1. Adding class to project (Click picture to view larger image)

  6. An Add Class dialog box should appear. Click the ATL Control, and then click Open.

  7. The ATL Control Wizard generates the appropriate code for you. This helps to simplify your coding. In the first dialog box of the wizard, in the Short Name text box, type SampleControl. After typing the short name, the other text boxes should autopopulate. Do not leave the wizard yet. There are a few more options to change.

  8. Click Options. Select the Connection Points check box.

  9. Click Interfaces. In the Not Supported list box, double-click the IPropertyNotifySink list item. This moves the interface over to the Supported list box. The IPropertyNotifySink interface is important because this is the method the ActiveX control uses to notify that InfoPath needs to get a new value from the control.

  10. Click Stock Properties. In the Not Supported list box, double-click the Enabled list item. This moves this property to the Supported list box. The Enabled property is necessary for InfoPath to disable this ActiveX control (when necessary, conditional formatting, after form has been digitally signed, and so on).

  11. Click Finish.

ActiveX controls that are used in InfoPath have restrictions that are stricter than ActiveX controls used in Microsoft Internet Explorer. For example, InfoPath requires that ActiveX controls be marked as both safe for scripting and safe for initialization. If you write custom ActiveX controls for use in forms, you must implement the IObjectSafety interface so that InfoPath recognizes that a particular control is marked safe for scripting and safe for initialization.

To mark the control as safe for scripting and initialization using the IObjectSafety interface

  1. Open the SampleControl.h file from the Header Files folder in the Solution Explorer.

  2. At the beginning of the class definition, find for the line that reads:

    class ATL_NO_VTABLE CSampleControl
    

    Then place this line after the colon(:) with the list of other interfaces. This should be around line 12.

    public IObjectSafetyImpl<CSampleControl, 
        INTERFACESAFE_FOR_UNTRUSTED_DATA | 
        INTERFACESAFE_FOR_UNTRUSTED_CALLER>,
    
  3. Place this line in the COM Interface Map:

    COM_INTERFACE_ENTRY(IObjectSafety)
    
  4. There is no need to write any code for the IObjectSafety interface because the steps that were completed use the stub implementation.

InfoPath interacts with ActiveX controls in a form through the use of binding and enabled properties. InfoPath uses the binding property to store and retrieve data, and the enabled property to either enable or disable a control.

To specify properties for an ActiveX control

  1. Switch the Solution Explorer to Class View using the tabs in the bottom of the docked window. You can also switch to Class View from the View menu.

  2. Right-click the ISampleControl. From the Add menu, click Add Property. . ..

  3. When the project was created, we added the Enabled stock property so that we only need a binding property. Since our control just outputs numbers, set the Property Type to LONG and the Property Name to Value.

    **Note   **You don't have to name the property Value, but it is helpful to do so because InfoPath automatically recognizes properties with this name as the binding property for the ActiveX control.

  4. Click Finish.

To add functionality to the control

At this point, the control does not do anything functionally useful. Here we add the functionality to the control and give it some rendering functionality, as well as the ability to react to user clicks.

  1. We need to keep track of the current count. We begin by creating a variable which stores the running total. Locate the class definition (in the SampleControl.h file) and after the opening curly brace({) and the public declaration, add:

    long m_nCurrentValue;
    
  2. Also, we should initialize it to zero, so within the class constructor, add:

    m_nCurrentValue=0;
    
  3. Locate the OnDraw method in the SampleControl.h file. There are two lines which create the pszText variable, followed by a TextOut method call. Replace those two lines with these lines:

    WCHAR    *pwszDisplayString = new WCHAR[MAX_CONTROL_TEXT];
            wsprintfW(pwszDisplayString,L"Value: %d",m_nCurrentValue);
            TextOutW(di.hdcDraw, 
                (rc.left + rc.right) / 2, 
                ((rc.top + rc.bottom) / 2), 
                pwszDisplayString, 
                lstrlenW(pwszDisplayString));    
            delete[MAX_CONTROL_TEXT] pwszDisplayString;
    

    The preceding lines make the control draw the current value of the control, instead of drawing the static string "ATL Control 7.0".

  4. The drawing code refers to a MAX_CONTROL_TEXT constant, which we should specify at the beginning of the code (just after the includes) in SampleControl.h:

    const int MAX_CONTROL_TEXT = 100;    
    
  5. In the Properties docked window, change the property grid to show the windows messages.

    Figure 2. Changing the property grid to show the windows messages

  6. Select the WM_RBUTTONUP item and click the drop-down. Select the <Add> OnRButtonUp option.

  7. Repeat for WM_LBUTTONUP.

  8. Now that the stubs for these two methods are created, the code needs to be written to handle clicks, and increment or decrement the current count:

    LRESULT CSampleControl::OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, 
        LPARAM /*lParam*/, BOOL& /*bHandled*/)
    {
            m_nCurrentValue++;
            FireViewChange();
            FireOnChanged(1);
    
            return 0;
    }
    
    LRESULT CSampleControl::OnRButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, 
        LPARAM /*lParam*/, BOOL& /*bHandled*/)
    {
            m_nCurrentValue--;
            FireViewChange();
            FireOnChanged(1);
    
            return 0;
    }
    
  9. Finally, we need to expose the m_nCurrentValue variable to the Value property. This can be accomplished by writing get_Value and put_Value as follows:

    STDMETHODIMP CSampleControl::get_Value(LONG* pVal)
    {
        *pVal = m_nCurrentValue;
    
        return S_OK;
    }
    
    STDMETHODIMP CSampleControl::put_Value(LONG newVal)
    {
        m_nCurrentValue = newVal;
    
        return S_OK;
    }
    

To compile the ActiveX control

  • On the Build menu, click Build Solution. . ..

Exercise 2: Making ActiveX Controls Available to Users

If you use a custom ActiveX control in a form, you must ensure that the control is installed and registered on users' computers. If you do not do this, users will not be able to open the form. You can use InfoPath to package an installation .cab file with your form template. This .cab file installs the ActiveX control (with the user's permission) and registers it for use. The following exercise shows you how to create this file.

To obtain the necessary command line tools

Certain command line tools are necessary for signing the package file. If you do not have the following files, you can download them from the Web. The following tools are included with the Internet Development Software Development Kit (SDK) and the .NET Framework SDK. If you already have these SDKs installed on your computer, then there is no need to download anything extra.

To obtain a test certificate

If you do not have a code signing certificate from a certificate authority, you need to get a test certificate.

  1. Open a command prompt window.
  2. The makecert.exe command line tool can generate a test certificate for testing purposes. At the command prompt, type makecert newCert.cer –sv privatekey.pvk.
  3. When prompted for password, click None.
  4. Because this certificate is only good for testing, your computer does not have the necessary certificate authority (CA) certificate root on your computer. To turn this on, at the command prompt, type setreg 1 true.

Now that you have a certificate installed on your computer, you need to prepare it for signing.

To prepare your certificate for signing

If your certificate file is a .cer file, you need to generate a .spc file (if you obtained the certificate as described above, you have a newCert.cer file).

  1. Open a command prompt window.
  2. An .spc file can be created by running the cert2spc.exe command line tool on your .cer file. At the command prompt, type Cert2Spc newCert.cer output.spc.

You are ready to sign the ActiveX control.

To create a distributable CAB file and digitally signing the CAB file

  1. In your existing Visual Studio solution, add a Setup project. From the File menu, point to New, then Project. . ..

  2. Name your project Cab1.

  3. Click Add to Solution.

  4. For the Project Types, select Setup and Deployment Projects. For the Template, select Cab Project. Click OK.

  5. In Solution Explorer, right-click your cab project (this should be a node at the bottom of the Solution Explorer), and then follow the Add menu to the Project Output menu item.

    Click here for larger image.

    Figure 3. Project Output menu item (Click picture to view larger image)

  6. Select the Primary Output, and click OK.

  7. Right-click the setup project and click Properties to open the properties of the setup project.

  8. Check Authenticode signing.

  9. To populate the Certificate File, click Browse and select the .spc file that you created.

  10. To populate Private Key File, click Browse and select the .pvk file that you created.

  11. The timestamp server URL is optional, but if you have an internet connection, you should specify this URL: http://timestamp.verisign.com/scripts/timstamp.dll.

  12. Click OK to close the properties.

  13. On the Build menu, click Rebuild Solution.

Exercise 3: Add ActiveX Control to InfoPath

Now that the ActiveX control is complete and you have packaged it, it is ready to be used in InfoPath. In the following exercise, you learn how to add the control to the Controls task pane.

To add the ActiveX control to the Controls task pane

  1. Create a blank form.

  2. From the Insert menu, click More Controls.

  3. At the bottom of the Controls task pane, click Add or Remove Custom Controls.

  4. In the Add or Remove Custom Controls dialog box, click Add.

  5. On the first page of the Add Custom Control Wizard, from the Select a control list, click the ActiveX control that you created (SampleControl Class), and then click Next.

  6. On the next page of the wizard, leave Don't include a .cab file selected. If you want to deploy the form to other users, use the setup cab that you created earlier.

  7. To continue, click Next.

  8. In the Binding property list on the next page of the wizard, click the Value property. The ActiveX uses this binding property to receive and store XML data.

  9. Click Next.

  10. In the Enable or Disable property list on the next page of the wizard, click Enabled, and then make sure that the value is set to true. This step is necessary for InfoPath forms that use digital signatures or conditional formatting.

  11. Click Next.

  12. You must now specify binding options for the ActiveX control. Although there are three types of binding options, for the purposes of this lab, you bind the control to a field with a simple data type. This data type is appropriate when the ActiveX control interacts with single values. By default, Text (string) is selected in the Select one or more data types list, and it also appears as the default data type. Change both to Whole Number (integer), because your control outputs numbers. InfoPath uses the default data type when you insert the ActiveX control into your form from the Controls task pane.

    Click here for larger image.

    Figure 4. Add Custom Controls Wizard (Click picture to view larger image)

Now that you have added the ActiveX control to the Controls task pane, you can add it to your form.

To add the ActiveX control to your form

  1. Drag and drop the newly-added control onto the form.
  2. Save the form and open it in the editor.
  3. Your ActiveX control now appears in your InfoPath form. You can click it with the left mouse button, which increments the value in the box, or with the right mouse button, which decrements the value.

Conclusion

In these exercises, you learned how to write a custom ActiveX control that meets all requirements for use in InfoPath. You also learned how to deploy the control to users' computers, how to add the control to the InfoPath Controls task pane, and how to insert it into the form.