2011-03-12 13 views
7

मेरे पास एक सूची बॉक्स है जिसमें फ़ाइलों की एक सूची है। क्या मैं खुले, गुणों को हटाने और नाम बदलने के लिए सूची बॉक्स में विंडोज राइट-क्लिक मेनू तक पहुंच सकता हूं?डिफ़ॉल्ट राइट-क्लिक मेनू दिखाएं - डेल्फी

उत्तर

8

किर्मिया जेडीआई जेसीएल लाइब्रेरी से JclShell इकाई की जांच करें, इस इकाई के अंदर DisplayContextMenu नामक एक फ़ंक्शन मौजूद है जो फ़ाइल से संबंधित संदर्भ मेनू दिखाता है। यह फ़ंक्शन IContextMenu इंटरफ़ेस को कॉल को समाहित करता है और आपके काम को और अधिक आसान बनाता है।

function DisplayContextMenu(const Handle: HWND; const FileName: string; 
    Pos: TPoint): Boolean; 
+0

+1 आप हैंडल पैरामीटर के रूप में क्या पास करते हैं? इसका क्या उपयोग है? –

+0

@ डेविड आप अपने फॉर्म के हैंडल को पास कर सकते हैं, यह हैंडल 'IContextMenu.InvokeCommand' में उपयोग किया जाता है जो 'CMINVOKECOMMANDINFO' संरचना http://msdn.microsoft.com/en-us/library/bb773215%28v= प्राप्त करता है vs.85% 29.aspx। – RRUZ

+0

क्या इस इकाई का कोई नया संस्करण है? (डेल्फी 2010 के लिए) – Kermia

2

मैं tpShellShock जैसे कुछ को देखने की सलाह दूंगा जब आप अपने डेल्फी ऐप में नियंत्रण जैसे खोल दिखाना चाहते हैं। यह पेड़ के दृश्य, सूची दृश्य इत्यादि प्रदान करता है जिसे एक एक्सप्लोरर विंडोज की तरह एक साथ जोड़ा जा सकता है। यह फ़ाइलों के लिए उपयुक्त प्रतीक प्रदर्शित करेगा। मुझे यकीन है कि यह उन सुविधाओं की पेशकश करता है जिनके बारे में आप बात करते हैं।

यदि आप आधुनिक यूनिकोड डेल्फी पर हैं तो इसे कुछ पोर्टिंग कार्य की आवश्यकता हो सकती है, लेकिन जब मैंने ऐसा किया है तो यह अपेक्षाकृत सरल साबित हुआ है।

इसमें कोई संदेह नहीं है कि अन्य पुस्तकालय हैं जो शैल नियंत्रण प्रदान करते हैं, यह केवल मैं ही परिचित हूं।

अन्यथा यदि आप अपने वर्तमान समाधान से चिपकना चाहते हैं तो अपने स्वयं के मेनू क्रियाओं को लागू करना सबसे आसान है। खुले और गुण उचित क्रिया के साथ ShellExecute के लिए बस सरल कॉल हैं। हटाएं DeleteFile और Rename को कॉल करने के लिए एक कॉल है MoveFile के लिए एक कॉल है।

5

IContextMenu इंटरफ़ेस देखें। लेकिन ध्यान रखें कि विंडोज शैल फ़ाइल नाम से अपनी वस्तुओं की पहचान नहीं करता है - असल में वे फाइल नहीं हो सकते हैं। यह आईडी के एक संयोजन का उपयोग करता है, और आपको उस आइटम आईडी सूची को प्राप्त करने की आवश्यकता हो सकती है जो फ़ाइल पर कुछ शैल फ़ंक्शंस का आविष्कार करने से पहले एक फ़ाइल है।

+0

ऐसा लगता है कि यह आपको संदर्भ मेनू में होने वाले शेल के बारे में बताता है। जैसा कि मैंने इसे पढ़ा है, आपको अभी भी मेनू को पॉप्युलेट करना होगा, और फिर डेल्फी ऑनक्लिक घटनाओं के जवाब में इस इंटरफ़ेस के माध्यम से कमांड का आह्वान करना होगा। क्या वो सही है? –

+0

+1 निश्चित रूप से ऑनक्लिक हैंडलर को लागू करने के लिए एक अच्छा तरीका दिखता है। –

+0

हां, आपको मेनू बनाना है (कम से कम यह आपको किसी भी प्रकार के मेनू का उपयोग करने की अनुमति देता है), वैसे भी यह आपको प्रत्येक तत्व का समर्थन देता है, और आपको खोल द्वारा परिभाषित उचित आदेश का आह्वान करने देता है। यह केवल फाइलों पर काम नहीं करता है, हालांकि यह उपयोगकर्ता प्रश्न से परे है। –

3

यहाँ एक सूची बॉक्स है, जो परियोजना निर्देशिका में फ़ाइल नाम के साथ से भर जाता है की 'OnContextPopup' घटना का उपयोग कर, उसके नाम पर जब दायाँ क्लिक किया है एक फ़ाइल का शॉर्टकट मेनू शुरू करने के लिए एक कार्यान्वयन उदाहरण है:

type 
    TForm1 = class(TForm) 
    ListBox1: TListBox; 
    procedure FormCreate(Sender: TObject); 
    procedure ListBox1ContextPopup(Sender: TObject; MousePos: TPoint; 
     var Handled: Boolean); 
    private 
    protected 
    procedure WndProc(var Msg: TMessage); override; 
    public 
    end; 

var 
    Form1: TForm1; 

implementation 

uses 
    shlobj, comobj; 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
var 
    SearchRec: TSearchRec; 
begin 
    ListBox1.Clear; 

    // populate list box with files in the project folder 
    if FindFirst(ExtractFilePath(Application.ExeName) + '*.*', 
       0, SearchRec) = 0 then 
    repeat 
     ListBox1.Items.Add(SearchRec.Name); 
    until FindNext(SearchRec) <> 0; 
    FindClose(SearchRec); 
end; 

var 
    // Required to handle messages for owner drawn items, as in 'SendTo' menu. 
    // Also used as a flag in WndProc to know if we're tracking a shortcut menu. 
    ContextMenu2: IContextMenu2 = nil; 

procedure TForm1.ListBox1ContextPopup(Sender: TObject; MousePos: TPoint; 
    var Handled: Boolean); 
var 
    Item: Integer; 
    DeskFolder, Folder: IShellFolder; 
    Eaten, Attributes: ULONG; 
    pIdl, FolderpIdl: PItemIDList; 
    ContextMenu: IContextMenu; 
    Menu: HMENU; 
    Pos: TPoint; 
    Cmd: DWORD; 
    CommandInfo: TCMInvokeCommandInfo; 
begin 
    Item := (Sender as TListBox).ItemAtPos(MousePos, True); 
    Handled := Item <> -1; 
    if not Handled then 
    Exit; 
    TListBox(Sender).ItemIndex := Item; 

    // IShellFolder for Desktop folder (root) 
    OleCheck(SHGetDesktopFolder(DeskFolder)); 

    // Item ID List for the folder that the file is in 
    Attributes := 0; 
    OleCheck(DeskFolder.ParseDisplayName(Handle, nil, 
        PWideChar(WideString(ExtractFilePath(Application.ExeName))), 
        Eaten, FolderpIdl, Attributes)); 

    // IShellFolder for the folder the file is in 
    OleCheck(DeskFolder.BindToObject(FolderpIdl, nil, IID_IShellFolder, Folder)); 
    CoTaskMemFree(FolderpIdl); 

    // Item ID List for the file, relative to the folder it is in 
    Attributes := 0; 
    OleCheck(Folder.ParseDisplayName(Handle, nil, 
      PWideChar(WideString(ExtractFileName(TListBox(Sender).Items[Item]))), 
      Eaten, pIdl, Attributes)); 

    // IContextMenu for the relative Item ID List 
    OleCheck(Folder.GetUIObjectOf(Handle, 1, pIdl, IID_IContextMenu, 
            nil, ContextMenu)); 
    CoTaskMemFree(pIdl); 

    Menu := CreatePopupMenu; 
    try 
    // Populate our menu with shortcut items 
    OleCheck(ContextMenu.QueryContextMenu(Menu, 0, 1, $7FFF, CMF_EXPLORE)); 

    // ContextMenu2 used in WndProc 
    ContextMenu.QueryInterface(IID_IContextMenu2, ContextMenu2); 
    try 
     Pos := TWinControl(Sender).ClientToScreen(MousePos); 
     // launch the menu 
     Bool(Cmd) := TrackPopupMenu(Menu, 
          TPM_LEFTBUTTON or TPM_RIGHTBUTTON or TPM_RETURNCMD, 
          Pos.X, Pos.Y, 0, Handle, nil); 
    finally 
     // clear so that we don't intervene every owner drawn menu item message in 
     // WndProc 
     ContextMenu2 := nil; 
    end; 

    // Invoke command if we have one 
    if Bool(Cmd) then begin 
     FillChar(CommandInfo, SizeOf(CommandInfo), 0); 
     CommandInfo.cbSize := SizeOf(CommandInfo); 
     CommandInfo.hwnd := Handle; 
     CommandInfo.lpVerb := MakeIntResource(Cmd - 1); 
     CommandInfo.nShow := SW_SHOWNORMAL; 

     OleCheck(ContextMenu.InvokeCommand(CommandInfo)); 
    end; 

    finally 
    DestroyMenu(Menu); 
    end; 
end; 

procedure TForm1.WndProc(var Msg: TMessage); 
begin 
    if ((Msg.Msg = WM_INITMENUPOPUP) or (Msg.Msg = WM_DRAWITEM) 
       or (Msg.Msg = WM_MEASUREITEM)) and Assigned(ContextMenu2) then 
    ContextMenu2.HandleMenuMsg(Msg.Msg, Msg.WParam, Msg.LParam) 
    else 
    inherited; 
end; 
संबंधित मुद्दे