'''Purpose:''' Demonstrate how to register file types under Windows ---- ''Why register a file type?'' Many Tcl-based systems deal with particular file types. Often, these files are Tcl scripts or other text that can be readily decoded from Tcl. Other times, they are more specialized formats. The Tk dialogs, tk_getOpenFile and tk_getSaveFile give a convenient way for applications to open and save files. Windows users, however, expect more: they generally expect to be able to open a file by double-clicking on it in the Explorer, to paste it as an enclosure to e-mail, or even to create a new file of a given type by using 'File->New->...' in the Explorer menu. They also expect to see appropriate icons for the files in the Explorer. All of these features are controlled by entries in the Windows system registry, so a Tcl program using the 'registry' package can set them up easily. Let's define a Tcl procedure, ''registerFileType'', that does the necessary work. ''What do we need to know?'' 1. We need the file extension (for example, Tcl scripts use ''.tcl'') for the proposed new file type. 1. We need a machine-readable 'class name' for the file extension. 1. We need a human-readable description of the file type (for display when the user selects 'View->Details' in the Explorer. 1. We need to know how to ''open'' the file. For this discussion, let's assume that we open a file by launching a particular Tcl script and passing the file name as its sole parameter: exec wish83.exe someScript.tcl someFile.xyz '''Example:''' Let's define a file type, ''.acd'', that's an 'address card file.' We'll use a class name of ''AddrCard'' and use ''CardFile.tcl'' to open it: registerFileType .acd AddrCard "Address Card File" \ [file join $scriptDir CardFile.tcl] ''What else may we want to specify?'' The above information is the minimal set needed to make the double-click work. In addition to this basic information, the programmer may want to provide: 1. An icon, so that the file displays nicely in the Explorer. 1. A MIME type, so that the file can be enclosed in e-mail. 1. An indication that new instances of this file type can be created from the 'File->New' menu in the Explorer. 1. An indication that the file is plain text 'under the hood.' If the file is plain text, ''registerFileType'' can add information that provides ''Edit'' and ''Print'' menus when the user right-clicks the mouse from the Explorer; the ''Edit'' menu will launch Notepad (or whatever editor the user likes for text files), and the ''Print'' menu will print the text file through 'notepad /P' or whatever other method the user uses. We specify these by using options after the four mandatory parameters to ''registerFileType'': * -icon ''pathName'',''n'' - Use the icon at ordinal position ''n'' within the file identified by ''pathName'', which may be an executable, DLL, ICO, or icon library. * -mimetype ''type'' - Use ''type'' (e.g., ''application/x-addr-card-file'') as the MIME type for the files. * -new ''boolean'' - Control whether or not the file should appear in the Explorer's 'File->New' menu. * -text ''boolean'' - Indicate whether or not the file contains plain text. '''Example:''' Expanding the definition of registering an address card file, we provide an icon file, a MIME type, and turn on the indication that the file is text and that it should appear in the Explorer's 'New' menu: RegisterFileType::RegisterFileType \ .acd \ "AddrCardFile" \ "Address Card File" \ [file join $scriptDir CardFile.tcl] \ -mimetype application/x-cardfile \ -icon [file join $scriptDir cardfile.ico],0 \ -new 1 \ -text 1 Without further ado, here's the source for RegisterFileType: ---- #---------------------------------------------------------------------- # # RegisterFileType::RegisterFileType -- # # Register a file type on Windows # # Author: # Kevin Kenny . # Last revised: 27 Nov 2000, 22:35 UTC # # Parameters: # extension -- Extension (e.g., .tcl) of the new type # being registered. # className -- Class name (e.g., "tclfile") of the new type # textName -- Textual name (e.g. "Tcl Script") of the # new type. # script -- Name of the file containing a Tcl script # to run when a file of the given type is # opened. The script will receive the name # of the file in [lindex $argv 0]. # # Options: # -icon FILENAME,NUMBER # Set the icon for files of the new type # to be the NUMBER'th icon in the given file. # The file must be a full path name. # -mimetype TYPE # Set the MIME type corresponding to the new # file type to the specified string. # -new BOOLEAN # If BOOLEAN is true, set things up so that # the new file type appears in the "New" menu # in the Explorer and the system tray. # -text BOOLEAN # If BOOLEAN is true, the new file type contains # plain ASCII text of some sort. Set the # Edit and Print actions to open and print # ASCII files. # # Results: # None. # # Side effects: # Adds the following keys to the system registry: # # HKEY_CLASSES_ROOT # (Extension) (Default value) ClassName # "Content Type" MimeType [1] # ShellNew "NullFile" "" [2] # (ClassName) (Default value) TextName # DefaultIcon (Default value) IconName,# [3] # Shell # Open # command (Default value) -SEE BELOW- # Edit # command (Default value) -SEE BELOW- [4] # Print # command (Default value) -SEE BELOW- [4] # MIME # Database # Content Type # (MimeType) (Default value) Extension [1] # # [1] These values are added only if the -mimetype option is used. # [2] This value is added only if the -new option is true. # [3] This value is added only if the -icon option is used. # [4] These values are added only if the -text option is true. # # The command to open the file consists of three arguments. # The first is the name of the current Tcl executable. The # second is the script name, and the third is "%1", which causes # the target file to be passed as a command-line argument. # The edit command is the command that opens text files, and the # print command is the command that prints text files. # #---------------------------------------------------------------------- proc RegisterFileType::RegisterFileType { extension className textName script args } { package require registry # extPath is the class path for the file's extension set extPath HKEY_CLASSES_ROOT\\$extension registry set $extPath {} $className sz # classPath is the class path for the file's class set classPath HKEY_CLASSES_ROOT\\$className registry set $classPath {} $textName sz # shellPath is the shell key within classPath set shellPath $classPath\\Shell # Set up the 'Open' action set openCommand {} append openCommand \" \ [file nativename [info nameofexecutable]] \ \" { } \" [file nativename $script] \" { } \"%1\" registry set $shellPath\\open\\command {} $openCommand sz # Process optional args foreach {key val} $args { switch -exact -- $key { -mimetype { # Set up the handler for the MIME content type, # and add the content type item to the database registry set $extPath "Content Type" $val sz set mimeDbPath \ "HKEY_CLASSES_ROOT\\MIME\\Database" append mimeDbPath "\\Content Type\\" $val registry set $mimeDbPath Extension \ $extension sz } -icon { # Add the file icon to the shell database if {![regexp {^(.*),([^,]*)} $val \ junk file icon]} { error "-icon option requires\ fileName,iconNumber" } registry set $classPath\\DefaultIcon {} \ [file nativename $file],$icon sz } -text { if {$val} { # Copy the Print action for text files # into the Print action for the new type set textPath \ HKEY_CLASSES_ROOT\\txtfile\\Shell if {![catch { registry get \ $textPath\\print\\command {} } pCmd]} { registry set \ $shellPath\\print\\command \ {} $pCmd sz registry set \ $shellPath\\print {} \ &Print sz } # Copy the Open action for text files # into the Edit action for the new type. if {![catch { registry get \ $textPath\\open\\command {} } eCmd]} { registry set \ $shellPath\\edit\\command \ {} $eCmd sz registry set \ $shellPath\\edit {} \ &Edit sz } } } -new { if {$val} { # Add the 'NullFile' action to the # shell's New menu registry set $extPath\\ShellNew NullFile \ {} sz } } default { error "unknown option $key, must be -icon,\ -mimetype, -new or -text" } } } } ---- [Nat Pryce] provides an alternative perspective on many of the same issues in his explanation of "Integrating Tcl with the NT Shell" [http://www.doc.ic.ac.uk/~np2/software/tcl-setup.html]. Also, one benefit of the [ActiveTcl] releases is to manage (some--which?) associations. ---- It is also useful to add right mouse button context menus as well as supporting dde. Dde can be used to call an active Tcl application when you launch a file rather than continue to bring up new instances of the TCL application. An example of how to register a context menu handler and dde is shown in [regContextHandler]. TFW