📄 imagecls.cpp
字号:
/*
** IMAGECLS.CPP
** Member functions of ImageClass.
**
** Author: C A Marriott
** Created: 15-FEB-93
**
** Revised:
** 19-FEB-93 Converted into a class.
** 21-FEB-93 We now always store the DIB in memory, which means there's no
** longer any need for the separate "hbiCurrent" BITMAPINFO
** structure.
** 26-FEB-93 Add function "SizeWindow" to resize window to fit image.
*/
// Standard precompilable headers:
#include "common.h" // common headers
#include <string.h> // string library header
#include "imagecls.h" // IMAGECLASS header
#include "gifcls.h" // GIFCLASS header
#define BFT_BITMAP 0x4d42 /* 'BM' */
/* macro to determine if resource is a DIB */
#define ISDIB(bft) ((bft) == BFT_BITMAP)
/* Macro to determine to round off the given value to the closest byte */
#define WIDTHBYTES(i) ((i+31)/32*4)
#define PALVERSION 0x300
#define MAXPALETTE 256 /* max. # supported palette entries */
// ImageClass::ImageClass
// Read an image into memory.
ImageClass::ImageClass( HWND hWindow, LPSTR szFileName )
// Input arguments:
// szFileName Pointer to filename buffer.
{
HCURSOR hOldCursor; // current cursor handle
HINSTANCE hInst; // application instance handle
extern HCURSOR hHourGlass; // hourglass cursor handle
// Store the window handle.
hWnd = hWindow;
// Load the menu from the resource file.
hInst = (HINSTANCE) GetWindowWord( hWindow, GWW_HINSTANCE );
hMenu = LoadMenu( hInst, "IMAGE" );
// Get the handle of the submenu to which window titles
// are to be attached.
hMenuWindow = GetSubMenu( hMenu, 1 );
// Set up the scroll bars to scroll 8 pixels at a time, leaving
// an 8-pixel overlap between pages.
ScrollSetup( hWnd, 8, 8, 8, 8 );
// Change the cursor to an hourglass.
hOldCursor = SetCursor( hHourGlass );
// Initialize the global data.
nUpdateCount = 0; // image update counter
bDIBToDevice = FALSE; // blit image to device
bImageValid = FALSE; // image data is valid
hpalCurrent = NULL; // palette handle
hdibCurrent = NULL; // handle to current memory DIB
hbmCurrent = NULL; // handle to current memory BITMAP
// Make a copy of the file name.
lstrcpy( achFileName, szFileName );
// Identify the file format.
IdentifyFileFormat();
// The action to take depends what the file format is:
switch (nFileFormat) {
// GIF file:
case FI_GIF:
ReadGIF();
break;
// DIB:
case FI_DIB:
default:
ReadDIB();
break;
}
// Restore the original cursor.
SetCursor( hOldCursor );
}
// ImageClass::~ImageClass
// Destructor for the image class.
ImageClass::~ImageClass()
{
// Free the data.
FreeData();
// Destroy the menu.
DestroyMenu( hMenu );
// Free the scroll bar data.
ScrollTerminate( hWnd );
}
// ImageClass::SetMenu
// Switch to the appropriate menu for this type of window.
void ImageClass::SetMenu( HWND hWndClient )
// Input arguments:
// hWndClient Handle of MDI client window.
{
// Select the menu.
SendMessage( hWndClient, WM_MDISETMENU, 0,
MAKELONG( hMenu, hMenuWindow ) );
}
// ImageClass::ReadDIB
// Attempt to read a DIB file.
BOOL ImageClass::ReadDIB()
{
// Load the DIB into memory.
hdibCurrent = OpenDIB();
// If we don't have a valid DIB, return an error code.
if (hdibCurrent == NULL) {
return FALSE;
}
// Create a GDI palette to match the bitmap colours.
// If we fail to create a palette, return an error code.
hpalCurrent = CreateDibPalette( hdibCurrent );
if (hpalCurrent == NULL) {
FreeData();
return FALSE;
}
// Create a memory DDB from the DIB.
if (hdibCurrent && !bDIBToDevice){
hbmCurrent = (HBITMAP) BitmapFromDib(hdibCurrent,hpalCurrent);
if (!hbmCurrent){
FreeData();
return FALSE;
}
}
// Set the flag to indicate that we now have a valid image in memory.
bImageValid = TRUE;
// Return a success code.
return TRUE;
}
// ImageClass::ReadGIF
// Attempt to read a GIF file.
BOOL ImageClass::ReadGIF()
// Return value:
// TRUE if the file is successfully read.
// FALSE if an error occurred.
{
GIF GIF; // GIF information
// Attempt to read the GIF file. Return a failure code if we are
// unable to do so.
hdibCurrent = GIF.Read( achFileName );
if (hdibCurrent==NULL) return FALSE;
// Create a GDI palette to match the bitmap colours.
// If we fail to create a palette, return an error code.
hpalCurrent = CreateDibPalette( hdibCurrent );
if (hpalCurrent == NULL) {
FreeData();
return FALSE;
}
// Create a memory DDB from the DIB.
if (hdibCurrent && !bDIBToDevice){
hbmCurrent = (HBITMAP) BitmapFromDib(hdibCurrent,hpalCurrent);
if (!hbmCurrent){
FreeData();
return FALSE;
}
}
// Set the flag to indicate that we now have a valid image in memory.
bImageValid = TRUE;
// Return a success code.
return TRUE;
}
// ImageClass::FreeData
// Free all currently active bitmap, DIB, and palette objects, and
// initialize their handles.
void ImageClass::FreeData()
{
// Free the GDI objects.
if (hpalCurrent)
DeleteObject(hpalCurrent);
if (hbmCurrent)
DeleteObject(hbmCurrent);
// Free the allocated memory.
if (hdibCurrent)
GlobalFree(hdibCurrent);
// Reset global variables.
bImageValid = FALSE;
hpalCurrent = NULL;
hdibCurrent = NULL;
hbmCurrent = NULL;
}
#ifdef NOTYET
// FileSave
// Save the current bitmap to file.
void FileSave( HWND hWnd )
// Input arguments:
// hWnd Main window handle.
{
int hFile; // file handle
WORD fFileOptions; // file options flag
BITMAPINFOHEADER bi; // bitmap header structure
extern OPENFILENAME FileData; // file information structure
extern HINSTANCE hInst; // application instance handle
// Set up header information for the current DIB.
DibInfo(hbiCurrent,&bi);
fFileOptions = 0;
// Set the appropriate options bit according to the compression
// type of the current DIB.
if (bi.biCompression == BI_RGB)
fFileOptions |= F_RGB;
else if (bi.biCompression == BI_RLE4)
fFileOptions |= F_RLE4;
else if (bi.biCompression == BI_RLE8)
fFileOptions |= F_RLE8;
// Set the appropriate options bit according to the bits per pixel
// of the current DIB.
switch (bi.biBitCount) {
case 1:
fFileOptions |= F_1BPP;
break;
case 4:
fFileOptions |= F_4BPP;
break;
case 8:
fFileOptions |= F_8BPP;
break;
case 24:
fFileOptions |= F_24BPP;
}
// Fill in the structure to display the "Save As" dialog.
FileData.lStructSize = sizeof(OPENFILENAME);
FileData.hwndOwner = hWnd;
FileData.hInstance = hInst;
FileData.lpstrFilter = szBitmapExt;
FileData.lpstrCustomFilter = NULL;
FileData.nMaxCustFilter = 0;
FileData.nFilterIndex = 1;
FileData.lpstrFile = (LPSTR)achFileName;
FileData.nMaxFile = 128;
FileData.lpstrFileTitle = NULL;
FileData.nMaxFileTitle = 0;
FileData.lpstrInitialDir = NULL;
FileData.lpstrTitle = NULL;
FileData.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
FileData.nFileOffset = 0;
FileData.nFileExtension = 0;
FileData.lpstrDefExt = (LPSTR)"";
FileData.lCustData = 0L;
FileData.lpfnHook = NULL;
FileData.lpTemplateName = NULL;
// Display the dialog.
hFile = GetSaveFileName( &FileData );
// If the user did not press the "Cancel" button, extract the DIB specs.
if (hFile!=0) {
if (fFileOptions & F_RGB)
bi.biCompression = BI_RGB;
if (fFileOptions & F_RLE4)
bi.biCompression = BI_RLE4;
if (fFileOptions & F_RLE8)
bi.biCompression = BI_RLE8;
if (fFileOptions & F_1BPP)
bi.biBitCount = 1;
if (fFileOptions & F_4BPP)
bi.biBitCount = 4;
if (fFileOptions & F_8BPP)
bi.biBitCount = 8;
if (fFileOptions & F_24BPP)
bi.biBitCount = 24;
// Realize a DIB in the specified format and obtain a handle to it.
hdibCurrent = RealizeDibFormat(bi.biCompression,bi.biBitCount);
if (!hdibCurrent){
ErrMsg("Unable to save the specified file");
return;
}
// Write the DIB.
StartWait();
if (!WriteDIB(achFileName,hdibCurrent))
ErrMsg("Unable to save the specified file");
EndWait();
}
}
// FilePrint
// Print the current DIB.
void FilePrint( HWND hWnd )
// Input arguments:
// hWnd Main window handle.
{
HDC hDC; // device context handle
BITMAPINFOHEADER bi; // bitmap header structure
int xSize, ySize, xRes, yRes; // printer size and resolution
int dx, dy; // margin sizes
RECT Rect; // bounding rectangle
extern char szBuffer[]; // global text buffer
extern RECT rcClip; // clipping rectangle
extern HINSTANCE hInst; // application instance handle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -