About 6 months back I wrote a weblog on how to integrate Windows .Net Controls with the ABAP Control Framework. Given the age of this technology I was a little surprised at how many interested responses I got to this weblog. Many people wanted to know how to do this same thing in classic VB as opposed to .Net. So for a while I have been planning to write a weblog on how to do this. So in my attempt to get caught up on my weblog backlog, I sat down to write this one.
I want to show how to integrate any ActiveX control with the ABAP control framework. This activeX control might have been written in Classic VB, C++, or any of the .Net CLR Languages. To demonstrate the flexibility of the control framework, I will use a delivered Microsoft ActiveX control as the example. I will show you how to write an ABAP control framework program that will work with the Windows Media Player control.
The Example Program
I wanted to use the Microsoft Windows Media Player Control. So I decided to write an MP3/WMA player in ABAP. Now I can listen to my music while I program! The following is a screen shot:
This application will keep a list of Music files stored on my local drive. I thought about actually uploading the files to the SAP system database, but I thought somebody might notice an overnight 20Gig growth in the database. The playlist however is stored in SAP and controlled via ABAP. When the end of a song is reached, the Media Player control will raise an event. That event will be trapped and processed in ABAP. ABAP is then responsible for choosing the next song and sending the command to the Media Player to start it.
The following is a diagram that shows how the ActiveX control communicates through the SAPGui to the ABAP OO Proxy class.
Let’s talk about what we see in this diagram. On the top we have the scope of the client (SAPGui). The bottom part of the diagram has everything that takes place on the Application Server. Our ActiveX Control will be hosted by an OLE Controller in the SAPGui. The Automation Contoller is piece of functionality built by SAP in the SAPGui. It is responsible for the lifetime of the ActiveX control. It also traps all the events raised by the ActiveX control and communicates them through the Automation Queue. There is an Automation Queue on both the Client and the Server. Since there could be a considerable lag between the Client and the Server it doesn’t make sense to create a complete round trip every time an event is raised. Therefore all events are queued on both sides until the most efficient time to communicate them.
Now back on the Server Side we have the ABAP Control Framework. This set of classes (CL_CFW) provide the low level interface between ABAP and the Frontend. They handle all the dirty work of the OLE Automation. All we are left to write is ABAP proxy class for the ActiveX control itself. This proxy class will contain the methods and events from the ActiveX control that we want to have access to in ABAP as well. It is this proxy class that will in turn interact with the ABAP Control Framework Classes.
Understanding the ActiveX Control
First of all before we can start programming from ABAP, we need to have a good understanding of how our ActiveX control is structured. We need to know what events and methods are available. Since this ActiveX control was created by a Third Party, we may not always have easy access to this information or any documentation about the control. Therefore I like to use the Visual Basic Object Browser to have my first look.
Now as you will see later, knowing the methods and events isn’t going to be enough. We are going to have to know the Hex Codes for the event Ids. The best way I have found to get these is to use the Microsoft OLE/COM Object Viewer.
To do I right mouse click on the object in question and choose View Type Information.
Then the ITypeLib Viewer opens in another window. I change my view in this tool to Group by Type Kind. I then open the Dispinterfaces node. Inside here I find the dispinterface _MediaPlayerEvents. This will list all the events, their parameters, and their event IDs. As you can see in this screen shot, the EndOfSteam event has the ID 0x00000bba.
Now I know that everyone can convert HEX to Integer in their head right? If not, the following is a little bit of ABAP code that I keep around to do the job for me. You should see tht 00000bba is integer 3002
So far we have access to the key pieces of information we will need. We have the names of the methods. We also have the ActiveX control’s ClassID/ProgramID: MediaPlayer.MediaPlayer.1. Finally we have the event Ids we will need: ENDOFSTREAM – 3002. We are ready to start programming from the ABAP side of the world now.
ABAP Proxy Class
From the ABAP side we will need to create our Proxy Class to expose our ActiveX control. We will start by creating a class that inherits from the SAP Control Framework class CL_GUI_CONTROL. We will also need to enter CNTL as a forward declaration.
Next we will create attributes matching up to the properties we saw in the ActiveX control. We can use these local attributes as a cache for the ActiveX control properties. ABAP programs can query these attributes instead of always making a round trip to the frontend. It is also helpful to create constants to match up to the ones declared in the ActiveX Control. This makes programming much simpler.
Now we come to the constructor of the Proxy Class. It is in this area that we make the connection to the control framework. We also instantiate the ActiveX control on the Front-End. The Windows Media Player is only available as an ActiveX control. Therefore if the Control Framework says that we are running in the Java SAPGui (not javabean is initial), we just raise a GUI_TYPE_NOT_SUPPORTED exception.
We will have several different types of methods in the proxy class. First up we need methods that can set properties in the ActiveX control. Most of the functionality is provided by the Control Framework itself.
Now we have the corresponding method that can get properties.
Call methods is just about as simple as working with properties. There are a set number of parameters that can be passed to the Call Method Proxy. You must specify in the p_count method how many proxy parameters you will be using.
Now we come to the subject of events. The first thing we need to code is a method in our proxy class that can allow our programs to set the registered events that we want to respond to. The following is the code to do that. Please note that set_registered_events is an inherited method that must be redefined.
Now we need a method that the Control Framework can call any time that it receives events from the Front-End. This method will be responsible for requesting any parameters that go along with this event. It then can dispatch this event to the proxy events. This is a redefinition of an inherited method.
Now we have a proxy class ready to use in any ABAP Program. This class can be worked with like any other Enjoy Control Class (ALV Grid, Tree Control, etc). The following is my MP3 player program that uses this class.
Of special note in the program is the example of how the automation queue works. Have a look at the following block of code:
As you can see here, we are creating several requests to the front-end control. It would be inefficient to make several round trips. Therefore on the ABAP Application Server all of these request are really only added to the Automation Queue. It is only when you issue the control framework flush, that these requests are sent to the front-end. They are all processed there completely before control returns from the front-end to the application server. Only then will the variables author and title be filled.
I hope that my little MP3 player shows you the power of what can be done with ABAP and the Control Framework. In the past few years, SAP’s focus has shifted away from the SAPGui (Fat Client) to the more socially acceptable Web Based Clients. However in many situations, the Fat Client still has advantages and capabilities that its thiner relative does not.