Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Problem beim Verknüpfung erstellen (https://www.delphipraxis.net/128459-problem-beim-verknuepfung-erstellen.html)

Sir K 30. Jan 2009 09:05


Problem beim Verknüpfung erstellen
 
Hallo Leute!
ich benutze die untere function von Delphi-Treff.de um eine Verknüpfung anzulegen...
Delphi-Quellcode:
function CreateLink(const AFilename, ALNKFilename, ADescription: string) : Boolean;
var
  psl : IShellLink;
  ppf : IPersistFile;
  wsz : PWideChar;
begin
  result:=false;
  if SUCCEEDED(CoCreateInstance(CLSID_ShellLink, nil,
  CLSCTX_inPROC_SERVER, IID_IShellLinkA, psl)) then
  begin
    psl.SetPath(PChar(AFilename));
    psl.SetDescription(PChar(ADescription));
    psl.SetWorkingDirectory(PChar(ExtractFilePath(AFilename)) ;);
    if SUCCEEDED(psl.QueryInterface(IPersistFile, ppf)) then
    begin
      GetMem(wsz, MAX_PATH*2);
      try
        MultiByteToWideChar(CP_ACP, 0, PChar(ALNKFilename), -1, wsz, MAX_PATH);
        ppf.Save(wsz, true);
        result:=true;
      finally
        FreeMem(wsz, MAX_PATH*2);
      end;
    end;
  end;
end;
Nur hab ich jetzt das Problem dass ich in einer Zeile beim compilieren die Meldung erhalte "Inkompatible Datentypen 'Char' und 'AnsiChar'". Kann mir einer sagen obs dafür ne funktion wie z.b IntToStr() oder StrToDate... usw gibt?
Delphi-Quellcode:
MultiByteToWideChar(CP_ACP, 0, PChar(ALNKFilename), -1, wsz, MAX_PATH);
Gruß
Sir K

nahpets 30. Jan 2009 10:00

Re: Problem beim Verknüpfung erstellen
 
Hallo,
Deine Funktion läßt sich mit meinem Delphi 7 problemlos kompilieren, deshalb muss ich mal die :glaskugel: befragen:
Probiere es bitte mal mit
Delphi-Quellcode:
MultiByteToWideChar(CP_ACP, 0, PAnsiChar(ALNKFilename), -1, wsz, MAX_PATH);

Klaus01 30. Jan 2009 10:08

Re: Problem beim Verknüpfung erstellen
 
.. mal eine kleine Frage am Rande,

Ist die Konvertierung von MultiByte(Ansi?) nach WideChar durch MultiByteToWideChar
überhaupt noch notwendig?

Zitat:

Zitat von DelphiHilfe
The MultiByteToWideChar function maps a character string to a wide-character (Unicode) string. The character string mapped by this function is not necessarily from a multibyte character set.

Bei Delphi2009 ist doch ein String schon ein UniCode String.
Grüße
Klaus

Sir K 30. Jan 2009 10:43

Re: Problem beim Verknüpfung erstellen
 
Zitat:

Zitat von nahpets
Hallo,
Deine Funktion läßt sich mit meinem Delphi 7 problemlos kompilieren, deshalb muss ich mal die :glaskugel: befragen:
Probiere es bitte mal mit
Delphi-Quellcode:
MultiByteToWideChar(CP_ACP, 0, PAnsiChar(ALNKFilename), -1, wsz, MAX_PATH);

Also habs jetzt selber mal untder Delphi7 ausprobiert und du hast recht da funktionierts einwandfrei, nur unterm RAD Studio 2009 bleibt die fehlermeldung... hab dann mal im 2009er das PChar() durch PAnsiChar() ersetzt. Dann wirds zwar compiliert aber der link wird nicht mehr erstellt.

Gruß
Sir K

Klaus01 30. Jan 2009 10:46

Re: Problem beim Verknüpfung erstellen
 
.. und wie schaut es so aus?

Delphi-Quellcode:
 begin
      //GetMem(wsz, MAX_PATH*2);
      try
        //MultiByteToWideChar(CP_ACP, 0, PChar(ALNKFilename), -1, wsz, MAX_PATH);
        ppf.Save(ALNKFileName, true);
        result:=true;
      finally
        //FreeMem(wsz, MAX_PATH*2);
      end;
    end;
Grüße
Klaus

nahpets 30. Jan 2009 10:46

Re: Problem beim Verknüpfung erstellen
 
Hallo,

dann befolge bitte mal den Rat von Klaus und lass die Zeile
Delphi-Quellcode:
MultiByteToWideChar(CP_ACP, 0, PAnsiChar(ALNKFilename), -1, wsz, MAX_PATH);
weg. Nach Aussage von Klaus ist dies für Deine Delphiversion nicht mehr erforderlich.

Sir K 30. Jan 2009 10:50

Re: Problem beim Verknüpfung erstellen
 
...dann gibts die meldung ink. datent. String und PWideChar ind der Zeile
Delphi-Quellcode:
ppf.Save(ALNKFileName, true)

nahpets 30. Jan 2009 10:53

Re: Problem beim Verknüpfung erstellen
 
Hallo,
Zitat:

Zitat von Sir K
...dann gibts die meldung ink. datent. String und PWideChar ind der Zeile
Delphi-Quellcode:
ppf.Save(ALNKFileName, true)

dann mal mit
Delphi-Quellcode:
ppf.Save(PWideChar(ALNKFileName), true)
versuchen.

DeddyH 30. Jan 2009 10:54

Re: Problem beim Verknüpfung erstellen
 
Dann versuch es mal so:
Delphi-Quellcode:
    if SUCCEEDED(psl.QueryInterface(IPersistFile, ppf)) then
    begin
      {GetMem(wsz, MAX_PATH*2);
      try
        MultiByteToWideChar(CP_ACP, 0, PChar(ALNKFilename), -1, wsz, MAX_PATH);
        ppf.Save(wsz, true);
        result:=true;
      finally
        FreeMem(wsz, MAX_PATH*2);
      end;}
      ppf.Save(PWideChar(ALNKFilename), true);
      result:=true;
    end;
Edith sagt: zu langsam :?

Sir K 30. Jan 2009 10:59

Re: Problem beim Verknüpfung erstellen
 
Zitat:

Zitat von nahpets
Hallo,
Zitat:

Zitat von Sir K
...dann gibts die meldung ink. datent. String und PWideChar ind der Zeile
Delphi-Quellcode:
ppf.Save(ALNKFileName, true)

dann mal mit
Delphi-Quellcode:
ppf.Save(PWideChar(ALNKFileName), true)
versuchen.

jo damit klappts nur seltsamerweise steht in dem erzeugten link kein ziehl...

Klaus01 30. Jan 2009 11:06

Re: Problem beim Verknüpfung erstellen
 
Delphi-Quellcode:
 
psl.SetPath(PChar(AFilename));
psl.SetDescription(PChar(ADescription));
psl.SetWorkingDirectory(PChar(ExtractFilePath(AFilename)) ;);
Pchar liefert einen Pointer auf ein UniCode String zurück.
Was psl.SetPath erwartet weiß ich nicht, vielleicht einen Pointer auf einen AnsiString.
Ich würde mal in diese Richtung suchen.

Grüße
Klaus

DeddyH 30. Jan 2009 11:06

Re: Problem beim Verknüpfung erstellen
 
Mal zum Testen alles explizit auf ANSI umgestellt. Funktioniert es so?
Delphi-Quellcode:
function CreateLink(const AFilename, ALNKFilename, ADescription: Ansistring) : Boolean;
var
  psl : IShellLink;
  ppf : IPersistFile;
  wsz : PWideChar;
begin
  result:=false;
  if SUCCEEDED(CoCreateInstance(CLSID_ShellLink, nil,
  CLSCTX_inPROC_SERVER, IID_IShellLinkA, psl)) then
  begin
    psl.SetPath(PAnsiChar(AFilename));
    psl.SetDescription(PAnsiChar(ADescription));
    psl.SetWorkingDirectory(PAnsiChar(ExtractFilePath(AFilename)) ;);
    if SUCCEEDED(psl.QueryInterface(IPersistFile, ppf)) then
    begin
      GetMem(wsz, MAX_PATH*2);
      try
        MultiByteToWideChar(CP_ACP, 0, PAnsiChar(ALNKFilename), -1, wsz, MAX_PATH);
        ppf.Save(wsz, true);
        result:=true;
      finally
        FreeMem(wsz, MAX_PATH*2);
      end;
    end;
  end;
end;

Sir K 30. Jan 2009 11:15

Re: Problem beim Verknüpfung erstellen
 
Zitat:

Zitat von DeddyH
Mal zum Testen alles explizit auf ANSI umgestellt. Funktioniert es so?
Delphi-Quellcode:
function CreateLink(const AFilename, ALNKFilename, ADescription: Ansistring) : Boolean;
var
  psl : IShellLink;
  ppf : IPersistFile;
  wsz : PWideChar;
begin
  result:=false;
  if SUCCEEDED(CoCreateInstance(CLSID_ShellLink, nil,
  CLSCTX_inPROC_SERVER, IID_IShellLinkA, psl)) then
  begin
    psl.SetPath(PAnsiChar(AFilename));
    psl.SetDescription(PAnsiChar(ADescription));
    psl.SetWorkingDirectory(PAnsiChar(ExtractFilePath(AFilename)) ;);
    if SUCCEEDED(psl.QueryInterface(IPersistFile, ppf)) then
    begin
      GetMem(wsz, MAX_PATH*2);
      try
        MultiByteToWideChar(CP_ACP, 0, PAnsiChar(ALNKFilename), -1, wsz, MAX_PATH);
        ppf.Save(wsz, true);
        result:=true;
      finally
        FreeMem(wsz, MAX_PATH*2);
      end;
    end;
  end;
end;

nein das gibts in den zeilen die meldung ink. dat. AnsiChar und Char
Delphi-Quellcode:
psl.SetPath(PAnsiChar(AFilename));
    psl.SetDescription(PAnsiChar(ADescription));
    psl.SetWorkingDirectory(PAnsiChar(ExtractFilePath(AFilename)));

DeddyH 30. Jan 2009 11:20

Re: Problem beim Verknüpfung erstellen
 
Dann muss ich mich leider ausklinken, da ich kein Delphi 2009 habe und nur noch herumraten könnte.

Sir K 30. Jan 2009 11:24

Re: Problem beim Verknüpfung erstellen
 
trotzdem danke für die bisherige Hilfe xD

Gruß
Sir K

BullsEye 30. Jan 2009 11:45

Re: Problem beim Verknüpfung erstellen
 
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation
USES SHLOBJ, ACTIVEX;
{$R *.dfm}

// Der Einfachheit halber heisst der Link genauso, wie die Datei
function CreateDesktopLink(const p_sFilePath : string;const p_sDesktopDir : string) : Boolean;

const // Fehlende Deklaration in Delphi
  // Zu finden in der Registry
  // HKEY_CLASSES_ROOT\Interface
  // nach IPersistFile suchen
  IID_IPersistFile: TGUID = '{0000010b-0000-0000-C000-000000000046}';

var
  slShellLink   : IShellLink;  // ShellLink Interface
  pfPersistFile : IPersistFile; // Shortcut (Link) Permanent speichern
  wszShortCut   : PWideChar;   // Buffer für den Shortcutnamen
  hRes          : HResult;     // Für Zwischenergebnisse
  sShortCut     : string;      // So heisst dann der Shortcut
  dwLen         : DWORD;

begin
  Result := false;
  // COM Object der Klasse ShellLink erzeugen
  hRes := CoCreateInstance(CLSID_ShellLink,     // ID von ShellLink (Typ TGUID)
                           nil,
                           CLSCTX_INPROC_SERVER,
                           IID_IShellLinkA,     // Referenz auf die Funktion
                           slShellLink);        // Pointer auf IShellLink Interface
  if hRes <> S_OK then
  begin
    exit;
  end;
  slShellLink.SetPath(PChar(p_sFilePath));                           // Auf diese Datei geht der Link
  hRes := slShellLink.QueryInterface(IID_IPersistFile,pfPersistFile); // Pointer auf IPersist holen
  if hRes <> S_OK then
  begin
    exit;
  end;
  dwLen := (MAX_PATH+1)*2;
  wszShortcut := AllocMem(dwLen);
  try
    sShortCut := ChangeFileExt(p_sFilePath,'.LNK');
    sShortCut := p_sDesktopDir + '\' + ExtractFileName(sShortCut);
    StringToWideChar(sShortCut,wszShortCut,dwLen);
    hRes := pfPersistFile.Save(wszShortCut, TRUE); // Jetzt noch den Link speichern
  finally
    FreeMem(wszShortCut,dwLen);  // und den Platz wieder freigeben
  end;
  Result := (hRes = S_OK);
end;



procedure TForm1.Button1Click(Sender: TObject);
var
  szDesktopFolder : PChar;

begin
  if Opendialog1.Execute then
  begin
    szDesktopFolder := StrAlloc(MAX_PATH+1);
    try
      if not SHGetSpecialFolderPath(self.Handle,szDesktopFolder,CSIDL_COMMON_DESKTOPDIRECTORY,false) then
      begin
        ShowMessage(SysErrorMessage(GetLastError));
        exit;
      end;
      if not CreateDesktopLink(OpenDialog1.FileName,szDesktopFolder) then
      begin
        ShowMessage(SysErrorMessage(GetLastError));
      end;
    finally
      StrDispose(szDesktopFolder);
    end;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Close;
end;

initialization
begin
  CoInitialize(nil);
end;

finalization
begin
  CoUninitialize;
end;

end.

Klaus01 30. Jan 2009 11:50

Re: Problem beim Verknüpfung erstellen
 
Laut msdn kann IShellLink Ansi und UniCode.

Delphi-Quellcode:
function CreateLink(const AFilename, ALNKFilename, ADescription: string) : Boolean;
var
  psl : IShellLink;
  ppf : IPersistFile;
begin
  result:=false;
  if SUCCEEDED(CoCreateInstance(CLSID_ShellLink, nil,
  CLSCTX_inPROC_SERVER, IID_IShellLinkA, psl)) then
  begin
    psl.SetPath(PWideChar(AFilename));
    psl.SetDescription(PWideChar(ADescription));
    psl.SetWorkingDirectory(PWideChar(ExtractFilePath(AFilename)) ;);
    if SUCCEEDED(psl.QueryInterface(IPersistFile, ppf)) then
    begin
      ppf.Save(PWideChar(ALNKFileName, true);
      // das result := true sollte noch irgendwo untergebracht werden.
    end;
  end;
end;
Weil, mkinzler hatte mal in einem Thread geschrieben:
Delphi2009 String = UniCode <> WideString

Dies ist auch mein letzter Versuch, ich habe auch kein Delphi2009 zur Verfügung.

Grüße
Klaus

Sir K 30. Jan 2009 12:06

Re: Problem beim Verknüpfung erstellen
 
geht leider auch nicht
trotzdem Danke xD

Gruß
Sir K

Micha88 26. Feb 2009 11:37

Re: Problem beim Verknüpfung erstellen
 
Folgende Funktion funktioniert unter RAD 2009 einwandfrei, benutze ich selber:

Delphi-Quellcode:
function CreateLink(const AFilename, ALNKFilename,
ADescription: AnsiString) : Boolean;
var
  psl : IShellLink;
  ppf : IPersistFile;
  wsz : PWideChar;
begin
  result:=false;
  if SUCCEEDED(CoCreateInstance(CLSID_ShellLink, nil,
  CLSCTX_inPROC_SERVER, IID_IShellLinkA, psl)) then
  begin
    psl.SetPath(PChar(AFilename));
    psl.SetDescription(PChar(ADescription));
    psl.SetWorkingDirectory(PChar(ExtractFilePath(AFilename)));
    if SUCCEEDED(psl.QueryInterface(IPersistFile, ppf)) then
    begin
      GetMem(wsz, MAX_PATH*2);
      try
        MultiByteToWideChar(CP_ACP, 0, PAnsiChar(ALNKFilename),
        -1, wsz, MAX_PATH);
        ppf.Save(wsz, true);
        result:=true;
      finally
        FreeMem(wsz, MAX_PATH*2);
      end;
    end;
  end;
end;
Aufruf:
Delphi-Quellcode:
 CreateLink('C:\TEST.exe', // Ziel
 vDesktopPfad + '\' + 'TEST.lnk', // Speicherort der verknüpfung
 'Das ist eine Testbeschreibung zu TEST.exe'); // Verknüpfungs Beschreibung

BlueStarHH 4. Jul 2009 11:41

Re: Problem beim Verknüpfung erstellen
 
Die Lösung aus Betrag #19 funktioniert zwar, ist aber nicht Unicode fähig. Die Lösung aus Beitrag #17 ist Unicode fähig. Damit diese funktioniert, muss IID_IShellLinkA durch IID_IShellLinkW ersetzt werden.

Dezipaitor 4. Jul 2009 17:26

Re: Problem beim Verknüpfung erstellen
 
Nanu, ich dachte die haben ALLES auf Unicode umgestellt. Da muss doch auch das gemacht worden sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:35 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