Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Explorer Popup Menu

Posted on 2001-07-10
5
Medium Priority
?
690 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 22

Expert Comment

by:Mohammed Nasman
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:
Mohammed Nasman earned 400 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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses

705 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