Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Drag&Drop aus neuem Outlook (https://www.delphipraxis.net/216882-drag-drop-aus-neuem-outlook.html)

stalkingwolf 17. Mär 2025 15:31

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

stalkingwolf 17. Mär 2025 17:44

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:
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;
Ein paar im Netz vermuten die Daten sind in Chromium Web Custom MIME Data Format.
Aber das ist nur immer um die 1500 Zeichen. Vermutlich nur Metadaten. Aber ich komme an die Infos nicht ran.

Redeemer 19. Mär 2025 17:18

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:

Zitat von stalkingwolf (Beitrag 1547197)
Wenn ich den Drag&Drop auf dem Desktop ablege, dann bekommt man mittlerweile eine .eml

Das war schon immer so.

himitsu 19. Mär 2025 17:36

AW: Drag&Drop aus neuem Outlook
 
Outlook hatte früher eine .MSG und keine .EML geliefert.

HolgerX 20. Mär 2025 06:12

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!

jbg 20. Mär 2025 20:22

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:
https://github.com/project-jedi/jvcl...795e4f7ddc067a

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;

Redeemer 21. Mär 2025 12:46

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.

himitsu 21. Mär 2025 13:30

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)

dummzeuch 21. Mär 2025 15:50

AW: Drag&Drop aus neuem Outlook
 
Zitat:

Zitat von Redeemer (Beitrag 1547336)
Wo ist eigentlich die vollständige Dokumentation von Jedi?

LOL

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:

https://wiki.delphi-jedi.org

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.

jbg 21. Mär 2025 16:14

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:
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;
Dann muss man diese Klasse registrieren:
Delphi-Quellcode:
initialization
  TNewAndClassicOutlookDataFormat.RegisterDataFormat;
Dann muss man an der TDropEmptyTarget Komponente die Eigenschaft "AllowAsyncTransfer" auf True stellen und beim DataFormatAdapter die "DataFormatClass"-Eigenschaft auf "TNewAndClassicOutlookDataFormat" setzen.
Delphi-Quellcode:
DropEmptyTarget1.AllowAsyncTransfer := True; // Required for the "New Outlook" to receive EML filenames
DataFormatAdapterOutlook.DataFormatClass := TNewAndClassicOutlookDataFormat;
DataFormatAdapterOutlook.Enabled := True; // Setting DataFormClass disables the DataFormat
Jetzt kann man im OnDrop-Ereignis die Dateinamen empfangen:
Delphi-Quellcode:
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;
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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:42 Uhr.
Seite 1 von 2  1 2      

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