Skip over navigation

How to add a program to the Explorer Send To menu

Why do it

If you are writing a general purpose file-related program it can be useful to add it to the Windows Explorer "Send To" menu. For example I place Windows Notepad on the "Send To" menu so I can easily view any file in the text editor:

Screen shot of an example of 'Send To' menu
Figure 1: Example of a 'Send-To' menu

How it's done

There are two stages achieving our goal:

  1. Ensuring our program can receive files sent from the "Send To" menu.
  2. Creating an entry for our program in the "Send To" menu.

Although you can create a special handler for the "Send To" menu, we will take the simple approach of simply storing a shortcut to our program in the menu.

Receiving files from the "Send To" menu

This is very simple. If the user selects one or more files, right clicks and selects Send To | Our program, Windows will simply start our program and pass the name(s) of the selected file(s) on the command line. So, to read the files sent from the "Send To" menu, we simply need to check our command line parameters.

We can do this in our application's FormCreate event handler as follows:

  1procedure TForm1.FormCreate(Sender: TObject);
  2var
  3  I: Integer;
  4begin
  5  for I := 1 to ParamCount do
  6    ProcessFile(ParamStr(I));
  7end;
Listing 1

where ProcessFile processes a given file in an application defined way. (In the demo program that accompanies this article we simply display the file names in a memo control).

That's all there is to handling the files. Now let's look at how we create the "Send To" menu entry.

Creating the "Send To" menu item

Windows stores the contents of a user's "Send To" menu in a special folder. We will need to add a shortcut to our program in that folder.

We must first find the path to the "Send To" folder. Each user has their own copy of this folder. We find its location by using the SHGetSpecialFolderLocation and SHGetPathFromIDList API calls (defined in the ShlObj unit) as follows:

  1function GetSendToFolder: string;
  2var
  3  pidl: PItemIDList;
  4  PPath: array[0..MAX_PATH] of AnsiChar;
  5begin
  6  Result := '';
  7  if SHGetSpecialFolderLocation(0, CSIDL_SENDTO, pidl) = NOERROR then
  8  begin
  9    try
 10      if SHGetPathFromIDList(pidl, PPath) then
 11        Result := PPath;
 12    finally
 13      CoTaskMemFree(pidl);
 14    end;
 15  end;
 16end;
Listing 2

We first use SHGetSpecialFolderLocation to get a PIDL representing the required folder. We pass CSIDL_SENDTO to the function to get the PIDL for the current user's "Send To" folder. If we succeed in getting the PIDL we then get the path to the folder by passing the PIDL to SHGetPathFromIDList and returning a string representation of the PChar buffer we passed to the function. Windows allocated memory for the PIDL using its task allocator. It is our responsibility to free the PIDL, using the CoTaskMemFree function (defined in the ActiveX unit).

Having found the path to the user's "Send To" folder we can now create a shortcut to our application in the folder. We may choose to do this in a set up program or by making this an option in our application. Whatever our choice, here is the code we use:

  1// ...
  2CreateShellLink(
  3  GetSendToFolder + '\' + 'My SendTo Item.lnk',
  4  ParamStr(0),
  5  'My SendTo Sample Program',
  6  ExtractFileDir(ParamStr(0)),
  7  '',
  8  '',
  9  -1
 10);
 11// ...
Listing 3

We are making use of the CreateShellLink function from the DelphiDabbler Code Snippets Database to create the shortcut to our program. The parameters passed to CreateShellLink are:

  1. The first parameter to CreateShellLink is the full path to the shortcut file – here we use the name of the "Send To" folder, as returned by GetSendToFolder, followed by the name of the shortcut file. Note that the "Send To" menu displays the name of this file, stripped of it's extension, so give the file a descriptive name.
  2. The second parameter is the name of the file referenced by the shortcut – our program in this case. ParamStr(0) stores the name of the program.
  3. The third parameter is a description of the shortcut (this is not displayed in the "Send To" menu).
  4. The fourth parameter is our program's working directory. This may be omitted if not required.
  5. The fifth parameter stores any command line that is to be passed to the program. We do not use this parameter here. Remember that the "Send To" menu also passes file names on the command line.
  6. The sixth parameter is not used here: when provided it specifies the file containing the shortcut's icon. Since we don't specify a file, the icon is assumed to be in the program file.
  7. The final parameter also related to the shortcut's icon. Specifying -1 indicates that the program's default icon should be used.

Since this article is not about how to create shell links, we will not go into detail of how this routine works or review its source code here. (The source code is included in the accompanying demo program.)

That's all folks

We have now covered the basics of adding an item to the "Send To" menu and in handling files "sent" to our program from the menu. The code presented can be used as a basis for implementing "Send To" menu support in your programs.

Demo program

A demo program to accompany this article can be found in the delphidabbler/article-demos Git repository on GitHub.

You can view the code in the article-12 sub-directory. Alternatively download a zip file containing all the demos by going to the repository's landing page and clicking the Clone or download button and selecting Download ZIP.

See the demo's README.md file for details.

This source code is merely a proof of concept and is intended only to illustrate this article. It is not designed for use in its current form in finished applications. The code is provided on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.

The demo is open source. See the demo's LICENSE.md file for licensing details.

Feedback

I hope you found this article useful.

If you have any observations, comments, or have found any errors there are two places you can report them.

  1. For anything to do with the article content, but not the downloadable demo code, please use this website's Issues page on GitHub. Make sure you mention that the issue relates to "article #12".
  2. For bugs in the demo code see the article-demo project's README.md file for details of how to report them.