Die Community zu .NET und Classic VB.
Menü

Cairo-Fenster mit vbRichClient erzeugen

 von 

Am Anfang war das Fenster 

Alle mir bekannten Visual Basic Versionen starten ein neues Projekt mit einer Form1. Beim Start dieses Projektes erzeugt VB von sich aus eine Instanz dieses Fensters, das über seinen Klassennamen, also Form1 angesprochen wird. Für Programmieranfänger ist das eine einfache Vorlage um in VB einzusteigen, aber auch gleichzeitig ein Grund für viele Missverständnisse über Instanziierung und Lebensdauer von Fenstern. Siehe dazu auch: Life Cycle of Visual Basic Forms

Cairo-Fenster entstehen aus normalen VB-Klassen und müssen instanziiert werden. In den VB-Projekteigenschaften können Sie keine Klasse als Startobjekt angeben. Da RC5-Projekte keine Formulare enthalten, bleibt nur noch die Sub Main als Einstiegspunkt für das Programm.

Im letzten Tutorial haben wir uns bereits eine kleine Vorlage für Cairo-Projekte angelegt. Auf dieser Vorlage wollen wir aufbauen und uns hier näher mit Cairo-Fenstern befassen. Schauen wir uns dazu noch mal die hier leicht modifizierte Sub Main an:

With Cairo.WidgetForms.Create(vbSizable, "Hallo Cairo!")
    .Show
End With
Cairo.WidgetForms.EnterMessageLoop
MsgBox "Ende"

Ich habe hier eine Message-Box-Anweisung eingefügt, um zu verdeutlichen was im Hintergrund passiert. Obwohl die Cairo-Form nicht modal aufgerufen wurde, erscheint die MsgBox erst nachdem wir das Fenster schließen. Was da genau passiert sehen wir, wenn wir bei gestarteter Anwendung das Programm pausieren lassen. Das Programm bleibt in der Zeile EnterMessageLoop stehen. Diese Anweisung ist erforderlich, weil im Projekt keine VB-Formen vorhanden sind. In der MessageLoop-Prozedur läuft eine Endlosschleife die (neben Unicode-basiertem TranslateMessageW und DispatchMessageW) auch kontinuierlich überprüft, ob noch Fenster geladen sind. Wenn die Anzahl der geladenen cWidgetForm-TopLevel-Fenster 0 ist, wird die Schleife und mit ihr auch die Prozedur verlassen.

Sie können der Prozedur EnterMessageLoop zwei optionale Parameter übergeben:

ModalWaitLoop As Boolean
CleanupRichClientDllAfterExit As Boolean = True

Bei gesetztem ModalWaitLoop-Flag werden dahinterliegende Fenster gesperrt (dieses Flag wird auch intern in der Form-Engine verwendet, wenn z.B. eine cWidgetForm.Show-Methode zusammen mit dem optionalen Parameter vbModal verwendet wird). Das optionale Flag CleanupRichClientDllAfterExit (das per Default auf True steht), sorgt dafür dass die RichClient-library intern gecachte Objekte sauber aufräumt. Dies passiert im Falle einer "reinen Cairo-Form-Applikation" automatisch (zum spätest möglichen Zeitpunkt, nachdem die letzte Form geschlossen wurde) und die Anwendung eine Zeile später über End Sub von Sub Main läuft.

In Anwendungen die den RC5 zusammen mit normalen VB-Forms verwenden, empfiehlt es sich diesen Cleanup manuell aufzurufen (New_c.CleanupRichClientDll, ebenfalls zum spätestmöglichen Zeitpunkt beim App-Shutdown), z.B. im Form_Terminate einer normalen VB-Main-Form (von der man weiß, dass selbige als letzte Form geschlossen wird).

Noch eine Sache ist hier ganz wichtig. Vor der MessageLoop haben wir ein CairoFenster mit With erstellt. VB erzeugt so ein Objekt, ohne dass wir den Verweis auf dieses Objekt in eine Variable speichern. Am Ende von With wird das Objekt von VB wieder zerstört, Sie können das prüfen, indem Sie folgenden Code in die cfMain-Klasse einfügen:

Private Sub Class_Terminate()
    Debug.Print "cfMain beendet"
End Sub

Dennoch bleibt unser Fenster bestehen und das Programm verweilt in der MessageLoop. Warum ist das so? Nun, ganz einfach: Der Aufruf der Create-Methode erzeugt ein Cairo-Fenster und liefert uns eine Referenz auf dieses Fenster. Gleichzeitig wird aber eine Referenz auch in der internen Collection der WidgetForms gehalten. Über diese Collection prüft die MessageLoop ob noch Fenster geladen sind. Cairo-Fenster die Sie mit Create erzeugen, sollten Sie auch wieder an geeigneter Stelle zerstören. Wenn Sie die interne cWidgetForm in die cfMain-Klasse kapseln, wie in unserem Beispiel mit Private WithEvents mForm As cWidgetForm, dann kommen Sie an diese Referenz nicht mehr so leicht heran. Deshalb sollten Sie die cfMain-Klasse um folgenden Code ergänzen:

Private Sub Class_Terminate()
    mForm.Unload
    Debug.Print "cfMain beendet"
End Sub

Das hat aber zur Folge, dass unsere ursprüngliche Main-Prozedur nicht mehr wie früher funktioniert. Nach End With wird nun auch die Cairo-Form zusammen mit dem cfMain-Objekt entladen. Die MessageLoop findet kein geladenes Fenster mehr und beendet die Anwendung.

Folglich müssen wir unseren Code in der Sub Main anpassen, statt With verwenden wir die Objektvariable fMain:

'With New cfMain
'    .Show
'End With
Dim fMain As New cfMain
fMain.Show
Cairo.WidgetForms.EnterMessageLoop

Sie werden nun feststellen, dass das Programm wieder funktioniert. Die Class_Terminate-Prozedur wird allerdings erst ausgeführt, wenn die fMain-Referenzvariable am Ende der Prozedur zerstört wird. Intern war also unsere cWidgetForm ebenfalls noch bis zum Programmende existent. Wenn Sie alle Objekte und deren belegte Ressourcen vorab freigeben wollen, müssen Sie an geeigneter Stelle die Objekt-Referenzen zerstören.

Dim fMain As New cfMain, fSplash As New cfSplash
fSplash.Show
fMain.Show
Set fSplash = Nothing
Cairo.WidgetForms.EnterMessageLoop

VB-Fenster vs. Cairo-Fenster  

Cairo-Fenster sind keine erweiterten VB-Fenster! Der gravierendste Unterschied aus Sicht eines VB-Entwicklers dürfte wohl sein, dass die Cairo-Fenster keine VB-Steuerelemente, auch keine VB-Benutzersteuerelemente und auch keine Zusatz-Steuerelemente von Microsoft (z.B. die Windows Common Controls, auch nicht die aus der VB5-Version) oder Fremdanbietern enthalten können. Das mag für viele VB-Entwickler hart klingen ist aber letzten Endes nur der Preis, den wir für eine Unabhängigkeit von Microsoft und eine spätere Plattformunabhängigkeit bezahlen müssen. Wer vorhandene Projekte auf Cairo migrieren will, muss Arbeit investieren. Anders aber als VB.Net ermöglicht der RichClient eine weiche Migration. Ihr Projekt darf aus VB- und Cairo-Fenstern bestehen. Sie können ihre VB-Fenster in Abhängigkeit von Zeit und Verfügbarkeit von Zusatz-Widgets (Cairo-Steuerelemente) nach und nach konvertieren.

