This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
More Windows 2000 UI Goodies: Extending Explorer Views by Customizing Hypertext Template Files |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Dino Esposito | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
he user interface for Windows® 2000 is based on the well-known Active Desktopâ€"a shell update originally introduced with Microsoft® Internet Explorer 4.0 under both Windows 95 and Windows NT® 4.0. (Active Desktop is now called Desktop Update under Windows 2000.) A couple aspects of the Windows 2000 desktop are worth exploring. The Desktop UpdateDesktop Update merges two different paradigms for the user interface. One is the standard Windows desktop, where the system determines the folder layouts and content. The second is an emerging information retrieval paradigmâ€"the Web browser. In the standard desktop, you have an ordered list of directories and files that you can't easily customize. This makes it easier for novice users to work effectively with the system.With a Web-style layout you can fill the right panel of the Explorer window with virtually any sort of information. Better yet, you can use anything that you can embed in a Web page, including ActiveX® controls, Java-language applets, animations, hyperlinks, script code, images and more. Is this useful? Well, I can think of one really good use: a folder customized by an administrator might significantly help novice users work more efficiently, potentially saving a number of help desk calls. On the other hand, folder customization should be the exclusive domain of power-users, administrators, and programmers. Figure 1 shows a completely custom folder view.
I have a personal experience that illustrates this point. A client company wanted me to help develop some Explorer extensions. I stayed about a week, wrote my code, taught my classes, and noticed how some staff members were not particularly skilled with Microsoft Excel and Word documents, although they understood the use of desktop icons and how to and print. For example, switching to a different document template, or even attaching it to an e-mail message, was often a problem. I soon realized that a slight customization of the folder view might have helped. I changed the template of the folders, adding some buttons that called specialized script functions to launch custom Microsoft Excel and Word documents. All of the computers in this group were running Windows 98. With Windows 2000, there are even more opportunities for customization. How it's DoneThe dialog box shown in Figure 2 contains all the controls you need to enable Web-style content in your folders. In particular, the radio buttons in the Web View frame affect the structure of the Explorer's right panel. A classic-style view is based on a simple listview control through which you see all the items contained in that folder. A Web-style view requires a more complicated hierarchy of windows and ends up showing the content through a WebBrowser control and a template HTML page.
Figure 3 illustrates the different sets of windows involved with both views. You can investigate this schema using a tool like Spy++. The blocks in Figure 3 contain the class names of the windows. ExploreWClass is the class name of the main Explorer window. Internet Explorer_Server is WebBrowser's main window. SHELLDLL_DefView acts as a container for any shell folder view that is available.
Today there are only two possible views. One is the Web view, available for both folders and file system directories. The other, available for directories only, is the thumbnails view. Under previous versions of Desktop Updateâ€"those for Windows 9x and Windows NT 4.0â€"both choices were listed on the View menu in Explorer. In Windows 2000, things have been clarified quite a bit. The thumbnails let you render the content of a directory. The Web view is a template-driven way to organize the entire folder, not just the part of it that shows the content. In other words, only the thumbnails view, not the Web view, is an option in the View menu, along with the regular optionsâ€"large and small icons, list, and details.
In principle, it seems possible to write custom views for the folder content to be made available from the View menu in Explorer (see Figure 4). In practice, this is undocumented so you should resort to a namespace extension if you need to create a virtual folder with custom content. For more information on this topic, see the article "Implementing a Web View Namespace Extension Using Active Directory Services" in the August 1998 issue of Microsoft Systems Journal. Working in Web View ModeWhen Explorer works in the Web view mode, each selected folder is displayed through a COM component called Shell DefView. (If you want to know more about its internals, look at it with the OLEView tool at https://www.microsoft.com/com/resources/oleview.asp.) Shell DefView is an ActiveX control that uses a listview to show all the files contained in a given folder. As I explained in my March 2000 article, the Windows 2000 shell allows you to change the standard set of columns this listview presents.A classic-style view simply forces the control to occupy the entire right pane in Explorer. The listview is created as a child of the control's main window, and the control acts as a message router between the Explorer framework and the hosted listview. The listview programming interface is replicated by the standard folder and desktop view. Thus it's hard to say whether the four listview states (large and small icons, list, and details) or the shell's different views came first. As a matter of fact, all changes in the overall user interface of the listviews (item underlining, hot-tracking, full row selection, and background bitmap) have been extended to folders and the desktop. Or was it the other way around? Confirming once more that the listview control plays a central role in the Explorer infrastructure, Spy++ reveals that the listview control is used to implement the thumbnails view and to arrange the icons on your desktop.
The key differences between a classic and a Web-style view are shown in Figure 5. You can see the structure of the right pane in Explorer in Web mode. The file list control is now just one of the elements that form the folder view. The right pane is fully occupied by a WebBrowser control. This fact has two important consequences. First, you can preview in the right pane any document that you can view in Internet Explorerâ€"including Microsoft Excel, Word, and PowerPoint® documents, and HTML pages.
You create a custom template through the folder customization wizard available from the folder's context menu (see Figure 6). Once you've worked through the wizard, the HTML template is stored in a hidden child subdirectory called Folder Settings. A desktop.ini file maintains the link to it like so:
The HTML template page, also known as a hypertext template (HTT), is the HTML page that the shell displays through the embedded WebBrowser control. The page is expected to include the ActiveX control showing the folder content. However, the HTT can have any content and can exploit any available object model to process its data. Any Dynamic HTML (DHTML) page can be used as a folder template. In doing so, you put an entire DHTML application into a folder in Windows. It's just like a namespace extension, but slightly less powerful. It's also much easier and quicker to write than a namespace extension. The Role of Hypertext TemplatesAn HTT file is not very different from an HTML page except for one small addition: an HTT may include some environment variables that you cannot access from a regular HTML file. Figure 7 describes all of these variables. They store information about the current folder (both path and folder name) and the system directory where all the system-provided HTT files can be found. Normally, HTTs are stored in the Web subdirectory of your Windows folder. Here you should find HTTs and all the helper files, like GIFs, JPGs, scripts, and so on. By default, all these files are hidden unless you turn on the "Show hidden files and folders" flag in the Folder Options dialog box.When the Web view mode is active and you attempt to open or explore a folder, Explorer attempts to locate a desktop.ini file via the specified path. If the file is found and the directory has the read-only attribute set, then the file content is read and processed. If desktop.ini has an entry called PersistMoniker as shown earlier, the specified HTT file is used as the template. If there's no HTT file in the current folder, then the system HTT for that type of folder is loaded and used. When the shell loads an HTT file, it does some extra work to initialize the environment and assign a consistent value to all the system variables. Figure 8 lists the primary HTT files found in Windows 2000. Notice that templates can also be used for floppy disks or shared folders. An HTT serves two main purposes. First, it allows you to insert facilities specific to the types of files the folder primarily contains. For example, My Pictures is a directory expected to contain mostly images (see Figure 9). The template adds a toolbar with image-specific functions such as zoom, print, preview, and size adjustments. The same pattern could be applied to folders and documents. HTTs are also quite useful for improving the overall Explorer user interface by adding facilities for things such as file selection and quick folder creation.
Through HTTs, namespace extensionsâ€"shell folders with custom contentâ€"can have Web views. A namespace extension that wants to expose a Web view must implement some extra interfaces, particularly IShellView2 and IPersistFolder2. Figure 10 shows how the special folders in Windows 2000 store information about their Web templates. In particular, the registry settings shown are taken from the My Network Places configuration. The registration schema, though, is always the same. Under the node of the extension's CLSID, create the following subtree
and set the PersistMoniker key to the HTT file you want to use. Changing Templates on the FlySo far I've promoted the idea that an HTT is a fixed attribute of a folder or category of folders. The template for a folder is identified by name, and any file with that name located in the correct directory can be used. But is there a way to write ASP-like HTTs? In other words, can you bind the choice of the folder template to runtime conditions, such as the name of the user who is currently logged in or the access privileges that are assigned to the user and stored in a particular database?Right now you simply cannot use an ASP page in place of an HTT. If you specify the template through an HTTP URL, nothing happens and the folder appears with the classic look. However, this doesn't mean there's no way to choose a template based on runtime conditions. One approach that comes to mind relies heavily on DHTML. You could use DHTML methods to populate the page with text that best suits the given runtime conditions. The code of the page may look like this:
The initialization function checks the global status and generates the proper code. This code might be embedded in the HTT itself, or it might come from an external file. An Improved Explorer ShellLet's concentrate now on the source code of the HTT template normally used for all file folders that haven't been customized yet through the folder customization wizard. This file is called folder.htt, as the PersistMoniker value of the following registry key confirms:
Folder.htt is a hidden file that can be found in the Web subdirectory of the Windows folder. The source code can be found in Figure 11.
Instead of using the standard gray buttons you usually find in HTML forms, I decided to utilize the HTML 4.0 and Internet Explorer-specific button tag.
The final effect, however, is the same. The buttons in Figure 1 are white and have a nonstandard appearance because they were modified by applying a Cascading Style Sheet (CSS) style like so:
If you apply the same CSS style to an <input> tag, you obtain exactly the same result. The template uses DHTML absolute positioning tables to place the various elements.
In Figure 12 you can see the layout of the folder.htt template. Basically, it is created by a sequence of <div> tags with an overlapped ActiveX controlâ€"the Shell DefView controlâ€"placed 200 pixels from the left border. The distance of the file list control from the browser bar with the treeview is therefore permanently fixed, and doesn't change if you change the Explorer window size.
A repeated separator would also graphically separate this new <div> from the rest of the page.
Creating a New FolderSo much for the presentation. Now let's focus on the code necessary to create a new folder. Open the command prompt and select all the files that match a pattern. The input box placed over the buttons is used to accept the text that the clicked button will interpret. For example, the text in the input box may be the name of the new folder, the command to execute (such as dir *.*), or the pattern for the files to select in the view (such as *.gif).Creating a new folder is as easy as calling a Win32® API function such as CreateDirectory or SHCreateDirectoryEx, which is more powerful and specific to Windows 2000. However, this is not something that can be accomplished from within a piece of script code. To work around this, I wrote an ATL COM Automation object tailored to the needs of the modified template. The progID is ShellUtils.Exec, and its dispatch table counts the following methods: NewFolderHere, DosFromHere, and ExecCommand. Since this object should be used from within an HTML page, I marked it safe for scripting. In ATL, this means you derive the class from the following:
To make the IObjectSafety interface externally available, you use this code:
The New button associates the JScript® NewFolder function with an onclick event. The function reads in the value of the textbox and calls NewFolderHere, passing the name of the current folder and the new subdirectory.
Since the ShellUtils.Exec object has been declared safe for scripting, you won't see any warning.
should assign the current path to the variable curPath. It works, but not in JScript. Suppose for a moment that the path evaluates to c:\winnt\web. In JScript, it ends up being:
As you should know, this is not valid because JScript, like C and C++, assigns a special meaning to the slash character. The same assignment should be rewritten with double slashes:
Unfortunately, this is not something you can ask the template preprocessor to do. The simplest solution is wrapping the variable assignment in a block of VBScript code:
Now you can use curPath as a global variable. If the input box is empty, the new folder takes the standard name New Folder.
At this point Explorer refreshes its user interface and displays the newly created subfolder. Notice that the call to SHChangeNotify is not strictly necessary to cause Explorer to refresh, but may help get the user feedback a little faster. A call to SHChangeNotify isn't mandatory since Explorer automatically installs a file notification object (FNO) in the folder that is currently opened. The FNO is a kernel object that gets signaled when any file system change occurs in the monitored subtree. An FNO tells you nothing about the particular change, just that something did occur. Thus, Explorer waits for an FNO notification, then refreshes its user interface. A direct call to SHChangeNotify may speed up this process. An Embedded Command ConsoleTo open the command prompt from the current folder, you might use the following code:
Under Windows 2000, the command prompt is cmd.exe or the value returned by the ComSpec environment variable. The working directory argument of CreateProcess causes the prompt to open where specified. The ShellUtils object runs this code through the DosFromHere method.
The buf variable contains all the text captured from the command execution. The problem is how to display the text in a consistent and effective way. You can create a hidden <div> below the FileList control and toggle its display state when there's a string to show. The <div> can occupy half the space of the FileList control, as shown in Figure 14. Using DHTML helps considerably in the implementation of this solution because its object model allows you to dynamically resize the FileList control and toggle the result panel's visibility.
To obtain the most flexibility, I chose to employ a DHTML scriptlet to render the output of the command. However, a simpler <div> or <span> tag would have worked just as well.
The scriptlet is implemented by textview.htm, a Web component with just one property: Text. The little pin icon simulates the button that closes the view. The MS-DOS command runs synchronously since WaitForSingleObject is used (see Figure 13). The code that resizes the FileList component, leaving space for the command prompt panel, looks like this:
The panel requires absolute positioning 200 pixels to the left and occupies the lower half of the frame.
While you can force a scriptlet to take all the available width (100 percent), there's no way to make it fully resizable for both width and height. Try assigning 100% to both width and height and you'll see that the latter will be ignored. In this scenario, dynamic properties, a little known feature of Internet Explorer 5.0 (the browser in Windows 2000) turns out to be quite useful.
mandates that the height of the element must always be half the height in pixels of the FileList control. Internet Explorer 5.0 ensures this and guarantees that, whatever the size of the Explorer window, the command prompt panel and the FileList control will share the vertical room if both are visible. The text that the command prompt panel displays is selectable and could be copied to the clipboard. This is another reason for using a scriptlet (namely an overlapping page) instead of a simpler <div>â€"the browser prevents you from selecting anything in the template page. A scriptlet, though, is entirely in a separate page. Selecting Matching FilesSuppose you need to copy all the files with a certain extension or that match a given pattern. Explorer doesn't provide any facility for thisâ€"usually you have to select the files one at a time or sort them and select manually.Windows 2000 provides a rich shell object model that, when invoked from the HTT template, allows you to access any single item in the current folder. Shell.Application has been available since the inception of the Active Desktop. If you never bothered to install the Active Desktop you'll probably be surprised by what Shell.Application allows you to do. Once you've created an instance of the root object, you can connect to any folder using the NameSpace method. The Visual Basic code necessary to access the Windows NT folder is:
This C++ code shows how to connect to the desktop folder:
The Folder object represents a folder or a directory. The FolderItem object renders an element of a folder. You can access the items within a folder through the Items collection.
As you can see, its logic is not really complex. The script walks through all the items stored in the current folder
and makes sure no items are selected. Then it selects all of the items that match the specified pattern. To verify the match, I'm using a VBScript function that emulates the behavior of the Visual Basic for Applications Like operator. You can find the source code for that in the helpers.vbs file in this month's source archive.
Figure 15 demonstrates the behavior of the Select button when it's called to select all the HTML files whose names begin with t. Notice that the Desktop Update template used for the Windows system folders (usually c:\winnt and c:\winnt\system32) is not folder.htt, so this functionality doesn't apply to those folders.
Windows 2000 extends the shell object model by defining the new IShellDispatch2 interface. This interface exposes additional methods that basically allow you to start, stop, and control system services. You usually do this through the Control Panel and the MMC application services.msc. Furthermore, with Windows Management Instrumentation (WMI) you can enumerate all the services available and create a new My Services folder, as shown in Figure 16. The HTT for that folder (included in this month's source archive) utilizes the ShellUtils.ExecCommand method to run a JScript batch operation that outputs on stdout all the services information retrieved through WMI.
Wscript.StdOut is a new feature of Windows Script Host (WSH) 2.0 that ships with Windows 2000. Notice that StdOut returns a valid text stream object only if you run the script through cscript.exe, the console engine for WSH. Here's the code that the HTT template employs to run the script and capture the console output for presentation:
The FormatData function simply creates an HTML table to present the data in an orderly fashion. Document Image ExtractorsA very handy feature that has been around since the introduction of the Active Desktop is the thumbnail viewer. It is an ActiveX control embedded in the standard HTT template that the shell utilizes to display a preview of a document when it is selected in the file list. You can use a control like this (ThumbCtl class) from within C++ applications to display GIF and JPEG images as well as to preview Microsoft Office documents. The control has a method called displayFile that does the whole job. It only takes the BSTR name of the file you want to display as an argument.
Windows 2000 uses this mechanism to let you preview a number of different file types, including BMP, GIF, JPEG, PNG, DOC, PPT, XLS, WMF, HTML, and even e-mail messages (*.eml). Notice that Office documents can be previewed only if they've been saved with an embedded preview picture. (There's a specific checkbox in the Properties dialog that enables this.)
The default value for the key is a CLSID pointing to the shell extension that actually provides the preview. This registration schema is similar to the one used by the infotip shell extensions I described in the March 2000 issue. The CLSID under the Shellex key is the GUID of an interface called IExtractImage, which turns out to be the key interface for implementing image extractors that extend the thumbnail viewer. Windows 2000 comes with a number of image extractors and you can add your own to the list.
The arguments pszPathBuffer and cchMax might be used to tell Explorer the path of the document so that it could be stored for later use. This is how you enable caching. The priority is normally used to indicate the amount of time needed to extract the image. The argument of type SIZE defines the space available for the image to display. Your extension will be responsible for providing bitmaps that fit into this area. The suggested color depth for the bitmap is passed via dwRecClrDepth.
The method returns NOERROR or an OLE-defined error code. It is responsible for retrieving the HBITMAP from the selected file. The shell extension receives the name of the selected file through the Load method of the IPersistFile interface. The name is typically stored in a member variable of the coclass implementing the shell extension. The shell will release the bitmap handle when it's no longer needed.
If you ask the shell to cache images, your extension won't be called when the user selects the same document again. In particular, the shell won't be capable of detecting any change in the file you may have entered in the meantime. To work around this limitation, a new and improved interface has been added with the introduction of Windows 2000: IExtractImage2. This interface defines one more function called GetDateStamp.
This function is supposed to return the timestamp when the image was last modified. Explorer compares this timestamp to the one it already holds and reloads the image when needed. ConclusionHTT templates allow you to customize both the appearance and the content of a folder. Writing an HTT template is surprisingly simple as compared to namespace extensions, which are more powerful and capable of a tighter integration with Explorer, but far more complex to understand and write.An HTT template is really a simple type of namespace extension. At the same time it's a way to improve the behavior and features of Explorer itself. By modifying the standard templates, you can add new facilities to the Windows 2000 shell user interface. In this article I showed you some new interfaces like IExtractImage and IExtractImage2, and demonstrated how to extend the system thumbnail viewer to work with your documents. Other shell interfaces you might want to look at are IDropTargetHelper and IDropSourceHelper. They allow you to provide more meaningful feedback when the user drags a shell object. These interfaces have been covered in MSDN Online (see https://msdn.microsoft.com/library/techart/ddhelp_pt2.htm). |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
For related articles see: https://msdn.microsoft.com/library/techart/ddhelp_pt1.htm https://msdn.microsoft.com/library/techart/ddhelp_pt2.htm https://msdn.microsoft.com/msdnmag/issues/0300/w2kui/w2kui.asp https://msdn.microsoft.com/library/techart/shellinstobj.htm Background information: https://msdn.microsoft.com/library/psdk/shellcc/Shell/shell_intro.htm https://msdn.microsoft.com/scripting/jscript/default.htm Dino Esposito is a senior trainer and consultant based in Rome. He has recently written Windows Script Host Programmer's Reference (WROX, 1999). You can reach Dino at desposito@vb2themax.com. |
From the June 2000 issue of MSDN Magazine.