📄 picture.cpp
字号:
//////////////////////////////////////////////////////////////////////
// Picture.cpp: implementation of the CPicture class.
// Lounge Stdio 2003
// 作者:边城浪子(QQ:16168666)
// E-mail: krh2001.lpfdiyvbb@163.com
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Picture.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPicture::CPicture()
:m_pPic(NULL), _h_him(0), _w_him(0), m_size(0,0)
{
}
CPicture::~CPicture()
{
Release();
}
void CPicture::Release()
{
if(m_pPic != NULL)
{
m_pPic->Release();
m_pPic = NULL;
_h_him = _w_him = 0;
m_size.cx = m_size.cy = 0;
}
}
BOOL CPicture::LoadPicture(LPCTSTR lpszResource, LPCTSTR lpszResType)
{
Release();
HINSTANCE hInst = AfxFindResourceHandle(lpszResource, lpszResType);
HRSRC hRsrc = ::FindResource(hInst, lpszResource, lpszResType);
if(hRsrc == NULL) return FALSE;
HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
if(hGlobal == NULL) return FALSE;
DWORD dwSize = SizeofResource(hInst, hRsrc);
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize);
if(hMem == NULL) return FALSE;
LPVOID pSrc = ::LockResource(hGlobal);
if(pSrc == NULL) {
::GlobalFree(hMem);
return FALSE;
}
LPVOID pDes = ::GlobalLock(hMem);
if(pDes == NULL){
//::GlobalUnlock(hGlobal);
::GlobalFree(hMem);
return FALSE;
}
memcpy(pDes, pSrc, dwSize);
//GlobalUnlock(hGlobal);
GlobalUnlock(hMem);
::FreeResource(hGlobal);
IStream* pStm = NULL;
CreateStreamOnHGlobal(hMem, TRUE, &pStm);
if(!SUCCEEDED(OleLoadPicture(pStm,dwSize,TRUE,IID_IPicture,(LPVOID*)&m_pPic)))
{
pStm -> Release();
::GlobalFree(hMem);
pStm = NULL;
return FALSE;
}
pStm->Release();
::GlobalFree(hMem);
CalcSize();
return TRUE;
}
BOOL CPicture::LoadPictureFromFile(LPCTSTR lpszFileName)
{
Release();
CFile file;
if(!file.Open(lpszFileName, CFile::modeRead))
return FALSE;
DWORD dwSize = file.GetLength();
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize);
if(hMem == NULL) return FALSE;
LPVOID pDes = ::GlobalLock(hMem);
if(pDes == NULL){
::GlobalFree(hMem);
return FALSE;
}
file.ReadHuge(pDes, dwSize);
file.Close();
GlobalUnlock(hMem);
IStream* pStm = NULL;
CreateStreamOnHGlobal(hMem, TRUE, &pStm);
if(!SUCCEEDED(OleLoadPicture(pStm,dwSize,TRUE,IID_IPicture,(LPVOID*)&m_pPic)))
{
pStm -> Release();
::GlobalFree(hMem);
pStm = NULL;
return FALSE;
}
pStm->Release();
::GlobalFree(hMem);
CalcSize();
return TRUE;
}
void CPicture::CalcSize()
{
if(m_pPic == NULL) return;
m_pPic->get_Width(&_w_him);
m_pPic->get_Height(&_h_him);
CDC* pDC = CWnd::GetDesktopWindow()->GetDC();
m_size.cx = _w_him;
m_size.cy = _h_him;
pDC->HIMETRICtoDP(&m_size);
CWnd::GetDesktopWindow()->ReleaseDC(pDC);
}
void CPicture::Draw(CDC* pDC, LPCRECT lprcDest, LPCRECT lprcSrc)
{
if(m_pPic)
{
CSize szOrig(lprcSrc->left, lprcSrc->top);
CSize szSrc(lprcSrc->right - lprcSrc->left, lprcSrc->bottom - lprcSrc->top);
pDC->DPtoHIMETRIC(&szOrig);
pDC->DPtoHIMETRIC(&szSrc);
m_pPic->Render(*pDC, lprcDest->left,lprcDest->top,lprcDest->right-lprcDest->left,
lprcDest->bottom-lprcDest->top, szOrig.cx, _h_him-szOrig.cy, szSrc.cx,
-szSrc.cy, NULL);
}
}
void CPicture::Draw(CDC* pDC, int xDest,int yDest, int cxDest, int cyDest ,
int xSrc ,int ySrc ,int cxSrc ,int cySrc)
{
Draw(pDC, CRect(xDest, yDest, xDest+cxDest, yDest+cyDest), CRect(xSrc, ySrc, xSrc+cxSrc, ySrc+cySrc));
}
BOOL CPicture::SaveAsBitmap(CString sFilePathName)
{
BOOL bResult = FALSE;
ILockBytes *Buffer = 0;
IStorage *pStorage = 0;
IStream *FileStream = 0;
BYTE *BufferBytes;
STATSTG BytesStatistics;
DWORD OutData;
long OutStream;
CFile BitmapFile; CFileException e;
double SkipFloat = 0;
DWORD ByteSkip = 0;
_ULARGE_INTEGER RealData;
CreateILockBytesOnHGlobal(NULL, TRUE, &Buffer); // Create ILockBytes Buffer
HRESULT hr = ::StgCreateDocfileOnILockBytes(Buffer,
STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage);
hr = pStorage->CreateStream(L"PICTURE",
STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, 0, &FileStream);
m_pPic->SaveAsFile(FileStream, TRUE, &OutStream); // Copy Data Stream
FileStream->Release();
pStorage->Release();
Buffer->Flush();
// Get Statistics For Final Size Of Byte Array
Buffer->Stat(&BytesStatistics, STATFLAG_NONAME);
// Cut UnNeeded Data Coming From SaveAsFile() (Leave Only "Pure" Picture Data)
SkipFloat = (double(OutStream) / 512); // Must Be In a 512 Blocks...
if(SkipFloat > DWORD(SkipFloat)) ByteSkip = (DWORD)SkipFloat + 1;
else ByteSkip = (DWORD)SkipFloat;
ByteSkip = ByteSkip * 512; // Must Be In a 512 Blocks...
// Find Difference Between The Two Values
ByteSkip = (DWORD)(BytesStatistics.cbSize.QuadPart - ByteSkip);
// Allocate Only The "Pure" Picture Data
RealData.LowPart = 0;
RealData.HighPart = 0;
RealData.QuadPart = ByteSkip;
BufferBytes = (BYTE*)malloc(OutStream);
if(BufferBytes == NULL)
{
Buffer->Release();
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, "Can not allocate enough memory\t", "Error", MB_OK | MB_ICONSTOP, LANG_ENGLISH);
}
Buffer->ReadAt(RealData, BufferBytes, OutStream, &OutData);
if(BitmapFile.Open(sFilePathName, CFile::typeBinary | CFile::modeCreate | CFile::modeWrite, &e))
{
BitmapFile.Write(BufferBytes, OutData);
BitmapFile.Close();
bResult = TRUE;
}
else // Write File Failed...
{
TCHAR szCause[255];
e.GetErrorMessage(szCause, 255, NULL);
HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
MessageBoxEx(hWnd, szCause, "error", MB_OK | MB_ICONSTOP, LANG_ENGLISH);
bResult = FALSE;
}
Buffer->Release();
free(BufferBytes);
return(bResult);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -