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 22.11.2002

Diese Seite wurde zuletzt aktualisiert am 22.11.2002
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...

Überdeckung prüfen

Zurück...


Anzeige

(-hg) mailto:hg_windowvisible@aboutvb.de

Wenn der Inhalt eines Fensters (Form, PictureBox, UserControl usw.) von Ihrem Programm selbst gezeichnet wird und dabei umfangreiche Zeichenoperationen anfallen, kann erübrigen sich diese Operationen teilweise oder völlig, wenn das Fenster zum Teil oder völlig von anderen Fenstern überdeckt wird.

Zum Testen einer Überdeckung ziehen wir die Clipping-Funktionen ("Clipping", zu Deutsch in etwa: "Beschnitt", "Zuschnitt") des Windows-GDI-APIs heran. Jedes Fenster kann in der Regel die Fläche seines Rechtecks nach Belieben selbst bemalen. Die erste und häufigste Abweichung von dieser Regel wendet Windows selber an, um den Darstellungsbereich eines teilweise verdeckten Fensters (oder Steuerelements, das ja auch ein Fenster ist) zu beschneiden, so dass dieses bei der Selbstdarstellung nicht in den Bereich des überdeckenden Fensters hinein malt. Ein solcher beschnittener Bereich wird "Region" genannt. Eine solche Region braucht noch nicht einmal rechteckig zu sein - denken Sie etwa an zwei versetzt mit etwas Abstand zueinander liegende Fenster, die ein drittes, dahinter liegendes Fenster teilweise überdecken. Selbst Fenster mit völlig unregelmäßigen und kurvigen Konturen sind möglich (etwa in Form eines Puzzle-Steines). Solche Regions (ja, es handelt sich hier um den englischsprachigen Begriff, daher diese Form des Plurals) können nach Bedarf erstellt und einem Geräte-Kontext (in dem die API-Zeichenvorgänge stattfinden) zugewiesen werden. Eine Region kann aber auch einem Fenster direkt zugewiesen werden und somit eine absolute, äußere Kontur für das Fenster dauerhaft festlegen.

Zur Prüfung der Überdeckung beschränken wir uns der Einfachheit halber auf einen Vergleich des Rechtecks eines Fensters mit dem umschließenden Rechteck der aktuellen Clipping-Region eines Fensters. Das Rechteck des Fensters liefert uns die API-Funktion GetClientRect und das die Clipping-Region umschließende Rechteck erhalten wir von der API-Funktion GetClipBox. Ob diese beiden Rechtecke übereinstimmen, sagt uns die API-Funktion EqualRect. Zusätzlich liefert uns der Aufruf von GetClipBox noch die Information, ob die aktuelle Clipping-Region ein einfaches Rechteck ist, oder ob sie durch teilweise Überdeckung des Fensters eine "komplexe" Region ist.

Diese Auswertungen zusammen übernimmt die folgende Hilfsfunktion WindowVisible, der sie das Fenster-Handle (hWnd) des betroffenen Fensters und dessen Geräte-Kontext (hDC) übergeben. Als Rückgabewert erhalten Sie einen Wert aus der Enumeration WindowVisibleConstants, der besagt, ob das Fenster völlig, teilweise oder gar nicht sichtbar ist.

Private Type RECT
  Left As Long
  Top As Long
  Right As Long
  Bottom As Long
End Type

Private Declare Function EqualRect Lib "user32" _
 (lpRect1 As RECT, lpRect2 As RECT) As Long
Private Declare Function GetClientRect Lib "user32" _
 (ByVal hWnd As Long, lpRect As RECT) As Long
Private Declare Function GetClipBox Lib "gdi32" _
 (ByVal hDC As Long, lpRect As RECT) As Long

Public Enum WindowVisibleConstants
  wvHidden
  wvPartialVisible
  wvCompleteVisible
End Enum

Public Function WindowVisible(hWnd As Long, ByVal hDC As Long) _
 As WindowVisibleConstants

  Dim nClientRect As RECT
  Dim nClipRect As RECT
  Dim nTestClip As Long
  Dim nTestEqual As Boolean
  
  Const NULLREGION = 1
  Const SIMPLEREGION = 2
  Const COMPLEXREGION = 3
  
  GetClientRect hWnd, nClientRect
  nTestClip = GetClipBox(hDC, nClipRect)
  nTestEqual = CBool(EqualRect(nClientRect, nClipRect))
  Select Case nTestClip
    Case COMPLEXREGION
      WindowVisible = wvPartialVisible
    Case SIMPLEREGION
      If nTestEqual Then
        WindowVisible = wvCompleteVisible
      Else
        WindowVisible = wvPartialVisible
      End If
    Case NULLREGION
      WindowVisible = wvHidden
  End Select
End Function

Die folgende Variante dieser Funktion WindowVisibleObj unterscheidet sich lediglich dadurch, dass Sie der Einfachheit halber ein Fenster oder Steuerelement als Objekt übergeben können, wenn dieses über die Eigenschaften hWnd und hDC verfügt.

Public Function WindowVisibleObj(Object As Object) _
 As WindowVisibleConstants

  Dim nClientRect As RECT
  Dim nClipRect As RECT
  Dim nTestClip As Long
  Dim nTestEqual As Boolean
  
  Const NULLREGION = 1
  Const SIMPLEREGION = 2
  Const COMPLEXREGION = 3
  
  With Object
    GetClientRect .hWnd, nClientRect
    nTestClip = GetClipBox(.hDC, nClipRect)
  End With
  nTestEqual = CBool(EqualRect(nClientRect, nClipRect))
  Select Case nTestClip
    Case COMPLEXREGION
      WindowVisibleObj = wvPartialVisible
    Case SIMPLEREGION
      If nTestEqual Then
        WindowVisibleObj = wvCompleteVisible
      Else
        WindowVisibleObj = wvPartialVisible
      End If
    Case NULLREGION
      WindowVisibleObj = wvHidden
  End Select
End Function

Zur Prüfung, ob sich ein bestimmter Punkt oder ein bestimmter rechteckiger Bereich des Fensters innerhalb der aktuellen Clipping-Region befindet, also sichtbar ist, können Sie die API-Funktionen PointVisible (als Alias von ursprünglich "PtVisible") und RectVisible direkt verwenden:

Public Declare Function PointVisible Lib "gdi32" _
 Alias "PtVisible" (ByVal hDC As Long, ByVal x As Long, _
 ByVal y As Long) As Long

Public Declare Function RectVisible Lib "gdi32" _
 (ByVal hDC As Long, lpRect As RECT) As Long

Beispiel-Projekt und Modul modWindowVisible (windowvisible.zip - ca. 3,3 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
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