Environment: Developed with VC 5.
This is a sample simple BMP viewer. It only shows
the minimum code for loading a BMP from a file
and showing it in a window. It does not do everything;
I get frustrated trying to figure out how to do something simple
using a sample that does everything. In particular, it does not
do palettes, which is something that seems to be important, but
also seems to be relatively complicated. I am not a graphics
expert so I invite an expert to create another article
documenting correspondingly simple palette processing and/or
printing and print preview processing.
Consistent with the theme of keeping things
simple, I will simply describe how to create a sample program and
supply relevant code here. You can use this code as a sample for
use in your project or use this code and instructions to create a
complete working sample.
To create a complete working sample, start by
generating an MDI application with a CScrollView view. You might
want to de-select the option for printing and print preview. Then:
Use ClassWizard to add processing for ID_FILE_NEW
in your application class, but do nothing more with it,
since we do not support bitmap creation.
Use ClassWizard to add processing for
DeleteContents in your document class and add the
following to it:
if (m_Bitmap.m_hObject != NULL)
m_Bitmap.DeleteObject();
Use ClassWizard to add processing for
OnOpenDocument in your document class and replace
all the generated code with the following:
if (IsModified())
TRACE0("Warning: OnOpenDocument replaces an unsaved document\n");
DeleteContents();
BeginWaitCursor();
HBITMAP hImage = (HBITMAP)LoadImage(NULL, lpszPathName, IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE);
EndWaitCursor();
if (!hImage) {
DWORD LastError = GetLastError();
AfxMessageBox("LoadImage failed");
return FALSE;
}
if (!m_Bitmap.Attach(hImage)) {
AfxMessageBox("Bitmap could not be attached");
return FALSE;
}
SetModifiedFlag(FALSE);
UpdateAllViews(NULL);
return TRUE;
Add the following to the header for the
document:
public:
HBITMAP GetHandle() const {return (HBITMAP)m_Bitmap.m_hObject;};
void SelectOldBitmap(CDC *pDCMem) {pDCMem->SelectObject(m_pOldBitmap);};
void SelectBitmap(CDC *pDCMem)
{m_pOldBitmap=pDCMem->SelectObject(&m_Bitmap);};
int GetBitmap(BITMAP* pBitMap) {return m_Bitmap.GetBitmap(pBitMap);};
protected:
CBitmap m_Bitmap;
CBitmap* m_pOldBitmap;
Use ClassWizard to remove
processing for OnInitialUpdate in your view class and delete
the function from the code
Add to the view constructor:
SetScrollSizes(MM_TEXT, CSize(0, 0));
Use ClassWizard to add processing for
OnUpdate in your view class and add the following to it:
CBMPLookDoc* pDoc = GetDocument();
CFrameWnd* pParentFrame = GetParentFrame();
BITMAP BitMap;
if (!pDoc->GetHandle())
return;
pDoc->GetBitmap(&BitMap);
SetScrollSizes(MM_TEXT, CSize(BitMap.bmWidth, BitMap.bmHeight));
pParentFrame->RecalcLayout();
ResizeParentToFit();
Finally, replace the OnDraw processing
with the following:
CBMPLookDoc* pDoc = GetDocument();
BITMAP BitMap;
CDC DCMem;
ASSERT_VALID(pDoc);
if (!pDoc->GetHandle())
return;
if (!DCMem.CreateCompatibleDC(pDC))
TRACE0("DCMem.CreateCompatibleDC failed\n");
pDoc->SelectBitmap(&DCMem);
pDoc->GetBitmap(&BitMap);
if (!pDC->BitBlt(0, 0, BitMap.bmWidth, BitMap.bmHeight, &DCMem, 0, 0, SRCCOPY))
TRACE0("BitBlt failed\n");
pDoc->SelectOldBitmap(&DCMem);
DCMem.DeleteDC();
You should also modify the "<filterName>"
and "<filterExt>" in the Document Template String
to use appropriate file extensions and ".bmp" for the
file extension. See CDocTemplate::GetDocString and Microsoft
Knowledge Base article "INFO: Format of the Document
Template String" (Article ID: Q129095) for information on
Document Template Strings. The string resource id for the string
is usually 129.
The LR_CREATEDIBSECTION flag in the LoadImage
function can probably be removed to improve performance, but the
documentaion for this and many, many other things need to be
studied because bitmaps and graphics are quite complex.
References
To go beyond this very simple sample, the MFC
DIBLook sample is an example of the type of sample that is too
complicated to get just the basics from but does show most of the
fancier stuff that should be done.
There is an abundance of documentation to wade
through in the section on Bitmaps in the GDI portion of Graphics
and Multimedia Services in the Platform SDK
documentation. For Windows 9X, in the Windows Base Services
chapter of the Platform SDK there is a Windows 95
Graphics Device Interface topic in Windows 95 System
Limitations in About Windows 95 in Windows 95
Features.
The Multimedia Technical Article DIBs and
Their Use might be helpful.
In the Microsoft Systems Journal Volume
12 Number 1 is the article More Fun with MFC: DIBs, Palettes,
Subclassing, and a Gamut of Reusable Goodies.
The following are Microsoft Knowledge Base
articles (the last two are from the Win16 knowledge base):
| Q94326 |
SAMPLE: 16 and 32 Bits-Per-Pel Bitmap Formats |
| Q158898 |
How To Use LoadImage() to Read a BMP File |
| Q124947 |
Retrieving Palette Information from a Bitmap
Resource |
| Q159649 |
PARSEBIT.EXE Directly Accesses the Bits of a DIB
Section |
| Q67883 |
How to Use a DIB Stored as a Windows Resource |
| Q83034 |
SAMPLE: Reading and Converting Between the Three
GDI Resources |
| Q81498 |
SAMPLE: DIBs and Their Uses |
History