विंडोज डिफ़ॉल्ट संदर्भ मेनू आइटम "कॉपी / कट / पेस्ट / डिलीट" के लिए एक आइकन कैसे निर्दिष्ट करें?


12

विंडोज 8 / 8.1 x64 के तहत, मैं डिफ़ॉल्ट विंडोज संदर्भ मेनू आइटम जैसे कॉपी , कट , पेस्ट , डिलीट , अनडू , रीडो और सेंड टू आइटम के लिए एक कस्टम आइकन असाइन करना चाहूंगा , जिसमें डिफ़ॉल्ट रूप से कोई भी आइकन हो:

यहां छवि विवरण दर्ज करें

जहां मैं रजिस्ट्री में उन संदर्भ मेनू आइटम के लिए "संदर्भ" का पता लगा सकता हूं, तो उनके लिए "आइकन" रजिस्ट्री मूल्य जोड़ सकते हैं?

या दूसरे शब्दों में, SendTo शेललेक्स जैसे शेल एक्सटेंशन मेनू में आइकन कैसे असाइन करें ?

अनुसंधान


जैसा कि @ Sk8erPeter ने टिप्पणी की है , ऐसा लगता है:

" Iconअलग - अलग संदर्भ मेनू संचालकों के लिए स्ट्रिंग मान जोड़ना जैसे काम करने के लिए कस्टम आइटम में जोड़ने पर काम नहीं करता है HKEY_CLASSES_ROOT\*\shell\MYCUSTOMKEY"


आप किस आइकन का जिक्र कर रहे हैं? क्या आपके पास स्क्रीनशॉट है?
रेस्टाफैरियन

@Raystafarian मैंने एक छवि के साथ सवाल अपडेट किया है।
इलेक्ट्रोस्टूडिओस

1
@Raystafarian: सवाल यह है कि मौजूदा मूल संदर्भ मेनू आइटम जैसे "कट" , "कॉपी" , "हटाएं" , "नाम बदलें" , आदि में एक कस्टम आइकन कैसे जोड़ा जाए, संदर्भ मेनू में एक नया कस्टम आइटम जोड़ते समय BTW , यह बहुत आसान है, क्योंकि आपको केवल Iconएक कुंजी में स्ट्रिंग मान जोड़ना होगा HKEY_CLASSES_ROOT\*\shell\MYCUSTOMITEM(और Iconजैसा होगा वैसा ही होगा %SystemRoot%\System32\shell32.dll,-133या sg। और)। लेकिन Iconअलग-अलग संदर्भ मेनू संचालकों के लिए स्ट्रिंग मान जोड़ना इन कस्टम आइटमों में जोड़ते समय काम नहीं करता है
Sk8erPeter 12

इसे स्पष्ट करने के लिए यहां एक और स्क्रीनशॉट है (दिलचस्प हिस्सा लाल सीमाओं में है): i.imgur.com/fmewg6L.png । BTW जैसा कि आप देख सकते हैं, मेरे पास कस्टम आइकन के साथ संदर्भ मेनू में कुछ कस्टम आइटम हैं (जैसे "नोटपैड ++ के साथ खोलें" ) - यह वही है जो हम मौजूदा सिस्टम संदर्भ मेनू आइटम के साथ प्राप्त करना चाहते हैं!
Sk8erPeter

1
@ Sk8erPeter इस समय मेरा सबसे अच्छा नेतृत्व एक शेल संदर्भ मेनू हैंडलर बनाने की संभावना है, SetMenuItemInfoजो प्रतिक्रिया में उपयोग करता है QueryContextMenu
बेन एन

जवाबों:


9

संबद्धता सूचना: मैं इस उत्तर में वर्णित सॉफ्टवेयर का लेखक हूं।

सबसे पहले, मुझे पता होगा कि मैंने इस प्रश्न के लिए C ++ और Win32 सीखा है ।

मैंने 64-बिट शेल एक्सटेंशन विकसित किया है जो एक संदर्भ मेनू हैंडलर के रूप में पंजीकृत होता है। जब इसे लागू किया जाता है, तो यह मौजूदा मेनू आइटम के माध्यम से दिलचस्प प्रविष्टियों की तलाश करता है। यदि यह एक को पाता है, तो यह उस पर एक आइकन चिपका देता है (जो पहले लोड हो चुका होगा)। फिलहाल, यह कॉपी , कट , डिलीट , पेस्ट , रीडो , सेंड टू और अंडरो के लिए दिखता है । आप कोड को संशोधित करके अपना खुद का जोड़ सकते हैं; इसके लिए प्रक्रिया नीचे वर्णित है। (क्षमा करें, मैं इसे कॉन्फ़िगर करने योग्य बनाने के लिए C ++ पर पर्याप्त अच्छा नहीं हूं।)

मनुष्य को ज्ञात सबसे खराब आइकन के साथ, क्रिया में इसका स्क्रीनशॉट:

कार्रवाई में

यदि आप वास्तव में चाहते हैं तो आप इन आइकन को डाउनलोड कर सकते हैं।

इसे स्थापित करना

इसे डाउनलोड करें (मेरे ड्रॉपबॉक्स से)। सूचना : इस फ़ाइल को मैलवेयर के कुछ रूप होने के रूप में एक VirusTotal स्कैनर द्वारा पता लगाया जाता है। यह समझ में आता है, यह देखते हुए कि मौजूदा प्रविष्टियों को हटाने के लिए किस तरह का काम करना है। मैं आपको अपना शब्द देता हूं कि यह आपके कंप्यूटर को कोई जानबूझकर नुकसान नहीं पहुंचाता है। यदि आपको संदेह है और / या आप इसे संशोधित और विस्तारित करना चाहते हैं, तो GitHub पर कोड देखें !

अपने C ड्राइव में एक फ़ोल्डर बनाएँ C:\shellicon:। निम्नलिखित शीर्षकों के साथ बीएमपी फ़ाइलें बनाएँ: copy, cut, delete, paste, redo, sendto, undo। (उम्मीद है कि यह स्पष्ट है कि कौन सा काम करता है।) ये चित्र शायद 16 से 16 पिक्सेल (या फिर आपकी बड़ी डीपीआई सेटिंग्स मेनू को मार्जिन बनाते हैं) होना चाहिए, लेकिन मुझे बड़ी के साथ भी सफलता मिली है। यदि आप चाहते हैं कि आइकन पारदर्शी दिखें, तो आपको उनकी पृष्ठभूमि को संदर्भ मेनू के समान रंग बनाना होगा। (यह ट्रिक ड्रॉपबॉक्स द्वारा नियोजित है।) मैंने एमएस पेंट के साथ अपने भयानक आइकन बनाए; अन्य कार्यक्रम संगत तरीके से सहेज सकते हैं या नहीं भी कर सकते हैं LoadImageA16 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_SYSTEMmii.dwItemDataMENUITEMINFOLR_LOADTRANSPARENTLoadImageA

यदि आपको छवि लोड करने में समस्या आती है, LR_DEFAULTSIZEतो LoadImageAकॉल्स से ध्वज को हटाने का प्रयास करें ।

C ++ में पर्याप्त रूप से कुशल कोई व्यक्ति संभवतः अन्य DLL से संसाधनों को पकड़ सकता है और उन्हें HBITMAPs में परिवर्तित कर सकता है , लेकिन यह कि मैं कोई नहीं हूं।

इसे संशोधित कर रहा है

मैंने इसे विजुअल स्टूडियो में लिखा, जिसे मैं विंडोज सी ++ के लिए सबसे अच्छा संपादक मानता हूं।

C ++ उपकरण स्थापित करने के बाद SLN फ़ाइल को Visual Studio 2015 में लोड करें। इसमें IconInjector.cpp, आप HBITMAPशीर्ष पर प्रविष्टियाँ जोड़ सकते हैं और नए आइकन जोड़ने के लिए LoadImageAकॉल कर सकते हैं Initializeelse ifअनुभाग में नीचे , wcscmpएक सटीक मिलान की तलाश के लिए कॉल का उपयोग करें, या एक विकल्प wcsstrकी उपस्थिति के लिए देखने के लिए कॉल करें। दोनों मामलों में, &Shift + F10 का उपयोग करते समय रेखांकित / त्वरक की स्थिति का प्रतिनिधित्व करता है। अपनी विधा को x64 में रिलीज़ करने और अपनी वास्तुकला के लिए सेट करें, और बनाएँसमाधान बनाएँ । आपको आउटपुट रजिस्टर करने में विफल होने के बारे में एक त्रुटि मिलेगी, लेकिन चिंता न करें; आप इसे मैन्युअल रूप से वैसे भी करना चाहते हैं। अंतिम एक्सप्लोरर, नए DLL ( \x64\Release\ContextIcons.dllसमाधान फ़ोल्डर में) को उस स्थान पर कॉपी करें , फिर regsvr32नृत्य करें।

विशेषताएं

MSDN के लेखकों और " द कम्प्लीट इडियट्स गाइड टू राइटिंग शेल एक्सटेंशन्स " के निर्माता को बहुत-बहुत धन्यवाद ।

प्रशंसा भाषण

इस शेल एक्सटेंशन के उत्पादन में मारे गए कई एक्सप्लोरर उदाहरणों के लिए: आप एक महान कारण के लिए मर गए, कि इंटरनेट पर कुछ लोगों के पास उनके शब्दों के बगल में आइकन हो सकते हैं।


वाह! मैं वास्तव में आपके प्रयासों की सराहना करता हूं, बहुत-बहुत धन्यवाद! (+1) मैंने पूरी कोशिश की लेकिन विंडोज 10 (बिल्ड 10240) पर संकलित संस्करण काम नहीं कर सका। मुझे नहीं पता कि समस्या क्या है, सभी bmp चित्र सही पथ में मौजूद हैं ( C:\shellicon\copy.bmp, आदि - ये बीएमपी प्रारूप में 20x20 पिक्सेल आइकन हैं) और मैंने कमांड प्रॉम्प्ट में एक व्यवस्थापक के रूप में डीएल को पंजीकृत किया regsvr32 ContextIcons.dllजिसके साथ सफलतापूर्वक भाग गया, लेकिन मुझे संदर्भ मेनू में कोई परिवर्तन नहीं दिख रहा है। मैंने कंप्यूटर को फिर से चालू किया, अपंजीकृत और फिर से dll को फिर से शुरू किया, लेकिन कोई बदलाव नहीं हुआ। मैं VS2015 में स्रोत संकलित करने की कोशिश कर रहा हूँ!
Sk8erPeter 21

@ Sk8erPeter MSDN ने कहा कि आइकन को 16x16 होना चाहिए, लेकिन मेरे लिए 20x20 काम करता है। शायद विंडोज 10 के लिए 16x16 की आवश्यकता है? ध्यान दें कि परिवर्तनों को प्रभावी करने के लिए आपको एक्सप्लोरर को पुनरारंभ करना होगा।
बेन एन

2
@ Sk8erPeter निश्चित रूप से, यहाँ आप जाते हैं । मैं GitHub पर कोड डालने के बारे में देखूंगा। अब विंडोज 10 डाउनलोड करने पर काम ...
बेन एन

2
आपको विश्वास नहीं होगा ... यह आपकी छवियों के साथ काम करता है! : D: D इसका मतलब है कि मेरे पास कुछ bmp फाइलें हैं, जिन्हें विंडोज हैंडल नहीं कर सका, पता नहीं क्यों (बाद में मैं इसे भी चेक करूंगा)। वैसे भी, बहुत बहुत धन्यवाद, आपका कोड वास्तव में समस्या हल करता है! :)
Sk8erPeter

1
@ बीन: ठीक है, धन्यवाद! :) यह थोड़ा अधिक सुविधाजनक होता। इस बीच BTW मुझे एहसास हुआ कि अगर मैं अपने पहले के काम नहीं करने वाले चित्रों को पौराणिक पेंट में खोलता हूं , और मैं "Save as"> "24-बिट बिटमैप (.bmp .dip)" करता हूं (इसलिए इसे BMP पर सहेजें। फिर से), और मैं एक स्रोत छवि के रूप में इस नई फ़ाइल का उपयोग करता हूं, यह काम करता है। बेशक, बिटमैप का आकार ठीक 16x16 पिक्सेल होना चाहिए। इसलिए पेंट अपेक्षित बिटमैप प्रारूप बनाता है जो 24 बिट प्रति पिक्सेल (16.7 मिलियन रंग), 96x96 डीपीआई और 16x16 पिक्सेल आकार में है। पहले मैंने .bmp फ़ाइलों में इरफ़ानव्यू में .png फ़ाइलों को परिवर्तित और आकार दिया था। ये आइकन काम नहीं करते थे।
228 बजे Sk8erPeter

1

मेरे पास एक टिप्पणी छोड़ने के लिए पर्याप्त प्रतिनिधि नहीं है, लेकिन ऐसा प्रतीत होता है कि यह जानकारी शेल 32.dll के अंदर समाहित है। फ़ाइलों को संकलित किया गया है, इसलिए यह देखना मुश्किल है कि इसमें क्या कार्य हैं, लेकिन यह एक प्रतीत होता है।

ब्याज की (रजिस्ट्री निर्यात):

HKEY_CLASSES_ROOT \ CLSID {} ​​3ad05575-8857-4850-9277-11b85bdb8e09

(डिफ़ॉल्ट) REG_SZ कॉपी / मूव / नाम बदलें / हटाएं / लिंक ऑब्जेक्ट

AppID REG_SZ {3ad05575-8857-4850-9277-11b85bdb8b09}

LocalizedString REG_EXPAND_SZ @% SystemRoot% \ system32 \ shell32.dll, -50176

InProcServer32 कुंजी के तहत यह shell32.dll का संदर्भ देता है। वहाँ कुछ अन्य लोगों के साथ-साथ प्रासंगिक लगने वाले नाम हैं। संभवतः ब्याज की भी windows.storage.dll है


1
रोचक जानकारी। हालाँकि, यह एक उत्तर के बजाय एक टिप्पणी लगती है। अब आपके पास हर जगह टिप्पणी करने के लिए पर्याप्त प्रतिनिधि है :)
बेन एन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.