![]() |
Drag&Drop aus neuem Outlook
Moin,
leider bekommen wir immer mehr Anfragen wegen Drag&Drop aus dem neuen Outlook. Die alte Version funktioniert leider gar nicht mehr. Hat sich jemand damit jemand schon beschäftigt? Im Netz habe ich leider nichts gefunden. Wenn ich den Drag&Drop auf dem Desktop ablege, dann bekommt man mittlerweile eine .eml Das nenne ich ja schon man fortschrittlich von Microsoft. Die Datei kann unser Programm dann auch einwandfrei verarbeiten. Nun kann ich unseren Kunden natürlich den Umweg über den Desktop erklären, aber wie Anwender so sind "Ging früher warum nicht? Nutze doch immer noch Outlook wie früher". ChatGPT erwähnt das der neue Austausch asynchron ist. Beim ablegen auf den Desktop fragt auch Outlook immer ob man die Datei beibehalten will und legt erst beim Klick auf Bestätigen die Datei ab. Gruß Sven |
AW: Drag&Drop aus neuem Outlook
Mal etwas rumgespielt und man erhält folgende Formate :
- DragContext - DragImageBits - chromium/x-renderer-taint - CF_HDROP - Chromium Web Custom MIME Data Format CF_HDROP bekomme ich nicht ausgelesen. Was normalerweise sonst immer funktioniert. DataObj.GetData(FmtEtc, Medium) ist nicht S_OK
Code:
Ein paar im Netz vermuten die Daten sind in Chromium Web Custom MIME Data Format.
procedure GetFileListFromObj(const DataObj: IDataObject; FileList: TStringList);
var FmtEtc: TFormatEtc; // specifies required data format Medium: TStgMedium; // storage medium containing file list DroppedFileCount: Integer; // number of dropped files Count,I: Integer; // loops thru dropped files FileNameLength: Integer; // length of a dropped file name FileName: pchar; // name of a dropped file begin FmtEtc.cfFormat := CF_HDROP; FmtEtc.ptd := nil; FmtEtc.dwAspect := DVASPECT_CONTENT; FmtEtc.lindex := -1; FmtEtc.tymed := TYMED_HGLOBAL; if DataObj.GetData(FmtEtc, Medium) = S_OK then begin try OleCheck(DataObj.GetData(FmtEtc, Medium)); try DroppedFileCount := DragQueryFile(Medium.hGlobal, $FFFFFFFF, nil, 255); for i := 0 to (DroppedFileCount - 1) do begin FileNameLength := DragQueryFile(Medium.hGlobal, i , nil, 0) + 1; FileName:= StrAlloc(FileNameLength); DragQueryFile(Medium.hGlobal,i , FileName, FileNameLength); FileList.Append( StrPas(FileName)); StrDispose(FileName); end; finally DragFinish(Medium.hGlobal); end; finally ReleaseStgMedium(Medium); end; end; end; Aber das ist nur immer um die 1500 Zeichen. Vermutlich nur Metadaten. Aber ich komme an die Infos nicht ran. |
AW: Drag&Drop aus neuem Outlook
Drag and Drop in mein Programm funktioniert bei uns übrigens auch bei aktuellen Office-365-Outlook (classic) nicht mehr (vorher, in Outlook 2016 MAK/C2R, funktionierten E-Mails und Anhänge im .eml-Format).
Ich hoffe sehr, dass niemand Outlook (new) verwendet versucht zu verwenden. Zitat:
|
AW: Drag&Drop aus neuem Outlook
Outlook hatte früher eine .MSG und keine .EML geliefert.
|
AW: Drag&Drop aus neuem Outlook
Hmm..
Wenn man ein bisschen googled bekommt man heraus, das Microsoft das Drag&Drop von Outlook 365 damals einfach nicht eingebaut hatte. In den letzten Jahren wurde 'Häpchenweise' etwas eingebaut, was aber nur ähnlich funktioniert. Ein wirklichen D&D ist es anscheinend nicht. MS will wohl, dass ihr keine Mails/Anhänge so einfach aus ihrem Universum (Outlook "Cloud") heraus bekommt! |
AW: Drag&Drop aus neuem Outlook
Microsoft habe beim neuen Outlook nicht nur beim Drag&Drop vom MSG-Format zum EML-Format gewechselt, sondern nutzt nun asynchrones Drag&Drop, das so gut wie keine (ältere) Anwendung implementiert.
Die JVCL-Komponente TJvDropTarget wurde im Dezember um das asynchrone Drag&Drop erweitert. Der entsprechende Git Commit ist: ![]() Ein aufs wesentliche reduziertes Beispiel mit der TJvDragTarget Komponente:
Delphi-Quellcode:
procedure TForm1.JvDropTargetDragAccept(Sender: TJvDropTarget; var Accept: Boolean);
begin Accept := (Sender.GetFilenames(nil) > 0) or // CF_HDROP (Sender.GetFileDescrCount > 0) or // CF_FILEDESCRIPTOR Sender.IsAsyncHDrop // "Neues Outlook" (WebApp) - Gültigkeit muss im OnDragDrop geprüft werden end; procedure TForm1.JvDropTargetDragDrop(Sender: TJvDropTarget; var Effect: TJvDropEffect; Shift: TShiftState; X, Y: Integer); var List: TStrings; begin // ... // GetFilenames bei Sender.IsAsyncHDrop = True funktioniert erst im OnDragDrop Sender.GetFilenames(List); // Dateien auf *.eml Suffix prüfen ... end; |
AW: Drag&Drop aus neuem Outlook
Damit kriege ich weder aus Outlook (classic) 365 noch Outlook 2016 irgendwas (weder Mails noch Anhänge). Dateien aus dem Explorer nimmt er. Ich habe keinen Filter drin, denn Outlook (classic) 365 liefert immer noch MSG. Mein bisheriges Outlook-Drag-and-Drop aus der Melander-Suite geht aber mit Outlook (classic) 365 nicht.
Wo ist eigentlich die vollständige Dokumentation von Jedi? Ich arbeite gerade das erste Mal damit. |
AW: Drag&Drop aus neuem Outlook
Doku?
Das ist doch selbsterklärend. :duck: Explorer nutzt CF_FILENAMES (je ANSI und Unicode) mit optionalem CF_FILEDESCRIPTOR Thunderbird CF_HDROP mit STGMEDIUM-Record, wo eine Liste zu TempFiles drin ist Outlook nutzt CF_HDROP mit IStream und das neue Outlook nutzt CF_HDROP mit IDataObjectAsyncCapability (bzw. eigentich IAsyncOperation) |
AW: Drag&Drop aus neuem Outlook
Zitat:
Die gab es noch nie, auch damals nicht, als das Projekt noch deutlich mehr aktive Mitglieder hatte. Du kannst bei Delphi-Bibliotheken inzwischen schon froh sein, dass es noch Updates gibt, über Doku denkt keiner mehr nach. Der ursprüngliche Ansatz liegt hier: ![]() Allerdings würde es mich nicht wunder, wenn dort keiner mehr die Zugangsdaten hätte. Wie immer bei Open Source Projekten: Wer Doku schreiben möchte, darf sich gerne anbieten. |
AW: Drag&Drop aus neuem Outlook
So, ich habe ein paar Minuten zeit gehabt und die Drag-and-Drop-Component-Suite etwas angeschaut. Eigentlich könnte die alles. Es ist nur nicht alles zusammengebaut.
Zuerst muss die Klasse TOutlookDataFormat um das Clipboard-Format TFileClipboardFormat erweitert werden und die Dateinamen, die per async. HDROP rein kommen, in einer Files-Stringliste abgelegt werden. Das macht die folgende DataFormat-Klasse. Man könnte das auch direkt in TOutlookDataFormat einbauen, aber so geht das auch, ohne Änderungen am Originalcode.
Delphi-Quellcode:
Dann muss man diese Klasse registrieren:
type
TNewAndClassicOutlookDataFormat = class(TOutlookDataFormat) private FFiles: TUnicodeStrings; protected class procedure RegisterCompatibleFormats; override; public constructor Create(AOwner: TDragDropComponent); override; destructor Destroy; override; function Assign(Source: TClipboardFormat): Boolean; override; function AssignTo(Dest: TClipboardFormat): Boolean; override; procedure Clear; override; property Files: TUnicodeStrings read FFiles; end; { TNewAndClassicOutlookDataFormat } class procedure TNewAndClassicOutlookDataFormat.RegisterCompatibleFormats; begin inherited RegisterCompatibleFormats; RegisterDataConversion(TFileClipboardFormat, 1); // New Outlook (WebApp) end; function TNewAndClassicOutlookDataFormat.Assign(Source: TClipboardFormat): Boolean; begin if Source is TFileClipboardFormat then begin FFiles.Assign(TFileClipboardFormat(Source).Files); Result := True; end else Result := inherited Assign(Source); end; function TNewAndClassicOutlookDataFormat.AssignTo(Dest: TClipboardFormat): Boolean; begin if Dest is TFileClipboardFormat then begin TFileClipboardFormat(Dest).Files.Assign(FFiles); Result := True; end else Result := inherited AssignTo(Dest); end; constructor TNewAndClassicOutlookDataFormat.Create(AOwner: TDragDropComponent); begin inherited Create(AOwner); FFiles := TUnicodeStringList.Create; end; destructor TNewAndClassicOutlookDataFormat.Destroy; begin FFiles.Free; inherited Destroy; end; procedure TNewAndClassicOutlookDataFormat.Clear; begin FFiles.Clear; inherited Clear; end;
Delphi-Quellcode:
Dann muss man an der TDropEmptyTarget Komponente die Eigenschaft "AllowAsyncTransfer" auf True stellen und beim DataFormatAdapter die "DataFormatClass"-Eigenschaft auf "TNewAndClassicOutlookDataFormat" setzen.
initialization
TNewAndClassicOutlookDataFormat.RegisterDataFormat;
Delphi-Quellcode:
Jetzt kann man im OnDrop-Ereignis die Dateinamen empfangen:
DropEmptyTarget1.AllowAsyncTransfer := True; // Required for the "New Outlook" to receive EML filenames
DataFormatAdapterOutlook.DataFormatClass := TNewAndClassicOutlookDataFormat; DataFormatAdapterOutlook.Enabled := True; // Setting DataFormClass disables the DataFormat
Delphi-Quellcode:
Um das "Bestätigen des Downloads" im New Outlook kommt man aber nicht herum, da es sich technisch dort um einen Download handelt. Und EML-Dateien "gefährlich" sind.
OutlookDataFormat := DataFormatAdapterOutlook.DataFormat as TNewAndClassicOutlookDataFormat;
if OutlookDataFormat.Files.Count > 0 then // "New Outlook" begin // Handle *.eml files for I := 0 to OutlookDataFormat.Files.Count - 1 do begin if SameText('.eml', ExtractFileExt(OutlookDataFormat.Files[I])) then begin Eml := TIdMessage.Create(nil); try Eml.LoadFromFile(OutlookDataFormat.Files[I]); // ... finally Eml.Free; end; end; end; end else begin // Handle "Classic Outlook" *.msg files OutlookDataFormat.Messages.LockSession; for I := 0 to OutlookDataFormat.Messages.Count - 1 do // ... end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz