Delphi-PRAXiS
Seite 1 von 7  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi DragOver vom Explorer erkennen (https://www.delphipraxis.net/79771-dragover-vom-explorer-erkennen.html)

Guido Eisenbeis 27. Okt 2006 23:08


DragOver vom Explorer erkennen
 
Hallo.

Wenn man im Explorer (oder vom Desktop) eine Datei per DragDrop ins eigene Formular zieht und dort loslässt, kann man sich die Daten der Quelle einverleiben.

Für mich geht es aber um den Schritt vorher: das "DragOver". Ich habe eine Anwendung aufgebaut, die virtuelle Explorer-Listviews benutzt. Betrachtet man nun ein einzelnes ListView, so kann es vom User auf- oder zugeklappt werden.

Was ich erreichen will, ist ein automatisches Aufklappen, wenn bei einem DragDrop vom Explorer mit der Maus über einen "Aufklapp"-Button gefahren wird.

Glaubt mir, ich habe mich schon dusselig gesucht! Im Internet, in den Foren, in der Delphi-Hilfe, der MSDN und wer weiß wo sonst noch! Ich weiß noch nicht mal, welche Suchbegriffe ich für dieses Thema nehmen soll. Zu "Drag & Drop", "DragOver", oder "Drag systemweit erkennen" gibt es Millionen "Treffer". Die haben jedoch alle nichts mit dem Thema zu tun.

Das Einzige was ich gefunden habe, ist "Eine Message vor WM_DropFiles (in der Art OnStartDrag)". Da hatte jemand genau das gleiche Problem. Leide bekam er keine Antwort!

Kurzfassung:

Wie kann ich über einem eigenen Control (z. B. TPanel) ein "DragOver" vom Explorer erkennen und z. B. ein ListView vergrößern ("aufklappen")?

Grüße,
Guido.

xaromz 28. Okt 2006 09:51

Re: DragOver vom Explorer erkennen
 
Hallo,

vielleicht kannst Du Dir mit IDropTargetHelper was basteln.

Oder noch einfacher: MSDN-Library durchsuchenIDropTarget:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Classes, Controls, Forms, ActiveX;

type
  TForm1 = class(TForm, IDropTarget)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    function DragEnter(const dataObj: IDataObject; grfKeyState: Longint;
      pt: TPoint; var dwEffect: Longint): HResult; stdcall;
    function DragOver(grfKeyState: Longint; pt: TPoint;
      var dwEffect: Longint): HResult; stdcall;
    function DragLeave: HResult; stdcall;
    function Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint;
      var dwEffect: Longint): HResult; stdcall;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Dialogs;

{ TForm1 }

function TForm1.DragEnter(const dataObj: IDataObject; grfKeyState: Integer;
  pt: TPoint; var dwEffect: Integer): HResult;
begin
  dwEffect := DROPEFFECT_COPY;
  Result := S_OK;
end;

function TForm1.DragLeave: HResult;
begin
  Result := S_OK;
end;

function TForm1.DragOver(grfKeyState: Integer; pt: TPoint;
  var dwEffect: Integer): HResult;
begin
  Color := RGB(Random(256), Random(256), Random(256));
  dwEffect := DROPEFFECT_COPY;
  Result := S_OK;
end;

function TForm1.Drop(const dataObj: IDataObject; grfKeyState: Integer;
  pt: TPoint; var dwEffect: Integer): HResult;
begin
  dwEffect := DROPEFFECT_COPY;
  Result := S_OK;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  R: Integer;
begin
  R := RegisterDragDrop(Handle, Self);
  if R <> S_OK then
    ShowMessage('Couldn''t initialize Drag''n''Drop!');
  Randomize;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  RevokeDragDrop(Handle);
end;

initialization
  OleInitialize(nil);
end.
Gruß
xaromz

xaromz 28. Okt 2006 13:30

Re: DragOver vom Explorer erkennen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

weil ich sowas schon lange machen wollte, habe ich gleich eine Komponente gebastelt, die das Droppen von Dateien behandelt.

Gruß
xaromz

Guido Eisenbeis 28. Okt 2006 15:41

Re: DragOver vom Explorer erkennen
 
Hallo xaromz.

Das hört sich doch gut an! Ich werde es heute noch ausprobieren und mich dann melden.

Bis hierhin schon mal vielen Dank.

