增加从资源加载图片的功能;修复可以手动修改窗口大小的Bug;

This commit is contained in:
Nomango 2018-04-27 00:16:14 +08:00
parent fca3ba9f25
commit 264a85b80e
8 changed files with 294 additions and 34 deletions

View File

@ -45,7 +45,7 @@ bool e2d::Window::__init()
nHeight = min(nHeight, screenHeight);
// 计算窗口大小
DWORD dwStyle = WS_OVERLAPPEDWINDOW &~ WS_MAXIMIZEBOX;
DWORD dwStyle = WS_OVERLAPPEDWINDOW &~ WS_MAXIMIZEBOX &~ WS_THICKFRAME;
RECT wr = { 0, 0, static_cast<LONG>(nWidth), static_cast<LONG>(nHeight) };
::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL);
// 获取新的宽高
@ -188,11 +188,10 @@ void e2d::Window::setTitle(String title)
::SetWindowText(s_HWnd, title);
}
void e2d::Window::setIcon(LPCTSTR pIconID)
void e2d::Window::setIcon(int pIconID)
{
HINSTANCE hInstance = ::GetModuleHandle(NULL);
HICON hIcon = (HICON)::LoadImage(hInstance, pIconID, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
HICON hIcon = (HICON)::LoadImage(hInstance, MAKEINTRESOURCE(pIconID), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
// 设置窗口的图标
::SendMessage(s_HWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
::SendMessage(s_HWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);

View File

@ -2,6 +2,7 @@
#include <map>
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
static std::map<int, ID2D1Bitmap*> s_mBitmapsFromResource;
e2d::Image::Image()
@ -14,37 +15,68 @@ e2d::Image::Image()
}
e2d::Image::Image(String strFileName)
: m_pBitmap(nullptr)
{
this->open(strFileName);
}
e2d::Image::Image(int resNameId, String resType)
: m_pBitmap(nullptr)
{
this->open(resNameId, resType);
}
e2d::Image::Image(String strFileName, double nCropX, double nCropY, double nCropWidth, double nCropHeight)
: m_pBitmap(nullptr)
{
this->open(strFileName);
this->crop(nCropX, nCropY, nCropWidth, nCropHeight);
}
e2d::Image::Image(int resNameId, String resType, double nCropX, double nCropY, double nCropWidth, double nCropHeight)
: m_pBitmap(nullptr)
{
this->open(resNameId, resType);
this->crop(nCropX, nCropY, nCropWidth, nCropHeight);
}
e2d::Image::~Image()
{
}
void e2d::Image::open(String strFilePath)
bool e2d::Image::open(String strFilePath)
{
WARN_IF(strFilePath.isEmpty(), "Image cannot load bitmap from NULL file name.");
if (strFilePath.isEmpty())
return;
return false;
if (!Image::preload(strFilePath))
{
WARN_IF(true, "Load Image from file failed!");
return;
return false;
}
m_pBitmap = s_mBitmapsFromFile.at(strFilePath.getHashCode());
m_fSourceCropX = m_fSourceCropY = 0;
m_fSourceCropWidth = m_pBitmap->GetSize().width;
m_fSourceCropHeight = m_pBitmap->GetSize().height;
return true;
}
bool e2d::Image::open(int resNameId, String resType)
{
if (!Image::preload(resNameId, resType))
{
WARN_IF(true, "Load Image from file failed!");
return false;
}
m_pBitmap = s_mBitmapsFromResource.at(resNameId);
m_fSourceCropX = m_fSourceCropY = 0;
m_fSourceCropWidth = m_pBitmap->GetSize().width;
m_fSourceCropHeight = m_pBitmap->GetSize().height;
return true;
}
void e2d::Image::crop(double x, double y, double width, double height)
@ -200,13 +232,146 @@ bool e2d::Image::preload(String fileName)
return SUCCEEDED(hr);
}
bool e2d::Image::preload(int resNameId, String resType)
{
if (s_mBitmapsFromResource.find(resNameId) != s_mBitmapsFromResource.end())
{
return true;
}
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
IWICBitmapScaler *pScaler = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
HRSRC imageResHandle = nullptr;
HGLOBAL imageResDataHandle = nullptr;
void *pImageFile = nullptr;
DWORD imageFileSize = 0;
// 定位资源
imageResHandle = ::FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), resType);
hr = imageResHandle ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// 加载资源
imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageResDataHandle ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 获取文件指针,并锁定资源
pImageFile = ::LockResource(imageResDataHandle);
hr = pImageFile ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 计算大小
imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageFileSize ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// 创建 WIC 流
hr = Renderer::getIWICImagingFactory()->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
// 初始化流
hr = pStream->InitializeFromMemory(
reinterpret_cast<BYTE*>(pImageFile),
imageFileSize
);
}
if (SUCCEEDED(hr))
{
// 创建流的解码器
hr = Renderer::getIWICImagingFactory()->CreateDecoderFromStream(
pStream,
NULL,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
if (SUCCEEDED(hr))
{
// 创建初始化框架
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// 创建图片格式转换器
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = Renderer::getIWICImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// 图片格式转换成 32bppPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// 从 WIC 位图创建一个 Direct2D 位图
hr = Renderer::getRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
s_mBitmapsFromResource.insert(std::pair<int, ID2D1Bitmap*>(resNameId, pBitmap));
}
// 释放相关资源
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
SafeReleaseInterface(&pScaler);
return SUCCEEDED(hr);
}
void e2d::Image::clearCache()
{
for (auto child = s_mBitmapsFromFile.begin(); child != s_mBitmapsFromFile.end(); child++)
for (auto bitmap : s_mBitmapsFromFile)
{
SafeReleaseInterface(&(*child).second);
SafeReleaseInterface(&bitmap.second);
}
s_mBitmapsFromFile.clear();
for (auto bitmap : s_mBitmapsFromResource)
{
SafeReleaseInterface(&bitmap.second);
}
s_mBitmapsFromResource.clear();
}
ID2D1Bitmap * e2d::Image::getBitmap()

View File

@ -12,16 +12,29 @@ e2d::Sprite::Sprite(Image * image)
open(image);
}
e2d::Sprite::Sprite(String imageFileName)
e2d::Sprite::Sprite(String strFilePath)
: m_pImage(nullptr)
{
open(imageFileName);
open(strFilePath);
}
e2d::Sprite::Sprite(String imageFileName, double x, double y, double width, double height)
e2d::Sprite::Sprite(int resNameId, String resType)
: m_pImage(nullptr)
{
open(imageFileName);
open(resNameId, resType);
}
e2d::Sprite::Sprite(String strFilePath, double x, double y, double width, double height)
: m_pImage(nullptr)
{
open(strFilePath);
crop(x, y, width, height);
}
e2d::Sprite::Sprite(int resNameId, String resType, double x, double y, double width, double height)
: m_pImage(nullptr)
{
open(resNameId, resType);
crop(x, y, width, height);
}
@ -29,7 +42,7 @@ e2d::Sprite::~Sprite()
{
}
void e2d::Sprite::open(Image * image)
bool e2d::Sprite::open(Image * image)
{
if (image)
{
@ -38,12 +51,41 @@ void e2d::Sprite::open(Image * image)
m_pImage->retain();
Node::setSize(m_pImage->getWidth(), m_pImage->getHeight());
return true;
}
return false;
}
void e2d::Sprite::open(String imageFileName)
bool e2d::Sprite::open(String strFilePath)
{
open(new Image(imageFileName));
if (!m_pImage)
{
m_pImage = new (std::nothrow) Image();
m_pImage->retain();
}
if (m_pImage->open(strFilePath))
{
Node::setSize(m_pImage->getWidth(), m_pImage->getHeight());
return true;
}
return false;
}
bool e2d::Sprite::open(int resNameId, String resType)
{
if (!m_pImage)
{
m_pImage = new (std::nothrow) Image();
m_pImage->retain();
}
if (m_pImage->open(resNameId, resType))
{
Node::setSize(m_pImage->getWidth(), m_pImage->getHeight());
return true;
}
return false;
}
void e2d::Sprite::crop(double x, double y, double width, double height)

