Tech Note 02b: Handling ActiveX events on multiple forms

February 22, 2005

© NSB Corporation. All rights reserved.

This Tech Note applies to versions of NS Basic/CE before 5.1. The problem was fixed in that release. The simplest way to get around this is to get the new version.

If you have a project with more than one form and you place an ActiveX control on other than the first form, events from that control will not be picked up in your code. In this document, we'll show you how to work around this.

This note applies to all versions of NS Basic/CE, from 1.0 to the current. It does not affect the intrinsic controls which are built into NS Basic/CE.

More detail on what is happening:

Here is the simplest program thats exhibits this behavior:

AddObject "GridCtrl.GridCtrl", "Grid1", 10, 30, 190, 64 
AddObject "CommandButton", "CommandButton1", 0, 0, 108, 21 
CommandButton1.Caption = "Show Grid2"
'CommandButton1_Click 'uncomment this and it works OK

Sub CommandButton1_Click
   AddObject "GridCtrl.GridCtrl", "Grid2", 10, 170, 190, 64
End Sub

Sub grid1_click
    MsgBox "Grid 1 clicked!"
End Sub

Sub grid2_click
    MsgBox "Grid 2 clicked!"
End Sub

This sample has two grids. One is created immediately; the other is created as the result of a button being clicked. Events from Grid1 are picked up, but not Grid2.

To confirm that this is the problem, uncomment the 4th statement. Grid2 will now be created at program startup and work properly.

How to work around:

ActiveX controls which need to respond to events need to be created at startup. There are a couple of problems that need to be worked around as a result: the control may show, even when it is not yet wanted, and getting this to work with the standard Forms code that NS Basic/CE generates. It's easy to work around both situations.

1. Hiding an ActiveX control until it is needed

Many ActiveX controls do not have a hide/show property to allow you to hide the control until it is needed. You can get around this by placing the ActiveX control onto a standard Frame object, then hiding and showing the frame.

Here is a sample:

AddObject "Frame","Frame2",10,10,20,20
AddObject "GridCtrl.GridCtrl","Grid2", 0,0,20,20,Frame2
Grid2 is created as a child of Frame2. Doing Frame1.hide will hide the grid.

2. Working with NS Basic/CE Forms

If you save a project you have created with NS Basic/CE as a .txt file and opened it in Notepad, you'll see that a section of code starting with "*** Begin Generated Code ***" has been added to the end of your program. This handles the creating, showing and hiding of objects and forms.

You'll notice that the same thing is happening as in our first sample. The objects on the second form are only created when you tap a button to go to the second form. The ActiveX objects on the second form will not send events to your program since they were not created during the original startup.

To remedy this, use the same code as above, plus a bit more:

AddObject "Frame","Frame2",10,10,20,20
AddObject "GridCtrl.GridCtrl","Grid2", 0,0,20,20,Frame2

Sub Form2_Load
    SetParent frame2,form2_form
End Sub
The Form2_Load subroutine is called after Form2 is created. The SetParent call places our Frame2 object onto Form2. Now, when Form2 is hidden and shown, our grid object will also be hidden and show.