Shell Integration


Because both SDI and MDI versions of the Rates of Return application use a file with a custom extension (.ror) and support opening such files from the command line, we've got the fundamentals in place to support full shell integration.

Integrating with the Shell

The shell we're interested in integrating with is the Explorer shell where users keep track of their documents (although the command line shell picks up some integration here, too). The simplest kind of shell integration for a document-based application is to make sure that the application's documents are associated with the application so that double-clicking on one of the documents opens the application with the document loaded. The trick is to place the correct entries in the Registry to map a custom file extensionsuch as .ror to a ProgID (programmatic identifier)and then to register one or more commands under the ProgID (mapping Open to launch SDIClient.exe or MDIClient.exe).

To add a custom extension, we need a new key under the HKEY_CLASSES_ROOT Registry hive for the extension that maps to the ProgID. To add a new ProgID, we also need a new key under HKEY_CLASSES_ROOT, along with a subkey for the Open command. The goal, as shown in the Registry Editor (regedit.exe), looks like Figure F.7 (for the custom extension) and Figure F.8 (for the associated open command).

Figure F.7. Mapping a Custom File Extension to a Custom ProgID


Figure F.8. Registering an Open Command with a Custom ProgID


Notice the use of the quoted %L argument in Figure F.8 as part of the full path to our custom application's .exe file. When the user double-clicks on a .ror file or right-clicks and chooses Open from the context menu, the command in the Registry is executed, replacing %L with the long name of the chosen file. The use of the double quotes surrounding %L ensures that even a file name with spaces will come through as a single argument.

Although .NET provides a set of classes for Registry manipulations in the Microsoft.Win32 namespace, when the FileDocument component is created (and the RegisterFileExtensionWithShell property is set to true), it handles the registration of your custom file extension for you.[7] After the registration of the file extension, when the user double-clicks a file with that extension, the application is executed with the arguments passed in the string array to the Main method. Consequently, when the application opens, a file is loaded as a document.

[7] Permission to write to the Registry is not available to ClickOnce applications unless they are awarded full trust or custom permissions that allow writing to the Registry. See Chapter 19 for details.

Document Icons

In addition, after the Open command is registered under Microsoft Windows XP, the shell replaces the unregistered extension icon (shown in Figure F.9) with an icon composed of a miniature icon from the application itself (shown in Figure F.10).

Figure F.9. Document File Without an Extension Association


Figure F.10. Shell-Created Document Icon Based on the Application's Icon (16 x 16)


If you prefer a custom icon for your document types, you can set the DefaultIcon key under the ProgID in the Registry. The key is the name of the Windows EXE or DLL containing native icons, followed by an icon indicator. If the indicator is negative, it's interpreted as a resource ID (after the minus sign is dropped). If the indicator is positive, it's interpreted as an offset into the list of native icons bundled into the EXE or DLL. For example, Figure F.11 shows the DefaultIcon key using an icon from the shell32.dll that comes with current versions of Windows.

Figure F.11. DefaultIcon Key


Notice the use of the %SystemRoot% variable in the key value. Like %L, this variable is expanded by the shell. Unfortunately, you can't use the DefaultIcon key to pull managed icon resources out of .NET assemblies, because the shell supports only native icon resources. To use a custom document icon, you must either bundle a separate DLL containing a native icon resource or use a tool to bundle the native icon resources into your application's assembly. The .NET command line compilers support bundling native resources, but VS05 does not (except for one special "application icon" that can be set in the project properties for your application).

The easiest way to distribute an icon resource with your application is to embed it into your EXE. Using ntrescopy.exe, which is discussed in Chapter 13: Resources, you can create a C++ DLL project to package your resources. Then, ntrescopy can copy icons from a .dll file you create into the target assembly, which can be either MDIClient.exe or SDIClient.exe. The samples for this chapter illustrate how to do this with the aid of post-build events in both the MDIClient and SDIClient projects. That sample, which you'll find at our web site (http://www.sellsbrothers.com/writing/wfbook), includes support for using the IconResourceIndex property of FileDocument to specify the index of the resource icon you want as the document icon. FileDocument then registers the icon when it registers the Open command.

The update of the DefaultIcon Registry key now forces the document icon to be loaded from the index in your application's assembly, resulting in the icons used in Figure F.12.

Figure F.12. Custom Resource Document Icon (32 x 32) and Application Icon


In addition to seeing their files in the Explorer, users are accustomed to seeing their most recently accessed documents in the Start | Documents menu.

Start | Documents

Ever since Windows 95, opened and saved files go into a systemwide MRU that's managed by the shell and is available from the documents item in the Start menu.[8] To add files to this list, you call the Win32 function SHAddToRecentDocs, which is exposed from shell32.dll. Unfortunately, there's no .NET wrapper for that function, so you have to use a bit of Win32 interop to gain access to it.[9]

[8] Depending on whether you're showing recent documents from the Start menu, and whether you're showing the "classic" Start menu, the documents item is labeled "Documents" or "My Recent Documents" under Windows XP.

[9] Check out Adam Nathan's most excellent site at http://pinvoke.net (http://tinysells.com/7) to look up the P/Invoke signature for this Win32 API and most others. The following shows SHAddToRecentDocs and a sample usage: http://www.pinvoke.net/default.aspx/shell32/SHAddToRecentDocs.html (http://tinysells.com/40).

Luckily, because the FileDocument component is in charge of when files are opened and saved, it can add the files to the documents menu for you. Because our custom extension has been registered with an icon, that icon is displayed in the list, as shown in Figure F.13.

Figure F.13. Custom Document Added to Start | Documents


Further, because we've already provided an Open command for our custom .ror extension in the shell, an instance of our application is loaded whenever a document from the documents menu is selected.




Windows Forms 2.0 Programming
Windows Forms 2.0 Programming (Microsoft .NET Development Series)
ISBN: 0321267966
EAN: 2147483647
Year: 2006
Pages: 216

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net