2009-06-03 8 views
0

Ich frage mich, ob jemand weiß, ob es eine Möglichkeit gibt, OLE-Datei ziehen aus einer C++ Win32-Anwendung ohne zu blockieren, bis der Ziehen abgeschlossen.Asynchrones OLE Drag & Drop möglich?

Ich verwende derzeit DoDragDrop(), um den Ziehvorgang zu starten, aber diese Funktion kehrt nicht zurück, bis der Ziehvorgang abgeschlossen ist. Das Problem dabei ist, dass die Animation in meinem Programm anhält, während ein Ziehen ausgeführt wird.

Ich habe versucht, diesen Befehl von einem neuen Thread zu starten, aber das hat nicht funktioniert, auch wenn ich OleInitialize() in diesem Thread aufgerufen habe.

Die einzige Sache, die ich fand, die damit verbunden war, ist die Datenoperation danach (wie Kopieren/Verschieben der Datei/Daten) asynchron. In meiner Anwendung Drag & Drop wird nicht für solche Operationen verwendet, so ist es kein Problem, und das Hauptproblem ist der Block, während der Benutzer das Ziehen ausführt. Bearbeiten: Um dies deutlicher zu machen: IAsyncOperation auf dem DataObject ist keine Lösung für dieses Problem, da es die Operation nur auftritt, nachdem die Daten asynchron verschoben wurden. Das Problem, das ich habe, ist das Blockierungsverhalten von dem Punkt, an dem der Benutzer das Ziehen beginnt, bis zu dem Moment, in dem er die Maustaste loslässt.

2 Lösungen kommen mir in den Sinn, aber ich hoffe, es wird einen leichteren oder besseren Weg geben, dies zu erreichen.

  1. Umsetzung meiner eigenen (nicht-ole) drag & Drop. Dies wäre mehr Arbeit, und ich fand es tatsächlich eine nette Funktion, dass es möglich war, Dateien aus meinem Programm in andere Programme zu ziehen.

  2. Erstellen/starten Sie einen neuen Prozess und starten Sie den Ziehvorgang von dort. Da ich keine Probleme habe, wenn ich eine Datei aus Windows Explorer in meine Anwendung ziehe, könnte das funktionieren. Der Drag sollte aber sofort starten, und ich habe keine Ahnung, ob die Erstellung eines neuen Prozesses eine spürbare Zeit in Anspruch nimmt.

Antwort

0

Ich bin in dieses geraten. Ich würde einen neuen Thread starten und dies tun. CreateProcess braucht Zeit, aber wahrscheinlich nicht viel. Sie könnten den Thread oder den Prozess immer im Voraus erstellen und ihn so synchronisieren, dass er direkt vor einem Aufruf von DoDragDrop() blockiert wird, und dann die Blockierung von der Hauptanwendung aufheben.

2

Wenn Ihr IDataObject die IAsyncOperation-Schnittstelle unterstützt, hat das IDropTarget die Option, IDropTarget :: Drop() schnell beenden zu lassen und dann die tatsächliche Übertragung asynchron durchzuführen. Das IDropTarget muss jedoch nicht IAsyncOperation unterstützen.

Dieses Verhalten wird in MSDN's documentation beschrieben. Außerdem wird DoDragDrop() nicht beendet, bis der Benutzer die Maus loslässt, um den Drop zu initialisieren, sodass Ihr Thread, der DoDragDrop() aufruft, weiterhin blockiert wird, während der Benutzer die Maus zieht.

1

Remys Antwort ist korrekt. Es gibt auch eine Reihe von Blog-Posts aus der The Old New Thing über die Implementierung IDataObject 's. Es geht nicht in IAsyncOperation, aber es ist ein Anfang.

2

Führen Sie Ihre Animation in einem separaten Thread aus.