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.

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...

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.

Share

About the Author

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!

For 180o, you can simply use the Render method and change the X/Y/W/H values around.
For 90o, you can extract the HBITMAP, HDC etc from the IPicture. From that you could
get the underlying data using GetDIBits.

The other option is to use GDI+ and the Image class. That has a constructor that take
a filename. It also has a RotateFlip method.

OK, here is a choice of functions to draw an IPicture into a rectangle. I've done four calls to Render, with it mirrored in all four combinations.
Mirrored twice becomes 180o rotate. Mirrored once is *not* 90o rotate.

You'll notice the one I have marked "the right way up" actually seems to invert the picture. That's because the screen coords work from the top left, and the IPicture seems to work from the bottom left.

As for writing a "IPicture *GetRotatedBy90 (IPicture *)" function, that is outside my immedidate experience. I'm sure it could be done, but not trivially.

For 90 and 270 degrees, I started using GDI+, and made a simple function that looks like this (taken from an MSDN sample)- the class member m_pStream is obtained earlier when I load the image, the m_hMemDC is passed into the function from the dc I already have, and the RotateFlipType is defined in GDIPLUS.H for all sorts of combinations