Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi AnsiString erzeugen (https://www.delphipraxis.net/149427-ansistring-erzeugen.html)

Berni68 21. Mär 2010 07:41


AnsiString erzeugen
 
Hallo,

wie kann man einen AnsiString dynamisch erzeugen und wieder freigeben?

Uwe Raabe 21. Mär 2010 08:35

Re: AnsiString erzeugen
 
Entweder verstehe ich deine Frage nicht richtig oder sie erübrigt sich, da Delphi die String-Verwaltung vollkommen transparent für den Programmierer vornimmt.

Berni68 21. Mär 2010 08:52

Re: AnsiString erzeugen
 
Es geht eigentlich um die "Typumwandlung string -> PAnsiChar"
ich habe eine TStringList x brauche die einzelnen Strings aber als AnsiString
was geht wenn man

var
h: AnsiString;

h:= x[i];
record.abc:= PAnsiChar(h);

Jetzt braucht man für jeden Eintrag in x ein h, also möchte ich ein AnsiString erzeugen.

Ich hoffe ich habe mich einigermassen verständlich ausgedrückt. Allerdings sieht man wohl dass mir hier noch das Verständnis fehlt.

Fridolin Walther 21. Mär 2010 09:12

Re: AnsiString erzeugen
 
Wozu willst Du überhaupt explizit einen PAnsiChar in Deinem Record eintragen, wenn AnsiString bereits ein Pointer ist? Das einzige was Du Dir durch PAnsiChar einfängst ist, daß Du Dich selbst um die Speicherverwaltung kümmern musst (was Dir ja offensichtlich Probleme bereitet).

Entsprechend wäre es sinnvoll .abc als AnsiString statt PAnsiChar zu definieren und via record.abs := AnsiString(x[i]); den String aus der Stringliste direkt zuzuweisen (was im Endeffekt den WideString aus der Stringlist in einen AnsiString konvertiert und einen Pointer auf den String in .abc packt).

Berni68 21. Mär 2010 09:29

Re: AnsiString erzeugen
 
Es geht um die Konvertierung einer Funktion von Delphi5 auf Delphi2010 (Die Funktion stammt allerdings nicht von mir)

Delphi-Quellcode:
function String2AnsiString(s:String):AnsiString;
var
  h: AnsiString;
begin
 h:= s;
 Result:= PAnsiChar(h);
end;
// uses MAPI
function SendEMail(Handle:THandle; Mail:TStrings):Cardinal;
type
  TAttachAccessArray= array [0..0] of TMapiFileDesc;
  PAttachAccessArray= ^TAttachAccessArray;
var
  MapiMessage: TMapiMessage;
  Receip: TMapiRecipDesc;
  Attachments: PAttachAccessArray;
  AttachCount: Integer;
  i1: integer;
  FileName: string;
  dwRet: Cardinal;
  MAPI_Session: Cardinal;
  WndList: Pointer;
  h1,h2: AnsiString;
begin
Result:= MAPI_E_FAILURE;
  dwRet:= MapiLogon(Handle, PAnsiChar(''), PAnsiChar(''), MAPI_LOGON_UI or MAPI_NEW_SESSION, 0, @MAPI_Session);

  if (dwRet<>SUCCESS_SUCCESS) then
    begin
      MessageBox(Handle, PChar('Error while trying to send email'), PChar('Error'), MB_ICONERROR or MB_OK);
    end
  else
    begin
      FillChar(MapiMessage, SizeOf(MapiMessage), #0);
      Attachments:= nil;
      FillChar(Receip, SizeOf(Receip), #0);

      if Mail.Values['to']<>'' then begin
        Receip.ulReserved:= 0;
        Receip.ulRecipClass:= MAPI_TO;
        Receip.lpszName:= PAnsiChar(String2AnsiString(Mail.Values['to']));            // geht
        Receip.lpszAddress:= PAnsiChar(String2AnsiString('SMTP:' + Mail.Values['to'])); // geht
        Receip.ulEIDSize:= 0;
        MapiMessage.nRecipCount:= 1;
        MapiMessage.lpRecips:= @Receip;
      end;

      AttachCount:=0;
      for i1:=0 to MaxInt do begin
        if Mail.Values['attachment' + IntToStr(i1)] = '' then break;
        Inc(AttachCount);
      end;
      if AttachCount>0 then begin
      showmessage(inttostr(AttachCount));
        GetMem(Attachments, SizeOf(TMapiFileDesc) * AttachCount);

        for i1:=0 to AttachCount-1 do begin
          FileName:= Mail.Values['attachment' + IntToStr(i1)];
          Attachments[i1].ulReserved:= 0;
          Attachments[i1].flFlags:= 0;
          Attachments[i1].nPosition:= ULONG($FFFFFFFF);
          h1:= FileName;
            Attachments[i1].lpszPathName:= PAnsiChar(h1);    // geht nicht mit String2AnsiString
          h2:= ExtractFileName(FileName);
            Attachments[i1].lpszFileName:= PAnsiChar(h2);    // geht nicht mit String2AnsiString
          Attachments[i1].lpFileType:= nil;
        end;
        MapiMessage.nFileCount := AttachCount;
        MapiMessage.lpFiles := @Attachments^;
      end;

      if Mail.Values['subject']<>'' then MapiMessage.lpszSubject:= PAnsiChar(String2AnsiString(Mail.Values['subject'])); // geht
      if Mail.Values['body']<>'' then MapiMessage.lpszNoteText:= PAnsiChar(String2AnsiString(Mail.Values['body'])); // geht

      WndList := DisableTaskWindows(0);
      try
        Result:= MapiSendMail(MAPI_Session, Handle, MapiMessage, MAPI_DIALOG, 0);
      finally
        EnableTaskWindows(WndList);
      end;
      MapiLogOff(MAPI_Session, Handle, 0, 0);
    end;
end;
Einfach anzuwenden:
Delphi-Quellcode:
procedure TTestForm.Mail1Click(Sender: TObject);
var
  mail: TStringList;
begin
  mail:= TStringList.Create;
  try
      mail.values['to']:= 'fifi@abc.de';
      mail.values['subject']:= 'subject';
      mail.values['body']:= 'body body body';
      mail.values['attachment0']:= 'C:\Anhang.txt';
      mail.values['attachment1']:= 'C:\Anhang2.txt';
    SendEMail(Self.Handle, mail);
  finally
    mail.Free;
  end;
end;
Die Funktion String2AnsiString hab ich 'dazugebastelt' (offensichtlich nicht wirklich verstanden)
geht aber bei den Datei-Anängen nicht Der Rest ist ok. Den Unterschied sehe ich nicht.
Jetzt mit den Variablen h1,h2: AnsiString; kommt logischerweise immer nur der letzte Anhang an also im Beispiel 'C:\Anhang2.txt';

Fridolin Walther 21. Mär 2010 09:50

Re: AnsiString erzeugen
 
Zitat:

Zitat von Berni68
Die Funktion String2AnsiString hab ich 'dazugebastelt' (offensichtlich nicht wirklich verstanden)
geht aber bei den Datei-Anängen nicht Der Rest ist ok. Den Unterschied sehe ich nicht.

Wozu die String2AnsiString Funktion? Letztlich willst Du ja ohnehin einen WideString zu einem AnsiString casten. Entsprechend tuts auch AnsiString(). Dadurch ersparst Du Dir übrigens auch die Hilfsvariablen.

Delphi-Quellcode:
// uses MAPI
function SendEMail(Handle:THandle; Mail:TStrings):Cardinal;
type
  TAttachAccessArray= array [0..0] of TMapiFileDesc;
  PAttachAccessArray= ^TAttachAccessArray;
var
  MapiMessage: TMapiMessage;
  Receip: TMapiRecipDesc;
  Attachments: PAttachAccessArray;
  AttachCount: Integer;
  i1: integer;
  FileName: string;
  dwRet: Cardinal;
  MAPI_Session: Cardinal;
  WndList: Pointer;
  h1,h2: AnsiString;
begin
Result:= MAPI_E_FAILURE;
  dwRet:= MapiLogon(Handle, PAnsiChar(''), PAnsiChar(''), MAPI_LOGON_UI or MAPI_NEW_SESSION, 0, @MAPI_Session);

  if (dwRet<>SUCCESS_SUCCESS) then
    begin
      MessageBox(Handle, PChar('Error while trying to send email'), PChar('Error'), MB_ICONERROR or MB_OK);
    end
  else
    begin
      FillChar(MapiMessage, SizeOf(MapiMessage), #0);
      Attachments:= nil;
      FillChar(Receip, SizeOf(Receip), #0);

      if Mail.Values['to']<>'' then begin
        Receip.ulReserved:= 0;
        Receip.ulRecipClass:= MAPI_TO;
        Receip.lpszName:= PAnsiChar(AnsiString(Mail.Values['to']));
        Receip.lpszAddress:= PAnsiChar(AnsiString('SMTP:' + Mail.Values['to']));
        Receip.ulEIDSize:= 0;
        MapiMessage.nRecipCount:= 1;
        MapiMessage.lpRecips:= @Receip;
      end;

      AttachCount:=0;
      for i1:=0 to MaxInt do begin
        if Mail.Values['attachment' + IntToStr(i1)] = '' then break;
        Inc(AttachCount);
      end;
      if AttachCount>0 then begin
        GetMem(Attachments, SizeOf(TMapiFileDesc) * AttachCount);

        for i1:=0 to AttachCount-1 do begin
          FileName:= Mail.Values['attachment' + IntToStr(i1)];
          Attachments[i1].ulReserved:= 0;
          Attachments[i1].flFlags:= 0;
          Attachments[i1].nPosition:= ULONG($FFFFFFFF);
          Attachments[i1].lpszPathName:= PAnsiChar(AnsiString(FileName));
          Attachments[i1].lpszFileName:= PAnsiChar(AnsiString(ExtractFileName(FileName)));
          Attachments[i1].lpFileType:= nil;
        end;
        MapiMessage.nFileCount := AttachCount;
        MapiMessage.lpFiles := @Attachments^;
      end;

      if Mail.Values['subject']<>'' then MapiMessage.lpszSubject:= PAnsiChar(AnsiString(Mail.Values['subject']));
      if Mail.Values['body']<>'' then MapiMessage.lpszNoteText:= PAnsiChar(AnsiString(Mail.Values['body']));

      WndList := DisableTaskWindows(0);
      try
        Result:= MapiSendMail(MAPI_Session, Handle, MapiMessage, MAPI_DIALOG, 0);
      finally
        EnableTaskWindows(WndList);
      end;
      MapiLogOff(MAPI_Session, Handle, 0, 0);
    end;
end;
Beim Debuggen wurden die Records übrigens korrekt gefüllt. Also sollte es funktionieren. Testen kann ichs allerdings nicht, da ich keinen MAPI fähigen Email Client installiert hab. Von MAPI im Allgemeinen würde ich übrigens abraten. Die Schnittstelle gilt als veraltet und soll "demnächst" komplett entfernt werden.

Berni68 21. Mär 2010 10:12

Re: AnsiString erzeugen
 
Mit der Konvertierung hast du vollkommern recht, das klappt jetzt soweit, (ist auch irgendwie logisch wenn man sich das jetzt so anschaut)
die Felder im Record weden auch gefüllt, es kommt im MailClient allerdings immer nur der letzte
Anhang an (obwohl MapiMessage.nFileCount auf dem richtigen wert steht)

Aber andersherum, was wäre eine Alternative zu mapi die ebenso einfach zu nutzen ist und vergleichbare Funktionalität bietet?


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:22 Uhr.

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