( Index )
Month

Brief Information about the March 2005 CSIG Meeting

ViewPICT - A viewer for BMP, JPG, etc. Files --- Windows API

3rd Tuesday of the month. 7:30PM - C/C++ Group, SPRS

Program Icon

Welcome to the C++ Users Group. This group is a "Special Interest Group" of the ACGNJ devoted to discussing programming languages in general and C, C++, and C++ for Windows programming in particular. Each month a small but hopefully useful program (complete with source code) is presented for discussion.

Bitmap processing will be demonstrated with an program called "ViewPICT". This is an update of a program presented here in July, 2001. Later that year, Paul DiLascia (MSDN Oct. 2001) wrote and article called "Displaying a JPG in your MFC Application" In that article, he created a class called CPicture that incapsulates some new functions. The advantage is that you are no longer limited to just .BMP files. JPG's and others are OK too. OleLoadPicture loads the picture from the stream and creates a new IPicture object you can use to display the picture. Here's what Paul says:


Displaying a JPG in your MFC Application 	-  MSDN Oct. 2001
--------------------------------------------------------------------------------
Paul DiLascia 
 
Question
In Visual Basic, I can display a JPG or GIF file by creating a picture control, but
how can I display a JPG in my MFC app?

Answer
Good question! Sometimes programmers who use Visual Basic seem to have it so easy.
Just plop a picture control in your form and awaaay you go...while C++ programmers
have to fret and strut. What are we supposed to do, write our own JPG decompression
functions? Of course not! In fact, C/C++ programmers can use the very same (almost)
picture control their Visual Basic counterparts use. I kid you not. The Visual Basic
picture control is based on a system COM class, IPicture (see Figure 1). IPicture
manages a picture object and its properties. Picture objects provide an abstraction
for bitmaps. Windows provides a standard implementation that knows how to handle
BMP, JPG, and GIF bitmaps. All you need to do is instantiate IPicture and call
Render. Instead of calling CoCreateInstance the normal way, you call a special
function called OleLoadPicture.

IStream* pstm = // needs a stream
IPicture* pIPicture;
hr = OleLoadPicture(pstm, 0, FALSE,
  IID_IPicture, (void**)&pIPicture);

OleLoadPicture loads the picture from the stream and creates a new IPicture object
you can use to display the picture.

rc = // rect to display in
// convert rc to HIMETRIC
spIPicture->Render(pDC, rc);

IPicture does all the nasties to figure out whether the image is a Windows bitmap,
JPEG, or GIF file; it even does icons and metafiles!

I have taken the original code and added the CPicture class. The original code was left in place but commented out. Now the functionality of the utility is greatly enhanced. The name has been changed from ViewBmp to ViewPICT since it handles most graphic pictures.

Simply drag and drop bitmap files from Windows Explorer and they will appear on the view screen. You may select all the files from a directory and drop them on the program.

If you drop more than one file, the program will present a slide show. The speed of presentation may be adjusted from the menu in the upper left corner. Use the space bar to pause the slide show. The right and left arrows determine the direction, forward or back.

At the meeting on Tuesday night we will be discussing the utility and the source code.


SAMPLE CODE
===========
void CVBDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
    // TODO: Add your message handler code here and/or call default
    CString rString;
    if (nChar == VK_SPACE) 
        switch (state)
            {
            case NORMAL:    state = PAUSE_DOWN;
                            KillTimer(timerID);
                            rString = csFiles[currentFile] + " ...WAITING...";
                            SetWindowText(rString);
                            break;
            case PAUSE_UP:  state = GETSET; break;
            }
    
    CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
    }


void CVBDlg::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
    if (nChar == VK_SPACE)
        switch (state)
            {
            case PAUSE_DOWN: state = PAUSE_UP; break;
            case GETSET:    state = NORMAL;
                            SetWindowText(csFiles[currentFile]);
                            timerID = SetTimer(1, 100, NULL); // Start timer.
                            break;
            }
    else if (nChar == VK_LEFT)
        {
        forward = false;
        }
    else if (nChar == VK_RIGHT)
        {
        forward = true;
        }
    
    CDialog::OnKeyUp(nChar, nRepCnt, nFlags);
    }


"Random Access" questions start at 7:30 Tuesday night. See you there.

SOURCE CODE

Source Code Files

For help, email me at b a r n o l d @ i e e e . o r g
Back to C++ Main Page