लघु जवाब
JAM सॉफ्टवेयर से ShellBrowser Components की कोशिश करो। उनके पास एक घटक है जो आपको एक्सप्लोरर के संदर्भ मेनू को आपके स्वयं के आदेशों के साथ एक TPopupMenu में मिश्रित करने देगा।
लांग जवाब
, एक्सप्लोरर मीनू हो रही है उसके गुण के सभी क्वेरी करने, और उन्हें अपने खुद मेनू में होस्टिंग संभव है, लेकिन क्या तुम सच में आराम से पढ़ने/निम्न स्तर के लेखन Win32 कोड होना चाहिए और सी का एक कामकाजी ज्ञान मदद करेगा। आपको कुछ गॉथ (नीचे कवर) के लिए भी देखना होगा। मैं बहुत सारे तकनीकी विवरणों के लिए रेमंड चेन की How to host an IContextMenu श्रृंखला पढ़ने की दृढ़ता से अनुशंसा करता हूं।
आसान दृष्टिकोण IContextMenu इंटरफेस के लिए क्वेरी करने के लिए है, तो HMENU, तो TrackPopupMenu का उपयोग करने देने के लिए Windows मेनू दिखाने है, तो अंत में InvokeCommand कहते हैं।
नीचे दिए गए कुछ कोड को अनचाहे किया गया है या हम जो भी उपयोग कर रहे हैं उससे संशोधित किया गया है, इसलिए अपने जोखिम पर आगे बढ़ें।
यहाँ कैसे आप एक आधार फ़ोल्डर के भीतर फ़ाइलों के एक समूह के लिए IContextMenu मिलता है, है:
function GetExplorerMenu(AHandle: HWND; const APath: string;
AFilenames: TStrings): IContextMenu;
var
Desktop, Parent: IShellFolder;
FolderPidl: PItemIDList;
FilePidls: array of PItemIDList;
PathW: WideString;
i: Integer;
begin
// Retrieve the Desktop's IShellFolder interface
OleCheck(SHGetDesktopFolder(Desktop));
// Retrieve the parent folder's PItemIDList and then it's IShellFolder interface
PathW := WideString(IncludeTrailingPathDelimiter(APath));
OleCheck(Desktop.ParseDisplayName(AHandle, nil, PWideChar(PathW),
Cardinal(nil^), FolderPidl, Cardinal(nil^)));
try
OleCheck(Desktop.BindToObject(FolderPidl, nil, IID_IShellFolder, Parent));
finally
SHFree(FolderPidl);
end;
// Retrieve PIDLs for each file, relative the the parent folder
SetLength(FilePidls, AFilenames.Count);
try
FillChar(FilePidls[0], SizeOf(PItemIDList) * AFilenames.Count, 0);
for i := 0 to AFilenames.Count-1 do begin
PathW := WideString(AFilenames[i]);
OleCheck(Parent.ParseDisplayName(AHandle, nil, PWideChar(PathW),
Cardinal(nil^), FilePidls[i], Cardinal(nil^)));
end;
// Get the context menu for the files from the parent's IShellFolder
OleCheck(Parent.GetUIObjectOf(AHandle, AFilenames.Count, FilePidls[0],
IID_IContextMenu, nil, Result));
finally
for i := 0 to Length(FilePidls) - 1 do
SHFree(FilePidls[i]);
end;
end;
वास्तविक मेनू आइटम आप IContextMenu.QueryContextMenu कॉल करने की आवश्यकता प्राप्त करने के लिए। आप DestroyMenu का उपयोग कर लौटे हुए एचएमईएनयू को नष्ट कर सकते हैं।
procedure InvokeCommand(const AContextMenu: IContextMenu; AVerb: PChar);
const
CMIC_MASK_SHIFT_DOWN = $10000000;
CMIC_MASK_CONTROL_DOWN = $20000000;
var
CI: TCMInvokeCommandInfoEx;
begin
FillChar(CI, SizeOf(TCMInvokeCommandInfoEx), 0);
CI.cbSize := SizeOf(TCMInvokeCommandInfo);
CI.hwnd := GetOwnerHandle(Owner);
CI.lpVerb := AVerb;
CI.nShow := SW_SHOWNORMAL;
// Ignore return value for InvokeCommand. Some shell extensions return errors
// from it even if the command worked.
try
AContextMenu.InvokeCommand(PCMInvokeCommandInfo(@CI)^)
except on E: Exception do
MessageDlg(Owner, E.Message, mtError, [mbOk], 0);
end;
end;
procedure InvokeCommand(const AContextMenu: IContextMenu; ACommandID: UINT);
begin
InvokeCommand(AContextMenu, MakeIntResource(Word(ACommandID)));
end;
अब आप शीर्षक प्राप्त करने के लिए GetMenuItemInfo समारोह का उपयोग कर सकते, बिटमैप, आदि, लेकिन एक बहुत आसान:
function GetExplorerHMenu(const AContextMenu: IContextMenu): HMENU;
const
MENUID_FIRST = 1;
MENUID_LAST = $7FFF;
var
OldMode: UINT;
begin
OldMode := SetErrorMode(SEM_FAILCRITICALERRORS or SEM_NOOPENFILEERRORBOX);
try
Result := CreatePopupMenu;
AContextMenu.QueryContextMenu(Result, 0, MENUID_FIRST, MENUID_LAST, CMF_NORMAL);
finally
SetErrorMode(OldMode);
end;
end;
यहाँ कैसे आप वास्तव में आदेश फोन उपयोगकर्ता मेनू से चयन किया है कि दृष्टिकोण TrackPopupMenu पर कॉल करना है और विंडोज़ को पॉपअप मेनू दिखाएं। यहाँ
procedure ShowExplorerMenu(AForm: TForm; AMousePos: TPoint;
const APath: string; AFilenames: TStrings;);
var
ShellMenu: IContextMenu;
Menu: HMENU;
MenuID: LongInt;
begin
ShellMenu := GetExplorerMenu(AForm.Handle, APath, AFilenames);
Menu := GetExplorerHMenu(ShellMenu);
try
MenuID := TrackPopupMenu(Menu, TPM_LEFTALIGN or TPM_TOPALIGN or TPM_RETURNCMD,
AMousePos.X, AMousePos.Y, 0, AForm.Handle, nil);
InvokeCommand(ShellMenu, MenuID - MENUID_FIRST);
finally
DestroyMenu(Menu);
end;
end;
आप वास्तव में मेनू आइटम/कैप्शन निकालने और उन्हें अपने खुद के पॉपअप मेनू में जोड़ने के लिए (हम टूलबार 2000 उपयोग और बिल्कुल ऐसा) चाहते हैं, अन्य बड़े मुद्दे हैं: यही कारण है कि कुछ इस तरह दिखेगा आप चलाएंगे में:
- "भेजें" मेनू में, और किसी भी अन्य लोगों कि मांग पर निर्माण कर रहे हैं काम नहीं करेगा जब तक कि आप संदेशों को संभालने और उन्हें IContextMenu2/IContextMenu3 इंटरफेस के गुजरती हैं।
- मेनू बिटमैप्स कुछ अलग प्रारूपों में हैं। डेल्फी विस्टा के बिना विस्टा उच्च-रंग वाले लोगों को संभाल नहीं पाता है, और पुराने लोगों को एक्सओआर का उपयोग करके पृष्ठभूमि रंग पर मिश्रित किया जाता है।
- कुछ मेनू आइटम मालिक-तैयार हैं, इसलिए आपको पेंट संदेशों को कैप्चर करना होगा और उन्हें अपने कैनवास पर पेंट करना होगा।
- संकेत तार तब तक काम नहीं करेंगे जब तक कि आप उनके लिए मैन्युअल रूप से क्वेरी नहीं करते।
- आपको आईसीएन्टेक्स्टमेनू और एचएमईएनयू के जीवनकाल को प्रबंधित करने की आवश्यकता होगी और पॉपअप मेनू बंद होने के बाद ही उन्हें रिलीज़ करना होगा।
आप स्वयं के संदर्भ मेनू आइटम बनाने के लिए या मौजूदा मेनू आइटम हेरफेर करने के लिए करना चाहते हैं? – Liton
@ लिटन, अपना खुद का खोल संदर्भ मेनू आइटम नहीं बना रहा है, लेकिन मौजूदा मेनू में निर्मित या तृतीय भाग आइटमों में हेरफेर करने के लिए। –