Wenn wir ein neues Fenster auf den Bildschirm bringen, wollen wir vorher das Aussehen und die Funktionalität dieses Fensters bestimmen. Dafür legen wir im Entwicklungsmodus die Werte bestimmter Eigenschaften im Eigenschaftenfenster fest. Eventuell passen wir einige Eigenschaften erst zur Laufzeit an, weil diese in Abhängigkeit von der Umgebung festgelegt werden. Viele der bekannten Eigenschaften aus VB-Fenstern finden Sie auch, wenn Sie im Objektkatalog die Klasse cWidgetForm analysieren. Dazu gehören die Klassiker zur Größe und Positionierung des Fensters: Left, Top, Width, Height. Auch die Methode Move zum Positionieren ist unverändert vorhanden. Das Aussehen des Fensters bestimmen Sie über BackColor, BorderStyle (die Einstellungen sind identisch, verwenden aber nicht Integer als Datentyp, sondern FormBorderStyleConstants), ControlBox, MaxButton, MinButton, Visible und WindowState. Da ist also vieles identisch und doch ist nicht alles gleich. Vielleicht war in ihrer VB-Form die Eigenschaft AutoRedraw eingeschaltet, weil Sie ihre Form mit den Grafik-Methoden Point, Line, Circle, PaintPicture und Print aufgehübscht haben. Über diverse Eigenschaften haben Sie dafür Linienbreiten, Stil und Farben festgelegt.

In der cWidgetForm gehören diese Eigenschaften nicht mehr zur Fenster-Klasse sondern in eine tiefere Abstraktionsschicht. Sie finden in den Eigenschaften der cWidgetForm das WidgetRoot-Objekt, welches eine zentrale Schicht für zukünftige Widgets bietet. Darüber hinaus finden Sie hier weitere Eigenschaften und Methoden, unter anderen auch das zum VB-Printer- DrawInterface kompatible VBDrawing-Objekt. Mit dessen Methoden und Eigenschaften können Sie mit nahezu unverändertem VB-Code ihre Grafikausgaben steuern. Folgendes Beispiel soll das verdeutlichen:

Public Sub Show()
   Dim DrawP As Printer
   Dim Draw As cVBDraw
   
   Set Draw = mForm.WidgetRoot.VBDrawing
   'cVBDraw implementiert das VB-Printer-Interface
   Set DrawP = Draw

   Draw.Cls

   DrawP.ScaleMode = vbPixels
   DrawP.DrawWidth = 10
   DrawP.Circle (160, 105), 60, vbRed
   DrawP.Line (112, 90)-(207, 120), vbGreen, B
   DrawP.CurrentX = 120
   DrawP.CurrentY = 96
   DrawP.ForeColor = vbBlue
   DrawP.FontSize = 12

   Draw.PrintText "Hallo Cairo!"
   Draw.CC.DrawRegularPolygon 160, 105, 100, 20, splNormal, 50
   Draw.CC.SetSourceColor vbBlack, 0.5
   Draw.CC.Stroke

   mForm.Refresh
End Sub

Wie Sie sehen, ist es nicht schwierig, die aus VB bekannten Grafik-Methoden auf die Cairo-Formen anzuwenden. Schauen wir uns in diesem Sinne auch die PaintPicture-Methode an. Vielleicht haben Sie diese Methode verwendet um ihre Fenster mit Hintergrundbildern zu gestalten. Eine PaintPicture-Methode werden Sie in der cWidgetForm-Klasse aber nicht finden. Da die Oberflächen der neuen Fenster mittels Cairo-Bibliothek gezeichnet werden, Sind die Alternativen vielfältig und sehr mächtig.

Für die relativ einfache Aufgabe einen Fensterhintergrund zu zeichnen ist der Aufwand gering:

Private Sub Class_Initialize()
  Set mForm = Cairo.WidgetForms.Create(...)
  mForm.WidgetRoot.ImageKey = "myFormBackground"
End Sub

ImageKey ist eine einfache String-Property. Diese bekommt einen Schlüssel zugewiesen, der ein Bild in einer globalen Bildersammlung repräsentiert. Diese Bildersammlung ist ein Cairo-Objekt, abgeleitet von der cImageList. Dieses Objekt müssen Sie nicht selbst instanziieren, weil es als Property der cCairo-Klasse zusammen mit dem globalen Cairo-Objekt (s. Sub Main) erzeugt wird. Allerdrings müssen Sie dafür sorgen, dass dieser Bild-Container die gewünschten Bild-Ressourcen enthält.

Lassen Sie uns deshalb einen kurzen Blick auf die cImageList-Klasse werfen. Sie können die Klasse ein wenig mit der ImageList aus den Common Controls vergleichen. Nur ist die RC5-ImageList viel mächtiger. Sie können hier alle Bildressourcen verwalten, die von Ihrem Programm benötigt werden. Dazu zählen neben normalen Bildern auch Form-Icons, Icons für Ihre Menüs, Steuerelemente und benutzerdefinierte Mauszeiger. Für das Befüllen der Liste bietet Ihnen diese diverse Methoden. Neben dem Einlesen von Bilddateien von einem Datenträger kann die Klasse auch aus Ressource-Dateien lesen oder Sie befüllen die Liste mit beliebigen Byte-Arrays. Hier ein einfaches Beispiel:

With Cairo.ImageList
  .AddImage "myFormBackground ", AppPath & "myBackground.jpg"
  .AddImage "progIcn", LoadResData(1, 3)
  .AddImage "myCursor", New_c.Crypt.Base64Dec("iVBORw0K...", True)
End With

Zurück zum Fensterhintergrund. Um das geladene und als Hintergrund gezeichnete Bild brauchen Sie sich nicht weiter zu kümmern. Beim Resizen des Fensters passt Cairo das Hintergrundbild automatisch den Fensterabmessungen an. Das bewirkt aber eine unschöne Verzerrung des Bildes. Bei Hintergrundbildern ist es eher so, dass diese gekachelt angezeigt werden. Um das zu erreichen, müssen wir eine weitere Eigenschaft setzen:

mForm.WidgetRoot.ImageKeyRenderBehaviour = ImgKeyRenderRepeat

Weitere Konstanten für das Rendern der Hintergründe sind ImgKeyRenderCentered, ImgKeyRenderLeft, ImgKeyRenderNone, ImgKeyRenderRepeat, ImgKeyRenderRight, ImgKeyRenderStretched, ImgKeyRenderTopCentered. Aus den Namen der Konstanten ergibt sich unmissverständlich deren Wirkung.

Bei dieser Gelegenheit wollen wir weitere Bildressourcen aus unserer Imagelist verwenden:

mForm.IconImageKey = "progIcn" 'Fenster-Icon
mForm.WidgetRoot.Widget.MouseIconImageKey = "myCursor"

Anders als in VB, können wir hier aus dem Vollen schöpfen: Cairo unterstützt TrueColor-Icons mit Alpha-Channel (32bit).

Ein noch viel mächtigeres Werkzeug zur Grafikausgabe auf einem Fenster stellt die Kombination Surface und CairoContext dar. Stellen Sie sich ein Surface als InMemory-Bitmap vor (hDIB). Mit dessen Methode CreateContext können wir uns so was wie eine Zeichenfläche erstellen, das CairoContext, auf dem Sie mit Cairo-Grafikmethoden arbeiten können. Solch einen Zeichenkontext bietet uns auch das hier verwendete VBDrawing-Objekt. Die verfügbaren Grafikmethoden sind so vielfältig, dass ich in diesen Artikel nicht alle beschreiben kann. Lassen Sie uns nur mal kurz reinschnuppern und unser Bild mit einer Cairo-Zeichenfunktion erweitern:

Public Sub Show()
   ...
   Draw.PrintText "Hallo Cairo!"

   Draw.CC.DrawRegularPolygon 160, 105, 100, 20, splNormal, 50
   Draw.CC.SetSourceColor vbBlack, 0.5
   Draw.CC.Stroke

   mForm.Refresh
End Sub

Wie Sie sehen, können die VB-Kompatiblen Methoden des VBDrawing mit den Zeichenmethoden auf dem Cairo-Context kombiniert werden.


Abbildung 1: Screenshot

In VB werden die Ausgaben grafischer Methoden in einer Form neu gezeichnet, wenn AutoRedraw True ist und die Fenstergröße sich ändert oder das zuvor verdeckte Fenster wieder sichtbar wird. In Cairo-Fenstern brauchen Sie sich nicht um die AutoRedraw-Eigenschaft kümmern. Ein Cairo-Fenster, genaugenommen die WidgetForm besitzt die oben genannte Cairo-Surface als Hintergrundpuffer für die Grafik-Ausgaben. Zuvor verdeckte Fenster werden daher automatisch neu gezeichnet, wenn sie wieder freigestellt (sichtbar) werden.

Beim Resizen des Fensters gilt das nicht. Alle Grafikausgaben über VBDrawing und CairoContext gehen bei einer Änderung der Fensterdimensionen verloren und müssen deshalb aktualisiert werden. Am besten lässt sich das über eine eigene Prozedur lösen, die alle Grafikausgaben vereint. Diese Prozedur wird im WidgetForm-Resize-Ereignis aufgerufen:

Private Sub mForm_Resize()
    Refresh
End Sub

Private Sub Refresh()
   Dim DrawP As Printer
   Dim Draw As cVBDraw
   ...
   mForm.Refresh  
End Sub

Sollten sich Ihre Grafikausgaben an den Fensterabmessungen orientieren, können Sie dafür die Werte aus mForm.ScaleWidth und mForm.ScaleHeight heranziehen - oder Sie verwenden gleich das erweiterte Resize-Ereignis:

Private Sub mForm_ResizeWithDimensions( _
    ByVal NewWidth As Long, _
    ByVal NewHeight As Long)

End Sub

Lassen Sie mich diese erweiterte Prozedur gleich als Übergang zum nächsten Kapitel verwenden:

Cairo-Fenster Extended  

StartUpPosition

An manchen Stellen ist die Arbeit mit VB mühselig oder gar "buggy". Das Positionieren von Fenstern ist zum Beispiel so ein Fall. Erstellen Sie mal ein neues VB-Fenster und setzen dessen StartUpPosition auf Bildschirmmitte. Starten Sie das Programm. Alles wie erwartet? Ok, nun fügen Sie diesem Fenster ein einfaches Menü hinzu und starten das Programm noch mal. Noch immer alles Ok? Selbst wenn Sie die Eigenschaft nachträglich wieder setzen, weigert sich VB das über einen Programmstart hinweg zu behalten. Zur Laufzeit ist diese Eigenschaft nicht verfügbar. Und es kommt noch schlimmer: Wenn Sie ihre IDE auf SDI eingestellt haben, reicht es aus, das Fenster im Entwurfsmodus einmal zu verschieben und schon steht die StartUpPosition wieder auf 0. Ihnen bleibt nur ein praxistauglicher Ausweg: Sie müssen ihr Fenster zur Laufzeit per Move-Methode an die richtige Stelle schieben. Wo aber ist die richtige Stelle? Wo ist die Bildschirmmitte wenn Sie zwei oder mehr Bildschirme verwenden? Wie ist dabei die Windows-Startleiste zu berücksichtigen? Alte VB-Entwickler haben sich schon lange mit solchen kleinen Unzulänglichkeiten ihrer IDE abgefunden. Dennoch ist es immer wieder aufs Neue ärgerlich zu wissen, dass uns diese Fehler für immer erhalten bleiben, weil Microsoft Entwicklung und Support für VB endgültig eingestellt hat. Zumal das nicht der einzige Fehler in VB ist.

Aus Kompatibilitätsgründen wohl, hat Olaf Schmidt auch den Cairo-Fenstern eine StartUpPosition spendiert, diese sollten Sie jedoch (zumindest in der aktuellen RC-Version) nicht verwenden, weil sie intern nicht implementiert ist. Dafür bietet Ihnen der vbRichClient bessere Alternativen, z.B. die Methoden CenterOn, MaximizeTo. Beide Methoden erwarten einen Parameter cDisplay. Damit können Sie den Bildschirm festlegen, der berücksichtigt wird wenn Sie die Methoden anwenden.

Den Bildschirm können Sie selbst bestimmen oder Sie lassen sich den aktuellen Bildschirm vom WidgetRoot-Objekt mitteilen. Die cDisplay-Klasse bietet uns einige interessante Eigenschaften wie die logische Position und die Abmessungen der Bildschirme (Absolute-Eigenschaften) in einem Bildschirmverbund oder die Work-Eigenschaften, die z.B. die Taskleiste berücksichtigen. Folgende kleine Prozedur zeigt Ihnen die Eigenschaften ihrer Bildschirmlandschaft:

Dim disp As cDisplay
For Each disp In New_c.Displays
  Debug.Print "DeviceName: " & disp.DeviceName
  Debug.Print "AbsoluteBottom: " & disp.AbsoluteBottom
  Debug.Print "AbsoluteLeft: " & disp.AbsoluteLeft
  Debug.Print "AbsoluteRight: " & disp.AbsoluteRight
  Debug.Print "AbsoluteTop: " & disp.AbsoluteTop
  Debug.Print "IsPrimary: " & disp.IsPrimary
  Debug.Print "WorkBottom: " & disp.WorkBottom
  Debug.Print "WorkLeft: " & disp.WorkLeft
  Debug.Print "WorkRight: " & disp.WorkRight
  Debug.Print "WorkTop: " & disp.WorkTop
Next disp

Wollen wir unser Fenster auf dem Bildschirm zentrieren, reicht der Aufruf der Methode CenterOn:

Public Sub Show()
    With mForm
        .CenterOn .WidgetRoot.CurrentMonitor
        .Show
    End With
End Sub

Als Parameter könnten Sie genauso einen anderen Monitor angeben, z.B. wie im folgenden Beispiel den Hauptmonitor Ihres PCs:

Public Sub Show()
    Dim display As cDisplay, displays As cDisplays
    Set displays = New_c.displays
    For Each display In displays
        If display.IsPrimary Then Exit For
    Next
    With mForm
        If Not display Is Nothing Then _
            .CenterOn display
        .Show
    End With
End Sub

Werkzeugsfenster

Ein weiteres Problem, mit den sich VB-Programmierer herumschlagen müssen, sind Fensterfunktionen und Eigenschaften die nur per API erreichbar sind. Dazu gehört zum Beispiel ein Werkzeugfenster über dem Hauptfenster zu halten und das Fenster in seinen Abmessungen zu begrenzen.

Ein Werkzeugfenster erzeugen Sie wie folgt (Code für eine cfToolBox-Klasse):

Option Explicit
Private WithEvents mForm As cWidgetForm

Private Sub Class_Initialize()
  Set mForm = Cairo.WidgetForms.Create(vbSizableToolWindow, _
              "ToolBox", , 100, 500)
  mForm.SetMinMaxDimensions MinWidth:=100, MaxWidth:=100
End Sub

Public Sub Show(OwnerForm As cWidgetForm)
    With OwnerForm.WidgetRoot.CurrentMonitor
        mForm.Move .WorkLeft, .WorkTop
    End With
    mForm.Show OwnerForm:=OwnerForm
End Sub

Dadurch dass wir nur die Parameter MinWidth und MaxWidth angeben, begrenzen wir das Fenster lediglich in der Breite, die Höhe des Fensters bleibt vom Anwender einstellbar. Beim Aufruf der Show-Methode übergeben wir einen OwnerForm-Parameter. Dieser repräsentiert das Eltern-Fenster. Darüber können wir den Bildschirm ermitteln, auf dem das Fenster positioniert ist. Dessen Work-Eigenschaften helfen uns das Werkzeugfenster zu positionieren. Das Werkzeugfenster wird im Hauptfenster wie folgt instanziiert und angezeigt:

Set mToolBox = New cfToolBox
mToolBox.Show mForm

Das Schöne an diesen Kind-Fenstern ist, dass der Entwickler sich um viele Routineaufgaben nicht mehr kümmern muss, dass erledigt der vbRichClient. Schließen Sie zum Beispiel das Eltern-Fenster, werden die Kind-Fenster ebenfalls geschlossen. Minimieren Sie das Eltern-Fenster, werden die Kind-Fenster ausgeblendet. Und Sie werden es bemerkt haben, das Kind-Fenster schwebt zuverlässig über dem Eltern-Fenster. Wenn die Fenster Ihrer Anwendung von einer anderen Anwendung verdeckt sind, reicht es aus eines der Fenster zu aktivieren, schon schiebt sich das andere Kind- oder Eltern-Fenster ebenfalls nach vorne.

