📄 enbitmap.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "EnBitmap.h"
#include <atlimage.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const int HIMETRIC_INCH = 2540;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CEnBitmap::CEnBitmap()
{
}
CEnBitmap::~CEnBitmap()
{
}
BOOL CEnBitmap::LoadImage(UINT uIDRes, LPCTSTR pszResourceType, HMODULE hInst, COLORREF crBack)
{
return LoadImage(MAKEINTRESOURCE(uIDRes), pszResourceType, hInst, crBack);
}
BOOL CEnBitmap::LoadImage(LPCTSTR lpszResourceName, LPCTSTR szResourceType, HMODULE hInst, COLORREF crBack)
{
ASSERT(m_hObject == NULL); // only attach once, detach on destroy
if (m_hObject != NULL)
return FALSE;
BYTE* pBuff = NULL;
int nSize = 0;
BOOL bResult = FALSE;
// first call is to get buffer size
if (GetResource(lpszResourceName, szResourceType, hInst, 0, nSize))
{
if (nSize > 0)
{
pBuff = new BYTE[nSize];
// this loads it
if (GetResource(lpszResourceName, szResourceType, hInst, pBuff, nSize))
{
IPicture* pPicture = LoadFromBuffer(pBuff, nSize);
if (pPicture)
{
bResult = Attach(pPicture, crBack);
pPicture->Release();
}
}
delete [] pBuff;
}
}
return bResult;
}
BOOL CEnBitmap::LoadImage(LPCTSTR szImagePath, COLORREF crBack)
{
ASSERT(m_hObject == NULL); // only attach once, detach on destroy
if (m_hObject != NULL)
return FALSE;
// If GDI+ is available, use that API because it supports more file formats and images with alpha channels.
// That DLL is installed with WinXP is available as redistributable from Microsoft for Win98+. As this DLL
// may not be available on some OS but we have to link statically to it, we have to take some special care.
//
// NOTE: Do *NOT* forget to specify /DELAYLOAD:gdiplus.dll as link parameter.
static int _bGdiPlusInstalled = -1;
if (_bGdiPlusInstalled == -1)
{
_bGdiPlusInstalled = 0;
HMODULE hLib = LoadLibrary(_T("gdiplus.dll"));
if (hLib != NULL)
{
_bGdiPlusInstalled = GetProcAddress(hLib, "GdiplusStartup") != NULL;
FreeLibrary(hLib);
}
}
if (_bGdiPlusInstalled > 0)
{
CImage img;
if (SUCCEEDED(img.Load(szImagePath)))
{
CBitmap::Attach(img.Detach());
return TRUE;
}
}
BOOL bResult = FALSE;
CFile cFile;
CFileException e;
if (cFile.Open(szImagePath, CFile::modeRead | CFile::typeBinary | CFile::shareDenyWrite, &e))
{
int nSize = cFile.GetLength();
BYTE* pBuff = new BYTE[nSize];
if (cFile.Read(pBuff, nSize) > 0)
{
IPicture* pPicture = LoadFromBuffer(pBuff, nSize);
if (pPicture)
{
bResult = Attach(pPicture, crBack);
pPicture->Release();
}
}
delete [] pBuff;
}
return bResult;
}
IPicture* CEnBitmap::LoadFromBuffer(BYTE* pBuff, int nSize)
{
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nSize);
void* pData = GlobalLock(hGlobal);
memcpy(pData, pBuff, nSize);
GlobalUnlock(hGlobal);
IStream* pStream = NULL;
IPicture* pPicture = NULL;
if (CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) == S_OK)
{
OleLoadPicture(pStream, nSize, FALSE, IID_IPicture, (LPVOID *)&pPicture);
pStream->Release();
}
return pPicture; // caller releases
}
BOOL CEnBitmap::GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void* pResource, int& nBufSize)
{
HRSRC hResInfo;
HANDLE hRes;
LPSTR lpRes = NULL;
bool bResult = FALSE;
// Find the resource
hResInfo = FindResource(hInst, lpName, lpType);
if (hResInfo == NULL)
return false;
// Load the resource
hRes = LoadResource(hInst, hResInfo);
if (hRes == NULL)
return false;
// Lock the resource
lpRes = (char*)LockResource(hRes);
if (lpRes != NULL)
{
if (pResource == NULL)
{
nBufSize = SizeofResource(hInst, hResInfo);
bResult = true;
}
else
{
if (nBufSize >= (int)SizeofResource(hInst, hResInfo))
{
memcpy(pResource, lpRes, nBufSize);
bResult = true;
}
}
UnlockResource(hRes);
}
// Free the resource
FreeResource(hRes);
return bResult;
}
BOOL CEnBitmap::Attach(IPicture* pPicture, COLORREF crBack)
{
ASSERT(m_hObject == NULL); // only attach once, detach on destroy
if (m_hObject != NULL)
return FALSE;
ASSERT(pPicture);
if (!pPicture)
return FALSE;
BOOL bResult = FALSE;
CDC dcMem;
CDC* pDC = CWnd::GetDesktopWindow()->GetDC();
if (dcMem.CreateCompatibleDC(pDC))
{
long hmWidth;
long hmHeight;
pPicture->get_Width(&hmWidth);
pPicture->get_Height(&hmHeight);
int nWidth = MulDiv(hmWidth, pDC->GetDeviceCaps(LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, pDC->GetDeviceCaps(LOGPIXELSY), HIMETRIC_INCH);
CBitmap bmMem;
if (bmMem.CreateCompatibleBitmap(pDC, nWidth, nHeight))
{
CBitmap* pOldBM = dcMem.SelectObject(&bmMem);
if (crBack != -1)
dcMem.FillSolidRect(0, 0, nWidth, nHeight, crBack);
HRESULT hr = pPicture->Render(dcMem, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, NULL);
dcMem.SelectObject(pOldBM);
if (hr == S_OK)
bResult = CBitmap::Attach(bmMem.Detach());
}
}
CWnd::GetDesktopWindow()->ReleaseDC(pDC);
return bResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -