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 30.08.2000

Diese Seite wurde zuletzt aktualisiert am 30.08.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicAddIns 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 zur AVB-Web-Site, Kontakt und Impressum

Zurück...

Kartesische Koordinaten

Zurück...

(-hg) mailto:hg_cartesianscalemode@aboutvb.de

Windows-typische Koordinatensysteme haben die Eigenart, nach rechts unten hin ausgerichtet zu sein. Das bedeutet, dass der Ursprung des Koordinatensystems links oben liegt und der positive Zuwachs der Y-Koordinate nach unten hin erfolgt. Beim mathematischen Standard-Koordinatensystem ("Kartesisches Koordinatensystem") ist die Y-Richtung umgekehrt ausgerichtet, von unten nach oben zeigend. Außerdem liegt der Ursprung logisch gesehen in der Mitte, so dass sowohl für X- als auch Y-Koordinaten positive und negative dargestellt werden können.

Zwar können Sie über API-Funktionen das Koordinatensystem eines Fensters (eines Forms, einer PictureBox usw.) entsprechend umorientieren und den Ursprung positionieren. Doch geraten damit die gewohnten ScaleMode-Eigenschaften (ScaleLeft, ScaleTop, ScaleWidth, ScaleHeight, ScaleX und ScaleY) ziemlich durcheinander. Und eine Größenänderung bei Beibehaltung des ScaleMode-Maßstabs ist auch nicht so einfach nachzuhalten.

Einfacher ist die Aufgabe mit ein paar wenigen Modifikationen in reinem Visual Basic zu bewerkstelligen. Um negative Koordinaten zu erhalten, müssen Sie lediglich einen negativen Wert für ScaleLeft (X-Achse) bzw. ScaleTop (Y-Achse) angeben, um den Nullpunkt einer Achse in Richtung Flächenmitte zu verschieben. Geben Sie die volle Breite bzw. die volle Höhe als negativen Wert an, liegt der jeweilige Achsen-Nullpunkt rechts bzw. unten, und Sie erhalten für die betreffende Achse nur noch negative Werte.

Dabei müssen Sie allerdings beachten, dass Sie alle Y-Werte zur Auswertung in den Mausereignissen oder bei der sonstigen Verwendung, etwa beim Zeichnen, mit minus 1 multiplizieren. Wenn der Ursprung nach einer Größenänderung der Fläche an der im Verhältnis gleichen Stelle liegen soll (etwa weiterhin rechts unten), sind die Eigenschaften ScaleLeft und ScaleTop entsprechend neu zu setzen.

Die hier vorgestellte Klasse CartesianScaleMode automatisiert das Verfahren für Standard-Positionen des Ursprungs: für oben links, oben mittig, oben rechts, links mittig, rechts mittig, unten links, unten mittig, unten rechts und in der Fläche zentriert. Sie übergeben der Methode Init ein Flächen-Objekt (ein Form oder eine PictureBox) und setzen im optionalen Parameter InitOrigin eine der Positionsangaben aus der Enumeration OriginConstants. Die Voreinstellung csoDefault (= 0) sorgt dafür, dass sich das Objekt dem Windows-Standard entsprechend verhält. Bei einer angegebenen Position merkt sich die Klasse die zunächst angetroffenen ScaleMode-Einstellungen unabhängig davon, ob ein Standard-ScaleMode (etwa vbTwips oder vbPixels) eingestellt ist, oder ob Sie eine der Eigenschaften benutzerdefiniert geändert haben. Die Eigenschaft Origin können Sie nachträglich jederzeit ändern (siehe herunterladbares Beispiel-Projekt).

In der Klasse wird eine Ereignis-Referenz auf das übergebene Objekt gesetzt. Die Klasse reagiert nun eigenständig auf Größenänderungen des Objekts (Resize-Ereignis) und auf dessen Mausereignisse. Letztere werden von einem klasseneigenen Ereignis durchgereicht, wobei die Y-Koordinate automatisch umgekehrt wird. Wie bereits erwähnt, brauchen Sie nun nur noch beim Zeichnen die Y-Koordinate mit minus 1 zu multiplizieren, wenn in der Eigenschaft Origin ein anderer Wert als csoDefault eingestellt ist.

Private mDefScaleMode As Integer
Private mDefScaleLeft As Single
Private mDefScaleTop As Single
Private mDefScaleWidth As Single
Private mDefScaleHeight As Single

Private WithEvents eForm As Form
Private WithEvents ePictureBox As PictureBox

Public Enum OriginConstants
  csoDefault
  csoLeftTop
  csoLeftBottom
  csoRightBottom
  csoRightTop
  csoCenterTop
  csoCenterBottom
  csoCenterLeft
  csoCenterRight
  csoCenter
End Enum

Public Event MouseDown(Button As Integer, Shift As Integer, _
 X As Single, Y As Single)
Public Event MouseMove(Button As Integer, Shift As Integer, _
 X As Single, Y As Single)
Public Event MouseUp(Button As Integer, Shift As Integer, _
 X As Single, Y As Single)

Private pOrigin As OriginConstants

Public Property Get Object() As Object
  If Not (eForm Is Nothing) Then
    Set Object = eForm
  ElseIf Not (ePictureBox Is Nothing) Then
    Set Object = ePictureBox
  End If
End Property

Public Property Get Origin() As OriginConstants
  Origin = pOrigin
End Property

Public Property Let Origin(ByVal New_Origin As OriginConstants)
  pOrigin = New_Origin
  If Not (eForm Is Nothing) Then
    eForm_Resize
  ElseIf Not (ePictureBox Is Nothing) Then
    ePictureBox_Resize
  End If
End Property

Public Sub Init(Object As Object, _
 Optional ByVal InitOrigin As OriginConstants = csoDefault)

  If Not (eForm Is Nothing) Then
    zResetFormScaleMode
    Set eForm = Nothing
  End If
  If Not (ePictureBox Is Nothing) Then
    zResetPictureBoxScaleMode
    Set ePictureBox = Nothing
  End If
  pOrigin = InitOrigin
  If TypeOf Object Is Form Then
    Set eForm = Object
    With eForm
      mDefScaleMode = .ScaleMode
      If mDefScaleMode = vbUser Then
        mDefScaleLeft = .ScaleLeft
        mDefScaleTop = .ScaleTop
        mDefScaleWidth = .ScaleWidth
        mDefScaleHeight = .ScaleHeight
      End If
    End With
    eForm_Resize
  ElseIf TypeOf Object Is PictureBox Then
    Set ePictureBox = Object
    With ePictureBox
      mDefScaleMode = .ScaleMode
      If mDefScaleMode = vbUser Then
        mDefScaleLeft = .ScaleLeft
        mDefScaleTop = .ScaleTop
        mDefScaleWidth = .ScaleWidth
        mDefScaleHeight = .ScaleHeight
      End If
    End With
    ePictureBox_Resize
  End If
End Sub

Public Sub Destroy()
  Class_Terminate
End Sub

Private Sub Class_Terminate()
  Set eForm = Nothing
  Set ePictureBox = Nothing
End Sub

Private Sub eForm_MouseDown(Button As Integer, Shift As Integer, _
 X As Single, Y As Single)

  If pOrigin Then
    Y = -Y
  End If
  RaiseEvent MouseDown(Button, Shift, X, Y)
End Sub

Private Sub eForm_MouseMove(Button As Integer, Shift As Integer, _
 X As Single, Y As Single)

  If pOrigin Then
    Y = -Y
  End If
  RaiseEvent MouseMove(Button, Shift, X, Y)
End Sub

Private Sub eForm_MouseUp(Button As Integer, Shift As Integer, _
 X As Single, Y As Single)

  If pOrigin Then
    Y = -Y
  End If
  RaiseEvent MouseUp(Button, Shift, X, Y)
End Sub

Private Sub eForm_Resize()
  With eForm
    If .WindowState <> vbMinimized Then
      zResetFormScaleMode
      Select Case pOrigin
        Case csoDefault
        Case csoLeftTop
        Case csoLeftBottom
          .ScaleTop = -.ScaleHeight + .ScaleY(1, vbPixels, .ScaleMode)
        Case csoRightBottom
          .ScaleLeft = -.ScaleWidth + .ScaleX(1, vbPixels, .ScaleMode)
          .ScaleTop = -.ScaleHeight + .ScaleY(1, vbPixels, .ScaleMode)
        Case csoRightTop
          .ScaleLeft = -.ScaleWidth + .ScaleX(1, vbPixels, .ScaleMode)
        Case csoCenterTop
          .ScaleLeft = -(.ScaleWidth / 2) + _
           .ScaleX(0.5, vbPixels, .ScaleMode)
        Case csoCenterBottom
          .ScaleLeft = -(.ScaleWidth / 2) + _
           .ScaleX(0.5, vbPixels, .ScaleMode)
          .ScaleTop = -.ScaleHeight + .ScaleY(1, vbPixels, .ScaleMode)
        Case csoCenterLeft
          .ScaleTop = -(.ScaleHeight / 2) + _
           .ScaleY(0.5, vbPixels, .ScaleMode)
        Case csoCenterRight
          .ScaleLeft = -.ScaleWidth + .ScaleX(1, vbPixels, .ScaleMode)
          .ScaleTop = -(.ScaleHeight / 2) + _
           .ScaleY(0.5, vbPixels, .ScaleMode)
        Case csoCenter
          .ScaleLeft = -(.ScaleWidth / 2) + _
           .ScaleX(0.5, vbPixels, .ScaleMode)
          .ScaleTop = -(.ScaleHeight / 2) + _
           .ScaleY(0.5, vbPixels, .ScaleMode)
      End Select
    End If
  End With