Alte und neue Fensterereignisse

Windows lebt von Nachrichten. Nachrichten werden von Fenstern empfangen, ausgewertet, verarbeitet, weitergeleitet usw. Die VB-Runtime wandelt einige dieser Nachrichten in Ereignisse (Events) um und macht diese in der IDE zugänglich. Viele Anwendungen kommen mit dem Standard-Events-Angebot von VB leider nicht aus. Mittels API kann sich auch hier der versierte Programmierer weiterhelfen. Allerdings betreten wir damit unsicheres Terrain. Subclassing nennt sich die Technik, mit der man an weitere Ereignisse, sprich Nachrichten, gelangt. Die Gefahren, die dabei im Hintergrund lauern, sind bekannt: allgemeine Sicherheitshinweise, Schutzverletzungen, Fehler beim Debuggen, Stapelüberläufe usw. Alle bewirken in der Regel den Absturz der Entwicklungsumgebung.

Die Cairo-Fenster kommen uns da entgegen und liefern uns weitere oder verbesserte Ereignisse, die das Leben des VB-Entwicklers angenehmer machen. Dazu gehören:

  • Activate / Deactivate: Anders als die VB-Ereignisse werden die Cairo-Pendanten zuverlässig ausgelöst, auch dann wenn Sie ein Fenster durch einen Taskwechsel aktivieren oder deaktivieren.

  • ActivateApp ist ein neues Ereignis, das Ihnen explizit den Wechsel zu oder von einer anderen Anwendung oder von einem anderen Thread signalisiert.

  • BubblingEvent ist ebenfalls neu und repräsentiert eine zentrale Anlaufstelle für alle möglichen Ereignisse die von Fenstern oder den darauf enthaltenen Steuerelementen ausgelöst werden. Über die Ereignisparameter können sie den Sender und die Nachricht zuordnen. Das erspart Ihnen vielfach die Deklaration mit WithEvents und erlaubt zentrale Ereignisbehandlung für gleichartige Steuerelemente.

  • DragOverDst / DragDropDst: Neue Drag & Drop Ereignisse, die nicht nur mit vbRichClient-Objekten (z.B. Widgets) funktionieren, sondern auch kompatibel zum normalen Ole-DragDrop sind (z.B. wird FileDragDrop von und zum Windows-Explorer voll unterstützt, unicodefähig und mit Support für die neuen Drag-Icons auf Win7/Win8).

  • MouseWheel benachrichtigt Sie über die Verwendung des Maus-Scrollrades.

  • ResizeWithDimensions: Das neue Ereignis liefert als Parameter die neuen Fensterabmessungen

Fazit  

Cairo-Fenster sind keine VB-Fenster. Die damit gravierendste Konsequenz besteht darin, dass Sie auf diesen Fenster keine VB-Steuerelemente platzieren können. Das RC5-Fenstermodel ist wesentlich näher an Windows, intern werden die Fenster mittels CreateWindowExW erzeugt. Zum Zeichnen der Oberflächen kommt die Cairo-Graphik-Bibliothek zum Einsatz.

Die Fenster bieten Schnittstellen zu den neuen Widgets, die ebenfalls auf Cairo basieren. Auf diesem Fundament können zukünftig vielfältige Steuerelemente erstellt werden, die im Aussehen und Funktion weit das Übertreffen, was VB-Programmierern bisher zur Verfügung stand. Ein Blick auf die Demos auf der vbRichClient-Seite lohnt sich.

Neue Eigenschaften, Methoden und Ereignisse machen die Arbeit mit den Fenstern komfortabel. Dennoch wurden auch alte VB-Schnittstellen weitgehend berücksichtigt.

Ein kleines Tutorial zur RC5-FormEngine mit entsprechendem VB6-code (über 6 Tutorial-Folder hinweg - sortiert von "easy" bis "advanced") findet sich auf: http://vbrichclient.com/#/en/Demos/GUI/FormEngine.htm

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Danke Wolfgang, Danke Olaf - Klaus Langbein 17.06.15 11:53 6 Antworten