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 17.04.2000

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

Verzögerte Ziehung

Zurück...


Anzeige

(-hg) mailto:hg_begindrag@aboutvb.de

Ob beim "klassischen" VB-Drag&Drop, beim OLE-Drag&Drop oder bei irgendwelchen anderen Ziehvorgängen mit der Maus - der Zieh-Vorgang sollte nach dem Niederdrücken der Maustaste erst nach einer kleinen Verschiebung des Mauszeigers anspringen. Dadurch ist es möglich, dass Sie unterscheiden können, ob der Anwender das betreffende Objekt lediglich zum Markieren oder Auswählen angeklickt hat, oder ob er tatsächlich einen Ziehvorgang einleiten möchte.

Wie aber sollten Sie beim Niederdrücken der Maustaste, also beim Eintreffen des MouseDown-Ereignisses bereits erahnen können, ob der Anwender den Mauszeiger noch bewegen wird oder nicht? Natürlich könnten Sie etwa im MouseDown-Ereignis die Position des Mauszeigers festhalten und in den eventuell eintreffenden nachfolgenden MouseMove-Ereignissen prüfen, ob sich der Mauszeiger mindestens um eine bestimmte Distanz in horizontaler und/oder vertikaler Richtung verschoben hat. Ist das der Fall, leiten Sie den Ziehvorgang ein. Anderenfalls führen Sie im MouseUp- oder im Click-Ereignis die eigentliche, reine Anklick-Funktionalität aus. Die vom System her vorgesehene minimale Bewegungsdistanz können Sie über die API-Funktion MSDN Library - API GetSystemMetricsGetSystemMetrics und deren Kennungen SM_CXDRAG und SM_CYDRAG ermitteln.

Sie können den ganzen Prüfungsvorgang aber auch einschließlich der Berücksichtigung der systemkonformen Distanz bereits im MouseDown-Ereignis der API-Funktion MSDN Library - API DragDetectDragDetect überlassen. Sie übergeben dieser Funktion das Fenster-Handle des betreffenden Objekts und die aktuelle Mauszeiger-Position. Sie können hier allerdings nicht die vom MouseDown-Ereignis übergebenen X- und Y-Koordinaten verwenden, da hier auf den ganzen Bildschirm bezogene Werte erwartet werden - diese können Sie mit der API-Funktion MSDN Library - API GetCursorPosGetCursorPos unmittelbar vorher ermitteln. Die Funktion wartet mit der Rückkehr so lange, bis entweder die Maustaste wieder an Ort und Stelle losgelassen oder bis der Mauszeiger um die eingestellte Distanz bewegt wurde. Im ersteren Fall ist der Rückgabewert 0 und Sie könnten hier zum Ziehvorgang alternativ auszuführenden Code unterbringen, und auch den Code, der sonst im nun nicht mehr ausgelösten MouseUp-Ereignis zu bearbeiten wäre. Ist der Mauszeiger genügend weit bewegt worden, gibt die Funktion 1 zurück und der Ziehvorgang sollte eingeleitet werden. Die weiteren Mausereignisse sowohl beim VB-Drag&Drop als auch beim OLE-Drag&Drop werden dann vom System selbst verwaltet.

Da Sie unbedingt die aktuelle Mauszeiger-Position benötigen und daher die Funktion GetCursorPos immer unmittelbar vorher aufrufen sollten, stecken wir die beiden zusammengehörenden Aufrufe in eine Hilfs-Funktion. Sie übergeben dieser das erwartete Fenster-Handle und erhalten True als Rückgabewert, wenn der Mauszeiger entsprechend bewegt worden war.

Wundern Sie sich nicht über gegebenenfalls abweichende Deklarationen der Funktion DragDetect, denen Sie anderenorts vielleicht begegnen (etwa im VB-API-Viewer - dort ist die Übergabe der Mausposition als benutzerdefinierte Variable des Typs POINTAPI deklariert). Sowohl die Funktion (als wohl auch die Deklarateure des API-Viewers) scheinen auf den ersten Blick noch in der 16-Bit-Welt zu leben und die Koordinaten des Mauszeigers als Integer-Wertepaar zu erwarten. Die Funktion ist ja aber eigentlich nicht für Visual Basic geschrieben worden, sondern zur Verwendung in der Fenster-Prozedur eines in C geschriebenen Windows-Programms gedacht gewesen. Und dort werden mit den Maus-Nachrichten die Koordinaten im höher- und niederwertigen Wort eines Long-Integers zusammengefasst angeliefert und können so direkt weitergereicht werden. In der 16-Bit-Welt entsprach das durchaus zufällig der damals gültigen Deklaration des Datentyps POINTAPI mit zwei Integer-Elementen - aber nicht mehr der heutigen mit zwei Long-Elementen. Der Versuch der direkten Übergabe in der heutigen Form, wie sie für die Funktion GetCursorPos benötigt wird, scheitert und wird von VB mit der Fehlermeldung "Falsche DLL-Aufrufkonvention" quittiert. Der Versuch, zusätzlich noch die alte Zwei-Integer-Version zu deklarieren und zu verwenden, scheitert jedoch gleichermaßen. Die ausdrückliche Zerlegung der Deklaration in zwei separate Integer-Parameter funktioniert hingegen.

Private Type POINTAPI
  X As Long
  Y As Long
End Type

Private Declare Function DragDetect Lib "user32" _
 (ByVal hWnd As Long, ByVal px As Integer, _
 ByVal py As Integer) As Long
Private Declare Function GetCursorPos Lib "user32" _
 (lpPoint As POINTAPI) As Long

Public Function BeginDrag(hWnd As Long) As Boolean
  Dim nPoint As POINTAPI
  
  GetCursorPos nPoint
  BeginDrag = CBool(DragDetect(hWnd, CInt(nPoint.X), CInt(nPoint.Y)))
End Function

Der Aufruf im MouseDown-Ereignis einer PictureBox sähe etwa wie folgend aus:

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

  If Button Then
    If BeginDrag(Me.hWnd) Then
      Picture1.Drag
    End If
  End If
End Sub

Modul modBeginDrag (modBeginDrag.bas - ca. 0,7 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