Link to home
Start Free TrialLog in
Avatar of otti
otti

asked on

Context Menu Handler - How?

What i like to add to my app:

You do a right click to file in the explorer, the appearing contextmenu should have an item i.e. "MyApp". Pointing on "myApp" should open an undermenü (Like SendTo) with some entrys that MyApp can execute.

I know i have to write a dll, but how? I use Delphi2 dev.

If someone can give me a piece of sourcecode a would be
very glad.

Thanks, Sascha
Avatar of dwwang
dwwang

Hi, the things you want to do is concerning Shell Extensions.
However, I forget whether it could be done in Delphi2.

If you can use Delphi3/4, it will be rather easy, since they
(at least delphi4) have some easy-to-understand demos.

you have to have the ability to declare types like that:
TContextMenu = class(TComObject, IShellExtInit, IContextMenu)
you're talking about the ..\shellext\contmenu.dpr, i assume...

Black Death.
Surely, but do you mean D2 also has such an example?
Avatar of otti

ASKER

Ok, but i have only D2 for use. I can not belevie thats impossible with D2.

Sascha
ASKER CERTIFIED SOLUTION
Avatar of ptmcomp
ptmcomp
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
well, I guess otti knows how to create extensions... I think he wanted to know how to do it in Delphi.

Although this question is locked, I'll still do my best to answer it!
What a coincidence - I just did the exact same thing two days ago and will paste some of my code. I'm using Delphi 4 and don't have Delphi 2 around to see if it works, but it should really be the same as long as "TRegistry" is available in Delphi 2.

This will create the extensions in Win95 and WinNT - if you need it for 16-bit Delphi, you need to use TIniFile. Let me know if you need that and I'll find a place to look it up (as a matter of fact, I know the place... I just have to find it again which will take ten minutes or so)

Basically, ptmcomp told you how to create the extension - just not how you would do it in Delphi. There are actually different ways of doing it.

One is this:
It assigns the extension *.vt1 to my program and tells Windows to use the first icon from the exe-file as the icon representing that file type. I think the first icon in the exe-file is the program's own icon.
Here we go:

  WITH TRegistry.Create DO BEGIN
  try
    RootKey := HKEY_CLASSES_ROOT;
    LazyWrite := false;
    {Add Program Support}
    OpenKey('.vt1\shell\open\command',true);
    {Invoke the program passing the file name as the first parameter}
    WriteString('',ParamStr(0)+' %1');
    {Add Icon Display}
    CloseKey;
    OpenKey('.vt1\DefaultIcon', true);
    {Use the first icon in the executable to display}
    WriteString('',ParamStr(0)+',0');
    CloseKey;
   except
     ShowMessage('Error creating file association');
   end;
   Free;
  END;
That's the "simplistic approach" ptmcomp described. It simply reassigns the "Open" command, but does not really "register" a new extension with all the bells and whistles.

That's what this code does:
  with TRegIniFile.Create('') do begin
   try
    RootKey := HKEY_CLASSES_ROOT;
    WriteString('.vt1','','HSVT');  //register the extension as file-type HSVT (name of my program)
    WriteString('HSVT','','Holgers vocabulary trainer'); // specify full-text name to display in Explorer
    WriteString('HSVT\DefaultIcon','',ParamStr(0)+',0');
    WriteString('HSVT\Shell','','Open'); //This_Is_Our_Default_Action
    WriteString('HSVT\Shell\Open', '', 'Open in HSVT.exe'); //specify text for default-action
    WriteString('HSVT\Shell\Open\command','',ParamStr(0)+' %1'); //specify command
//    WriteString('HSVT\Shell\First_Action','','This is our first action');
//    WriteString('HSVT\Shell\First_Action\command','','C:\MyApp.Exe /LotsOfParamaters %1');
//    WriteString('HSVT\Shell\Second_Action','','This is our second action');
//    WriteString('HSVT\Shell\Second_Action\command','','C:\MyApp.Exe /TonsOfParameters %1');
   except
     ShowMessage('Error creating context menus');
   end;
   Free;
  end;

I haven't used the "FirstAction" / "SecondAction" yet, but this code shows you how to do it. This code WOULD actually work in BOTH Win95/NT AND in Win-16 bit as well, but I'm afraid TRegIniFile is not available in Delphi2. You should be able to easily figure out the necessary registry entries from the above post, though.

You mentioned writing a DLL and I assume you're not familiar with the concept of registering file types? You don't need a DLL --- if a user clicks your file or chooses a context menu item, your programm will be called with the parameters you specified in the registry entries - the %1 is replaced by the file type. Your program can then read the "command line parameters" and do whatever it deems necessary ;-))

e.g.: Place something like this in your TForm1.FormCreate;
  FOR Ct:=1 TO ParamCount DO BEGIN   //look at the parameters one by one
    s:=ParamStr(Ct);
    P:=POS('-bdir:',s);
    IF P=1 THEN BaseDir:=copy(s,7,Length(s)-7)
    ELSE BEGIN
      P:=POS('-logon:',s);
      IF P=1 THEN BEGIN //is a logon parameter
        UName:=copy(s,8,POS('/',s)-8);
        UPW:=copy(s,POS('/',s)+1,Length(s)-POS('/',s));
        UM.LogOn(UName,UPW);
      END
      ELSE BEGIN                     //is a file to open
        INC(FCt);                         //increase FileCount
        FList[FCt]:=ParamStr(Ct); //add file name to list
      END;
    END;
  END;
(just to give you an idea)

I hope that answers your questions (also hope to get some points for it :-))
If something doesn't work, feel free to ask :-)
In that case, please also specify the target platform(s)! ooops, stupid me - Delphi 2 can't even compile for 16-bit Delphi! Well, I'm not going to delete all my remarks about 16-bit - they are still valid! If the compiler complains, please let me know what it says since I don't have Delphi 2. The code DOES work in my program so I know it's correct ;-))

Good luck!
Avatar of otti

ASKER

Hi ptmcomp! Hi Holger!

A really great missunderstanding! What you have explained is how to register filetypes. That's really easy and i know how to do it.

What i want is such a thing Winzip does: Right click on a file should give me a contextmenu with i.e. an icon next to the entry.

For this solution i need an Activex Dll, that i have to register with a CSLID to the registry and which is called everytime a right click was done in the explorer.

ptmcomp: You gave me a really good hint how to do this without a activex dll. If i add my command to  .../*/Shell/MyItem it works almost perfectly. What i don't like is that the menuentry is inserted to the top of the popupmenu and i don't get a undermenu like "Sendto". But your solution is *much* simpler as programming an activex dll. So i think i will use this way. I will grade your answer as a "C" (In fact it is a workaround) and you will get the Points.
Perhaps you know how to create a submenu or a to include a horizontal line? (Don't know the english word. A "-" for a delphi menuitem does this)

Holger: Really much work, and very detailed answer but -sorry - i know this already. PtmComp gave me the hint to use the .../*/Shell, this i didn't know and helps me to include a "Works-with-any-filetype-conetxtmenu" to my app.

Greetings, Sascha