Erstellen von ActiveX-Controls mit Visual Basic
Im folgenden wird anhand einer Beispielanwendung (ein leicht modifiziertes FlexGrid) gezeigt wie man ein ActiveX-Control erstellt.
1.Visual Basic starten
2. Bei New Project ActiveX-Control wählen
Für das Control soll eine Komponente namens MSFlexGrid
verwendet werden. Wenn diese schon auf der Komponentenleiste vorhanden ist (verweilt man einen Augenblick mit dem Mauszeigen über den Symbolen so bekommt man als Kurzinformation den jeweiligen Namen angezeigt) dann anklicken und auf dem Hauptformular den Bereich markieren den es einnehmen
soll.Falls es noch nicht vorhanden ist: Rechte Maustaste auf die Komponentenleiste -> Components.
In dem nun folgenden Dialog Microsoft FlexGrid Control wählen. Falls dies nicht angezeigt wird dann die Check Box "selected Items only" disablen.
Falls die Komponente auch jetzt nicht zu sehen ist mit browse nach der Datei
suchen (Msflxgrd.ocx).Das MSFlexGrid jetzt wie oben schon beschrieben auf dem Control einfügen.
Zunächst ist sinnvollerweise die Schnittstelle (d.h. die
Funktionen, Prozeduren, Events und Properties die für die übergeordnete
Komponente sichtbar ist) zu definieren. Dafür gibt es einen Wizard (ActiveX
Interface Control Wizard).
Um diesen aufzurufen (wie auch alle anderen Wizards) in der Menueleiste Add-Ins
Will man einen Wizard benutzen, der hier noch nicht aufgelistet ist dann auf Add In Manager klicken. In dem nun folgenden Dialog kann man einen Wizard zu den schon eingebundenen hinzuwählen. Hierfür muss man den entsprechenden Wizard auswählen und dann die Check-Box "Load/Unload" aktivieren. Will man den Wizard wieder deaktivieren so muss diese Checkbox deaktivieren werden. Mit der Check-Box "Load on StartUp" kann man festlegen, dass der Wizard bei jedem Start von Visual Basic geladen
wird.Startet man den ActiveX Interface Control Wizard so kann man
zunächst auswählen welche Standard-Funktionen und Properties in die Schnittstelle integriert werden sollen. Von dieser Auswahl soll nur in zwei
Fällen abgewichen werden:Clear links auswählen und ">" drücken
BackStyle rechts auswählen und "<" drücken
Mit Clear sollen alle Zelleninhalte gelöscht werden. MSFlexGrid hat keine Property Backstyle, deswegen soll diese hier entfallen.
Mit "next" gelangt man zum
nächsten Dialog bei dem man eigene Funktionen und Properties anlegen kann.
Dafür "new" klicken und den Namen angeben.Also z.B. "Clear" angeben, "Method" wählen und mit OK bestätigen. Die Eingaben können jederzeit mit edit verändert werden und mit delete wieder gelöscht werden.
Hier eine Übersicht über alle Funktionen/Properties, die definiert werden müssen:
Name | Typ |
---|---|
AdjustSize | Method |
GetValue | Method |
SetValue | Method |
SetColumnWidth | Method |
SetRowHeight | Method |
SetColumns | Method |
SetRows | Method |
CellSelect | Event |
Changed | Event |
Resize | Event |
Wählt man dann "next", so kann man nun zu jeder Funktion/Property/Event angeben auf welche Funktionen/Properties/Events sich
diese auswirken (bzw. bei Events von welchen anderen Events diese ausgelöst werden).Hierzu einige Beispiele:
1.Die Funktion "Clear" soll dem Benutzer ermöglichen
Zellinhalte des Grids zu löschen. Diese Funktionalität stellt das FlexGrid schon zur Verfügung die entsprechende Funktion beim FlexGrid heißt auch "Clear". Diese beiden Funktionen müssen jetzt also verbunden werden. In der linken Auswahlbox also "Clear" auswählen. Bei "maps to .. Control" den Namen der vorgefertigten FlexGrid Komponente auswählen und dann bei "member" die Funktion "Clear" (Memberfunktion von
FlexGrid) auswählen.
Nun wird also bei jedem Aufruf von <eigeneKomponente>.Clear
<FlexGrid>.Clear aufgerufen.2. Das Event "CellSelect" soll ausgelöst werden
wenn der Benutzer eine neue Zelle selektiert hat. Auch dazu gibt es bereits ein vorgegebenes Event des FlexGrids (SelChange). Das eigene Event "CellSelect" muss also nur noch verbunden werden mit dem schon vorhandenen. Man wähle also "CellSelect" in der linken Auswahlbox. Bei maps to Control gibt man auch hier den Namen des FlexGids an und bei
"member" "SelChange".3. Mit der Funktion "AdjustSize" sollen die Bezeichner
für alle Spalten und Zeilen neu gezeichnet werden. Eine solche Funktion ist bei dem vorgefertigten FlexGrid nicht vorhanden. Hier muss die entsprechende Funktionalität selbst ausprogrammiert werden. In einem solchen Fall lässt man
"maps to" frei.Auch bei den Standard-Properties muss die Verbindung explizit
angegeben werden (also durch "maps to" wie oben).
Einige Properties sind schon als Standard-Properties vorhanden z.B. "Refresh" diese müssen und können nicht neu definiert werden
("The member name you have created already exist").um die die einzelnen Schritte nachvollziehen zu können hier alle Angaben in der Übersicht:
eigene | Name | maps to Control | member |
---|---|---|---|
ja | AdjustSize | - | - |
nein | BackColor | MsFlexGrid1 | BackColor |
nein | BorderStyle | MsFlexGrid1 | BorderStyle |
ja | Changed | MsFlexGrid1 | SelChange |
nein | Clear | MsFlexGrid1 | Clear |
nein | Click | MsFlexGrid1 | Click |
nein | DblClick | MsFlexGrid1 | DblClick |
nein | Enabled | MsFlexGrid1 | Enabled |
nein | Font | MsFlexGrid1 | Font |
nein | ForeColor | MsFlexGrid1 | ForeColor |
ja | GetValue | - | - |
nein | KeyDown | MsFlexGrid1 | KeyDown |
nein | KeyPress | MsFlexGrid1 | KeyPress |
nein | KeyUp | MsFlexGrid1 | KeyUp |
nein | MouseDown | MsFlexGrid1 | MouseDown |
nein | MouseMove | MsFlexGrid1 | MouseMove |
nein | MouseUp | MsFlexGrid1 | MouseUp |
nein | Refresh | MsFlexGrid1 | Refresh |
nein | Resize | - | - |
ja | SetColumns | - | - |
ja | SetColumnWidth | - | - |
ja | SetRowHeight | - | - |
ja | SetRows | - | - |
ja | SetValue | - | - |
nein | Resize | - | - |
Klickt man nun auf next, so kann man zu den selbst
geschriebenen Funktionen und Events Parameter, Returnwerte und Defaultwerte angeben. "cellSelect" wird hier nicht aufgeführt, da dieses Event durch "maps to" bereits fest zu einem bestehenden Event zugeordnet
ist.Hier die dort einzutragenden Werte:
Name | ReturnType | Arguments |
---|---|---|
AdjustSize | Empty | - |
GetValue | Variant | key As String |
Resize | - | - |
SetCoulumns | Variant | columns As Integer |
SetColumnWidth | Variant | width As Integer |
SetRowHeight | Variant | height As Long |
SetRows | Variant | rows As Variant |
SetValue | Variant | value As String, key As String |
Nun wieder auf Next klicken. Man hat nun noch die Möglichkeit
sich einen Report anzeigen zu lassen. Dieser enthält allgemeine Anweisungen wie
man ein ActiveX-Control testet und debuggt.Die Mappings die man dem ActiveX Control Interface Wizard
angegeben hat finden sich im Quelltext nun wieder. Als Beispiel sei hier die
Clear Funktion gezeigt:'WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES!
'MappingInfo=MSFlexGrid1,MSFlexGrid1,-1,Clear
Public Sub Clear()
MSFlexGrid1.Clear
End Sub
Will man es also dabei belassen, dass die Clear Funktion hier
nur die Clear-Funkion des MsFlexGrids aufruft so ist hier nichts mehr zu verändern. Will man aber z.B., dass auch die Bezeichnungen der Spalten und
Zeilen neu gezeichnet werden, so kann man hier entsprechendes einfügen:'WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES!
'MappingInfo=MSFlexGrid1,MSFlexGrid1,-1,Clear
Public Sub Clear()
MSFlexGrid1.Clear
AdjustSize
End Sub
die Funktion AdjustSize ist dabei aber zur Zeit noch leer:
'WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES!
'MemberInfo=5
Public Sub AdjustSize()
End Sub
auch hier soll Funktionalität eingefügt werden:
Public Sub AdjustSize()
'passt die Zellgroesen neu an und zeichent die Beschriftungen neu
SetColumnWidth ((width - scrollBarBreite) / MSFlexGrid1.Cols)
SetRowHeight ((height - scrollBarHoehe) / MSFlexGrid1.rows)
ColumnLabels
RowLabels
End Sub
MSFlexGrid1 ist das MsFlexGrid. Cols gibt die Anzahl der
Spalten rows die Anzahl der Zeilen zurück. "scrollBarBreite" ist eine Konstante, die die Größe des sichtbaren Scrollbalkens berücksichtigt. SetColumnWidth, SetRowHeigth sind noch zu programmierende Schnittstellenfunktionen, die die Spaltenbreite und Zeilenhöhe setzten. "ColumnLabels" und "RowLabels" sind private (also nach außen nicht
sichtbare Funktionen).Hier der Quelltext für die beiden letztgenannten:
Private Sub RowLabels()
'schreibe in jede Zeile ihre Nummer (die Nummerierung beginnt mit 1)
MSFlexGrid1.Col = 0
For i = 1 To MSFlexGrid1.rows - 1
MSFlexGrid1.Row = i
MSFlexGrid1.Text = i
Next
End Sub
Private Sub ColumnLabels()
'schreibe in jede Spalte ihren Bezeichner
MSFlexGrid1.Row = 0
For i = 1 To MSFlexGrid1.Cols - 1
MSFlexGrid1.Col = i
MSFlexGrid1.Text = ConvertZahlToBuchstaben(i)
Next
End Sub
Mit MSFlexGrid1.Col setzt man die aktuelle Spalte, mit MSFlexGrid1.Row die aktuelle Zeile. Mit MSFlexGrid1.Text kann man in die dadurch
festgelegte Zelle einen Text schreiben....
3. Testen und Debugging
Um das ActiveX-Control zu testen benutzt man Übehrlicherweise
Programmgruppen. Diese ermöglichen es mehrere Projekte zusammenzufügen und damit ein Projekt (das Control) in ein anderes (z.B. eine StandardEXE oder auch
ein ActiveX-Control) einzufügen und damit zu testen.Theoretisch kann man auch ein Control Komplett kompilieren,
installieren und dann als *.ocx Datei in eine andere Anwendung einzubauen. Dieser Weg ist jedoch im Normalfall nicht zu empfehlen, da das komplette Kompilieren
und Installieren wesentlich mehr Zeit in Anspruch nimmt.
So erstellt man eine Programmgruppe:
- den Quelltexteditor für das Control schließen (mit dem "x" des zugehörigen Fensters)
- File -> addProject
- nun die Art der Anwendung wählen mit der man das Control testen will (vorzugsweise eine StandardEXE)
- das Control erscheint nun auf der Komponentenleiste. (Ist es grau schattiert so wurde der Quelltexteditor nicht richtig geschlossen)
- nun kann man das eigene Control wie jedes bestehende in das Formular einbinden.
Ist das eingefügte Control grau schattiert so deutet das
genauso wie oben für das Symbol in der Komponentenleiste darauf hin das der
Quelltexteditor für dieses noch offen ist.
Damit nun die neu hinzugefügte standardExe startet und nicht das Control
allein, wählt man das dazugehörige Projekt mit der linken Maustaste, betätigt
dann die rechte und wählt aus dem Kontextmenue "set as start up"
Will man nun Veränderungen an dem ActiveX-Control vornehmen,
so öffnet man wieder den zugehörigen Quelltexteditor (Doppelklick auf das
Formular in der Projektansicht) nimmt die Veränderungen vor und schließt den
Quelltexteditor wieder.
Eine wichtige Eigenschaft des Controls, sowie des zugehörigen
Projektes ist der Name. Diesen kann man in den zugehörigen Propertywindow sehen und verändern. Der Name ist wichtig, da die ProgID (also der Bezeichner der das Control in der Registry identifiziert) sich aus dem Namen des Projekts und dem Namen des zugehörigen Controls zusammensetzt. Ist also der Name des Projektes "ClassiX" und der des Controls "Grid" so ist die ProgID =
"ClassiX.Grid".In den ActiveX Control Testcontainer z.B.(der Teil des
Microsoft Visual Studio 6.0 ist) wird das Control über diesen Namen
geladen.Diesen Testcontainer startet man durch Start -> Programme
-> Microsoft Visual Studio 6.0 -> Microsoft Visual Studio 6.0 Tools ->
ActiveX Control Test ContainerDurch Edit -> Insert New Control kann man ein neues Control einbinden. Dafür muss das Control natürlich zunächst installiert sein. Siehe hierzu weiter unten im Kapitel Installation.
Beachte: Das Control kann in dem oben beschriebenen
Testcontainer ebenso wie in den ClassiX®-Testcontainer nur gestartet werden, wenn es nicht gleichzeitig in der VisualBasic Entwicklungsumgebung läuft. In dem Microsoft-Testcontainer lässt es sich zwar aufrufen, es werden aber keine
Events angezeigt.
4.Installation
Falls das Projekt noch nicht gespeichert wurde, so wird man
spätestens bei der Kompilation aufgefordert das Projekt zu speichern. Hierbei sollte man beachten, dass die ocx-Datei automatisch den gleichen Namen erhält wie die Datei unter der man das Projekt gespeichert hat. Hat man also das Projekt gespeichert unter Project1 (wie es Visual Basic als default vorgibt), so
heißt die ocx-Datei Project1.ocx.Das zu kompilierende Projekt markieren (falls eine
Programmgruppe erstellt wurde) und dann den "Package
and Deployment Wizard" aufrufen. Auch
dieser ist über AddIns (Menue) aufzurufen, bzw. falls er noch nicht eingebunden
ist von dort aus einzubinden (siehe oben bei "ActiveX
Interface Control Wizard").
In dem ersten Auswahlfenster ist die Art der Anwendung zu wählen. Will man ein übliches Setup Programm zur Installation erstellen so ist "Package"
zu wählen.Findet der Wizard eine schon bestehende Anwendung (*.ocx) so wird
nachgefragt ob diese verwendet werden soll oder ob eine neue erstellt werden soll. Hat man Veränderungen vorgenommen so sollen diese im Normalfall auch kompiliert werden, deshalb ist es hier fast immer sinnvoll "neu kompilieren" zu wählen. Beim ersten Erstellen ist aber keine alte ocx
Datei vorhanden, deswegen entfällt hier diese Nachfrage.
Im nächsten Fenster ist ein Script für den Kompiliervorgang zu wählen (siehe
in der Microsoft Dokumentation für Details).
Man wähle hier einfach das "Standard Setup Package 1". Ebenso auf der
nächsten Seite "Standard Setup Package" als Package Typ. In dem
Folgenden Fenster ist das Verzeichnis für die Setupdatei und die zugehörigen
Dateien anzugeben.
Im nächsten Schritt kann man auswählen welche Dateien mit ausgeliefert werden
sollen (die Vorauswahl ist hier zu empfehlen). Dann kann man wählen ob eine
große *.cab Datei erstellt werden soll oder mehrere kleine, wie der Titel der
Installation sein soll, in welcher Programmgruppe für die Komponente ein
Eintrag erstellt werden soll (wähle hier z.B.:
Für Details zum Installationsvorgang bitte die Onlinehilfe von Microsoft konsultieren.