Solved

Explorer Popup Menu

Posted on 2001-07-10
5
676 Views
Last Modified: 2010-04-06
I'm making an application and I need for to have a option to open it on the Windows Explorer popup menu(show's when you right click a file) with all files but one(the file type my program actually reads) sort like winzip does. and for one special file type(the file type my program actually reads) I also need some special options on it's popup menu.
I've been checking the registry for it but all I saw were keys inside the ContextMenuHandlers (at HKEY_CLASSES_ROOT\*\ShellEx) with the names of programs that do such and at the (standart) of those keys were values like {FF678...423A4} and something like that.
I found those keys with those values inside the CLSID key(at HKEY_CLASSES_ROOT).
Does this have anything to do with it?
I'm making the this program in delphi reason why I'm asking here first before asking at the windows group.
I'd appreciate any help.

Luiz Paulo
0
Comment
Question by:luizpaulo
  • 2
  • 2
5 Comments
 
LVL 22

Expert Comment

by:mnasman
ID: 6272271
you will fine an example came with delphi, look at the project called contmenu.dpr in this path

\Delphi5\Demos\Activex\Shellext

send me email at nasman@mogaza.org, and i will send you an article about enhanced version of this demo with the source code

Best regards
Mohammed Nasmna
0
 

Author Comment

by:luizpaulo
ID: 6275770
I have D3 and there it has a example like at \Demos\Shellext but the example doesn't say anything about
the CLSID key you have to make(I mean how to generate those {FF678...423A4} numbers), plus It doesn't explain anything about the COM stuff(which I know very little about)
Where can I read more about this?
Thanks for the help.

Luiz Paulo
0
 
LVL 1

Expert Comment

by:SBSen
ID: 6275965
Hi

I mean how to generate those {FF678...423A4} numbers
In the Editor just press ctrl+shift+g
It will give u the GUID u can use it for u r application.

Another easy way have without any Com dll for the Explorer
menu.
u can just add u r application to SendTo folder in u r system.
It will actomatically come in the SendTo list of u r system.

below I have coding of jEdit Context menu
******************
unit ContextM;

interface

uses
       Windows, ActiveX, ComObj, ShlObj, graphics;

type
       TContextMenu = class(TComObject, IShellExtInit, IContextMenu)
       private
             FFileName: array[0..MAX_PATH] of Char;
             FFileNameList: String;
             BT: TBitmap;
       protected
             { IShellExtInit }
             function IShellExtInit.Initialize = SEIInitialize; // Avoid compiler warning
             function SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
                   hKeyProgID: HKEY): HResult; stdcall;
             { IContextMenu }
             function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,
                   uFlags: UINT): HResult; stdcall;
             function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
             function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
                   pszName: LPSTR; cchMax: UINT): HResult; stdcall;
       end;

const
       Class_ContextMenu: TGUID = '{E15E69D0-E84D-4A69-9E3C-51839D60C9C2}';

implementation

uses ComServ, SysUtils, ShellApi, Registry;

function TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
       hKeyProgID: HKEY): HResult;
var
       StgMedium: TStgMedium;
       FormatEtc: TFormatEtc;
       Count, Loop: Byte;
begin
       // Fail the call if lpdobj is Nil.
       if (lpdobj = nil) then begin
             Result := E_INVALIDARG;
             Exit;
       end;

       with FormatEtc do begin
             cfFormat := CF_HDROP;
             ptd := nil;
             dwAspect := DVASPECT_CONTENT;
             lindex := -1;
             tymed := TYMED_HGLOBAL;
       end;

       // Render the data referenced by the IDataObject pointer to an HGLOBAL
       // storage medium in CF_HDROP format.
       Result := lpdobj.GetData(FormatEtc, StgMedium);
       if Failed(Result) then
       begin
             Exit;
       end;
       // File(s) is selected, retrieve the file name and store it in FFileName.
       // FFileNameList Soters the List of files.
       if (DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0) > 0) then begin
             Count := DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0);
             for Loop := 0 to Count - 1 do begin
                   DragQueryFile(StgMedium.hGlobal, Loop, FFileName, SizeOf(FFileName));
                   FFileNameList := FFileNameList + FFileName+' ';
             end;
             //       if (DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0) = 1) then begin
             //       DragQueryFile(StgMedium.hGlobal, 0, FFileName, SizeOf(FFileName));
             Result := NOERROR;
       end
       else begin
             FFileName[0] := #0;
             Result := E_FAIL;
       end;
       ReleaseStgMedium(StgMedium);
end;

function TContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
       idCmdLast, uFlags: UINT): HResult;
begin
       Result := 0; // or use MakeResult(SEVERITY_SUCCESS, FACILITY_NULL, 0);
       //Load the image from RES file.
       if BT = nil then
             BT := TBitmap.Create;
       BT.LoadFromResourceName(HInstance, 'BTM');

       if ((uFlags and $0000000F) = CMF_NORMAL) or
             ((uFlags and CMF_EXPLORE) <> 0) then begin
             // Add one menu item to context menu
             InsertMenu(Menu, indexMenu, MF_STRING or MF_BYPOSITION, idCmdFirst,
                   '&jEdit');
             SetMenuItemBitmaps(Menu, indexMenu, MF_STRING or MF_BYPOSITION, BT.Handle, BT.Handle);
             // Return number of menu items added
             Result := 1; // or use MakeResult(SEVERITY_SUCCESS, FACILITY_NULL, 1)
       end;
end;

function GetjEditPath: string;
// Returns string containing path to jEdit command line
var
       Reg: TRegistry;
begin
       Reg := TRegistry.Create;
       try
             with Reg do begin
                   RootKey := HKEY_LOCAL_MACHINE;
                   OpenKey('\SOFTWARE\jEdit\3.3', False);
                   Result := ReadString('App');
             end;
             if AnsiPos(' ', Result) <> 0 then
                   Result := ExtractShortPathName(Result);
                   Result := Result + ' %S';
       finally
             Reg.Free;
       end;
end;

function TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
resourcestring
       sPathError = 'Error setting current directory';
var
       H: THandle;
       PrevDir: string;
begin
       Result := E_FAIL;
       // Make sure we are not being called by an application
       if (HiWord(Integer(lpici.lpVerb)) <> 0) then
       begin
             Exit;
       end;
       // Make sure we aren't being passed an invalid argument number
       if (LoWord(lpici.lpVerb) <> 0) then begin
             Result := E_INVALIDARG;
             Exit;
       end;

       // Execute the command specified by lpici.lpVerb
       // by invoking the jEdit command line .
       PrevDir := GetCurrentDir;
       try
             if not SetCurrentDir(ExtractFilePath(FFileName)) then
                   raise Exception.CreateRes(@sPathError);

             H := WinExec(PChar(Format(GetjEditPath, [FFileNameList])), lpici.nShow);
             if (H < 32) then
                   MessageBox(lpici.hWnd, 'Error Opening jEdit .', 'Error',
                         MB_ICONERROR or MB_OK);
             Result := NOERROR;
       finally
             SetCurrentDir(PrevDir);
       end;
end;


function TContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
       pszName: LPSTR; cchMax: UINT): HRESULT;
begin
       if (idCmd = 0) then begin
             if (uType = GCS_HELPTEXT) then
      // return help string for menu item
      StrCopy(pszName, 'Open File in jEdit');
    Result := NOERROR;
  end
  else
    Result := E_INVALIDARG;
end;

type
       TContextMenuFactory = class(TComObjectFactory)
       public
             procedure UpdateRegistry(Register: Boolean); override;
       end;

procedure TContextMenuFactory.UpdateRegistry(Register: Boolean);
var
       ClassID: string;
begin
       if Register then begin
             inherited UpdateRegistry(Register);

             ClassID := GUIDToString(Class_ContextMenu);
             CreateRegKey('IQL\shellex', '', '');
             CreateRegKey('IQL\shellex\ContextMenuHandlers', '', '');
             CreateRegKey('IQL\shellex\ContextMenuHandlers\ContMenu', '', ClassID);

             if (Win32Platform = VER_PLATFORM_WIN32_NT) then
                   with TRegistry.Create do
                   try
                         RootKey := HKEY_LOCAL_MACHINE;
                         OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions', True);
                         OpenKey('Approved', True);
                         WriteString(ClassID, 'jEdit Context Menu Shell Extension');
                   finally
                         Free;
                   end;
       end
       else begin
             DeleteRegKey('IQL\shellex\ContextMenuHandlers\ContMenu');
             DeleteRegKey('IQL\shellex\ContextMenuHandlers');
             DeleteRegKey('IQL\shellex');

             inherited UpdateRegistry(Register);
       end;
end;

initialization
       TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,
             '', 'jEdit Context Menu Shell Extension', ciMultiInstance,
             tmApartment);
end.

******************
if u have any doubt mail me
regards
sbsen.
0
 
LVL 22

Accepted Solution

by:
mnasman earned 100 total points
ID: 6275982
Hello Luiz

  if you want to read more about com, look at this site

http://delphi.about.com/cs/comoleactivex/index.htm

0
 

Author Comment

by:luizpaulo
ID: 6280667
Thanks for the help Mohammed, with your code(on the email), sbsen's code, and delphi's demo I acomplished what I desired.
I also wanna thank sbsen but I can only give points to one person, but your help was appreciated. I gave the points to Mohammed because he was the first one.
Thanks for the help.

Luiz Paulo
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now