View File

@ -67,7 +67,7 @@ public:
// ÉèÖô°¿Úͼ±ê
static void setIcon(
LPCTSTR pIconID
int pIconID
);
// »ñÈ¡´°¿Ú±êÌâ

View File

@ -583,15 +583,21 @@ class Image :
public Object
{
public:
// 创建一个空的图片
// 创建一个空的图片对象
Image();
// 从本地文件中读取资源
// 加载图片文件
Image(
String strFilePath /* 图片文件路径 */
);
// 从本地文件中读取资源
// 加载图片资源
Image(
int resNameId, /* 图片资源名称 */
String resType /* 图片资源类型 */
);
// 加载图片文件并裁剪
Image(
String strFilePath, /* 图片文件路径 */
double nCropX, /* 裁剪位置 X 坐标 */
@ -600,13 +606,29 @@ public:
double nCropHeight /* 裁剪高度 */
);
// 加载图片资源并裁剪
Image(
int resNameId, /* 图片资源名称 */
String resType, /* 图片资源类型 */
double nCropX, /* 裁剪位置 X 坐标 */
double nCropY, /* 裁剪位置 Y 坐标 */
double nCropWidth, /* 裁剪宽度 */
double nCropHeight /* 裁剪高度 */
);
virtual ~Image();
// 从本地文件中读取图片
void open(
// 加载图片文件
bool open(
String strFilePath
);
// 加载图片资源
bool open(
int resNameId, /* 图片资源名称 */
String resType /* 图片资源类型 */
);
// 将图片裁剪为矩形
void crop(
double nCropX, /* 裁剪位置 X 坐标 */
@ -645,11 +667,17 @@ public:
// 获取 ID2D1Bitmap 对象
ID2D1Bitmap * getBitmap();
// 预加载资源
// 预加载图片文件
static bool preload(
String strFileName /* 图片文件路径 */
);
// 预加载图片资源
static bool preload(
int resNameId, /* 图片资源名称 */
String resType /* 图片资源类型 */
);
// 清空缓存
static void clearCache();

View File

@ -487,19 +487,35 @@ public:
// 创建一个空精灵
Sprite();
// 从 EImage 对象创建精灵
// 从 Image 对象创建精灵
Sprite(
Image * image
);
// 从文件图片创建精灵
// 加载图片文件
Sprite(
String imageFileName
String strFilePath /* 图片文件路径 */
);
// 创建精灵并裁剪图片
// 加载图片资源
Sprite(
String imageFileName,
int resNameId, /* 图片资源名称 */
String resType /* 图片资源类型 */
);
// 加载图片文件
Sprite(
String strFilePath, /* 图片文件路径 */
double x,
double y,
double width,
double height
);
// 加载图片资源
Sprite(
int resNameId, /* 图片资源名称 */
String resType, /* 图片资源类型 */
double x,
double y,
double width,
@ -508,25 +524,31 @@ public:
virtual ~Sprite();
// 从本地文件加载图片
virtual void open(
String imageFileName
// 加载图片文件
bool open(
String strFilePath
);
// 加载图片资源
bool open(
int resNameId, /* 图片资源名称 */
String resType /* 图片资源类型 */
);
// 加载图片
virtual void open(
bool open(
Image * image
);
// 将图片裁剪为矩形
virtual void crop(
void crop(
double x,
double y,
double width,
double height
);
// 获取 EImage 对象
// 获取 Image 对象
virtual Image * getImage() const;
// 渲染精灵

View File

@ -208,6 +208,7 @@
<SDLCheck>false</SDLCheck>
<DebugInformationFormat>None</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -229,6 +230,7 @@
<SDLCheck>false</SDLCheck>
<DebugInformationFormat>None</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

View File

@ -131,6 +131,7 @@
<SDLCheck>false</SDLCheck>
<DebugInformationFormat>None</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -152,6 +153,7 @@
<SDLCheck>false</SDLCheck>
<DebugInformationFormat>None</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>