Web View

Objectives

The objectives of this chapter are to:

·       Introduce  the Web View feature in the integrated Windows Shell

·       Examine how it works behind the scene

·       Describe the FileList and Thumbnail Viewer Controls

·       Describe the format of Folder.htt

·       Explain how to customise Web View without programming

·       Provide examples of adding programmatic features to Web View

Introduction

Windows Explorer contains two panes – the left pane contains a tree control displays the hierachy of the shell namespace and the right pane contains a detailed view of shell namespace node which has been selected in the treeview. The “classic” Windows 95 Explorer provides this detailed view in the form of a listview control, which may be configured to display data in large icon, small icon, list and report (detail) modes. WebView is an additional view first supported with IE4. WebView enables users to view folder contents as web pages, using the same four modes as with listview - large icon, small icon, list and report (detail). Anything you can do in a webpage you can do inside Explorer. The classic Explorer provided a listview control which completely filled the view pane of Explorer. Apart from deciding which of the large icon, small icon, list or details modes to use, there was no way of configuring this, unless you wrote your own namespace extension. Now with Web View you can cutomise how the view pane is filled in, and optionally add your own programmatic elements.

Getting Started

WebView is only available when you have IE5 or IE4 installed, either when it comes with the OS (IE5 with Windows 2000, IE4 with Windows 98) or when you install it manually. You must also have the Active Desktop component installed – right click the mouse while the cursor is somewhere on the desktop, and if  “Active Desktop” appears in the context menu, then you have it installed. If it is not there, go to the Control Panel, click on “Add/Remove Programs”, select “Internet Explorer” and in the dialog which appears select “Install Active Desktop”. This will connect to the Microsoft web site, and present you with a list of additional components which you may install – select “Active Desktop Update” from the list, and install it.

How does WebView work?

Web View is just another way of viewing the contents of a folder – and you must select WebView as the way which you wish to view the folder from theView drop-down menu.

A file called folder.htt is used to configure the display of the folder contents. A system-wide version of this file is located under C:\Windows\Web\folder.htt or C:\Winnt\Web\folder.htt and it may also be placed in individual folders. When Explorer is browsing a particular folder, it first looks if a local folder.htt file is available, and if not it uses the system-wide one. The folder.htt file is a text file with HTML markup, and may be edited using a text editor (e.g. Notepad) or a full HTML editor. When you are viewing a particular folder and right click to bring up the context menu, and select “Customize this Folder...”, if a local folder.htt file is available it is displayed in an editor, and if not available then the system-wide file folder.htt is copied into the  current folder, and then it is displayed in an editor. You may also customise the system-wide folder.htt.

The default folder.htt displays the folder title as large font HTML string, some details on the selection (file size, last edit date etc.), and then uses two ActiveX controls – the FileList Control and the Thumbnail Viewer Control – to display the contents of the folder, and a thumbnail image of the selected folder item.

You may also configure you rdesktop to behave as a web page. This means that the “classic” Windows 95 desktop (which is actually a listview control in large icon mode[1])  is replaced with a web page, and this too may then be configured.

Sources of Information

There is very little published covering Web View.

Check out:

·       The “Content Delivery Mechanisms” article in the SiteBuilder Network (formerly part of Internet Client SDK)

·       Microsoft Knowledge Base: Q181689

·       C:\Windows\Web\folder.htt or C:\Winnt\Web\folder.htt

Detailed Description of Folder.htt

Folder.htt is at the root of web view functionality and you will need to understand it completely in order to correctly customise it. “htt” stands for hypertext template file – it is in fact html. Folder.htt is a long file but the indivudal sections within are reasonably easy to understand.

It starts off with a <HTML> tag and finishes with a </HTML> tag. The three top-level blocks are <STYLE></STYLE>, <HEAD></HEAD> and <BODY></BODY>.

Style Block

The STYLE block specifies widths and colours for various objects:

<style>

body        {font: 8pt/10pt verdana; margin: 0}

#Banner           {position: absolute; width: 100%; height: 88px;

background: URL(res://webvw.dll/folder.gif) no-repeat top left}

#MiniBanner {position: absolute; width: 100%; height: 32px;

                background: window}

#Icon       {position: absolute; left: 11px; top: 12px; width: 64px;

                height: 64px}

#FileList   {position: absolute; left: 30%; top: 88px; width: 1px;

                height: 1px}

#Media      {margin-left: 20px; margin-top: 10px}

#Panel      {position: absolute; top: 88px; width: 30%;

                background: window; overflow: auto}

#PieChart   {width: 100px; height: 50px; margin-top: 10px}

#Thumbnail  {width: 160px; height: 160px; margin-top: 0px}

#Status     {margin-left: 20px}

p           {margin-left: 20px; margin-right: 8px}

p.Title     {font: 16pt/16pt verdana; font-weight: bold;

                  color: #0099FF}

p.Warning   {font-weight: bold; color: red}

p.Links     {margin-top: 4px}

a:link      {color: #FF6633}

a:visited   {color: #0099FF}

a:active    {color: black}

</style>

HEAD block

The head block contains definitions of variables (principally strings) and a number of javascript functions.

<head>

<!--allow references to any resources you might add to the folder -->

<!--(a "webbot" is a special wrapper for FrontPage compatibility) -->

<!-- webbot bot="HTMLMarkup" tag="base" startspan -->

<base href="%THISDIRPATH%\">

<!-- webbot bot="HTMLMarkup" endspan -->

<script language="JavaScript">

      var L_Intro_Text  = "Select an icon to view its description.";

      var L_Multiple_Text     = " objects selected.";

      var L_Size_Text         = "Size: ";

      var L_FileSize_Text     = "Total File Size: ";

      var L_Delimiter_Text    = ",";

      var L_Bytes_Text        = "&nbsp;bytes";

      var L_Attributes_Text   = "Attributes";

      var L_Codes_Text        = "RHSACE";

      var L_ReadOnly_Text     = "Read-only";

      var L_Hidden_Text       = "Hidden";

      var L_System_Text       = "System";

      var L_Archive_Text      = "Archive";

      var L_Compressed_Text   = "Compressed";

      var L_Encrypted_Text    = "Encrypted";

      var L_NoAttributes_Text = "(none set)";

      var timer               = 0;

      var wantMedia           = false; // cool, but may hinder

                                          media file manipulation

FixSize Function

The FixSize function is used to determine the sizes of elements when teh window size changes.

function FixSize() {

            // this function handles fixed panel sizing and

            // collapsing when the window resizes

            var hideTop = 200;

            var hideLeft      = 400;

            var miniHeight    = 32;

            var ch            = document.body.clientHeight;

            var cw            = document.body.clientWidth;

            if (hideTop > ch) {

            document.all.Banner.style.visibility = "hidden";

                  document.all.MiniBanner.style.visibility="visible";

                  document.all.FileList.style.top = miniHeight;

                  document.all.Panel.style.top = miniHeight;

            } else {

                document.all.Banner.style.visibility = "visible";

                document.all.MiniBanner.style.visibility = "hidden";

                document.all.FileList.style.top =

(document.all.Banner.offsetHeight - 32) + "px";

                  document.all.Panel.style.top =

(document.all.Banner.offsetHeight) + "px";

                  document.all.Rule.style.width =

 (cw > 84 ? cw - 84 : 0) + "px";     

            }

            if (hideLeft > cw) {

                  document.all.Panel.style.visibility = "hidden";

                  document.all.FileList.style.pixelLeft = 0;

                  document.all.FileList.style.pixelTop =

document.all.Panel.style.pixelTop;

            } else {

                  document.all.Panel.style.visibility = "visible";

                  document.all.FileList.style.pixelLeft =

document.all.Panel.style.pixelWidth;

            }

            document.all.FileList.style.pixelWidth =

cw - document.all.FileList.style.pixelLeft;

            document.all.FileList.style.pixelHeight =

ch - document.all.FileList.style.pixelTop;

            document.all.Panel.style.pixelHeight =

ch - document.all.Panel.style.pixelTop;

      }

FormatNumber Utility Function

FormatNumber converts integers into strings. A delimiter character (set to ‘,’ above), is positioned between each three digits – to separate out thousands in the number.

      function FormatNumber(n) {

            var t = "";

            var i, j = 0;

            for (i = n.length - 1; i >= 0; i--) {

                  t = n.charAt(i) + t;

                  if (i && ((++j % 3) == 0))

                        t = L_Delimiter_Text + t;

            }

            return t;

      }

Init Function

The Init function calls FixSize and initialises the innerHtml text.

      function Init() {

      // call our FixSize() function whenever the window gets resized

            window.onresize = FixSize;

            FixSize();

            Info.innerHTML = L_Intro_Text;

      }

      </script>

SelectionChanged Event for FileList Control

The SelectionChanged event handler for the FileList control is the most important (and longest!)  function in folder.htt. It is called whenever the file selection is changed in the file list, and it populate various parts of the web view with information regarding the selected item.

It first determines if one or more items have been selected. If multiple items have been selected it prints the combined size of the items and returns.  If a single item has been selected it prints various attributes of the item – size, type, name, date of last change and other details.  Finally it generates a thumbnail for the selected item. If the item is a multimedia or sound file, it is played – otherwise the thumbnail viewer control is told to generate the thumbnail.

      <script language="JavaScript" for="FileList"

event="SelectionChanged">

      //this script updates the left info Panel when you select icons

      var items   = FileList.FocusedItem;

      var fldr    = FileList.Folder;

      var name;

      var data;

      var text;

      var title;

      var size = 0;

      var i;

      // cancel any pending status message

      if (timer) {

            window.clearTimeout(timer);

            timer = 0;

      }

      // erase any visible thumbnail since the selection changed

      document.all.Thumbnail.style.display = "none";

      document.all.Status.style.display = "none";

      // stop & destroy any media player

      if (wantMedia)

            document.all.Media.innerHTML = "";

      data = FileList.SelectedItems().Count;

      if (data == 0) {

            // nothing selected?

            Info.innerHTML = L_Intro_Text;

            return;

      }

      else if (data > 1) {

            // more than one item selected?

            text = data + L_Multiple_Text + "<br>";

            if (data <= 100) {

                  for (i = 0; i < data; i++)

                    size +=

          FileList.SelectedItems().Item(i).Size;

                  if (size)

                  text += "<br>" + L_FileSize_Text +

 FormatNumber(size.toString())+L_Bytes_Text+"<br>";

                  if (data <= 16)

                        for (i = 0; i < data; i++)

                              text += "<br>" +

FileList.SelectedItems().Item(i).Name;

                  }

                  Info.innerHTML = text;

                  return;

            }

            // name

            name = fldr.GetDetailsOf(items, 0);

            text = "<b>" + name + "</b>";

            // type

            data = fldr.GetDetailsOf(items, 2);

            if (data)

                  text += "<br>" + data;

            // date

            data = fldr.GetDetailsOf(items, 3);

            if (data)

            text+="<br><br>"+fldr.GetDetailsOf(null, 3)+":<br>"+data;

            // size?

            size = FileList.SelectedItems().Item(0).Size;

            if (size)

               if (size < 1000)

                  text += "<br><br>" + L_Size_Text+size+L_Bytes_Text;

               else {

                  data = fldr.GetDetailsOf(items, 1);

                  if (data)

                        text += "<br><br>" +

fldr.GetDetailsOf(null, 1) + ": " + data;

                  else

                        text += "<br><br>" + L_Size_Text +

  FormatNumber(size.toString())+L_Bytes_Text;

            }

            // extra details?

            for (i = 4; i < 10; i++) {

                  title = fldr.GetDetailsOf(null, i);

                  if (!title)

                        break;

                  data = fldr.GetDetailsOf(items, i);

                  if (title == L_Attributes_Text) {

                        var code;

                        var s = "";

                        text += "<br><br>" + title + ": ";

                        for (i = 0; i < 6; i++) {

                              code = L_Codes_Text.charAt(i);

                              if (data.indexOf(code) > -1) {

                                    if (s)

                                          s += ", ";

                                    if (i == 0)

                                          s += L_ReadOnly_Text;

                                    else if (i == 1)

                                          s += L_Hidden_Text;

                                    else if (i == 2)

                                          s += L_System_Text;

                                    else if (i == 3)

                                          s += L_Archive_Text;

                                    else if (i == 4)

                                          s += L_Compressed_Text;

                                    else if (i == 5)

                                          s += L_Encrypted_Text;

                              }

                        }

                        if (!s)

                              s = L_NoAttributes_Text;

                        text += s;

                  }

                  else if (data)

                        text += "<br><br>" + title + ":<br>" + data;

            }

            // tip?

            data = fldr.GetDetailsOf(items, -1);

            if (data && data != name) {

                  var start;

                  var end;

                  var theLink;

                  var a;

                  // parse lines for Office files without breaking

// links below

                  a = data.split("\n");

                  data = a.join("<br>\n");

                  // look for embedded links

                  text += "<br><br>";

                  start = data.indexOf("http://");

                  if (start < 0)

                        start = data.indexOf("file://");

                  if (start < 0)

                        text += data;

                  else {

                        end = data.indexOf(" ", start);

                        if (end < 0)

                              end = data.length;

                        if (start > 0)

                              text += data.substring(0, start - 1);

                        theLink = data.substring(start, end);

                        text += theLink.link(theLink);

                        if (end < data.length)

                           text += data.substring(end+1,data.length);

                  }

            }

            // replace Info with the new text

            Info.innerHTML = text;

            if (wantMedia) {

            // show media preview or thumbnail based on fileextension

            var ext = name.substring(name.lastIndexOf(".") + 1,

 name.length);

            ext = ext.toLowerCase();           

            if (ext == 'avi' || ext == 'mov' || ext == 'mpe' ||

ext == 'mpeg' || ext == 'mpg') {

                  // show a movie player

                  document.all.Media.innerHTML = '<object id="Player"

style="width: 160px; height: 148px" classid=clsid:05589FA1-C356-11CE-BF01-00AA0055595A>

<param name="FileName" value="' + items.Path + '"><param name=ShowDisplay value=0><param name=BorderStyle value=0></object>'

                              return;

            }

else if (ext == 'aif' || ext == 'aifc' ||

ext == 'aiff' || ext == 'au' ||

ext == 'mid' || ext == 'rmi' ||

ext == 'snd' || ext == 'wav') {

                              // show a sound player

document.all.Media.innerHTML = '<object id="Player"

style="width: 160px; height: 28px"

classid=clsid:05589FA1-C356-11CE-BF01-00AA0055595A>

<param name="FileName" value="' + items.Path+'">

<param name=ShowDisplay value=0></object>'

                  return;

            }

      }

      // try to generate a new thumbnail asynchronously, and delay

// the status message one second

      if (Thumbnail.displayFile(items.Path))

      timer = window.setTimeout('document.all.Status.style.display

 = ""', 1000);

</script>

OnThumbnailReady Event for Thumbnail Viewer Control

The OnThumbnailReady event handler is called when the thumbnail is ready for display.

<script language="JavaScript" for="Thumbnail"

event="OnThumbnailReady">

// when a valid thumbnail has been generated, display it

window.clearTimeout(timer);

timer = 0;

document.all.Status.style.display = "none";

if (document.all.Thumbnail.haveThumbnail() &&

document.all.Media.innerHTML == "")

      document.all.Thumbnail.style.display = "";

</script>

</head>

Body Block

The BODY block contains the layout information – a table which has nowrap turned on – the title area is set to teh folder name – and a left panel contrains informaiton on teh selected item and the thumbnail view, and a right panel contains the filelist control. There are also some commented out links – which you may replace with links to your own internet/intranet.

<body scroll=no onload="Init()">

<!-- start normal banner -->

<div id="Banner" style="visibility: hidden">

<!-- using a table with nowrap to prevent word wrapping -->

<table><tr><td nowrap>

<p class=Title style="margin-left: 104px; margin-top: 16px">

<!--webbot bot="HTMLMarkup" startspan alt="&lt;B&gt;&lt;I&gt;

Web View Folder Title&lt;/I&gt;&lt;/B&gt;&nbsp;" -->

%THISDIRNAME%

<!--webbot bot="HTMLMarkup" endspan -->

</td></tr></table>

<!-- this is more efficient than a long graphic, but we have to

adjust it in FixSize() -->

<hr id="Rule" size=1px color=black style="position: absolute;

top: 44px; left: 84px">

<!-- this is our awesome icon extractor -->

<object id=Icon classid="clsid:E5DF9D10-3B52-11D1-83E8-00A0C90DC849">

<param name="scale" value=200>

</object>

</div>

<!-- end normal banner -->

<!-- start mini banner -->

<div id="MiniBanner" style="visibility: hidden">

<!-- using a table with nowrap to prevent word wrapping -->

<table><tr><td nowrap>

<p class=Title style="margin-left: 16px; margin-top: 4px">

<!--webbot bot="HTMLMarkup" startspan alt="&lt;B&gt;&lt;I&gt;

Web View Folder Title&lt;/I&gt;&lt;/B&gt;&nbsp;" -->

%THISDIRNAME%

<!--webbot bot="HTMLMarkup" endspan -->

</td></tr></table>

</div>

<!-- end mini banner -->

<!-- start left info panel -->

<div id="Panel">

<p style="margin-top: 16px");

<span id="Info">

</span>

<!-- HERE'S A GOOD PLACE TO ADD A FEW LINKS OF YOUR OWN -->

<!-- (examples commented out)

<p>

<a href="http://www.mylink1.com/">Custom Link 1</a>

<p class=Links>

<a href="http://www.mylink2.com/">Custom Link 2</a>

-->

<p>

<!-- this is the thumbnail viewer control -->

<object id=Thumbnail classid=

 "clsid:1D2B4F40-1F10-11D1-9E88-00C04FDCAB92" style="display: none">

</object>

<!-- this is the status message that pops up during thumbnail generation -->

<div id="Status" style="display: none">

Generating thumbnail...

</div>

<!- this contains the ActiveMovie control for later instantiation ->

<div id="Media">

</div>

</div>

<!-- end left info panel -->

<!-- this is the standard file list control -->

<!-- webbot bot="HTMLMarkup" startspan u-src="

file:///C:\Program Files\Microsoft FrontPage Express\Data\FoldData.gif"-->

<object id="FileList" border=0 tabindex=1 classid=

"clsid:1820FED0-473E-11D0-A96C-00C04FD705A2"

</object>

<!-- webbot bot="HTMLMarkup" endspan -->

</body>

Now we have complete our examination of folder.htt – to start seriously configuring web view it is necessary to understand this file – though it is long it is not very complex.

Detailed Description of Desktop.ini

When you choose to customise web view for a particular folder, in addition to folder.htt a file called desktop.ini is also copied into the local folder. This is a much shorter file, and contains settings which inform the shell from which file to extract the web settings (folder.htt in our case).

[ExtShellFolderViews]

Default={5984FFE0-28D4-11CF-AE66-08002B2E1262}

{5984FFE0-28D4-11CF-AE66-08002B2E1262}

={5984FFE0-28D4-11CF-AE66-08002B2E1262}

[{5984FFE0-28D4-11CF-AE66-08002B2E1262}]

PersistMoniker=file://Folder.htt

[.ShellClassInfo]

ConfirmFileOp=0

FileList Control

The FileList ActiveX Control is located in shdocvw.dll which resides in the Windows System directory.

Its CLSID is:

CLSID = 1820FED0-473E-11D0-A96C-00C04FD705A2

It has no ProgID registered.

This control displays the contents of a folder in ActiveX control.

IDL for FileList Control

The interfaces exposed by the FileList control are not official documented by Microsoft – but we can extract the interface definition using the COM Viewer tool.

It shows that FileList is defined as a coclass with two interfaces – IShellFolderViewDual and DShellFolderViewEvents.

[

     odl,

     uuid(E7A1AF80-4D96-11CF-960C-0080C7F4EE85),

     helpstring("definition of interface IShellFolderViewDual"),

     hidden,

     dual,

     oleautomation

]

interface IShellFolderViewDual : IDispatch {

[id(0x60020000), propget, helpstring("Get Application object")]

     HRESULT _stdcall Application([out, retval] IDispatch** ppid);

[id(0x60020001), propget, helpstring("Get Parent object")]

     HRESULT _stdcall Parent([out, retval] IDispatch** ppid);

[id(0x60020002),propget, helpstring("Get the folder being viewed")]

     HRESULT _stdcall Folder([out, retval] Folder** ppid);

[id(0x60020003), helpstring("The collection of Selected Items in folder")]

    HRESULT _stdcall SelectedItems([out,retval]FolderItems** ppid);

[id(0x60020004), propget, helpstring("The currently focused item in the folder")]

    HRESULT _stdcall FocusedItem([out, retval] FolderItem** ppid);

[id(0x60020005), helpstring("Select the item")]

    HRESULT _stdcall SelectItem(

                  [in] VARIANT* pvfi,

                  [in] int dwFlags);

[id(0x60020006), helpstring("Show items menu and return command selected")]

    HRESULT _stdcall PopupItemMenu(

                  [in] FolderItem* pfi,

                  [in, optional] VARIANT vx,

                  [in, optional] VARIANT vy,

                  [out, retval] BSTR* pbs);

[id(0x60020007), propget, helpstring("Returns the scripting automation model.")]

       HRESULT _stdcall Script([out, retval] IDispatch** ppDisp);

[id(0x60020008), propget, helpstring("Returns the view options for showing a folder.")]

       HRESULT _stdcall ViewOptions([out, retval] long* plViewOptions);

    };

[

      uuid(62112AA2-EBE4-11CF-A5FB-0020AFE7292D),

      helpstring("Event interface for ShellFolderView")

]

dispinterface DShellFolderViewEvents {

     properties:

     methods:

    [id(0x000000c8), helpstring("The Selection in the view changed.")]

       void SelectionChanged();

    };

[

     uuid(1820FED0-473E-11D0-A96C-00C04FD705A2),

     hidden

]

coclass WebViewFolderContents {

        [default] interface IShellFolderViewDual;

        [default, source] dispinterface DShellFolderViewEvents;

};

Thumbnail Viewer Control

The thumbnail Viewer is an ActiveX control located in webvw.dll[2] which resides in the Windows SYSTEM directory.

Its CLSID is:

1D2B4F40-1F10-11D1-9E88-00C04FDCAB92

and its ProgID is:

ThumbCtl.ThumbCtl

We see from the use of the thumbnail viewer in folder.htt that the main method is displayFile, which takes a filename as a parameter and prepares the thumbnail. What seems to happen is that thumbnail first determines if the file is a well-known bitmap format (BMP, JPEG, GIF) and is so extracts a suitable thumbnail from the file. If not, the thumbnail Viewer determins if the file is in structured storage format, and if it has a summary information property set. One of the fields in the summary information is a thumbnail view – if this is filled in then the thnumbnail viewer control extracts this thumbnail and displays it. If the summary information is present but the thumbnail field is empty, then no thumbnail is displayed. We will shortly look at programmaticlly creating this summary information property set – for now yo may experiement using Microsoft WORD 97. You determine if a thumbnail is saved in the summary information by going into the File menu and selecting the Properties menuitem. If you wish to save the thumbnail make sure to check (turn on) the “Save Preview Picture” checkbox at the bottom of the Summary property page[3].

WebviewFolderIcon

WebviewFolderIcon is also defined in webvw.dll.

Its CLSID is:

e5df9d10-3b52-11d1-83e8-00a0c90dc849

and its ProgID is:

WebviewFolderIcon.WebviewFolderIcon

The appropriate lines from folder.htt states:

<!-- this is our awesome icon extractor -->

<object id=Icon classid="clsid:E5DF9D10-3B52-11D1-83E8-00A0C90DC849">

<param name="scale" value=200>

</object>

There is an additional entry in teh registry called WebViewCoord – though this is not actually used in folder.htt.

It’s CLSID is:

7A707490-260A-11D1-83DF-00A0C90DC849

Its ProgID is:

WebViewCoord.WebViewCoord

It is also implemented in webvw.dll but there are no entries ofr it in the typelibrary which is bound into webvw.dll.

IDL for Thumbnail Viewer Control/WebviewFolderIcon

The COM Viewer tool produces the following IDL for the thumbnail viewer control (go into Com Viewer, select “View type library”, and navigate to the windows system directory, and select webview.dll).

// Generated .IDL file (by the OLE/COM Object Viewer)

// typelib filename: <could not determine filename>

// Forward declare all types defined in this typelib

dispinterface DThumbCtlEvents;

interface IThumbCtl;

interface IWebViewFolderIcon;

[

  uuid(CD603FC0-1F11-11D1-9E88-00C04FDCAB92),

  version(1.0),

  helpstring("webvw 1.0 Type Library")

]

library WEBVWLib

{

importlib("stdole2.tlb");

    [

      uuid(58D6F4B0-181D-11D1-9E88-00C04FDCAB92),

      helpstring("Event interface for ThumbCtl")

    ]

    dispinterface DThumbCtlEvents {

        properties:

        methods:

            [id(0x000000c8), helpstring("The Thumbnail is ready

to be displayed.")]

            void OnThumbnailReady();

    };

    [

      uuid(1D2B4F40-1F10-11D1-9E88-00C04FDCAB92),

      helpstring("ThumbCtl Class")

    ]

    coclass ThumbCtl {

        [default] interface IThumbCtl;

        [default, source] dispinterface DThumbCtlEvents;

    };

    [

      odl,

      uuid(E8ACCAE0-23E6-11D1-9E88-00C04FDCAB92),

helpstring("IThumbCtl Interface"),

      dual,

      oleautomation

    ]

    interface IThumbCtl : IDispatch {

        [id(0x00000001), helpstring("method displayFile")]

        HRESULT _stdcall displayFile(

                     BSTR bsFileName,

                     [out, retval] VARIANT_BOOL* __MIDL_0016);

        [id(0x00000002), helpstring("method haveThumbnail")]

        HRESULT _stdcall haveThumbnail([out, retval]

VARIANT_BOOL* __MIDL_0017);

        [id(0x00000003), propget, helpstring(

"property freeSpace")]

        HRESULT _stdcall freeSpace([out, retval]

BSTR* __MIDL_0018);

        [id(0x00000004), propget, helpstring(

"property usedSpace")]

        HRESULT _stdcall usedSpace([out, retval]

BSTR* __MIDL_0019);

        [id(0x00000005), propget, helpstring(

"property totalSpace")]

        HRESULT _stdcall totalSpace([out, retval]

BSTR* __MIDL_0020);

    };

    [

      uuid(E5DF9D10-3B52-11D1-83E8-00A0C90DC849),

      helpstring("WebViewFolderIcon Class")

    ]

    coclass WebViewFolderIcon {

        [default] interface IWebViewFolderIcon;

    };

    [

      odl,

      uuid(E52B4910-3EB2-11D1-83E8-00A0C90DC849),

      helpstring("IWebViewFolderIcon Interface"),

      dual,

      oleautomation

    ]

    interface IWebViewFolderIcon : IDispatch {

        [id(0x00000001), propget, helpstring("property scale")]

        HRESULT _stdcall scale([out, retval] int* __MIDL_0021);

        [id(0x00000001), propput, helpstring("property scale")]

        HRESULT _stdcall scale([in] int __MIDL_0021);

    };

};

Thumbnail Extractors

Looking in the registry there are a number of other interesting entries. There is no documentation for these anywhere, and COM Viewer cannot find an embedded typelibrary in the thumbvw.dll file which they all reside. From the naming one would assume that they are used by the thumbnail Viewer control to extract/generate appropriate thumbnails for a variety of data sources.

Shell.ThumbnailView

·  CLSID = {8BEBB290-52D0-11D0-B7F4-00C04FD706EC}

·  ProgID = Shell.ThumbnailView

·  Location = thumbvw.dll

Shell.ThumbnailExtract.BMP

·  CLSID = {8A4D3EDC-13A4-11D1-9A22-00C04FC2D6C1}

·  ProgID = Shell.ThumbnailExtract.BMP

·  Location = thumbvw.dll

Shell.ThumbnailExtract.Docfile

·  CLSID = {9DBD2C50-62AD-11D0-B806-00C04FD706EC}

·  ProgID = Shell.ThumbnailExtract.Docfile

·  Location = thumbvw.dll

Shell.ThumbnailExtract.Html

·  CLSID = {EAB841A0-9550-11CF-8C16-00805F1408F3}

·  ProgID = Shell.ThumbnailExtract.Html

·  Location = thumbvw.dll

Shell.ThumbnailExtract.Lnk

·  CLSID = {500202A0-731E-11D0-B829-00C04FD706EC}

·  ProgID = Shell.ThumbnailExtract.Lnk

·  Location = thumbvw.dll

Shell.ThumbnailExtract.Office

·  CLSID = {1AEB1360-5AFC-11D0-B806-00C04FD706EC}

·  ProgID = Shell.ThumbnailExtract.Office

·  Location = thumbvw.dll

ImgCtx graphics file extractor

·  CLSID={7376D660-C583-11d0-A3A5-00C04FD706EC}

·  No ProgID

·  Location = SHDOCVW.DLL

Writing your own Extractors

As there is no description of these extractors, or of the API between the extractor and the Thumbnail Viewer Control, there is no easy way of creating your own extractor (what interface will you use?[4]).

Configuring an Extrzctor for your own file type

Most developers can use one of the provided thumbnail extractors – e.g. they have a standard bitmap format or use structured storeage and embed a “SummaryInformation” stream with thumbnail with a well—known name directly under the root storage.

Imagine we have a filetype called .dod and we wish to configure the Docfile extractor for it.

Under HKEY_CLASSES_ROOT\.dod, we need to create a key ShellEx, and under this a key BB2E617C-0920-11d1-9A0B-00C04FC2D6C1 which is used to identify the extractor.

[HKEY_CLASSES_ROOT\.dod]

[HKEY_CLASSES_ROOT\.dod\ShellEx]

[HKEY_CLASSES_ROOT\.dod\ShellEx\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}]

@="{9DBD2C50-62AD-11d0-B806-00C04FD706EC}"

To see this in action take a JPEG file (.jpg) and a MS-WORD file (.doc). These file types are configured under HKEY_CLASSES_ROOT\.jpg\ShellEx to use the ImgCtx graphics file extractor and under HKEY_CLASSES_ROOT\.doc\ShellEx to use the docfile extractor. When you select them in web view you will see a nice thumbnail appear[5].

If you change the suffixes, (.xx1 and .xx2), you will see no thumbnails in webview. (assuming no filetypes., and hence no ShellEx\ have been configured for .xx1 and .xx2).

Now change the .doc file to .dod, (assuming we have added appropriate entries as above). The thumbnail is now visible in web view.



[1] Most people don’t know that!

[2] We know it is this file because using the CLSID of thumbnail viewer (which we get from folder.htt) we can look up the InprocServer32 entry in the registry, and it says it is webvw.dll.

[3] To give you a rough estimate of the increase in file size, this author turned it on for a document whose front-page consisted of a few words of text in large bold and a 20K gif picture, and the file size increased by 160K.

[4] Though you could write an extractor, configure it for a particular file type (suffix), and discover the GUI which the Thumbnail Extractor wiill use as the interface which it requests. Prehaps this is a well-known GUID – this is left as an exercise for the reader!

[5] For .DOC files, you must have saved a thumbnail in the summary information – as discussed previously, this is done in MS-WORD’s File menu, Properties menuitem, SUmmary tab, “Save Preview Picture” checkbox.