2017-01-31 1 views
0

Ich möchte eine OLE Drag & Drop-Funktion implementieren. Dazu muss ich feststellen, dass die Maustaste angeklickt und bewegt wurde. Dann rufe ich DoDragDrop an, um die Drag & Drop-Funktion zu starten.IDropSourceNotify - wie zu implementieren

Um die Drag & Drop-Funktion zu erhalten, muss ich zuvor RegisterDragDrop aufrufen, um ein Fenster als Ziel der Drag & Drop-Operation zu registrieren. Wie die meisten Anwendungen basiert mein Hauptfenster auf mehreren Unterfenstern: TreeView, ListView, Edit, etc .. Mit IDropTarget::DragOver kann ich erkennen, ob das Zielunterfenster die Drag & Drop-Operation akzeptiert. Das funktioniert gut, wenn ich ein Objekt aus einer anderen Anwendung ziehe und der Mauszeiger auch zeigt, wenn das Ziel-Unterfenster den Drag & Drop-Vorgang akzeptiert.

Aber wenn ich die Drag & Drop-Funktion in meiner Anwendung mit DoDragDrop starten, ändert sich der Mauszeiger jetzt automatisch. Warum?

So kann ich die IDropSource::GiveFeedback Methode verwenden, um den Cursor des Zielunterfenster zu ändern. Aber ich kann nicht herausfinden, welches Unterfenster den Cursor ändern muss.

Wenn ich recht habe, sollte die IDropSourceNotify diese Informationen bereitstellen. Aber wie kann ich diese Klasse in den Drag & Drop-Betrieb einbeziehen?

Zusätzlich verstehe ich nicht, warum ich selbst mit dem Mauszeiger umgehen muss, wenn das Quellfenster in meiner Anwendung ist - aber es wird automatisch behandelt, wenn das Quellfenster in einer anderen Anwendung ist.

Last but not least, wenn ich den Cursor meines Unterfensters innerhalb IDropSource::GiveFeedback ändere, wird es gezeigt, wie ich es änderte. Aber da der Hauptthread innerhalb DoDragDrop ist, frage ich mich, wie Windows den geänderten Cursor erkennt. Wenn ich recht habe, frage Windows meine Anwendung mit der WM_NCHITTEST Nachricht, welcher Cursor angezeigt werden soll. Aber wie beantwortet meine Anwendung diese Nachricht, während der Haupt-Thread innerhalb DoDragDrop blockiert ist?

Ich arbeite mit Delphi XE4 auf einem Windows 7-System.

+0

Ihr Objekt muss 2 Schnittstellen 'IDropSourceNotify' und 'IDropSource' implementieren.Sie übergeben 'IDropSource' zu' DoDragDrop', 'IDropSourceNotify' System erhalten, wenn Aufruf' QueryInterface' auf 'IDropSource' – RbMm

+0

@RbMm Ich kann nicht sehen, wie IDropSourceNotify hier relevant ist. IDropSourceNotify wurde mit Vista eingeführt und IDropSource (einschließlich der Möglichkeit, den Cursor zu steuern) wurde in W2K eingeführt. – SpeedFreak

+0

@SpeedFreak - Frage war, wie "IDropSourceNotify" implementieren, und was also "IDropSourceNotify" später eingeführt wurde? – RbMm

Antwort

2

Die Drop-Quelle sollte keine Annahmen über das Drop-Ziel treffen - und niemals versuchen, die Benutzeroberfläche des Ziels zu ändern. Mit anderen Worten: Verwechseln Sie nicht die Cursor-Eigenschaft des Steuerelements unter dem Cursor.

Der Rückgabewert von IDropSource.GiveFeedback weist Windows an, entweder die standardmäßigen Drag-Drop-Cursor zu verwenden oder Sie selbst mit diesen Details zu arbeiten.

Wenn Sie DRAGDROP_S_USEDEFAULTCURSORS zurückgeben, wird der Standardcursor verwendet, der dem aktuellen Tropfeneffekt entspricht (der an GiveFeedback übergebene Parameter wird verwendet). Wenn Sie S_OK zurückgeben, können Sie den Cursor setzen, indem Sie die API-Funktion SetCursor aufrufen.

Ich würde empfehlen, dass Sie einfach DRAGDROP_S_USEDEFAULTCURSORS zurückgeben.

Eigentlich, es sei denn, Sie haben einen brennenden Wunsch, die inneren Details von COM-basierten Drag & Drop zu lernen, würde ich Ihnen empfehlen Google Drag Drop Delphi und verwenden Sie eine der bereits verfügbaren Bibliotheken.

Verwandte Themen