The Customer + .NET GridView User Control sample shows a Windows Forms user control wrapped as an ActiveX control. Since Dialog System can host ActiveX controls, the new Windows Forms user control is built to be exposed as an ActiveX control. The sample shows how a user control can be hosted, how it can have methods invoked and how it can fire events, which can be consumed in the Dialog System application.
The sample is based on the original CustGrid sample from Dialog System. It has two projects: one is the original CustGrid sample and the second contains the code for a simple Windows Forms DataGridView user control written in COBOL. The DataGridView control is similar to the one used in the Customer samples (Customer +.NET WPF User Control and Customer + WinForm). Here, in this sample, the DataGridView is a .NET user control instead of a WPF user control or a control contained in Windows Forms.
The following diagram shows the native code on the left, with Dialog System handling the screenset. The managed code is on the right, with the Windows Forms user control wrapped as an ActiveX. The image also shows the native code interfacing with a COM Callable Wrapper (CCW) containing the managed code.
In this sample, the control is not a complete implementation of a grid control and the application is not a complete implementation. The sample is designed to illustrate the principles only.
The CustGrid project contains the original CustGrid project from Dialog System and contains:
INVOKE RowSet "GetSelect" USING theRow RETURNING Numeric-Value INVOKE RowSet "Remove" USING Numeric-Value
Where RowSet is defined in the COM interface for the Windows Forms user control. See the ControlInterface.cbl section, later in this topic.
The GridViewUserControl project is registered for COM interop. In addition, the COMRegister() method puts the appropriate entries into the registry so that ActiveX containers see this as a control. This is covered in more detail later.
The managed COBOL grid user control is exposed to COM by declaring a class interface, an events interface, and the class itself, as follows:
The project contains other classes to complete the implementation:
ControlInterface.cbl defines the interface that exposes the methods and properties of the control to COM:
interface-id MicroFocus.VisualCOBOL.ISampleGridView attribute Guid("5A0AED5B-7D47-48C9-9F95-DEE8BC2D4807"). method-id get property RowSet. ...
GridViewControl.cbl contains the class that defines the behavior of the DataGridView control. Its main task is to replicate the behavior of the old ActiveX control in the new DataGridView control.
GridViewControl.cbl includes the following code that is of interest:
Define the SampleGridView class, which inherits from the Windows Forms UserControl class and implements the ISampleGridView interface declared in ControlInterface.cbl. It also implements the ISerializable interface, which enables the class to control its serialization behavior:
Class-id SampleGridView inherits type System.Windows.Forms.UserControl implements type System.Runtime.Serialization.ISerializable type MicroFocus.VisualCOBOL.ISampleGridView
Enable the class to be serialized. This attribute is required even though the class also implements the ISerializable interface to control the serialization process:
Make the managed class visible to COM. In other words, exposes the class to COM:
Specify the ProgID for the COM object. This is a human-readable version of the class identifier (CLSID) used to identify COM/ActiveX objects:
attribute ProgId ("MicroFocus.VisualCOBOL.SampleGridView")
Generate a class interface that supports early and late binding:
attribute ClassInterface (type ClassInterfaceType::AutoDual)
Specify the interface ISampleGridView as the default interface to expose to COM:
attribute ComDefaultInterface (type of MicroFocus.VisualCOBOL.ISampleGridView)
Identify the IGridViewEvents as the interface to be exposed as COM event sources for the library WindowsFormsControlLibrary1.dll (which is built by the GridViewUserControl project):
attribute ComSourceInterfaces (type of GridViewUserControl.IGridViewEvents)
Specify an explicit GUID. This is useful during the debugging phase, as it avoids a new GUID being generated each time you build and register:
Adds an entry to the Registry for the specified object. It sets the appropriate entries to register the object as an ActiveX, so that ActiveX containers see this as a control. This enables Dialog System to list the ActiveX as one of the controls available for import.
The project property Register for COM Interop registers the object as COM, but does not register it as ActiveX.
Removes the entry for the specified object from the Registry.
Create an instance of the SampleGridView.
This is used as part of serialization of the control. However, this sample does not have anything to persist so this method is unused.
Implements the interface ISampleGridView. Creates an instance of the row.
This enables the Windows Forms user control to access the DataGridView user control.
01 OrdersGridView type System.Windows.Forms.DataGridView. method-id. get property OrderGrid. procedure division returning thegrid as type DataGridView. set thegrid to self::OrdersGridView goback. end method.
Handles the cell editing event and invokes FireOnChanged().
method-id OrdersGridView_CellEndEdit final private. procedure division using by value sender as object e as type System.Windows.Forms.DataGridViewCellEventArgs. invoke self::FireOnChanged (e::RowIndex, e::ColumnIndex)
Defines the delegates for our events.
01 OnRowSelected type RowSelectedEventHandler event public. 01 OnRowDeleted type RowDeletedEventHandler event public. 01 OnChanged type RowChangedEventHandler event public. ... delegate-id RowSelectedEventHandler. delegate-id RowDeletedEventHandler. delegate-id RowChangedEventHandler.
GridViewEvents.cbl defines an interface for the events and assigns each event a COM dispatch identifier (DispId), as follows:
method-id OnRowSelected attribute DispId(29). procedure division using by value row as binary-long, coln as binary-long. ... method-id OnRowDeleted attribute DispId(18). method-id OnChanged attribute DispId(6).
The events correspond to the delegates defined in the SampleGridView class in GridViewControl.cbl.
Note, this interface is not implemented in our solution.