End Sub

Private Sub ePictureBox_MouseDown(Button As Integer, _
 Shift As Integer, X As Single, Y As Single)

  If pOrigin Then
    Y = -Y
  End If
  RaiseEvent MouseDown(Button, Shift, X, Y)
End Sub

Private Sub ePictureBox_MouseMove(Button As Integer, _
 Shift As Integer, X As Single, Y As Single)

  If pOrigin Then
    Y = -Y
  End If
  RaiseEvent MouseMove(Button, Shift, X, Y)
End Sub

Private Sub ePictureBox_MouseUp(Button As Integer, _
 Shift As Integer, X As Single, Y As Single)

  If pOrigin Then
    Y = -Y
  End If
  RaiseEvent MouseUp(Button, Shift, X, Y)
End Sub

Private Sub ePictureBox_Resize()
  With ePictureBox
    zResetPictureBoxScaleMode
    Select Case pOrigin
      Case csoDefault
      Case csoLeftTop
      Case csoLeftBottom
        .ScaleTop = -.ScaleHeight + .ScaleY(1, vbPixels, .ScaleMode)
      Case csoRightBottom
        .ScaleLeft = -.ScaleWidth + .ScaleX(1, vbPixels, .ScaleMode)
        .ScaleTop = -.ScaleHeight + .ScaleY(1, vbPixels, .ScaleMode)
      Case csoRightTop
        .ScaleLeft = -.ScaleWidth + .ScaleX(1, vbPixels, .ScaleMode)
      Case csoCenterTop
        .ScaleLeft = -(.ScaleWidth / 2) + .ScaleX(0.5, vbPixels, _
         .ScaleMode)
      Case csoCenterBottom
        .ScaleLeft = -(.ScaleWidth / 2) + .ScaleX(0.5, vbPixels, _
         .ScaleMode)
        .ScaleTop = -.ScaleHeight + .ScaleY(1, vbPixels, .ScaleMode)
      Case csoCenterLeft
        .ScaleTop = -(.ScaleHeight / 2) + .ScaleY(0.5, vbPixels, _
         .ScaleMode)
      Case csoCenterRight
        .ScaleLeft = -.ScaleWidth + .ScaleX(1, vbPixels, .ScaleMode)
        .ScaleTop = -(.ScaleHeight / 2) + .ScaleY(0.5, vbPixels, _
         .ScaleMode)
      Case csoCenter
        .ScaleLeft = -(.ScaleWidth / 2) + .ScaleX(0.5, vbPixels, _
         .ScaleMode)
        .ScaleTop = -(.ScaleHeight / 2) + .ScaleY(0.5, vbPixels, _
         .ScaleMode)
    End Select
  End With
End Sub

Private Sub zResetFormScaleMode()
  With eForm
    .ScaleMode = mDefScaleMode
    If mDefScaleMode = vbUser Then
      .ScaleLeft = mDefScaleLeft
      .ScaleTop = mDefScaleTop
      .ScaleWidth = mDefScaleWidth
      .ScaleHeight = mDefScaleHeight
    End If
  End With
End Sub

Private Sub zResetPictureBoxScaleMode()
  With ePictureBox
    .ScaleMode = mDefScaleMode
    If mDefScaleMode = vbUser Then
      .ScaleLeft = mDefScaleLeft
      .ScaleTop = mDefScaleTop
      .ScaleWidth = mDefScaleWidth
      .ScaleHeight = mDefScaleHeight
    End If
  End With
End Sub


Beispiel-Projekt und Klasse CartesianScaleMode (cartesianscalemode.zip - ca. 13 KB)



Komponenten-Übersicht

Schnellsuche



Zum Seitenanfang

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

Zum Seitenanfang

Zurück...

Zurück...