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 Kontext Menu Handler..? (https://www.delphipraxis.net/96103-kontext-menu-handler.html)

Prototypjack 18. Jul 2007 18:50


Kontext Menu Handler..?
 
Moin,

Ich habe da ein Problem:
Ich habe bereits vorher schon Kontext-Menu-Handler geschrieben, alle funktionierten tadellos, doch sie hatten nur einen einzigen Menüpunkt. Da ich, nach mehreren fehlgeschlagenen Versuchen, keine Lust mehr hatte mir eine selbst gebaute Lösung zu bauen, habe ich mich nach eine Fertigen umgesehen um dort zu lernen wie man das macht. Diese fand ich auch, und zwar hier.
Doch sobald ich mein Projekt auf diese Methode angepasst hatte, war überhaupt kein Kontext-Menü mehr zu sehen. Als ich dann wieder Stunden mit der Fehlersuche (von dem ich bis gerade eben sicher war, er läge auf meiner Seite) herumgeschlagen hatte, kam ich auf die Idee zu Testzwecken meinem kompletten eigenen Code zu verwerfen und stattdessen den aus dem Tutorial zu verwenden. Siehe da, es geht! Alles was ich da noch tun musste, war die Erweiterung auf Exe (oder Zip/WasAuchImmer) zu beschränken und da machte ich eine Interessante Beobachtung:
Mein eigener Code war die ganze zeit korrekt, bzw so korrekt wie der aus dem Tutorial, denn sobald man die Extension auf eine einzige Erweiterung begrenzt ist's zappenduster.
Die große Preisfrage ist nun: Was zum Geier muss ich machen um die Funktion der DLL auf eine einzige Extension (zu Testzwecken hier ".Zip) zu beschränken?

Achja:
Ich habe den Code so abgeändert, alles andere ist gleich geblieben und auf der oben genannten Seite einsehbar (sogar fertig zum herunterladen):
Delphi-Quellcode:
procedure TDFKontextMenuShellExtFactory.UpdateRegistry(Register: boolean);
var
  ClassID: string;
begin
  if Register then
  begin
    inherited UpdateRegistry(Register);

    ClassID := GUIDToString(GUID_TDFKontextMenuShellExt);

    // Die Shell-Erweiterung wird hier für Ordner (Folder) registriert
    // Der Text DFKontextMenu ist frei wählbar und charakterisier die eigene Erweiterung

    // Die Shell-Erweiterung wird hier für alle Dateien registriert
    // ansonsten muss statt des Sterns (alle Dateien) die konkrete Dateiendung
    // stehen, z. B. '.zip'
    // Der Text DFKontextMenu ist frei wählbar und charakterisier die eigene Erweiterung
    CreateRegKey('.zip\shellex', '', '');
    CreateRegKey('.zip\shellex\ContextMenuHandlers', '', '');
    CreateRegKey('.zip\shellex\ContextMenuHandlers\DFKontextMenu', '', ClassID);

    // Shell-Erweiterung als "genehmigt" eintragen
    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, 'DFKontextMenu');
        finally
          Free;
        end;
  end
  else
  begin
    // wird die Shell-Erweiterung wieder entfernt, werden die Einträge der
    // Registrierung gelöscht
    DeleteRegKey('.zip\shellex\ContextMenuHandlers\DFKontextMenu');

    inherited UpdateRegistry(Register);
  end;
end;
Falls da ein ganz einfacher Fehler drin liegt und ich mir selbst blöd vorkomme, wenn ich die Lösung sehe, gibt's für den Finder ein Getränk in der DP-Bar :mrgreen:

Grüße & Danke,
Max

teebee 18. Jul 2007 20:27

Re: Kontext Menu Handler..?
 
Du trägst die Erweiterung etwas "zu früh" ein.

Schau Dir mal den Standardwert des Schlüssels ".zip" an. Bei mir heisst der z.B. "WinRar.ZIP". Und dann schau mal nach einem Schlüssel mit genau diesem Namen.
Der Standardwert eines "Dateiendungsschlüssels" ist gleichzetig der Name des Schlüssels, unterhalb dem Du die Shell-Erweiterung eintragen musst.

Sinnvollerweise vergibst Du vorher einen eigenen Standardwert für die gewünschte Dateiendung, unter einem Schlüssel mit diesem Namen legst Du dann die entsprechenden Verweise auf Deine Shell-Erweiterung an.

Die "Dateiendung" * spielt hier eine Sonderrolle, da die Erweiterungen hier direkt vor Ort eingetragen werden.

Gruß, teebee

Prototypjack 18. Jul 2007 20:33

Re: Kontext Menu Handler..?
 
Moin,

Stimmt, das dachte ich auch zuerst, aber folgender Code bringt auch keine Besserung:
Delphi-Quellcode:
procedure TDFKontextMenuShellExtFactory.UpdateRegistry(Register: boolean);
var
  ClassID: string;
  rgHandle: HKEY;
  lpType, cbData: DWORD;
  lExe: string;
begin
  inherited;
  //Filestrings zuweisen
  if RegOpenKeyEx(HKEY_CLASSES_ROOT, '.zip', 0, KEY_READ, rgHandle) =
    ERROR_SUCCESS then
  begin
    try
      if RegQueryValueEx(rgHandle, '', nil, @lpType, nil, @cbData) =
        ERROR_SUCCESS then
      begin
        setlength(lExe, cbData);
        RegQueryValueEx(rgHandle, '', nil, nil, @lExe[1], @cbData);
        setlength(lExe, cbData - 1);
      end;
    finally
      RegCloseKey(rgHandle);
    end;
  end;
  if Register then
  begin
    inherited UpdateRegistry(Register);
    ClassID := GUIDToString(GUID_TDFKontextMenuShellExt);
    try
      CreateRegKey(lExe + '\shellex', '', '');
      CreateRegKey(lExe + '\shellex\ContextMenuHandlers', '', '');
      CreateRegKey(lExe + '\shellex\ContextMenuHandlers\DFKontextMenu', '', ClassID);
      CreateRegKey('CLSID', '', '');
      CreateRegKey('CLSID\' + ClassID, '', '');
      CreateRegKey('CLSID\' + ClassID + '\InProcServer32', '', 'C:\Dokumente und Einstellungen\Max\Desktop\DFKontextMenu');
      CreateRegKey('CLSID\' + ClassID + '\InProcServer32', 'ThreadingModel', 'Apartment');
    except
    end;
//    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, 'DFKontextMenu');
//        finally
//          Free;
//        end;
  end
  else
  begin
    try
      DeleteRegKey(lExe + '\shellex\ContextMenuHandlers\DFKontextMenu');
    except
    end;
  end;
end;
Grüße,
Max

Edit: Code verändert. Siehe übernächster Beitrag

teebee 18. Jul 2007 20:51

Re: Kontext Menu Handler..?
 
Dann fällt mir erst mal nur ein, nach dem Registrieren der Erweiterung die Registry zu überprüfen, ob wirklich überall, wo was stehen muss, auch das steht, was da hingehört. Siehe Creating Shell Extension Handlers

Prototypjack 18. Jul 2007 22:57

Re: Kontext Menu Handler..?
 
Moin,

Ich hatte tatsächlich vergessen etwas in die Registry einzutragen (Das mit dem InProcServer. Ich habe es dem obigen Code bereits hinzugefügt).
Aber entgegen aller Erwartungen funktioniert es immer noch nicht. :cry:

Ich verzweifle langsam...

Grüße,
Max

teebee 19. Jul 2007 07:20

Re: Kontext Menu Handler..?
 
Du trägst als InProcServer nur den Pfad zu Deiner DLL ein, nicht den kompletten Dateinamen.

Gruß, teebee

Prototypjack 19. Jul 2007 11:31

Re: Kontext Menu Handler..?
 
Moin,

Zitat:

Zitat von teebee
Du trägst als InProcServer nur den Pfad zu Deiner DLL ein, nicht den kompletten Dateinamen.

Gruß, teebee

Das MSDN sagt da aber was anderes. Auch egal, ich habe alle Methoden durch: Voller Dateiname, Dateipfad ohne Backslash, Dateipfad mit Backslash.

Nichts funktioniert

Kann mir den wirklich niemand helfen? Ich verzweifel hier wirklich langsam

Grüße,
Max

Prototypjack 19. Jul 2007 13:39

Re: Kontext Menu Handler..?
 
Moin,

Ich konnte das Problem weiter eingrenzen:
Die Erweiterung funktioniert nur, wenn ich einen unbeschriebenen Typ benutze (.abc z.B.), sobald ich aber bereits registriert Typen wie .Exe oder .Zip erweitern möchte, wird die Erweiterung einfach nicht angezeigt.
Was sagt uns das? Sagt uns das überhaupt was? :mrgreen:

Grüße,
Max

teebee 22. Jul 2007 20:47

Re: Kontext Menu Handler..?
 
Da Deine Shell-Erweiterung mit einem eigenen Dateityp funktioniert, hast Du sie also schon mal korrekt registriert. Wenn sie allerdings mit einem Typ, für den bereits andere Erweiterungen registriert sind, nicht angezeigt wird, könnte es sein, dass mit dem Rückgabewert aus QueryContextMenu etwas nicht stimmt. (Dieser Rückgabewert ist der Startwert für die IDs der Menüeinträge der folgenden Extension-Handler.)
Laut MSDN solltest Du folgenden Wert zurückgeben:
Delphi-Quellcode:
MakeResult(SEVERITY_SUCCESS,0,GrößteID-KleinsteID+1);
D.h., falls Du das verlinkte Tutorial so übernommen hast, solltest Du als Result nicht 4 sondern 5 übergeben, da das Untermenü selbst auch eine ID bekommen hat (idCmdFirst+4):
Code:
(idCmdFirst+4) - idCmdFirst + 1 = 5
Könnte mir vorstellen, dass hier das Problem liegt,

Gruß, teebee


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