This article describes the techniques and code used during my presentations at the Carolina Code Camp 2012 and at the May 2012 meeting of the North Carolina PowerBuilder User Group.
The techniques described here utilize Visual Basic .Net (coded in Visual Studio 2010) with the Interop Forms Toolkit available from Microsoft. The Interop Forms Toolkit was originally intended as a ‘bridge’ between the VB 6 world and VB .Net. It allows you to host any .Net control in any Win32 application that supports COM. The current version supports Visual Studio 2005, 2008, and 2010.
In this example we are creating a horizontal track bar control to use in a PB application (PB12.5). Why not use the PB control you say? Well, we want one which allows us to control the background color.
First create a project in Visual Studio and under ‘Visual Basic’ – ‘Windows’ choose the VB6 Interop UserControl. Give the control a meaningful name at the bottom, I picked ‘vb_trackbar’.
In the Solution Explorer you should see a number of components which are automatically created. Almost all the work is done in the ‘InterobUserControl.vb’ element
Double click on the ‘InteropUserControl.vb’ element to bring it up in design mode so the actual control can be built.
Choose a Trackbar from the tools window in Visual Studio
and drop it on the usercontrol. Rearrange its size and position as appropriate
Now choose a Label and drop it on the control.
Change the backcolor of the trackbar to yellow; the name to TB; the Margin to 0,0,0,0; the Maximum to 100; the TickFrequency to 10; and the TickStyle to Both.
Modify the background color of the label and the usercontrol itself to yellow. Rename the control to ‘IOP_Trackbar’, the label to ‘LB_Value’, and give the label a border.
Right click on the ‘InteropUserControl.vb’ element from the Project window and choose ‘View Code’
You will see code like this (this is from Visual Studio 2010).
Here is the code to add.
Public Event tbScroll()
Public Event tbValuechanged()
Private Sub TB_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TB.Scroll
LB_Value.Text = TB.Value.ToString()
Private Sub TB_Valuechanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TB.ValueChanged
Public Sub tbSetBackColor(ByVal testval As Integer)
Dim myColor As Color = ColorTranslator.FromWin32(testval)
TB.BackColor = myColor LB_Value.BackColor = myColor BackColor = myColor End Sub
Public Shadows Property TBBackgroundColor() As Integer
Set(ByVal value As Integer)
TB.BackColor = ActiveXControlHelpers.GetColorFromOleColor(value)
Public Shadows Property TBValue() As Integer
Set(ByVal value As Integer)
TB.Value = value
In the first portion there are two events we want to expose to PowerBuilder so we can write code in our PB app to respond to the control. These are ‘tbScroll’ and ‘tbValuechanged’. One is triggered in response to the Scroll event on the trackbar (which we named ‘TB’) and the other by the Valuechanged event. In the tbScroll event we are setting the Text in the label (we called it ‘LB_Value’) on the userobject to the Value property of the Trackbar.
We also are creating a method, tbSetBackColor, which can be called from our PB app to set the background colors of the userobject, trackbar, and label.
Finally we are exposing two properties of the Trackbar so we can either set or get them from our PB app. These are called ‘TBBackgroundColor’ and ‘TBValue’.
The last thing we need to do in Visual Studio is to add an Interface to the project so the events we are exposing can be seen from within PowerBuilder. From the Project menu choose ‘Add New Item’.
Then under the ‘Common Items’ choose ‘Interface’
In the code for the interface, replace it with the following.
Public Interface iIOP_Trackbar
The first thing to do now is to replace the example GUID with one of your own (Visual Studio can generate one). Also give the Interface a more meaningful name – ‘iIOP_Trackbar’ in this example. Within the interface definition are the two events which will be visible from within PowerBuilder.
With this done you can now build the solution from the ‘Build’ menu
This will create and register the dll on the machine.
Now in PowerBuilder the control will be available when you choose to add an userobject.
The events are visible in Powerscript.
Now in the tbscroll event on our ole control we put the following.
ll_val = ole_1.object.event tbvalue()
htb_1.position = ll_val
st_1.text = string(ll_val)
Code in the tbvaluechanged event on the ole control
sle_2.text = 'tbvaluechanged at ' + string(Now(),'hh:mm:ss')
Code to set the color of the ole control.
IF sle_1.text = string(RGB(0,174,221)) THEN
ll_color = 15780518
ll_color = RGB(0,174,221)
sle_1.text = string(ole_1.object.tbbackgroundcolor())
Running the application gives the following
See the original control background color. Clicking the Set Color button gives this
Moving the trackbar ole control results in this.
There are a couple of things to look out for when using the techniques described here. The first is that any events exposed via the .Net Interface must have some sort of Powerscript in them within PB. Failure to do this results in an ‘unhandled exception’ application crash. There may be some way to prevent this from within Visual Basic but I am not sure.
The other issue is that if you have to change your VB.Net component you must re add it to your window/form within PowerBuilder. Usually I will add a second ole object to the existing window, transfer all the code from the old ole control, delete the original control, and finally rename the new control to that of the old control. This is the biggest issue I have with working with ‘roll your own’ ole controls. If anyone knows of a work around for this I would like to hear it.
Visual studio and PB files can be downloaded from here.
The video presentation of this is on YouTube.