संबद्धता सूचना: मैं इस उत्तर में वर्णित सॉफ्टवेयर का लेखक हूं।
सबसे पहले, मुझे पता होगा कि मैंने इस प्रश्न के लिए C ++ और Win32 सीखा है ।
मैंने 64-बिट शेल एक्सटेंशन विकसित किया है जो एक संदर्भ मेनू हैंडलर के रूप में पंजीकृत होता है। जब इसे लागू किया जाता है, तो यह मौजूदा मेनू आइटम के माध्यम से दिलचस्प प्रविष्टियों की तलाश करता है। यदि यह एक को पाता है, तो यह उस पर एक आइकन चिपका देता है (जो पहले लोड हो चुका होगा)। फिलहाल, यह कॉपी , कट , डिलीट , पेस्ट , रीडो , सेंड टू और अंडरो के लिए दिखता है । आप कोड को संशोधित करके अपना खुद का जोड़ सकते हैं; इसके लिए प्रक्रिया नीचे वर्णित है। (क्षमा करें, मैं इसे कॉन्फ़िगर करने योग्य बनाने के लिए C ++ पर पर्याप्त अच्छा नहीं हूं।)
मनुष्य को ज्ञात सबसे खराब आइकन के साथ, क्रिया में इसका स्क्रीनशॉट:
यदि आप वास्तव में चाहते हैं तो आप इन आइकन को डाउनलोड कर सकते हैं।
इसे स्थापित करना
इसे डाउनलोड करें (मेरे ड्रॉपबॉक्स से)। सूचना : इस फ़ाइल को मैलवेयर के कुछ रूप होने के रूप में एक VirusTotal स्कैनर द्वारा पता लगाया जाता है। यह समझ में आता है, यह देखते हुए कि मौजूदा प्रविष्टियों को हटाने के लिए किस तरह का काम करना है। मैं आपको अपना शब्द देता हूं कि यह आपके कंप्यूटर को कोई जानबूझकर नुकसान नहीं पहुंचाता है। यदि आपको संदेह है और / या आप इसे संशोधित और विस्तारित करना चाहते हैं, तो GitHub पर कोड देखें !
अपने C ड्राइव में एक फ़ोल्डर बनाएँ C:\shellicon
:। निम्नलिखित शीर्षकों के साथ बीएमपी फ़ाइलें बनाएँ: copy
, cut
, delete
, paste
, redo
, sendto
, undo
। (उम्मीद है कि यह स्पष्ट है कि कौन सा काम करता है।) ये चित्र शायद 16 से 16 पिक्सेल (या फिर आपकी बड़ी डीपीआई सेटिंग्स मेनू को मार्जिन बनाते हैं) होना चाहिए, लेकिन मुझे बड़ी के साथ भी सफलता मिली है। यदि आप चाहते हैं कि आइकन पारदर्शी दिखें, तो आपको उनकी पृष्ठभूमि को संदर्भ मेनू के समान रंग बनाना होगा। (यह ट्रिक ड्रॉपबॉक्स द्वारा नियोजित है।) मैंने एमएस पेंट के साथ अपने भयानक आइकन बनाए; अन्य कार्यक्रम संगत तरीके से सहेज सकते हैं या नहीं भी कर सकते हैं LoadImageA
। 16 16 से 24-बिट रंग की गहराई 96 पिक्सेल प्रति इंच पर छवि गुणों का सबसे विश्वसनीय सेट लगता है।
DLL को सभी उपयोगकर्ताओं के लिए सुलभ रखें, जो फ़ोल्डर आपने अभी बनाया है वह एक अच्छा विकल्प है। DLL वाले फ़ोल्डर में एक व्यवस्थापक प्रॉम्प्ट खोलें और करें regsvr32 ContextIcons.dll
। यह खोल प्रकार के लिए पंजीकरण जानकारी बनाता है *
, Drive
, Directory
, और Directory\Background
। यदि आप कभी शेल एक्सटेंशन को हटाना चाहते हैं, तो करें regsvr32 /u ContextIcons.dll
।
प्रासंगिक कोड
मूल रूप से, एक्सटेंशन सिर्फ हर संदर्भ मेनू आइटम के पाठ पर सवाल उठाता है GetMenuItemInfo
और यदि उपयुक्त हो, तो आइकन को समायोजित करता है SetMenuItemInfo
।
विज़ुअल स्टूडियो ATL परियोजनाओं के लिए बहुत सारे जादुई रहस्यमय कोड उत्पन्न करता है , लेकिन यह सामग्री है IconInjector.cpp
, जो संदर्भ मेनू हैंडलर को लागू करती है:
// 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;
}
ध्यान दें कि HBITMAP
एस को कभी भी साफ नहीं किया जाता है, लेकिन यह बहुत ज्यादा मायने नहीं रखता है कि एक्सप्लोरर के बंद होने पर DLL का सामान चला जाएगा। प्रतीक मुश्किल से किसी भी स्मृति को लेते हैं।
यदि आप 32-बिट के लिए संकलन कर रहे हैं, तो पहला पैरामीटर इसके बजाय GetCommandString
सिर्फ एक UINT
है UINT_PTR
।
यदि आप वास्तव में पारदर्शी आइकन चाहते हैं, तो आपको वांछित आइकन के साथ एक विंडो बनानी होगी और फिर MSDN लेख के निचले भाग में बताए अनुसार हैंडल को विंडो में सेट mii.hBmpItem
करना होगा । मैं यह जानने में सक्षम नहीं था कि शेल एक्सटेंशन से विंडोज़ कैसे बनाई जाए। के झंडे के रूप में आशाजनक लगता है , लेकिन इसके अपने नुकसान हैं - विशेष रूप से, जब तक आप 256-रंग के बिटमैप का उपयोग नहीं करते हैं तब तक काम नहीं करते हैं।HBMMENU_SYSTEM
mii.dwItemData
MENUITEMINFO
LR_LOADTRANSPARENT
LoadImageA
यदि आपको छवि लोड करने में समस्या आती है, LR_DEFAULTSIZE
तो LoadImageA
कॉल्स से ध्वज को हटाने का प्रयास करें ।
C ++ में पर्याप्त रूप से कुशल कोई व्यक्ति संभवतः अन्य DLL से संसाधनों को पकड़ सकता है और उन्हें HBITMAP
s में परिवर्तित कर सकता है , लेकिन यह कि मैं कोई नहीं हूं।
इसे संशोधित कर रहा है
मैंने इसे विजुअल स्टूडियो में लिखा, जिसे मैं विंडोज सी ++ के लिए सबसे अच्छा संपादक मानता हूं।
C ++ उपकरण स्थापित करने के बाद SLN फ़ाइल को Visual Studio 2015 में लोड करें। इसमें IconInjector.cpp
, आप HBITMAP
शीर्ष पर प्रविष्टियाँ जोड़ सकते हैं और नए आइकन जोड़ने के लिए LoadImageA
कॉल कर सकते हैं Initialize
। else if
अनुभाग में नीचे , wcscmp
एक सटीक मिलान की तलाश के लिए कॉल का उपयोग करें, या एक विकल्प wcsstr
की उपस्थिति के लिए देखने के लिए कॉल करें। दोनों मामलों में, &
Shift + F10 का उपयोग करते समय रेखांकित / त्वरक की स्थिति का प्रतिनिधित्व करता है। अपनी विधा को x64 में रिलीज़ करने और अपनी वास्तुकला के लिए सेट करें, और बनाएँ → समाधान बनाएँ । आपको आउटपुट रजिस्टर करने में विफल होने के बारे में एक त्रुटि मिलेगी, लेकिन चिंता न करें; आप इसे मैन्युअल रूप से वैसे भी करना चाहते हैं। अंतिम एक्सप्लोरर, नए DLL ( \x64\Release\ContextIcons.dll
समाधान फ़ोल्डर में) को उस स्थान पर कॉपी करें , फिर regsvr32
नृत्य करें।
विशेषताएं
MSDN के लेखकों और " द कम्प्लीट इडियट्स गाइड टू राइटिंग शेल एक्सटेंशन्स " के निर्माता को बहुत-बहुत धन्यवाद ।
प्रशंसा भाषण
इस शेल एक्सटेंशन के उत्पादन में मारे गए कई एक्सप्लोरर उदाहरणों के लिए: आप एक महान कारण के लिए मर गए, कि इंटरनेट पर कुछ लोगों के पास उनके शब्दों के बगल में आइकन हो सकते हैं।