Guido.

Guido Eisenbeis 28. Okt 2006 18:59

Re: DragOver vom Explorer erkennen
 
Hallo xaromz.

Als Allererstes ein dickes Dankeschön! Die Komponente funktioniert (fast) wunderbar.

Für meine Zwecke sind insbesondere die Ereignisse "DragEnter" und "DragLeave" geeignet. Umgangssprachlich ist es zwar richtig, dass ich beim "DragOver" über z. B. Panel1 das ListView1 zeigen will. Programmiertechnisch sieht das anders aus:
Genaugenommen soll, wie oben schon angedeutet, "DragEnter" ermittelt werden. Ab dann läuft eine Verzögerung von ca. 0,5 bis 1 Sekunde an. Wird das Panel1 innerhalb dieser Verzögerung wieder verlassen (= "DragLeave"), so wird das Zeigen des ListView1 NICHT ausgeführt.

Insofern ist deine Komponente genau das Richtige für meine Zwecke!

2 Probleme bestehen noch:

Erstens:

Wie kann ich mehrere Controls an "ShellDroper" zuweisen? So dass z. B. Panel1 .. Panelx überwacht werden.

Zweitens:

Mein Test-Programm enthält die Form1, darauf sind zwei Panels (Panel1 und Panel2). Panel1 habe ich der Komponente ("ShellDropper1") zur Designtime zugewiesen. Während der Ausführung des Test-Programms funktioniert alles ( "DragEnter", "DragOver" und "DragLeave"). Jedoch beim Beenden des Test-Programms wird folgende Exeption ausgelöst:

----------------------------------------
Debugger Exception Notification
----------------------------------------
Project Project1.exe raised exception class EInvalidOperation with message 'Control 'Panel1' has no parent window'.

Danach habe ich im Code deiner Komponente fogendes hinzugefügt:
Delphi-Quellcode:
 ...

initialization
  OleInitialize(nil);

finalization
  OleUninitialize; // <-- hinzugefügt (Ist das richtig/notwendig?)

end.
Leider bleibt die oben beschriebene Exeption.

Wie kann das behoben werden?


Nochmal dickes Lob für die Komponente! Ich hoffe, dass wir zumindest das Problem mit der Exeption lösen können.

Gruß,
Guido.

xaromz 28. Okt 2006 23:15

Re: DragOver vom Explorer erkennen
 
Hallo,
Zitat:

Zitat von Guido Eisenbeis
Erstens:

Wie kann ich mehrere Controls an "ShellDroper" zuweisen? So dass z. B. Panel1 .. Panelx überwacht werden.

Dazu musst Du die Komponente etwas umbauen. Schau Dir mal die beiden Methoden "Enable" und "Disable" an. Dort wird das Control als DropTarget registriert bzw. abgemeldet. Wenn Du mehrere Controls hast, musst Du eben eine Liste verwalten. Vielleicht habe ich am Sonntag etwas Zeit, das Ganze umzuschreiben.
Zitat:

Zitat von Guido Eisenbeis
Zweitens:

Mein Test-Programm enthält die Form1, darauf sind zwei Panels (Panel1 und Panel2). Panel1 habe ich der Komponente ("ShellDropper1") zur Designtime zugewiesen. Während der Ausführung des Test-Programms funktioniert alles ( "DragEnter", "DragOver" und "DragLeave"). Jedoch beim Beenden des Test-Programms wird folgende Exeption ausgelöst:

Das liegt daran, dass beim Zerstören der Komponente das Control wieder abgemeldet werden muss. Dazu wird das Handle des Controls verwendet. Wenn dieses aber schon zerstört wird, dann ist das Handle ungültig und der Aufruf schlägt fehl. Ich sehe mir das noch mal genauer an.

Gruß
xaromz

xaromz 29. Okt 2006 10:13

Re: DragOver vom Explorer erkennen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

so, jetzt kann die Komponente auch mit mehreren Controls umgehen.
Das Control, für welches das Ereignis gerade gilt, steckt im "Sender".

Die Exception sollte jetzt nicht mehr kommen. Leider habe ich es aber nicht hinbekommen, ein Control abzumelden, bevor es sein Handle verliert. Deshalb kann ich nicht garantieren, dass es hier kein Ressourcenleck gibt. Aber eigentlich sollte Windows erkennen, dass das Handle zerstört wird und selbiges abmelden.

