C++ Builder Snippets  

Erstellen, Auslesen und Ändern von Desktop-Verknüpfungen (shell shortcuts):
 
Dieser Snippet besteht aus zwei Funktionen: bool CreateShortcut(TShortcutCfg* sCfg, int ilFolder) und bool ReadShortcut(TShortcutCfg* sCfg, AnsiString slFileName). Wie die Funktionsnamen bereits verraten, wird mit Hilfe der CreateSchortcut() eine neue Verknüpfung erzeugt (bzw. eine geänderte gespeichert). Mit Hilfe der ReadShortcut() kann die Konfiguration einer Vernknüpfung ausgelesen werden.

Beide Funktionen erwarten einen Zeiger auf die TShortcutCfg-Struktur als Parameter. Diese Struktur wird folgendermaßen deklariert:
//---------------------------------------------------------------------------
// Struktur mit der Konfiguration einer Windows-Verknüpfung (Shell Shortcut)
//---------------------------------------------------------------------------
struct TShortcutCfg
{
  // Member-Variablen:
  AnsiString slShortcutName;   // Name der Verknüpfung
  AnsiString slLnkDir;         // Physikalischer Pfad zum Shortcut-Verzeichnis
  AnsiString slDestFile;       // "Zieldatei" der Verknüpfung
  AnsiString slArguments;      // Übergabepatrameter
  AnsiString slIconFile;       // Name der Datei mit dem Symbol
  int        ilIconIndex;      // Index des Icons in der EXE oder DLL-Datei
  AnsiString slWorkingDir;     // Das zu übergebende Arbeitsverzeichnis
  AnsiString slDescription;    // Kommentar zur Verknüpfung
  WORD       wlHotKey;         // Tastenkombination (Hotkey)
  int        ilShowCmd;        // Fenster-Anzeigemodus für den Programmstart

  // Konstruktor (Initialiserung der int-Membervariablen)
  TShortcutCfg() { ilShowCmd = SW_SHOWNORMAL; wlHotKey = 0; ilIconIndex = 0; }
};

Hier noch einige Erläuterungen zu den einzelnen Member-Variablen der TShortcutCfg-Struktur:
  AnsiString slShortcutName;   // Name der Verknüpfung -> wird auf dem Desktop/
                               // im Startmenü/etc. neben dem Symbol angezeigt.
                               // Verknüpfungsname entspriicht dem Dateinamen
                               // der Verknüpfung ohne Erweiterung .lnk.

  AnsiString slLnkDir;         // Physikalischer Pfad zum
                               // Verknüpfungsverzeichnis

  AnsiString slDestFile;       // "Zieldatei" der Verknüpfung -> kann eine
                               // beliebige Exe-Datei oder eine Datendatei mit
                               // registrierter Erweiterung (z.B. .html) sein
                               // Diese Datei wird beim Doppelklick auf die
                               // Verknüpfung ausgeführt bzw. geöffnet.

  AnsiString slArguments;      // String mit den beim Programmstart zu
                               // übergebenden Parameter (kann leer bleiben)

  AnsiString slIconFile;       // Name der Datei mit dem Symbol (Icon) für
                               // die Verknüpfung (exe, dll oder ico-Datei)
                               // Wird ein leerer String übergeben, verwendet
                               // Windows ein Standard-Icon der Zieldatei.
                               // (kann leer bleiben)

  int        ilIconIndex;      // Index des Icons in der EXE oder DLL-Datei
                               // (Indexierung beginnt bei 0, kann 0 bleben)

  AnsiString slWorkingDir;     // Das zu übergebende Arbeitsverzeichnis
                               // (kann i.d.R. leer bleiben - je nach
                               // Anforderungen der aufzurufenden Anwendung)

  AnsiString slDescription;    // Kommentar zur Verknüpfung (Kommentar ist
                               // meines Wissens nur im Eigenschaften-
                               // Dialog der Verknüpfung unter NT sichtbar)
                               // (kann leer bleiben)

  WORD       wlHotKey;         // Tastenkombination (Hotkey) für den Aufruf
                               // der Verknüpfung. Aufbau:
                               // - Low-Order Byte  -> virtueller Tastencode
                               //   (z.B. 'K', VK_F1 etc.)
                               // - High-Order Byte -> Modifizierer-Flags
                               //   (binäre ODER Kombination aus Flags
                               //   HOTKEYF_ALT, HOTKEYF_CONTROL und
                               //   HOTKEYF_SHIFT möglich)
                               // (kann 0 bleiben)

  int        ilShowCmd;        // Fenster-Anzeigemodus für den Programmstart
                               // Folgende Konstanten können verwendet werden:
                               // SW_SHOWNORMAL (default)  -> normales Fenster
                               // SW_SHOWMINNOACTIVE       -> minimiert starten
                               // SW_SHOWMAXIMIZED         -> maximiert starten
                               // (kann i.d.R. SW_SHOWNORMAL bleiben)

Und nun die eigentlichen Funktionen:
//---------------------------------------------------------------------------
// Funktion CreateShortcut() erzeugt eine neue Verknüpfung (shell shortcut)
//---------------------------------------------------------------------------
// Übergabeparameter:
//
// sCfg     -> Zeiger auf TShortcutCfg-Instanz mit der Konfguration
//             der Verknüpfung
// ilFolder -> Zielfolder-Id Konstante (z.B. CSIDL_DESKTOP,CSIDL_STARTUP
//             usw. definiert in der Datei ..\cbuilder\include\shlobj.h)
//             (siehe auch Snippet: Namen der Systemverzeichnisse ermitteln)
// Hinweis:
// Das Zielverzeichnis für die Verknüpfung kann ebenfalls in der slLnkDir-
// Membervariablen der TShortcutCfg als Pfad definiert werden. In diesem
// Fall muss der Wert von ilFolder auf -1 gesetzt werden.
//
// Rückgabewert: bei fehlerfreien Ausführung wird true zurückgelifert,
//               anderenfalls false.
//---------------------------------------------------------------------------
// Beispielaufrufe:
//
// - - - - - - - - - - - - -
//
// TShortcutCfg sShortcut;
// sShortcut.slDestFile = "c:\\windows\\calc.exe";
// sShortcut.slShortcutName = "Rechner";
// CreateShortcut(&sShortcut, CSIDL_PROGRAMS);
//
// - - - - - - - - - - - - -
//
// char cBuf[MAX_PATH];
// GetSystemDirectory(cBuf, sizeof(cBuf));
//
// TShortcutCfg sShortcut;
// sShortcut.slDestFile = ParamStr(0);
// sShortcut.slShortcutName = "Mein Programm";
// sShortcut.slArguments = "/n";
// sShortcut.slIconFile = AnsiString(cBuf) + "\\shell32.dll";
// sShortcut.ilIconIndex = 5;
// sShortcut.slWorkingDir = ExtractFilePath(ParamStr(0));
// sShortcut.slDescription = "Test-Programm";
// sShortcut.wlHotKey = MAKEWORD(VK_F8, HOTKEYF_CONTROL | HOTKEYF_SHIFT);
// sShortcut.ilShowCmd = SW_SHOWMAXIMIZED;
//
// if(!CreateShortcut(&sShortcut, CSIDL_DESKTOP))
//   ShowMessage("Fehler beim Erzeugen der Verknüpfung aufgetreten !");
//---------------------------------------------------------------------------
// Hinweis: evtl. müssen an Anfang der Source-Datei folgende
// Anweisungen hizugefügt werden:
//
// #define NO_WIN32_LEAN_AND_MEAN
// #include <shlobj.hpp>
//---------------------------------------------------------------------------
#include <filectrl.hpp>

bool CreateShortcut(TShortcutCfg* sCfg, int ilFolder)
{
  char cBuf[MAX_PATH];
  bool blRetVal = true;   // Rückgabewert
  wchar_t wsz [MAX_PATH]; // Buffer für Unicode String
  IShellLink *psl;
  AnsiString slShortcutFile;

  if(ilFolder >= 0)
  {
    // Shortcut-Verzeichnis bestimmen und den Namen der LNK-Datei erzeugen
    LPITEMIDLIST pidl;
    SHGetSpecialFolderLocation(0, ilFolder, &pidl);
    SHGetPathFromIDList(pidl, cBuf);
    if(DirectoryExists(AnsiString(cBuf)))
    {
      slShortcutFile = AnsiString(cBuf) + "\\" + sCfg->slShortcutName + ".lnk";
      slShortcutFile.WideChar(wsz, MAX_PATH);
    }
    else blRetVal = false;
  }
  else if(DirectoryExists(sCfg->slLnkDir))
  {
    slShortcutFile = IncludeTrailingBackslash(sCfg->slLnkDir) +
      sCfg->slShortcutName + ".lnk";
    slShortcutFile.WideChar(wsz, MAX_PATH);
  }
  else blRetVal = false;

  if(blRetVal)
  {
    // COM-Bibliothek initialisieren
    blRetVal = CoInitialize(NULL) == S_OK;
    if(blRetVal)
    {
      // IShellLink Objekt erzeugen
      blRetVal = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
        IID_IShellLink, (void **)&psl) >= 0;

      if(blRetVal)
      {
        IPersistFile *ppf;

        // Zeiger auf IPersistFile-Interface (zum Speichern der
        // Verknüpfung) besorgen
        blRetVal = psl->QueryInterface(IID_IPersistFile, (void **)&ppf) >= 0;
        if(blRetVal)
        {
          // Zieldatei der Verknüpfung setzen
          if(sCfg->slDestFile != EmptyStr)
            blRetVal = psl->SetPath(sCfg->slDestFile.c_str()) >= 0;

          // Übergabeparameter der Verknüpfung setzen
          if(blRetVal && sCfg->slArguments != EmptyStr)
            blRetVal = psl->SetArguments(sCfg->slArguments.c_str()) >= 0;

          // Icon zuweisen:
          if(blRetVal && sCfg->slIconFile != EmptyStr &&
            FileExists(sCfg->slIconFile))
            psl->SetIconLocation(sCfg->slIconFile.c_str(), sCfg->ilIconIndex);

          // Arbeitsverzeichnis für die Verknüpfung zuweisen:
          if(blRetVal && sCfg->slWorkingDir != EmptyStr)
            psl->SetWorkingDirectory(sCfg->slWorkingDir.c_str());

          // Kommentar für die Verknüpfung zuweisen
          // (Kommentar ist meines Wissens nur im Eigenscharten-
          // Dialog der Verknüpfung unter NT sichtbar)
          if(blRetVal && sCfg->slDescription != EmptyStr)
            psl->SetDescription(sCfg->slDescription.c_str());

          // Hotkey zuweisen:
          if(blRetVal && sCfg->wlHotKey != 0)
            psl->SetHotkey(sCfg->wlHotKey);

          // Fenster-Modus zuweisen:
          if(blRetVal && sCfg->ilShowCmd != 0)
            psl->SetShowCmd(sCfg->ilShowCmd);

          // Verknüpfung speichern
          if(blRetVal) blRetVal = ppf->Save (wsz, TRUE) >= 0;

          // Zeiger auf IPersistFile freigeben
          ppf->Release ();
        }
        // Zeiger auf IShellLink freigeben
        psl->Release ();
      }
      // COM-Bibliothek freigeben
      CoUninitialize();
    }
  }
  return blRetVal;
}

//---------------------------------------------------------------------------
// Funktion ReadShortcut() liest die Konfiguration einer Verknüpfung
// in die übergeben TShortcutCfg-Instanz ein
//---------------------------------------------------------------------------
// Übergabeparameter:
//
// sCfg       -> Zeiger auf TShortcutCfg-Instanz mit der Konfguration
//               der Verknüpfung
// slFileName -> Name der einzulesenden Verknüpfungsdatei
//               (z.B. "C:\\WINDOWS\\SENDTO\\Proton.lnk")
//
// Rückgabewert: bei fehlerfreien Ausführung wird true zurückgelifert,
//               anderenfalls false.
//---------------------------------------------------------------------------
// Beispielaufruf:
//
// TShortcutCfg sShortcut;
// if(ReadShortcut(&sShortcut, "C:\\WINDOWS\\SENDTO\\Proton.lnk"))
//   ShowMessage("Shortcut " + sShortcut.slShortcutName +
//     " ist mit der Datei " + sShortcut.slDestFile + " verknüpft");
//---------------------------------------------------------------------------
bool ReadShortcut(TShortcutCfg* sCfg, AnsiString slFileName)
{
  bool blRetVal = true;   // Rückgabewert
  wchar_t wsz [MAX_PATH]; // Buffer für Unicode String
  char buf[MAX_PATH];
  IShellLink *psl;
  slFileName.WideChar(wsz, MAX_PATH);

  if(blRetVal)
  {
    // COM-Bibliothek initialisieren
    blRetVal = CoInitialize(NULL) == S_OK;
    if(blRetVal)
    {
      // IShellLink Objekt erzeugen
      blRetVal = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
        IID_IShellLink, (void **)&psl) >= 0;

      if(blRetVal)
      {
        IPersistFile *ppf;

         // The IShellLink Interface supports the IPersistFile
         // interface. Get an interface pointer to it.
        blRetVal = psl->QueryInterface(IID_IPersistFile, (void **)&ppf) >= 0;

        // Zeiger auf IPersistFile-Interface (zum Speichern der
        // Verknüpfung) besorgen
        if(blRetVal)
        {
          // Verknüpfungsdatei laden:
          blRetVal = ppf->Load(wsz, TRUE) >= 0;

          // Zieldatei der Verknüpfung lesen
          if(blRetVal)
          {
            // Zieldatei der Verknüpfung lesen:
            psl->GetPath(buf, MAX_PATH, NULL, 0);
            sCfg->slDestFile = AnsiString(buf);

            // Übergabeparameter der Verknüpfung lesen
            psl->GetArguments(buf, MAX_PATH);
            sCfg->slArguments = AnsiString(buf);

            // Symbolinformationen lesen:
            int ilIndex = 0;
            if(psl->GetIconLocation(buf, MAX_PATH, &ilIndex) == NOERROR)
            {
              sCfg->slIconFile = AnsiString(buf);
              sCfg->ilIconIndex = ilIndex >= 0 ? ilIndex : 0;
            }

            // Arbeitsverzeichnis der Verknüpfung lesen
            psl->GetWorkingDirectory(buf, MAX_PATH);
            sCfg->slWorkingDir = AnsiString(buf);

            // Kommentar für die Verknüpfung lesen
            psl->GetDescription(buf, MAX_PATH);
            sCfg->slDescription = AnsiString(buf);

            // Hotkey zuweisen:
            psl->GetHotkey(&sCfg->wlHotKey);

            // Fenster-Modus zuweisen:
            psl->GetShowCmd(&sCfg->ilShowCmd);

          }
          // Zeiger auf IPersistFile freigeben
          ppf->Release ();
        }

        // Zeiger auf IShellLink freigeben
        psl->Release ();
      }
      // COM-Bibliothek freigeben
      CoUninitialize();
    }
    if(blRetVal)
    {
      sCfg->slLnkDir = IncludeTrailingBackslash(ExtractFilePath(slFileName));
      slFileName = ExtractFileName(slFileName);
      sCfg->slShortcutName = slFileName.Length() ? slFileName.
        SubString(1, slFileName.Length()-ExtractFileExt(
        slFileName).Length()) : EmptyStr;
    }
  }
  return blRetVal;
}

Schauen Sie sich auch das Beispielprojekt an:
Screenshot der Beispielanwendung:


  Download BCB5
Projekt-Quellcode
Download
Demo-Exe


© '99-2001 by S. Kreutzmann