Previous IDL Connectivity Bridges: Using ActiveX Controls in IDL Next

Example: Spreadsheet Control

This example uses an ActiveX control that displays a spreadsheet interface. The control, contained in the file msowc.dll, is installed along with a typical installation of Microsoft Office. If the control is not present on your system (you'll know the control is not present if the example code fails when trying to realize the widget hierarchy), the example will not run.

The spreadsheet control has the program ID:

OWC.Spreadsheet.9  

and the class ID:

{0002E510-0000-0000-C000-000000000046}  
  

 


Note
The spreadsheet control used in this example is included with older versions of Microsoft Office; it is discussed in Microsoft Knowledge Base Article 248822. Newer versions of Microsoft Office may include spreadsheet controls with updated program and class IDs.

Information about the spreadsheet control's properties and methods was gleaned from Microsoft Excel 97 Visual Basic Step by Step by Reed Jacobson (Microsoft Press, 1997) and by inspection of the control's interface using the OLE/COM Object Viewer application provided by Microsoft. It is beyond the scope of this manual to describe the spreadsheet control's interface in detail.


Example Code
The following section develops an IDL routine called ActiveXExcel that illustrates use of the spreadsheet ActiveX control within an IDL widget hierarchy. The complete .pro file is included in the examples\doc\bridges\COM subdirectory of the IDL distribution as ActiveXExcel.pro.

  1. Create a function that will retrieve data from cells selected in the spreadsheet control. The function takes two arguments: an object reference to the IDLcomActiveX object that instantiates the spreadsheet control, and a variable to contain the data from the selected cells.
  2. FUNCTION excel_getSelection, oExcel, aData  
    

     

  3. Retrieve an object that represents the selected cells. Note that when the ActiveX control returns this object, IDL automatically creates an IDLcomActiveX object that makes it accessible within IDL.
  4.    oExcel->GetProperty, SELECTION=oSel  
    

     

  5. Retrieve the total number of cells selected.
  6.    oSel->GetProperty, COUNT=nCells  
    

     

  7. If no cells are selected, destroy the selection object and return zero (the failure code).
  8.    IF (nCells LT 1) THEN BEGIN  
          OBJ_DESTROY, oSel  
          RETURN, 0  
       ENDIF  
    

     

  9. Retrieve objects that represent the dimensions of the selection.
  10.    oSel->GetProperty, COLUMNS=oCols, ROWS=oRows  
    

     

  11. Get the dimensions of the selection, then destroy the column and row objects.
  12.    oCols->GetProperty, COUNT=nCols  
       OBJ_DESTROY, oCols  
       oRows->GetProperty, COUNT=nRows  
       OBJ_DESTROY, oRows  
    

     

  13. Create a floating point array with the same dimensions as the selection.
  14.    aData = FLTARR(nCols, nRows, /NOZERO);  
    

     

  15. Iterate through the cells, doing the following:
    • Retrieve an object that represents the cell. Note that the numeric index of the FOR loop is passed to the GetProperty method as an argument.
    •  

    • Get the value contained in the cell.
    •  

    • Set the appropriate element of the aData array to the cell's value.
    •  

    • Destroy the object.
    •    FOR i=1, nCells DO BEGIN  
            oSel->GetProperty, ITEM=oItem, i  
            oItem->GetProperty, VALUE=vValue  
            aData[i-1] = vValue  
            OBJ_DESTROY, oItem  
         ENDFOR  
      

     

  16. Destroy the selection object.
  17.    OBJ_DESTROY, oSel  
    

     

  18. Return one (the success code) and end the function definition.
  19.    RETURN, 1  
      
    END  
    

     

  20. Next, create a procedure that sets the values of the cells in the spreadsheet. This procedure takes one argument: an object reference to the IDLcomActiveX object that instantiates the spreadsheet control.
  21. PRO excel_setData, oExcel  
    

     

  22. Define the size of the data array.
  23.    nX = 20  
    

     

  24. Get an object representing the active spreadsheet.
  25.    oExcel->GetProperty, ActiveSheet=oSheet  
    

     

  26. Get an object representing the cells in the spreadsheet.
  27.    oSheet->GetProperty, CELLS=oCells  
    

     

  28. Generate some data.
  29.    im = BESELJ(DIST(nX))  
    

     

  30. Iterate through the elements of the data array, doing the following:
    • Retrieve an object that represents the cell that corresponds to the data element. Note that the numeric indices of the FOR loops are passed to the GetProperty method as arguments.
    •  

    • Set the value of the cell.
    •  

    • Destroy the object.
    •    FOR i=0, nX-1 DO BEGIN  
            FOR j=0, nX-1 DO BEGIN  
               oCells->GetProperty, ITEM=oItem, i+1, j+1  
               oItem->SetProperty, VALUE=im(i,j)  
               OBJ_DESTROY, oItem  
            ENDFOR  
         ENDFOR  
      

     

  31. Destroy the spreadsheet and cell objects, and end the procedure.
  32.    OBJ_DESTROY, oSheet  
       OBJ_DESTROY, oCells  
      
    END  
    

     

  33. Next, create a procedure to handle events generated by the widget application.
  34. PRO ActiveXExcel_event, ev  
    

     

  35. The user value of the top-level base widget is set equal to a structure that contains the widget ID of the ActiveX widget. Retrieve the structure into the variable sState.
  36.    WIDGET_CONTROL, ev.TOP, GET_UVALUE=sState, /NO_COPY  
    

     

  37. Use the value of the DISPID field of the event structure to sort out "selection changing" events.
  38.   IF (ev.DISPID EQ 1513) THEN BEGIN  
    

     

  39. Place data from selected cells in variable aData, using the excel_getSelection function defined above. Check to make sure that the function returns a success value (one) before proceeding.
  40.     IF (excel_getSelection(sState.oExcel, aData) NE 0) THEN BEGIN  
    

     

  41. Get the dimensions of the aData variable.
  42.        szData = SIZE(aData)  
    

     

  43. If aData is two-dimensional, display a surface, otherwise, plot the data.
  44.        IF (szData[0] GT 1 AND szData[1] GT 1 AND szData[2] GT 1) $  
             THEN SURFACE, aData $  
           ELSE $  
             PLOT, aData  
        ENDIF  
      
      ENDIF  
      
    

     

  45. Reset the state variable sState and end the procedure.
  46.   WIDGET_CONTROL, ev.TOP, SET_UVALUE=sState, /NO_COPY  
      
    END  
    

     

  47. Create the main widget creation routine.
  48. PRO ActiveXExcel  
      
       !EXCEPT=0  ; Ignore floating-point underflow errors.  
    

     

  49. Create a top-level base widget.
  50.    wBase = WIDGET_BASE(COLUMN=1, $  
          TITLE="IDL ActiveX Spreadsheet Example")  
    

     

  51. Instantiate the ActiveX spreadsheet control in a widget.
  52.    wAx=WIDGET_ACTIVEX(wBase, $  
          '{0002E510-0000-0000-C000-000000000046}', $  
          SCR_XSIZE=600, SCR_YSIZE=400)  
    

     

  53. Realize the widget hierarchy.
  54.    WIDGET_CONTROL, wBase, /REALIZE  
    

     

  55. The value of an ActiveX widget is an object reference to the IDLcomActiveX object that encapsulates the ActiveX control. Retrieve the object reference in the variable oExcel.
  56.    WIDGET_CONTROL, wAx, GET_VALUE=oExcel  
    

     

  57. Turn off the TitleBar property on the spreadsheet control.
  58.    oExcel->SetProperty, DisplayTitleBar=0  
    

     

  59. Populate the spreadsheet control with data, using the excel_setData function defined above.
  60.    excel_setData, oExcel  
    

     

  61. Set the user value of the top-level base widget to an anonymous structure that contains the widget ID of the spreadsheet ActiveX widget.
  62.    WIDGET_CONTROL, wBase, SET_UVALUE={oExcel:oExcel}  
    

     

  63. Call XMANAGER to manage the widgets, and end the procedure.
  64.    XMANAGER,'ActiveXExcel', wBase, /NO_BLOCK  
    END  
    

Running the ActiveXExcel procedure display widgets that look like the following:

 

Figure 4-2: An IDL Widget Program Using an ActiveX Spreadsheet Control

Figure 4-2: An IDL Widget Program Using an ActiveX Spreadsheet Control

  IDL Online Help (March 06, 2007)