Hinweis zur Mitgliedschaft: Ich bin der Autor der in dieser Antwort genannten Software.
Zunächst einmal werde ich wissen, dass ich C ++ und Win32 nur für diese Frage gelernt habe .
Ich habe eine 64-Bit-Shell-Erweiterung entwickelt, die als Kontextmenü-Handler registriert wird. Wenn es aufgerufen wird, durchsucht es die vorhandenen Menüelemente und sucht nach interessanten Einträgen. Wenn es einen findet, klebt es ein Symbol (das zuvor geladen worden sein muss). Im Moment wird nach Kopieren, Ausschneiden, Löschen, Einfügen, Wiederholen, Senden an und Rückgängig gesucht . Sie können Ihren eigenen Code hinzufügen, indem Sie den Code ändern. Die Vorgehensweise dazu ist unten beschrieben. (Sorry, ich bin in C ++ nicht gut genug, um es konfigurierbar zu machen.)
Ein Screenshot davon in Aktion mit den hässlichsten Icons, die man kennt:
Sie können diese Symbole herunterladen, wenn Sie wirklich möchten.
Einrichten
Laden Sie es herunter (von meiner Dropbox). Hinweis : Diese Datei wird von einem VirusTotal-Scanner als Malware erkannt . Dies ist verständlich, wenn man die Art der Dinge beachtet, die es zum Schlagen der vorhandenen Einträge tun muss. Ich gebe Ihnen mein Wort, dass es Ihrem Computer keinen absichtlichen Schaden zufügt. Wenn Sie misstrauisch sind und / oder es ändern oder erweitern möchten, lesen Sie den Code auf GitHub !
Erstellen Sie einen Ordner in Ihrem Laufwerk C: C:\shellicon
. Erstellen Sie BMP - Dateien mit den folgenden Titeln: copy
, cut
, delete
, paste
, redo
, sendto
, undo
. (Hoffentlich ist es offensichtlich, wer was macht.) Diese Bilder sollten wahrscheinlich 16 mal 16 Pixel groß sein (oder wie groß Ihre DPI-Einstellungen den Menürand bilden), aber ich habe auch mit größeren Bildern Erfolg gehabt. Wenn Sie möchten, dass die Symbole transparent aussehen, müssen Sie nur deren Hintergrundfarbe wie das Kontextmenü festlegen. (Dieser Trick wird auch von Dropbox angewendet.) Ich habe mit MS Paint meine schrecklichen Icons gemacht; andere Programme können auf eine kompatible Weise speichern LoadImageA
. 16 x 16 bei 24 Bit Farbtiefe bei 96 Pixel pro Zoll scheint der zuverlässigste Satz von Bildeigenschaften zu sein.
Legen Sie die DLL an einem für alle Benutzer zugänglichen Ort ab. Der Ordner, den Sie gerade erstellt haben, ist eine gute Wahl. Öffnen Sie eine Admin-Eingabeaufforderung in dem Ordner, der die DLL enthält regsvr32 ContextIcons.dll
. Dies schafft Registrierungsinformationen für den Shell - Typen *
, Drive
, Directory
, und Directory\Background
. Wenn Sie die Shell-Erweiterung jemals entfernen möchten, tun Sie dies regsvr32 /u ContextIcons.dll
.
Relevanter Code
Grundsätzlich fragt die Erweiterung nur den Text jedes Kontextmenüelements mit ab GetMenuItemInfo
und passt gegebenenfalls das Symbol mit an SetMenuItemInfo
.
Visual Studio generiert eine Menge magischen, geheimnisvollen Code für ATL-Projekte. Dies ist jedoch der Inhalt von IconInjector.cpp
, der den Kontextmenü-Handler implementiert:
// IconInjector.cpp : Implementation of CIconInjector #include "stdafx.h" #include "IconInjector.h" #include <string> // CIconInjector HBITMAP bmpCopy = NULL; HBITMAP bmpCut = NULL; HBITMAP bmpUndo = NULL; HBITMAP bmpRedo = NULL; HBITMAP bmpSendto = NULL; HBITMAP bmpDel = NULL; HBITMAP bmpPaste = NULL; STDMETHODIMP CIconInjector::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID) { // Load the images bmpCopy = (HBITMAP)LoadImageA(NULL, "C:\\shellicon\\copy.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); bmpCut = (HBITMAP)LoadImageA(NULL, "C:\\shellicon\\cut.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); bmpUndo = (HBITMAP)LoadImageA(NULL, "C:\\shellicon\\undo.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); bmpRedo = (HBITMAP)LoadImageA(NULL, "C:\\shellicon\\redo.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); bmpSendto = (HBITMAP)LoadImageA(NULL, "C:\\shellicon\\sendto.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); bmpDel = (HBITMAP)LoadImageA(NULL, "C:\\shellicon\\delete.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); bmpPaste = (HBITMAP)LoadImageA(NULL, "C:\\shellicon\\paste.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); int err = GetLastError(); return S_OK; } STDMETHODIMP CIconInjector::QueryContextMenu(HMENU hmenu, UINT uMenuIndex, UINT uidFirst, UINT uidLast, UINT flags) { using namespace std; if (flags & CMF_DEFAULTONLY) return S_OK; // Don't do anything if it's just a double-click int itemsCount = GetMenuItemCount(hmenu); for (int i = 0; i < itemsCount; i++) { // Iterate over the menu items MENUITEMINFO mii; ZeroMemory(&mii, sizeof(mii)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_FTYPE | MIIM_STRING; mii.dwTypeData = NULL; BOOL ok = GetMenuItemInfo(hmenu, i, TRUE, &mii); // Get the string length if (mii.fType != MFT_STRING) continue; UINT size = (mii.cch + 1) * 2; // Allocate enough space LPWSTR menuTitle = (LPWSTR)malloc(size); mii.cch = size; mii.fMask = MIIM_TYPE; mii.dwTypeData = menuTitle; ok = GetMenuItemInfo(hmenu, i, TRUE, &mii); // Get the actual string data mii.fMask = MIIM_BITMAP; bool chIcon = true; if (wcscmp(menuTitle, L"&Copy") == 0) { mii.hbmpItem = bmpCopy; } else if (wcscmp(menuTitle, L"Cu&t") == 0) { mii.hbmpItem = bmpCut; } else if (wcscmp(menuTitle, L"&Paste") == 0) { mii.hbmpItem = bmpPaste; } else if (wcscmp(menuTitle, L"Se&nd to") == 0) { mii.hbmpItem = bmpSendto; } else if (wcsstr(menuTitle, L"&Undo") != NULL) { mii.hbmpItem = bmpUndo; } else if (wcsstr(menuTitle, L"&Redo") != NULL) { mii.hbmpItem = bmpRedo; } else if (wcscmp(menuTitle, L"&Delete") == 0) { mii.hbmpItem = bmpDel; } else { chIcon = false; } if (chIcon) SetMenuItemInfo(hmenu, i, TRUE, &mii); free(menuTitle); } return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0); // Same as S_OK (= 0) but is The Right Thing To Do [TM] } STDMETHODIMP CIconInjector::InvokeCommand(LPCMINVOKECOMMANDINFO info) { return S_OK; } STDMETHODIMP CIconInjector::GetCommandString(UINT_PTR, UINT, UINT*, LPSTR, UINT) { return S_OK; }
Beachten Sie, dass die HBITMAP
s niemals bereinigt werden. Dies ist jedoch nicht so wichtig, da die DLL-Dateien beim Schließen des Explorers verschwinden. Die Icons nehmen sowieso kaum Speicher in Anspruch.
Wenn Sie für 32-Bit kompilieren, ist der erste Parameter GetCommandString
nur a UINT
statt a UINT_PTR
.
Wenn Sie wirklich transparente Symbole wollen, müssen Sie zunächst ein Fenster mit dem gewünschten Symbol und setzen Sie erstellen müssen, mii.hBmpItem
um HBMMENU_SYSTEM
in und legte den Griff in die Fenster mii.dwItemData
, wie im unteren Teil der beschriebenen auf dem MSDN - ArtikelMENUITEMINFO
. Ich konnte nicht herausfinden, wie man Fenster aus Shell-Erweiterungen erstellt. LR_LOADTRANSPARENT
Sieht vielversprechend aus LoadImageA
, aber es hat seine eigenen Fallstricke. Insbesondere funktioniert es nicht, wenn Sie 256-Bit-Bitmaps verwenden.
Wenn beim Laden von Bildern Probleme auftreten, entfernen Sie die LR_DEFAULTSIZE
Markierung von den LoadImageA
Aufrufen.
Jemand, der über ausreichende Kenntnisse in C ++ verfügt, könnte wahrscheinlich Ressourcen aus anderen DLLs holen und in HBITMAP
s konvertieren, aber das ist nicht jemand.
Ändern Sie es
Ich habe dies in Visual Studio geschrieben, das meiner Meinung nach der beste Editor für Windows C ++ ist.
Laden Sie die SLN-Datei nach der Installation der C ++ - Tools in Visual Studio 2015. In IconInjector.cpp
, können Sie hinzufügen HBITMAP
Einträge nach oben und LoadImageA
ruft in Initialize
neue Symbole hinzuzufügen. else if
Verwenden Sie unten in diesem Abschnitt einen wcscmp
Anruf, um nach einer genauen Übereinstimmung wcsstr
zu suchen, oder einen Anruf, um nach dem Vorhandensein eines Teilstrings zu suchen. In beiden Fällen &
repräsentiert das die Position der Unterstreichung / des Beschleunigers bei Verwendung von Umschalttaste + F10. Stellen Sie den Modus auf Release und Ihre Architektur auf x64 ein, und führen Sie Build → Build Solution aus . Sie erhalten eine Fehlermeldung, dass die Ausgabe nicht registriert wird. Machen Sie sich jedoch keine Sorgen. Sie möchten dies sowieso manuell tun. Beenden Sie den Explorer, kopieren Sie die neue DLL ( \x64\Release\ContextIcons.dll
im Lösungsordner) an den Ort und führen Sie dann den regsvr32
Tanz aus.
Namensnennungen
Vielen Dank an die MSDN-Autoren und an den Ersteller von " The Complete Idiots Guide to Writing Shell Extensions ", auf den ich ausführlich Bezug genommen habe.
Lobrede
Zu den vielen Explorer-Instanzen, die bei der Produktion dieser Shell-Erweiterung getötet wurden: Sie starben für einen guten Grund, dass einige Personen im Internet neben ihren Wörtern Symbole haben können.