ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 13.01.2000

Diese Seite wurde zuletzt aktualisiert am 13.01.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Zurück...


Anzeige

(-hg) mailto:hg_coolcontrols@aboutvb.de

Auf allem, wo "cool" draufsteht, muss auch Cooles drin sein, nicht wahr? Immer noch ein ziemlich neuer Schrei, wenn auch nicht mehr der allerneueste, sind sogenannte Cool-Controls. Sie gehören inzwischen hundertprozentig zum Web- wie auch zum Internet Explorer- und Windows 98-Stil. Und überhaupt sind solch coole Effekte überall dort angesagt, wo dem Anwender klipp und klar gezeigt werden muss, dass sich der Mauszeiger über irgendetwas befindet - dass er sich genau dort befindet, und nicht etwa woanders...

Beim Toolbar-Steuerelement aus der mit Visual Basic 6 mitgelieferten neueren Variante der Common Controls 2 (MSComctl.ocx) können Sie über die neue Style-Eigenschaft den Stil tbrFlat (= 1) wählen, und schon haben Sie coole, flache Toolbar-Buttons, die ganz Internet Explorer-like beim Darüberfahren mit dem Mauszeiger ihre Erhabenheit zur Schau stellen. Wollen Sie Ihre selbsterstellten Steuerelemente auch in die Gattung der Cool-Schränke, pardon, Cool-Controls einreihen, müssen Sie die notwendige Funktionalität allerdings auch selbst programmieren. Eine Bitte dazu am Rande: Seien Sie nicht gar ganz so cool, wie die Entwickler der Corel 8-Suite - dort machen in den Dialogen sämtliche Steuerelemente auf derart coole Weise auf sich aufmerksam, dass es einem davon eiskalt den Rücken herunterläuft. Kurz gesagt: Das ist des Guten zuviel, und es nervt einfach nur noch.

Da UserControl-Coolness eben nicht mehr der neueste Schrei ist, werden Sie vielleicht hier und da bereits Code-Beispiele dazu gesehen haben. Die weniger ernstzunehmenden Beispiele verlassen sich allein auf die Auswertung der Koordinaten X und Y im MouseMove-Ereignis und vergessen dabei, dass die MouseMove-Ereignisse zu den am unzuverlässigsten eintreffenden Ereignissen zählen. Bei einer allzuschnellen Bewegung der Maus bekommt das Steuerelement gar nicht mehr mit, dass der Mauszeiger seinen Bereich verlassen hat und macht seine Coolness nicht ordentlich rückgängig. Die ausführlichere Darstellung derartigen Codes können wir uns daher schenken.

Die meisten besseren Beispiele setzen dagegen auf die API-Funktionen MSDN Library - API SetCaptureSetCapture und MSDN Library - API ReleaseCaptureReleaseCapture. Der Aufruf von SetCapture mit dem Fenster-Handle eines Steuerelements sorgt dafür, dass danach alle Mausereignisse weiterhin an dieses Steuerelement geschickt werden, auch wenn der Mauszeiger sich nicht mehr darüber befinden sollte. Erst ein Klick auf ein anderes Fenster oder Steuerelement gibt die Mausereignisse wieder frei - dieser erste Klick gelangt jedoch noch nicht an sein darunter liegendes Ziel, sondern zunächst noch an den mit SetCapture eingefangenen Empfänger. Ein Task-Wechsel (Wechsel der aktiven Anwendung) beendet dieses Einfangen ebenfalls, da SetCapture nur innerhalb der gleichen Anwendung wirkt. Außerdem kann der Empfänger ausdrücklich wieder über die API-Funktion ReleaseCapture freigegeben werden.

Auf diesem Verfahren, nämlich Einfangen des Mauszeigers per SetCapture und kontrolliertes Freigeben per ReleaseCapture, beruht das Grundprinzip der steuerelementaren Coolness. Der oben beschriebene Effekt kann so nicht eintreten - das Steuerelement, das den Mauszeiger eingefangen hat, weiß so lange über die Position desselben Bescheid, wie es ihn noch nicht ausdrücklich wieder freigegeben hat. Die Frage, wann der Mauszeiger denn nun wieder freizugeben wäre, wird wieder anhand einer Prüfung der X- und Y-Koordinaten des MouseMove-Ereignisses entschieden.


Ein schlichter Cool-Effekt

Das folgende Code-Beispiel zeigt ein mögliches Grundgerüst für den simplen Cool-Effekt, bei dem die Hintergrundfarbe eines UserControls geändert wird, wenn sich der Mauszeiger darüber bewegt.

Private mBackColor As Long

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
  mBackColor = UserControl.BackColor
End Sub

Private Sub UserControl_MouseMove(Button As Integer, Shift As _
 Integer, X As Single, Y As Single)
  With UserControl
    Select Case X
      Case 0 To .ScaleWidth
        Select Case Y
          Case 0 To .ScaleHeight
            SetCapture .hwnd
            .BackColor = vbBlue
            Exit Sub
        End Select
    End Select
    ReleaseCapture
    .BackColor = mBackColor
  End With
End Sub

Befindet sich der Mauszeiger innerhalb der Fläche des UserControls, wird der Mauszeiger eingefangen, die Hintergrundfarbe geändert und die Ereignis-Prozedur wieder verlassen. In allen übrigen Fällen wird der Mauszeiger wieder freigegeben und die Hintergrundfarbe auf den Originalwert zurück gesetzt.

Handelt es sich um einen komplexeren Effekt, bei dem zusätzliche oder aufwändigere Zeichenoperationen anfallen, sollte die Notwendigkeit der Ausführung des Cool-Effekts vorher geprüft werden, um Zeit zu sparen oder unschöne Flackereffekte zu vermeiden. Der sicherste Weg ist die Prüfung über die API-Funktion MSDN Library - API GetCaptureGetCapture, ob das UserControl bereits den Mauszeiger eingefangen hat. GetCapture gibt das Fenster-Handle zurück, dem der Mauszeiger aktuell zugeordnet ist.

            '...
            If GetCapture() <> .hwnd Then
              SetCapture .hwnd
              .BackColor = vbBlue
            End If
            Exit Sub
            '...

Aber schauen Sie sich einmal die folgende animierte Grafik an. Das coole Steuerelement rechts in Form1 ist genau so programmiert. Sie können das auch anhand des Code-Beispiels selbst ausprobieren ( Download Beispiel-ProjektDownload am Ende des Artikels).


Cool, auf der rechten Seite aber nicht ganz so wie beabsichtigt

Drei Schwachstellen werden hier sichtbar. Die erste tritt wegen der optischen Wirkung sehr deutlich zu Tage: Befindet sich das Form mit dem coolen Steuerelement nicht im Vordergrund (beide Forms gehören zur gleichen Anwendung), bekommt das Steuerelement dies gar nicht mit. Es prüft weiterhin seine eigene Fläche, auch wenn diese zu einem guten Teil verdeckt ist. Es bleibt weiterhin im coolen Zustand (und wird sicher irgend wann erfrieren...).

Die zweite Schwachstelle zeigt sich beim Klicken auf die rechte Schaltfläche der davor liegenden Form - sie reagiert nicht, weil der Empfänger der Mausereignisse immer noch das dahinterliegende Steuerelement ist. Der vergebliche Klick kann aber stattdessen, wie dargestellt, bewirken, dass das Form mit jenem Steuerelement aktiviert wird und in den Vordergrund springt. Dies war aber bestimmt nicht die Absicht des klickenden Anwenders. Die dritte Schwachstelle ist, dass das angeklickte Form bestenfalls im Vordergrund bleibt, die Schaltfläche jedoch erst nach einem zweiten Klick darauf reagiert.

Statt nun komplizierte API-Operationen anzustellen, um Vorder- und Hintergrund zu ermitteln, die überdeckten und freien Flächen dazu und mehr, können Sie es sich einfacher machen. Es reicht eine Prüfung, ob gerade der Punkt unter dem Mauszeiger von Windows selbst dem UserControl zugerechnet wird. Windows geht dabei von der Reihenfolge der Fenster (Forms und Steuerelemente - alles, was ein Fenster-Handle hat und nicht durchsichtig ist) in der z-Achse aus und gibt beim Aufruf der API-Funktion MSDN Library - API WindowFromPointWindowFromPoint mit den Koordinaten des Mauszeigers das Fenster-Handle jeweils obersten Elements zurück. Dieses kann sowohl ein Hauptfenster (Form) oder ein Steuerelement sein. Allerdings müssen der Funktion WindowFromPoint auf den ganzen Bildschirm bezogene absolute Pixel-Koordinaten übergeben werden. Es gibt zwar einige Möglichkeiten, mit Hilfe von diversen API-Funktionen die lokalen X- und Y-Koordinaten des UserControl-MouseMove-Ereignisses in absolute Bildschirm-Koordinaten umzurechnen. Doch dazu müssten die MouseMove-Koordinaten erst einmal in Pixel umgerechnet werden. Viel schneller und einfacher liefert uns der Aufruf der API-Funktion MSDN Library - API GetCursorPosGetCursorPos die gewünschten Koordinaten, sogar gleich als Pixel-Werte.

Ein zeitsparender Nebeneffekt dieser Technik ist dazu, dass die ursprüngliche, letztlich das Problem verursachende Prüfung entfällt, ob sich die X- und Y-Koordinaten innerhalb des UserControls befinden. Das "coolere" linke Steuerelement in Form1 beruht auf dem folgenden Code:

Private Type POINTAPI
  X As Long
  Y As Long
End Type

Private Declare Function GetCapture Lib "user32" () As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint _
 As POINTAPI) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function SetCapture Lib "user32" (ByVal hwnd _
 As Long) As Long
Private Declare Function WindowFromPoint Lib "user32" _
 (ByVal xPoint As Long, ByVal yPoint As Long) As Long

Private Sub UserControl_MouseMove(Button As Integer, Shift _
 As Integer, X As Single, Y As Single)
  Dim nPoint As POINTAPI
  Dim nHWnd As Long
  
  GetCursorPos nPoint
  nHWnd = WindowFromPoint(nPoint.X, nPoint.Y)
  With UserControl
    If nHWnd = .hwnd Then
      If GetCapture() <> nHWnd Then
        SetCapture nHWnd
        .BackColor = vbBlue
      End If
      Exit Sub
    End If
    ReleaseCapture
    .BackColor = mBackColor
  End With
End Sub

So sieht ein "richtig cooles" Code-Grundgerüst für coole Steuerlemente aus


Beispiel-Projekt CoolControlTest (coolctrl.zip - ca. 3 KB)






Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche



Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer