Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C++
Article

Image Tip - A popup thumbnail shell extension

Rate me:
Please Sign up or sign in to vote.
3.89/5 (10 votes)
8 Mar 20043 min read 91.7K   2.4K   33   17
A graphical tooltip to show the contents of jpgs, bmps etc

Introduction

During my day job, I write software that makes ultrasonic scans of aircraft parts. (If you are an part aircraft manufacturer, buy our kit!). These scans are essentially large 8 bit bitmaps, with some job specific extra information. In order to quickly tell these files apart, I wanted an InfoTip shell extension that could either display description text stored in these files, or a preview image (also stored in the files).

Writing the text popup was trivial. But search as I might, I didn't find any graphical equivalent. So I got my hands dirty and wrote it!

Once I'd done that, I thought this might be quite and handy utility for image files too. Theoretically, you could adapt this to play the first 5s of a music file for mp3s etc. That is an exercise for the reader...

How it works... aka The light bulb moment.

I tried for ages to hook into the info tip creation cycle, seeing if I could integrate myself a little earlier. Eventually I gave up. At two am, I woke up with a dead simple idea. Return a blank tooltip, and use than moment to generate my own tooltipesque picture window. After having proved my idea, I went back to bed. Most of my best work is done when I'm asleep. At least, that's what I tell my colleagues when the wake me up at my desk!

The shell extension...

The shell extension itself was premade by a shell extension wizard. (See bibliography). I only really had to change the GetInfoTip function.

HRESULT CImage_Tip::GetInfoTip ( DWORD   dwFlags, LPWSTR* ppwszTip )
{
  static std::wstring  m_FileNameLast;

  // We're going to create our own tooltipesque window, 
  // but with a the CPreviewBitmap in it...
//  wchar_t  buf [512];
//  wcscpy (buf, L"CImage_Tip::GetInfoTip (). m_Filename = '");
//  wcscat (buf, m_FileName.c_str ());
//  wcscat (buf, L"' m_FileNameLast = '");
//  wcscat (buf, m_FileNameLast.c_str ());
//  wcscat (buf, L"'\n");
//  OutputDebugStringW (buf);

  // Return a blank tooltip.
  IMalloc *pMalloc;
  if ( FAILED( SHGetMalloc ( &pMalloc )))
    return E_FAIL;
  *ppwszTip = (LPWSTR) pMalloc->Alloc ( (1) * sizeof(wchar_t) );
  if ( NULL == *ppwszTip )
  {
    pMalloc->Release();
    return E_OUTOFMEMORY;
  }
  (*ppwszTip) [0] = 0;
  pMalloc->Release();

  // Make sure we haven't recently shown this item, 
  // otherwise Explorer will keep on trying...
  if (m_FileName.compare (m_FileNameLast))
    CGraphicTip::ShowTip (m_FileName);  // This is all that's needed here!
  m_FileNameLast.erase ();
  m_FileNameLast.append (m_FileName);
  
  return S_OK;
}

I had to make sure that explorer wasn't making repeat requests for the same tip, otherwise the screen ended up getting very busy. Once that was in place, I simply created a new CGraphicTip object, which made its own window, message loop, and tidying up bit.

The graphic popup window...

This is pretty much a mini app in its own right. Created with a filename as a parameter, it loads the image using IPicture, and creates a window scaled down to a maximum of 200 x 200, and shows it a little way from the cursor.

The object contains its own message loop, and window procedure. I used classic Win32, as MFC seemed like major overkill, and I've yet to play with WTL. Using Win32 windowing code felt like a bit of a nostalgia trip. Beside, all MFC / WTL would do is the same job, but more hidden.

Please forgive the lack of comments, but there are only a few routines, and I try to use very obvious function / variable names...

class CGraphicTip
{
public:
  static BOOL  ShowTip (std::wstring FileName);

protected:
  CGraphicTip ();
  ~CGraphicTip ();

  static  DWORD WINAPI TipThread ( LPVOID lpParameter );
  static  LRESULT CALLBACK TipProc ( HWND hwnd, UINT uMsg, 
    WPARAM wParam, LPARAM lParam );
  static  SIZE  GetCorrectedOutputSize (const SIZE szIn, 
    const SIZE sizeBounding);

  LRESULT  OnPaint ();

  HANDLE  m_hThreadHandle;
  DWORD  m_dwThreadID;
  
