📄 childfrm.cpp
字号:
// ChildFrm.cpp : implementation of the CChildFrame class
//
#include "stdafx.h"
#include "PCXView.h"
#include <io.h> // _filelength()
#include "ChildFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChildFrame
IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)
BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
//{{AFX_MSG_MAP(CChildFrame)
ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
ON_WM_CREATE()
ON_WM_SETFOCUS()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChildFrame construction/destruction
CChildFrame::CChildFrame() : psBmpInfo(NULL), pabRawBitmap(NULL),
BitmapSize(CSize(0,0))
{
// TODO: add member initialization code here
}
CChildFrame::~CChildFrame()
{
if ( psBmpInfo )
delete [] psBmpInfo;
if ( pabRawBitmap )
delete [] pabRawBitmap;
}
BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CMDIChildWnd::PreCreateWindow(cs) )
return FALSE;
cs.style = WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
| FWS_ADDTOTITLE | WS_THICKFRAME;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
cs.lpszClass = AfxRegisterWndClass(0);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CChildFrame diagnostics
#ifdef _DEBUG
void CChildFrame::AssertValid() const
{
CMDIChildWnd::AssertValid();
}
void CChildFrame::Dump(CDumpContext& dc) const
{
CMDIChildWnd::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CChildFrame message handlers
void CChildFrame::OnFileClose()
{
SendMessage(WM_CLOSE);
}
int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// create a view to occupy the client area of the frame
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("Failed to create view window\n");
return -1;
}
return 0;
}
void CChildFrame::OnSetFocus(CWnd* pOldWnd)
{
CMDIChildWnd::OnSetFocus(pOldWnd);
m_wndView.SetFocus();
}
BOOL CChildFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// let the view have first crack at the command
if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
// otherwise, do default handling
return CMDIChildWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
//
// *** LoadPCX
//
void CChildFrame::LoadPCX( LPCSTR lpcszFilename )
{
// Standard PCX header
struct PCXHead {
char ID;
char Version;
char Encoding;
char BitPerPixel;
short X1;
short Y1;
short X2;
short Y2;
short HRes;
short VRes;
char ClrMap[16*3];
char Reserved1;
char NumPlanes;
short BPL;
short Pal_t;
char Filler[58];
} sHeader;
// Open the file and put its entire content in memory
FILE *pFile = fopen( lpcszFilename, "rb" );
if ( !pFile )
{
MessageBox("Unable to open the PCX file");
return;
}
const long clFileSize = _filelength(_fileno(pFile));
BYTE *pabFileData = (BYTE *)new BYTE[ clFileSize ];
fread( pabFileData, clFileSize, 1, pFile );
fclose( pFile );
// Get the header
memcpy( &sHeader, pabFileData, sizeof(sHeader) );
// Each scan line MUST have a size that can be divided by a 'long' data type
int iScanLineSize = sHeader.NumPlanes * sHeader.BPL;
ldiv_t sDivResult = ldiv( iScanLineSize, sizeof(long) );
if ( sDivResult.rem > 0 )
iScanLineSize = (iScanLineSize/sizeof(long)+1) * sizeof(long);
// Set the bitmap size data member
BitmapSize = CSize( sHeader.X2-sHeader.X1+1, sHeader.Y2-sHeader.Y1+1 );
const long clImageSize = iScanLineSize * BitmapSize.cy;
// Set the bitmap information
psBmpInfo = (BITMAPINFO *)new BYTE[ sizeof(BITMAPINFOHEADER) +
(sizeof(RGBQUAD)*256) ];
psBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
psBmpInfo->bmiHeader.biWidth = BitmapSize.cx;
psBmpInfo->bmiHeader.biHeight = -BitmapSize.cy;
psBmpInfo->bmiHeader.biPlanes = sHeader.NumPlanes;
psBmpInfo->bmiHeader.biBitCount = sHeader.BitPerPixel;
psBmpInfo->bmiHeader.biCompression = BI_RGB;
psBmpInfo->bmiHeader.biSizeImage = 0;
psBmpInfo->bmiHeader.biXPelsPerMeter = 0;
psBmpInfo->bmiHeader.biYPelsPerMeter = 0;
psBmpInfo->bmiHeader.biClrUsed = 0;
psBmpInfo->bmiHeader.biClrImportant = 0;
// Prepare a buffer large enough to hold the image
pabRawBitmap = (BYTE *)new BYTE[ clImageSize ];
if ( !pabRawBitmap )
{
MessageBox( "Can't allocate memory for the image" );
delete [] pabFileData;
return;
}
// Get the compressed image
long lDataPos = 0;
long lPos = 128; // That's where the data begins
for ( int iY=0; iY < BitmapSize.cy; iY++ )
{
// Decompress the scan line
for ( int iX=0; iX < sHeader.BPL; )
{
UINT uiValue = pabFileData[lPos++];
if ( uiValue > 192 ) { // Two high bits are set = Repeat
uiValue -= 192; // Repeat how many times?
BYTE Color = pabFileData[lPos++]; // What color?
if ( iX <= BitmapSize.cx )
{ // Image data. Place in the raw bitmap.
for ( BYTE bRepeat=0; bRepeat < uiValue; bRepeat++ )
{
pabRawBitmap[lDataPos++] = Color;
iX++;
}
}
else
iX += uiValue; // Outside the image. Skip.
}
else
{
if ( iX <= BitmapSize.cx )
pabRawBitmap[lDataPos++] = uiValue;
iX++;
}
}
// Pad the rest with zeros
if ( iX < iScanLineSize )
{
for ( ;iX < iScanLineSize; iX++ )
pabRawBitmap[lDataPos++] = 0;
}
}
if ( pabFileData[lPos++] == 12 ) // Simple validation
// Get the palette
for ( short Entry=0; Entry < 256; Entry++ )
{
psBmpInfo->bmiColors[Entry].rgbRed = pabFileData[lPos++];
psBmpInfo->bmiColors[Entry].rgbGreen = pabFileData[lPos++];
psBmpInfo->bmiColors[Entry].rgbBlue = pabFileData[lPos++];
psBmpInfo->bmiColors[Entry].rgbReserved = 0;
}
delete [] pabFileData;
// Resize/Repaint the window
const CSize BorderSize( GetSystemMetrics( SM_CXEDGE ) +
GetSystemMetrics( SM_CXFRAME ) - 1,
GetSystemMetrics( SM_CYEDGE ) +
GetSystemMetrics( SM_CYFRAME ) - 1 );
SetWindowPos( NULL, 0, 0, BitmapSize.cx + (BorderSize.cx*2),
BitmapSize.cy + (BorderSize.cy*2)+GetSystemMetrics(SM_CYCAPTION),
SWP_NOMOVE | SWP_NOZORDER );
}
BOOL CChildFrame::OnEraseBkgnd(CDC* pDC)
{
if ( pabRawBitmap && psBmpInfo )
// Display the image
SetDIBitsToDevice( *pDC, 0, 0,
BitmapSize.cx, BitmapSize.cy, 0, 0,
0, BitmapSize.cy,
pabRawBitmap, psBmpInfo, DIB_RGB_COLORS);
return CMDIChildWnd::OnEraseBkgnd(pDC);;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -