Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Registry, Dateien mit Programm verknüpfen (https://www.delphipraxis.net/41011-registry-dateien-mit-programm-verknuepfen.html)

Prototypjack 24. Feb 2005 15:44


Registry, Dateien mit Programm verknüpfen
 
Hallo,
Ich schreibe z.Z. einen universal NotePad.
Jetzt würde mich interessieren wie ich es anstelle das wie, zb. bei Winrar, bei jeder Datei im Kontext steht "Mit NotePad bearbeiten" und bei einem klick darauf mein Programm mit Parametern geöffnet wird.
Das soll wirklich bei jeder Datei(ausser Binären vielleicht und Ordnern) stehen.
Kann mir da jemand helfen?
Danke schonmal,
Gruß,
Max

MathiasSimmack 24. Feb 2005 15:47

Re: Registry, Dateien mit Programm verknüpfen
 
Auch du könntest die Suche benutzen. Das Thema Hier im Forum suchenDateityp ist IMHO auch schon X Mal durchgekaut worden.

Prototypjack 24. Feb 2005 16:08

Re: Registry, Dateien mit Programm verknüpfen
 
Ich habe eben nochmal alles durchsucht aber ich finde keine funktion die auf einen Schlag alle(!) Dateiendungen registriert
Entweder bin ich blind oder...
Naja, bitte nochmals um Hilfe.
Gruß,
Max

MathiasSimmack 24. Feb 2005 16:10

Re: Registry, Dateien mit Programm verknüpfen
 
Pah, und das bei den Zauberworten in deinem eigenen Beitrag:
Zitat:

Zitat von Prototypjack
Ich habe eben nochmal alles durchsucht aber ich finde keine funktion die auf einen Schlag alle(!) Hier im Forum suchenDateiendungen registriert


Prototypjack 24. Feb 2005 16:39

Re: Registry, Dateien mit Programm verknüpfen
 
Argh!
Ich sagte bereits das ich nichts finde. Ich habe gerade wieder die Suche benutzt aber ich finde keine Methode.
Ich will jegliche Datei(ausser Binäries) ein Kontextmenüeintrag verpassen.
Wenn ich wirklich zu dumm bin dann bitte gib mir den Link zur Methode.
Bitte wiederrum um Hilfe
Gruß,
Max

Matze 24. Feb 2005 16:42

Re: Registry, Dateien mit Programm verknüpfen
 
Registrieren muss du die Dateitypen, meines Wissens, nacheinander, eben in einer for-Schleife o.Ä.
[cl]Dateiendung*[/cl]

Wie man allerdings den Kontext dazu einträgt, weiß ich auch nicht.

Nachtrag: Müsste das nicht der Beschreibungstext sein, den man beim Registrieren sowieso mit angibt?

Prototypjack 24. Feb 2005 16:48

Re: Registry, Dateien mit Programm verknüpfen
 
Ja das ist genau mein Problem, ich habe keine Ahnung welche Dateitypen ich da registriere(Winrar steht ja auch bei allen drin(es ist unmöglich das der Programmierer wusste was er da alles registriert))
Nur falls nicht bekannt ist: Mit Kontextmenüeintrag meine Wenn man per Rechtsklick auf die Datei geht sollte dastehen "Mit NotePad bearbeiten".
Das soll bei allen bekannten und unbekannte Dateien darstehen(mittlerweile ist es mir egal ob Binär oder nicht)
Danke und ich bitte nochmals um weitere Hilfe
Gruß,
Max

Matze 24. Feb 2005 16:53

Re: Registry, Dateien mit Programm verknüpfen
 
Zitat:

Zitat von Prototypjack
es ist unmöglich das der Programmierer wusste was er da alles registriert

:shock:

Zitat:

Zitat von Prototypjack
"Mit NotePad bearbeiten".

Das steht bei mir nirgendwo, meinst du "Öffnen mit ..." oder was genau? Ich verstehe dein problem noch nicht ganz.
Oder wie bei WinRar, dass dasteht "Add to Dateiname.rar"?

Prototypjack 24. Feb 2005 16:59

Re: Registry, Dateien mit Programm verknüpfen
 
Zitat:

Zitat von Matze
Oder wie bei WinRar, dass dasteht "Add to Dateiname.rar"?

Das meine ich, nur soll darstehen "Mit NotePad öffnen" und dann soll der Dateiname per Parameter übergeben werden.
Habt ihr jetzt verstanden was ich meine.

BTW.: Ich habe jetzt herausgefunden das es bei WinRAR über einen InProcServer gelöst wird jetzt ist mein Problem: Was zum Teufel ist ein InProcServer und wie benutze ich so etwas?
Gruß,
Max

shmia 24. Feb 2005 16:59

Re: Registry, Dateien mit Programm verknüpfen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Man kann Verknüpfungen zu allen Dateitypen schaffen und zwar unter:
Code:
HKEY_CLASSES_ROOT\*
Siehe Anhang

Du kannst nun die "Öffnen Mit" Liste im Registryzweig "OpenWithList" erweitern oder
du musst
einen Shell Context Menu Handler programmieren.
So ein Shell Context Menu Handler ist etwas kompliziert...
http://www.delphipraxis.net/internal...ct.php?t=15838

Prototypjack 24. Feb 2005 18:09

Re: Registry, Dateien mit Programm verknüpfen
 
ok. :pale:
Das ist ja völlig neue Materie.
Hat vielleicht jemand Sachen dazu die sich auf Delphi beziehen?
Denn das Beispiel da oben bezieht sich nur auf das auslesen der Händlers nicht auf das schreiben derselben(soweit ich das verstanden habe)
Ich zähle auf euch :?

MathiasSimmack 24. Feb 2005 18:58

Re: Registry, Dateien mit Programm verknüpfen
 
Warum willst du denn mit Kanonen auf Spatzen schießen? Du brauchst keine Shell-Erweiterung wie WinRar. Für deine Zwecke reicht auch ein Eintrag in dem Schlüssel, den shmia gezeigt hat. Entschuldige bitte, aber man kann es auch übertreiben. :roll:

Prototypjack 24. Feb 2005 19:10

Re: Registry, Dateien mit Programm verknüpfen
 
Boah... Hast du heute 'nen schlechten Tag oder was?
Naja egal... Bin auch schon müde
Ich will das mit diesem Handler machen weil man das "Öffnen Mit"-Menü leicht übersieht und ausserdem ist es so einfach schneller verfügbar.
Und ganz nebenbei lerne ich wie das funktioniert, denn sowas brauche ich sicher auch noch für spätere Projekte.
Gruß,
Max

MathiasSimmack 24. Feb 2005 20:02

Re: Registry, Dateien mit Programm verknüpfen
 
Zitat:

Zitat von Prototypjack
Boah... Hast du heute 'nen schlechten Tag oder was?

Eigentlich immer, aber die Antworten hättest du auch bekommen, wenn es mir *jubeljauchz* gehen würde. Ich sehe den Sinn nicht so ganz. Du willst dein Programm als Editor reagieren. Dafür brauchst du keine Shell-Extension. Erstell einfach einen eigenen Eintrag für dein Programm und setze den unter shell als Standard rein. Dann geht bei einem Doppelklick dein Editor auf, und im Kontextmenü steht er auch drin. Das "Öffnen mit"-Menü ist ein Spezialmenü, in dem du mehrere Programme auflisten kannst, die den gleichen Typ auflisten können sollen. Für eine Shell-Erweiterung (DLL) findest du übrigens ein einfaches Beispiel im Delphi-Ordner.

Prototypjack 24. Feb 2005 20:04

Re: Registry, Dateien mit Programm verknüpfen
 
Ich will das Programm nicht als Standard registrieren.
Ich will dir nicht zu nahe treten.
Das Beispiel im Delphiordner funktioniert nur leider nicht.
Gruß,
Max

MathiasSimmack 24. Feb 2005 20:30

Re: Registry, Dateien mit Programm verknüpfen
 
Zitat:

Zitat von Prototypjack
Ich will das Programm nicht als Standard registrieren.

Dann lass einfach diesen Schritt weg und erzeuge nur einen Registryeintrag für dein Programm.

Zitat:

Ich will dir nicht zu nahe treten.
Bist du bis jetzt nicht. Schaffst du aber auch gar nicht. Ich meine, wer glaubt, dass ich schlechte Laune habe, oder einen schlechten Tag, ... nun ja ... :roll:

Zitat:

Das Beispiel im Delphiordner funktioniert nur leider nicht.
Ich würde mir eine genauere Fehlerbeschreibung wünschen, denn ich persönlich habe auf der Basis dieses Beispiels selbst schon recht problemlos drei (oder waren es doch mehr? :gruebel:) Shell-Erweiterungen geschrieben. Und die haben alle funktioniert.

Prototypjack 25. Feb 2005 13:39

Re: Registry, Dateien mit Programm verknüpfen
 
Zitat:

Zitat von MathiasSimmack
Dann lass einfach diesen Schritt weg und erzeuge nur einen Registryeintrag für dein Programm.

Wie genau meinst du das?

Zitat:

Zitat von MathiasSimmack
Bist du bis jetzt nicht. Schaffst du aber auch gar nicht. Ich meine, wer glaubt, dass ich schlechte Laune habe, oder einen schlechten Tag, ... nun ja ... :roll:

Gut, aber lassen wir das.
Zitat:

Zitat von MathiasSimmack
Ich würde mir eine genauere Fehlerbeschreibung wünschen, denn ich persönlich habe auf der Basis dieses Beispiels selbst schon recht problemlos drei (oder waren es doch mehr? :gruebel:) Shell-Erweiterungen geschrieben. Und die haben alle funktioniert.

Ja das ist das Problem. Dumm bin ich nicht, wenn ich eine Fehlermeldung hätte würde ich es mir ableiten aber es geht schlicht und einfach nicht. Nichts kommt garnichts(Und JA ich habe die DLL registriert)

MathiasSimmack 25. Feb 2005 14:48

Re: Registry, Dateien mit Programm verknüpfen
 
Was, das Beispiel von Borland geht nicht mal bei dir? Sprich: Kompilieren, registrieren und eine DPR-Datei rechtsklicken und im Menü den neuen Punkt "Compile" bewundern ... all das klappt nicht?

bigg 25. Feb 2005 15:04

Re: Registry, Dateien mit Programm verknüpfen
 
Also eine Shell-Erweiterung hat schon seine Vorteile:
Wenn man mehrere Dateien gleichzeitig öffnen möchte, ist sie unverzichtbar.
(z. B. 1000 Dateien dem Hauptprogramm übergeben)

Wenn du nur eine Datei öffnen möchtest, empfiehlt sich die
einfache Variante ohne DLL.

MathiasSimmack 25. Feb 2005 15:16

Re: Registry, Dateien mit Programm verknüpfen
 
Wenn ich das Programm richtig gestalte, dass es nur eine Instanz von sich selbst akzeptiert und jede weitere übergebene Datei an die schon offene Instanz weiterreicht, dann brauche ich auch keine Shell-Erweiterung. :stupid:

bigg 25. Feb 2005 15:27

Re: Registry, Dateien mit Programm verknüpfen
 
Da muß ich dich leider enttäuschen, Mathias.
Es ist zwar möglich aber nich schnell genug.

Für die einfache Variante:
Wenn du dem Programm 1000 Parameter übergeben möchtest, heißt das für den Explorer:
Starte 1000 mal das Programm. Du hast dann nur eine Anwendung offen, aber das ständige
Starten drückt auf die Zeit.

DLL-Variante:
Der Explorer übergibt alle Dateinamen an eine Shell-DLL weiter,
von der DLL aus, sendest du alle Paramter an deine Hauptanwendung.
Das heißt 1x Starten und viel viel Zeit sparen.

Deswegen benutzen auch Packer eine Shell-Erweiterung. :zwinker:

MathiasSimmack 25. Feb 2005 15:29

Re: Registry, Dateien mit Programm verknüpfen
 
Zitat:

Zitat von bigg
Da muß ich dich leider enttäuschen, Matthias.

Ich bin gar nicht enttäuscht. Na ja, höchstens über das T, das zuviel ist ... :mrgreen:
Aber enttäuscht wg. der Thematik? Nee, ich weiß ja auch nicht alles. Viel, manchmal mehr als mir lieb ist, aber eben nicht alles ... ;)

bigg 25. Feb 2005 15:32

Re: Registry, Dateien mit Programm verknüpfen
 
Das liegt sicherlich auch daran, dass man im Netz nicht soviel darüber findet.
(Shellerweiterung)

Und schon gar nicht in Object Pascal.

Prototypjack 25. Feb 2005 16:07

Re: Registry, Dateien mit Programm verknüpfen
 
Das habe ich bisher.
irgendwie will der code aber nicht so richtig, kann sich den mal jemand ansehen?
Danke schonmal
Delphi-Quellcode:
unit main;

interface

uses
  ComServ, SysUtils, ShellAPI, Registry, Classes, Windows, ActiveX, ComObj, ShlObj, Graphics, Dialogs;

const
  GUID_Tnp2cont: TGUID = '{44FC978E-C20B-42D2-A6BD-DD3968D43172}';

type
  Tnp2cont = class(TComObject, IShellExtInit, IContextMenu)
    protected
      function IShellExtInit.Initialize = SEInitialize;
      function SEInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult; stdcall;
      function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast, uflags: UINT): HResult; stdcall;
      function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
      function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT; pszName: LPSTR; cchMax: UINT): HResult; stdcall;
  end;

implementation

var
  FFileName: array[0..MAX_PATH] of Char;
  hBmp: TBitmap;

type
  Tnp2contFactory = class(TComObjectFactory)
    public
      procedure UpdateRegistry(Register: boolean); override;
  end;

function Tnp2cont.SEInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
  hKeyProgID: HKEY): HResult;
var
  StgMedium: TStgMedium;
  FormatEtc: TFormatEtc;
begin
  if (lpdobj = nil) then begin
    Result := E_INVALIDARG;
    Exit;
  end;

  with FormatEtc do begin
    cfFormat := CF_HDROP;
    ptd     := nil;
    dwAspect := DVASPECT_CONTENT;
    lindex  := -1;
    tymed   := TYMED_HGLOBAL;
  end;
  Result := lpdobj.GetData(FormatEtc, StgMedium);
  if Failed(Result) then
    Exit;
  if (DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0) = 1) then begin
    DragQueryFile(StgMedium.hGlobal, 0, FFileName, SizeOf(FFileName));
    Result := NOERROR;
  end
  else begin
    FFileName[0] := #0;
    Result := E_FAIL;
  end;
  ReleaseStgMedium(StgMedium);
end;

function Tnp2cont.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
          idCmdLast, uFlags: UINT): HResult;
begin
  Result := 0;

  if ((uFlags and $0000000F) = CMF_NORMAL) or
     ((uFlags and CMF_EXPLORE) <> 0) then begin

    InsertMenu(Menu, indexMenu, MF_STRING or MF_BYPOSITION, idCmdFirst,
      'Mit NotePad2 bearbeiten');

    Result := 1;
  end;
end;

function Tnp2cont.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
resourcestring
  sPathError = 'Error setting current directory';

var
  H: THandle;
  PrevDir: string;
 
begin
  Result := E_FAIL;
  if (HiWord(Integer(lpici.lpVerb)) <> 0) then
  begin
    Exit;
  end;
  if (LoWord(lpici.lpVerb) <> 0) then begin
    Result := E_INVALIDARG;
    Exit;
  end;
  PrevDir := GetCurrentDir;
  try
    if not SetCurrentDir(ExtractFilePath(FFileName)) then
      raise Exception.CreateRes(@sPathError);

    H := WinExec(PChar(Format(extractfilepath(paramstr(0))+'notepad2.exe', [FFileName])), lpici.nShow);

    if (H < 32) then
      MessageBox(lpici.hWnd, 'NotePad2 konnte nicht gestartet werden.', 'Error',
        MB_ICONERROR or MB_OK);
    Result := NOERROR;
  finally
    SetCurrentDir(PrevDir);
  end;
end;

function Tnp2cont.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
  pszName: LPSTR; cchMax: UINT): HResult;
begin
  if (idCmd = 0) then begin
    if (uType = GCS_HELPTEXT) then
      // return help string for menu item
      StrCopy(pszName, 'Diese Datei mit NotePad2 bearbeiten.');
    Result := NOERROR;
  end
  else
    Result := E_INVALIDARG;
end;

procedure Tnp2contfactory.UpdateRegistry(Register: Boolean);
var
  ClassID: string;
begin
  if Register then begin
    inherited UpdateRegistry(Register);

    ClassID := GUIDToString(GUID_Tnp2cont);
    CreateRegKey('*\shellex', '', '');
    CreateRegKey('*\shellex\ContextMenuHandlers', '', '');
    CreateRegKey('*\shellex\ContextMenuHandlers\DFKontextMenu', '', ClassID);

    if (Win32Platform = VER_PLATFORM_WIN32_NT) then
      with TRegistry.Create do
        try
          RootKey := HKEY_LOCAL_MACHINE;
          OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions', True);
          OpenKey('Approved', True);
          WriteString(ClassID, 'NP2');
        finally
          Free;
        end;
  end
  else begin
    DeleteRegKey('*\shellex\ContextMenuHandlers\DFKontextMenu');
    DeleteRegKey('*\shellex\ContextMenuHandlers');
    DeleteRegKey('*\shellex');

    inherited UpdateRegistry(Register);
  end;
end;

initialization
  // hier wird die Erweiterung registriert
  Tnp2contFactory.Create(ComServer, Tnp2cont, GUID_Tnp2cont,
    '', 'NotePad2', ciMultiInstance, tmApartment);
  hBmp := TBitmap.Create;
  // Bild aus Ressourcendatei laden (der Name der Bildressource muss als 2. Parameter angegeben
  // werden - auf keinen Fall den DefaultNamen belassen, den der Bildeditor vergibt!
  hBmp.LoadFromResourceName(hInstance, 'NOTEPAD2');
finalization
  // Bitmap wieder freigeben
  hBmp.Free;

end.

bigg 25. Feb 2005 16:22

Re: Registry, Dateien mit Programm verknüpfen
 
Es wäre gut, wenn du "deinen" Quellcode besser auskommentieren würdest.
PS: Was funktioniert denn nicht genau.

Prototypjack 25. Feb 2005 16:29

Re: Registry, Dateien mit Programm verknüpfen
 
Alles scheint zu funzen bis auf Invokecommand(Wird ausgeführt wenn das Item angeklickt wird) Da sollte dann mein Prog mit Params. starten
Sry wegen der Commentierung.
Gruß,
Max

bigg 25. Feb 2005 16:38

Re: Registry, Dateien mit Programm verknüpfen
 
Du mußt dir jetzt irgendwie den Programmpfad deines Editors holen.
Ich speichere den Programmpfad in der Registry.

Außerdem mußt du nun feststellen, ob dein Programm bereits läuft.
Wenn es läuft sendest du eine Nachricht mit allen Parametern an dein Programm.

Ansonsten mußt du eben dein Programm starten und solange warten, bis es gestartet ist.
Und anschließend senden.....

Prototypjack 25. Feb 2005 16:42

Re: Registry, Dateien mit Programm verknüpfen
 
Das Programm wird ja gestartet. Der Pfad sollte auch korrekt sein und die Parameter werden ebenfalls übergeben aber es funktioniert nicht. Nichts wird gestartet.

bigg 25. Feb 2005 16:52

Re: Registry, Dateien mit Programm verknüpfen
 
Zitat:

Das Programm wird ja gestartet .... Nichts wird gestartet.....
Was denn nun?
Wird es gestartet oder nicht?

Prototypjack 25. Feb 2005 16:54

Re: Registry, Dateien mit Programm verknüpfen
 
Achso sorry,
Ich wollte sagen die DLL wird richtig abgearbeitet bis zum Punkt wo das Programm starten soll. Naja die Parameter sollte richtig sein und der Pfad auch aber das Programm wird nicht gestartet und die vorgefertigte Fehlermeldungwird ausgegeben.
Gruß,
max

bigg 25. Feb 2005 17:04

Re: Registry, Dateien mit Programm verknüpfen
 
Und woher soll deine DLL wissen was es starten soll?
Du mußt dein Programm starten.

Der Explorer(.exe) muß immer wieder neu gestartet werden, wenn du etwas an der DLL geändert hast.
Also einmal kurz abmelden und gleich wieder anmelden.

Prototypjack 25. Feb 2005 17:12

Re: Registry, Dateien mit Programm verknüpfen
 
Öhm, ja...
Hast du mal in den Code geschaut?
Da wird mein Programm per Handel und WinExec mit den Params gestartet aber es startet nicht.
Gruß,
Max

bigg 25. Feb 2005 17:30

Re: Registry, Dateien mit Programm verknüpfen
 
Delphi-Quellcode:
invokeCommand:..
[b]extractfilepath(paramstr(0)[/b]
Mach doch mal Showmessage(paramstr(0));
Und was steht da? Ich weiß es :P

1.
Du solltest den Programmpfad in der Registry speichern. (nur Speichern)
Den Programmpfad speichert nur dein Hauptprogramm.

2.
Die DLL holt sich nun den Programmpfad aus der Registry (nur Lesen).

3. Wenn es die Datei gibt, startest du sie......

Prototypjack 25. Feb 2005 18:02

Re: Registry, Dateien mit Programm verknüpfen
 
Selbst wenn ich einen festen Pfad angebe(zu Testzwecken) funktioniert es nicht
Was ist an dem Code falsch, ich drehe noch durch
Gruß,
Max

bigg 25. Feb 2005 19:33

Re: Registry, Dateien mit Programm verknüpfen
 
ShellExecute() bzw. CreateProcess() funktionieren in jedem Fall.

Delphi-Quellcode:
 Selbst wenn ich einen festen Pfad angebe(zu Testzwecken) funktioniert es nicht
Wenn du der Funktion falsche Parameter übergibst, ist das auch kein wunder.

PS: Ein Programm zu starten sollte nun wirklich keine Hürde darstellen.

Prototypjack 25. Feb 2005 19:36

Re: Registry, Dateien mit Programm verknüpfen
 
Ja mit festen Pfad meinte ich: Ich habe das extractfilepath(paramstr(0)); Teil rausgenommen und durch c:\ ersetzt!
Und die Parameter müssen richtig sein, soweit ich das verstanden habe.
Ich geh und versuchs nochmal mit Shellexecute
Gruß,
Max


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