PowerBuilder – Using .Net Visual Controls in PB Classic Applications

Posted on Tuesday, June 5th, 2012 at 5:27 pm in

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.

   'Please enter any new code here, below the Interop code

    ' event to show in PB
    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()
        RaiseEvent tbScroll()
    End Sub
    Private Sub TB_Valuechanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TB.ValueChanged
        RaiseEvent tbValuechanged()
    End Sub

    ' method to call from PB
    Public Sub tbSetBackColor(ByVal testval As Integer)
        Dim myColor As Color = ColorTranslator.FromWin32(testval)

        TB.BackColor = myColor ' set color on trackbar
        LB_Value.BackColor = myColor ' set color on label
        BackColor = myColor ' set color on interop control
    End Sub
    ' Property get/set
    Public Shadows Property TBBackgroundColor() As Integer
            Return ActiveXControlHelpers.GetOleColorFromColor(TB.BackColor)
        End Get
        Set(ByVal value As Integer)
            TB.BackColor = ActiveXControlHelpers.GetColorFromOleColor(value)
        End Set
    End Property
    ' this is the value of the trackbar
    Public Shadows Property TBValue() As Integer
            Return TB.Value
        End Get
        Set(ByVal value As Integer)
            TB.Value = value
        End Set
    End Property

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.

<guid("ca16a9e8-02c7-43d2-90f6-4ef30885a338"), _="" interfacetype(cominterfacetype.interfaceisidispatch)=""> _
Public Interface iIOP_Trackbar
    <dispid(1)> _
    Sub tbScroll()
    <dispid(2)> _
    Sub tbValuechanged()
End Interface</dispid(2)></dispid(1)></guid("ca16a9e8-02c7-43d2-90f6-4ef30885a338"),>

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.

long ll_val
//report on the current value of the control
//this uses the 'getter' method to return the track bar value from the .net control
ll_val = ole_1.object.event tbvalue()
//move the PB control
htb_1.position = ll_val
// show value
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.

long ll_color

// set the desired color on the control
IF sle_1.text = string(RGB(0,174,221)) THEN
	ll_color = 15780518
	ll_color = RGB(0,174,221)
// call method on .Net control to set the background colors
ole_1.object.event tbsetbackcolor(ll_color)
// get the color value using the 'getter' method in .Net class
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.

You might also be interested in