  std::wstring  m_FileName;
  IPicture      *m_Picture;
  SIZE          m_szHiMetric;
  HWND          m_hWnd;
};

Installing the extension...

If you haven't compiled it yourself, you'll need to put the dll in an obvious location, fire up a command prompt, go to the dll's directory, and type:

regsvr32 ImageTip.dll"
to install, and
regsvr32 /u ImageTip.dll"
to uninstall.

Things to do...

  • An installation program.
  • A way of changing maximum tip size, and duration at runtime.
  • A way of changing which file types are "tipped" at runtime.
  • Make the tip appear above / to the left when necessary.
  • An uninstallation program!
  • Bibliography

    The following codeproject articles made my life veeeeery easy:

    Context Menu Shell Extension AppWizard by Maxime Labelle.

    which seemed heavily based on...

    The Complete Idiot's Guide to Writing Shell Extensions - Part III by Michael Dunn. I cannot recommend his shell extension series highly enough.

    History

    v1.0

    Uploaded to Code Project. The software is perfect already. Honest. Would these eyes lie?

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    Software Developer (Senior)
    Sweden Sweden
    I have now moved to Sweden for love, and recently married a lovely Swede.


    -----------------
    I started programming on BBC micros (6502) when I was six and never quite stopped even while I was supposed to be studying physics and uni.

    I've been working for ~13 years writing software for machine control and data analysis. I now work on financial transaction transformation software, for a Software company in Gamlastan, Stockholm.
    Look at my articles to see my excellent coding skills. I'm modest too!

    Comments and Discussions

     
    QuestionFeature request Pin
    gauravkale30-Apr-13 2:19
    gauravkale30-Apr-13 2:19 
    GeneralXP crashing problem solved Pin
    Phil.Benson16-Feb-05 22:04
    professionalPhil.Benson16-Feb-05 22:04 
    GeneralRotating an Image Pin
    Alex Evans4-Jan-05 9:25
    Alex Evans4-Jan-05 9:25 
    GeneralRe: Rotating an Image Pin
    Iain Clarke, Warrior Programmer4-Jan-05 21:38
    Iain Clarke, Warrior Programmer4-Jan-05 21:38 
    GeneralRe: Rotating an Image Pin
    Alex Evans5-Jan-05 9:44
    Alex Evans5-Jan-05 9:44 
    GeneralRe: Rotating an Image Pin
    Iain Clarke, Warrior Programmer5-Jan-05 21:39
    Iain Clarke, Warrior Programmer5-Jan-05 21:39 
    GeneralRe: Rotating an Image Pin
    Alex Evans6-Jan-05 9:21
    Alex Evans6-Jan-05 9:21 
    QuestionHow can I hook the listview? Pin
    K7magi20-Nov-04 14:59
    K7magi20-Nov-04 14:59 
    Generaldoesn't work in xp Pin
    eversor22-Aug-04 3:45
    eversor22-Aug-04 3:45 
    GeneralXP & Missing IDL file. Pin
    Iain Clarke, Warrior Programmer11-Mar-04 5:08
    Iain Clarke, Warrior Programmer11-Mar-04 5:08 
    GeneralRe: XP & Missing IDL file. Pin
    .dan.g.11-Mar-04 15:46
    professional.dan.g.11-Mar-04 15:46 
    GeneralShock! Horror! I'm not perfect.... *sniff*. Pin
    Iain Clarke, Warrior Programmer10-Mar-04 5:44
    Iain Clarke, Warrior Programmer10-Mar-04 5:44 
    Generalbad crash.... Pin
    Kandjar10-Mar-04 4:55
    Kandjar10-Mar-04 4:55 
    GeneralRe: bad crash.... Pin
    Iain Clarke, Warrior Programmer10-Mar-04 5:48
    Iain Clarke, Warrior Programmer10-Mar-04 5:48 
    GeneralRe: bad crash.... Pin
    Kandjar10-Mar-04 22:23
    Kandjar10-Mar-04 22:23 
    In fact, I don't have a lot of pictures here with me, so I tried your program on a big picture (my wallpaper), it's maybe that which made the program crash with the explorer...
    GeneralBBC Micros Pin
    .dan.g.9-Mar-04 20:16
    professional.dan.g.9-Mar-04 20:16 
    GeneralRe: BBC Micros Pin
    Iain Clarke, Warrior Programmer9-Mar-04 22:41
    Iain Clarke, Warrior Programmer9-Mar-04 22:41 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.