Gruß
xaromz

Guido Eisenbeis 29. Okt 2006 12:15

Re: DragOver vom Explorer erkennen
 
Hallo xaromz.

Hier schon mal ein Vorweg-Lob! In meinem Kurztest hat das sehr gut hingehauen. Und außerdem die Eingabe für mehrere Contols find ich gelungen!

Den Bereich "TShellDropper.Notification" hatte ich schon im Auge. Da scheint sich ja auch was getan zu haben.

Ich werde den neuen Code heute noch ausführlich testen und melde mich dann.

Bis dahin: Danke!

Guido.

Guido Eisenbeis 30. Okt 2006 21:04

Re: DragOver vom Explorer erkennen
 
Hallo xaromz.

Es gibt eine gute und eine schlechte Nachricht.

Zuerst die Gute:

So wie die Komponente "ShellDropper" angelegt ist, das find ich echt genial. Es können kompfortabel mehrere Controls zur Überwachung angegeben werden. Jedes Control kann einzeln enabled oder disabled werden. Trozdem benutzen alle Controls die gleichen Event-Routinen (z. B. für DragEnter und DragLeave). Dadurch ist die Handhabung wirklich gut. Der Betrieb funktioniert dann auch wirklich so, wie man es sich vorstellt.

Dann die Schlechte:

Nach der Benutzung der Komponente in der IDE verhält sich die IDE "sonderbar". Es kommen z. B. Exeptions wenn ich den Code von dieser oder von anderen Komponenten ansehe. Z. B. "Forms" oder "Windows".

Dann ist es mir fast unmöglich, eine "ShellDropper"-Komponente zu löschen. Das heißt, ich setzt eine Komponente auf ein leeres Form. Ob ich nun ein anderes Control zur Überwachung zuweise oder nicht, wenn ich die "ShellDropper"-Komponente löschen will beginnt ein Exeption-Regen:

Error
---------------------------
Access violation at address 51F3155D in module 'rtl100.bpl'. Read of address 95D5C950.
---------------------------

Error
---------------------------
Invalid pointer operation
---------------------------

Error
---------------------------
Borland Delphi for Microsoft Windows: bds.exe - Fehler in Anwendung
---------------------------
Die Ausnahme "Unbekannter Softwarefehler" (0x0eedfade) ist in der Anwendung an der Stelle 0x7c81eb33 aufgetreten.
---------------------------

---------------------------
Application Error
---------------------------
Exception EInvalidPointer in module rtl100.bpl at 0000657D.Invalid pointer operation.
---------------------------


Hat das vielleicht mit dem Ressourcenleck zu tun, das du erwähnt hast?

Gruß,
Guido.

xaromz 30. Okt 2006 22:37

Re: DragOver vom Explorer erkennen
 
Hallo,
Zitat:

Zitat von Guido Eisenbeis
Zuerst die Gute:
...

Das hört man gerne.
Zitat:

Zitat von Guido Eisenbeis
Dann die Schlechte:

Nach der Benutzung der Komponente in der IDE verhält sich die IDE "sonderbar". Es kommen z. B. Exeptions wenn ich den Code von dieser oder von anderen Komponenten ansehe. Z. B. "Forms" oder "Windows".

Dann ist es mir fast unmöglich, eine "ShellDropper"-Komponente zu löschen. Das heißt, ich setzt eine Komponente auf ein leeres Form. Ob ich nun ein anderes Control zur Überwachung zuweise oder nicht, wenn ich die "ShellDropper"-Komponente löschen will beginnt ein Exeption-Regen:

Das hört man nicht so gerne.
Ich habe die Komponente nur in Delphi 2006 getestet, da funktioniert sie einwandfrei. Sie ist eigentlich auch so konstruiert, dass sie in der IDE nicht aktiv wird. Ich werde mir das noch mal ansehen.
Zitat:

Zitat von Guido Eisenbeis
Hat das vielleicht mit dem Ressourcenleck zu tun, das du erwähnt hast?

Wahrscheinlich nicht, aber ausschließen kann ich es nicht. Tritt der Fehler sofort auf, oder erst, nachdem Du das Programm einmal gestartet hast?

Gruß
xaromz


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:04 Uhr.
Seite 1 von 7  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz