Extracting+a+file's+thumbnail

//by Richard Russell, July 2007//

Several file types can have associated thumbnail images, which are displayed (for example) in Windows Explorer's **Thumbnails** view. Examples of such file types are image files (e.g. BMP, GIF, JPEG), PowerPoint files, Word and Excel files (when the **Save preview picture** option is enabled) and folders.

Displaying such thumbnails in your own program, should you want to, is quite tricky, but is made simple using the **FN_thumbnail** function listed in this article. This function returns a //handle// to the thumbnail image, which you can use as you would any other image handle. For example you can use it to display the image in a **static control**, either in a dialogue box or on your main output window.

The code below will display, in a static control, the thumbnail for the file **CLOCK.JPG**:

code format="bb4w" INSTALL @lib$+"WINLIB5" xpos% = 100 ypos% = 100 cx% = 128 cy% = 128 _WS_BORDER = &800000 _SS_BITMAP = &0E _STM_SETIMAGE = &172 file$ = "C:\Program Files\BBC BASIC for Windows\EXAMPLES\GRAPHICS\CLOCK.JPG" hsb% = FN_staticbox("", xpos%, ypos%, cx%, cy%, 0, _WS_BORDER OR _SS_BITMAP) hbm% = FN_thumbnail(file$, cx%, cy%) SYS "SendMessage", hsb%, _STM_SETIMAGE, 0, hbm% code Here **xpos%** and **ypos%** are the position where you want the static control to be displayed (pixels from the top left-hand corner) and **cx%** and **cy%** are the desired width and height in pixels. If you want to display the thumbnail for a folder **don't** include a trailing backslash (**\**) in the pathname you specify.

When you have finished with the image you should delete its handle as follows:

code format="bb4w" SYS "DeleteObject", hbm% code Don't do this whilst the image is still displayed, since it will not refresh correctly when uncovered, or when restored after being minimised.

The **FN_thumbnail** function is listed below. Its parameters are the file or folder whose thumbnail is wanted and the preferred width and height of the thumbnail in pixels. It returns a handle to the thumbnail image, or zero if the file does not have a thumbnail. An error will result if the file/folder does not exist or the file is an unsuitable type.

code format="bb4w" DEF FN_thumbnail(file$, cx%, cy%) LOCAL patha%, pathw%, name%, ole32%, shfroot%, shf%, pidl%, iei%, flags%, hbm% LOCAL IShellFolder{}, IExtractImage{}, IID{}, size{} DIM patha% LOCAL 260, pathw% LOCAL 521 DIM IShellFolder{QueryInterface%, AddRef%, Release%, ParseDisplayName%, \ \               EnumObjects%, BindToObject%, BindToStorage%, CompareIDs%, \ \               CreateViewObject%, GetAttributesOf%, GetUIObjectOf%, \ \               GetDisplayNameOf%, SetNameOf%} DIM IExtractImage{QueryInterface%, AddRef%, Release%, GetLocation%, Extract%} DIM IID{a%,b%,c%,d%}, size{cx%,cy%} SYS "LoadLibrary", "OLE32.DLL" TO ole32% SYS "GetProcAddress", ole32%, "CoInitialize" TO `CoInitialize` SYS "GetProcAddress", ole32%, "CoUninitialize" TO `CoUninitialize` SYS `CoInitialize`, 0 SYS "GetFullPathName", file$, 260, patha%, ^name% SYS "MultiByteToWideChar", 0, 0, patha%, -1, pathw%, 260 SYS "SHGetDesktopFolder", ^shfroot% IF shfroot%=0 ERROR 100, "SHGetDesktopFolder failed" !(^IShellFolder{}+4) = !shfroot% SYS IShellFolder.ParseDisplayName%, shfroot%, 0, 0, pathw%, 0, ^pidl%, 0 IF pidl%=0 ERROR 100, "IShellFolder::ParseDisplayName failed (1)" IID.a% = &000214E6 : REM IID_IShellFolder IID.b% = &00000000 IID.c% = &000000C0 IID.d% = &46000000 SYS "SHBindToParent", pidl%, IID{}, ^shf%, 0 IF shf%=0 ERROR 100, "SHBindToParent failed" SYS IShellFolder.Release%, shfroot% !(^IShellFolder{}+4) = !shf% SYS "MultiByteToWideChar", 0, 0, name%, -1, pathw%, 260 SYS IShellFolder.ParseDisplayName%, shf%, 0, 0, pathw%, 0, ^pidl%, 0 IF pidl%=0 ERROR 100, "IShellFolder::ParseDisplayName failed (2)" IID.a% = &BB2E617C : REM IID_IExtractImage IID.b% = &11D10920 IID.c% = &C0000B9A IID.d% = &C1D6C24F SYS IShellFolder.GetUIObjectOf%, shf%, 0, 1, ^pidl%, IID{}, 0, ^iei% IF iei%=0 ERROR 100, "IShellFolder::GetUIObjectOf failed" !(^IExtractImage{}+4) = !iei% size.cx% = cx% size.cy% = cy% _IEIFLAG_ORIGSIZE = &40 _IEIFLAG_QUALITY = &200 flags% = _IEIFLAG_ORIGSIZE OR _IEIFLAG_QUALITY SYS IExtractImage.GetLocation%, iei%, pathw%, 260, 0, size{}, 24, ^flags% SYS IExtractImage.Extract%, iei%, ^hbm% SYS IShellFolder.Release%, shf% SYS IExtractImage.Release%, iei% SYS `CoUninitialize` = hbm% code