120 lines
3.5 KiB
C++
120 lines
3.5 KiB
C++
#pragma once
|
|
#include <GdiPlus.h>
|
|
|
|
#include "win32_op.h"
|
|
|
|
class GdiplusErrorHandler {
|
|
public:
|
|
void operator<<(Gdiplus::Status p_code) {
|
|
if (p_code != Gdiplus::Ok) {
|
|
throw pfc::exception(pfc::string_formatter() << "Gdiplus error (" << (unsigned) p_code << ")");
|
|
}
|
|
}
|
|
};
|
|
|
|
class GdiplusScope {
|
|
public:
|
|
GdiplusScope() {
|
|
Gdiplus::GdiplusStartupInput input;
|
|
Gdiplus::GdiplusStartupOutput output;
|
|
GdiplusErrorHandler() << Gdiplus::GdiplusStartup(&m_token,&input,&output);
|
|
}
|
|
~GdiplusScope() {
|
|
Gdiplus::GdiplusShutdown(m_token);
|
|
}
|
|
|
|
PFC_CLASS_NOT_COPYABLE_EX(GdiplusScope);
|
|
private:
|
|
ULONG_PTR m_token;
|
|
};
|
|
|
|
static HBITMAP GdiplusLoadBitmap(UINT id, const TCHAR * resType, CSize size) {
|
|
using namespace Gdiplus;
|
|
try {
|
|
|
|
|
|
pfc::ptrholder_t<uResource> resource = LoadResourceEx(core_api::get_my_instance(),MAKEINTRESOURCE(id),resType);
|
|
if (resource.is_empty()) throw pfc::exception_bug_check();
|
|
|
|
pfc::com_ptr_t<IStream> stream; stream.attach( SHCreateMemStream((const BYTE*)resource->GetPointer(), resource->GetSize()) );
|
|
if ( stream.is_empty() ) throw std::bad_alloc();
|
|
|
|
GdiplusErrorHandler EH;
|
|
pfc::ptrholder_t<Image> source = new Image(stream.get_ptr());
|
|
|
|
EH << source->GetLastStatus();
|
|
pfc::ptrholder_t<Bitmap> resized = new Bitmap(size.cx, size.cy, PixelFormat32bppARGB);
|
|
EH << resized->GetLastStatus();
|
|
|
|
{
|
|
pfc::ptrholder_t<Graphics> target = new Graphics(resized.get_ptr());
|
|
EH << target->GetLastStatus();
|
|
EH << target->SetInterpolationMode(InterpolationModeHighQuality);
|
|
EH << target->Clear(Color(0,0,0,0));
|
|
EH << target->DrawImage(source.get_ptr(), Rect(0,0,size.cx,size.cy));
|
|
}
|
|
|
|
HBITMAP bmp = NULL;
|
|
EH << resized->GetHBITMAP(Gdiplus::Color::White, & bmp );
|
|
return bmp;
|
|
} catch(...) {
|
|
PFC_ASSERT( !"Should not get here");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
static HICON GdiplusLoadIcon(UINT id, const TCHAR * resType, CSize size) {
|
|
using namespace Gdiplus;
|
|
try {
|
|
|
|
|
|
pfc::ptrholder_t<uResource> resource = LoadResourceEx(core_api::get_my_instance(),MAKEINTRESOURCE(id),resType);
|
|
if (resource.is_empty()) throw pfc::exception_bug_check();
|
|
|
|
pfc::com_ptr_t<IStream> stream; stream.attach( SHCreateMemStream((const BYTE*)resource->GetPointer(), resource->GetSize()) );
|
|
if (stream.is_empty()) throw std::bad_alloc();
|
|
|
|
GdiplusErrorHandler EH;
|
|
pfc::ptrholder_t<Image> source = new Image(stream.get_ptr());
|
|
|
|
EH << source->GetLastStatus();
|
|
pfc::ptrholder_t<Bitmap> resized = new Bitmap(size.cx, size.cy, PixelFormat32bppARGB);
|
|
EH << resized->GetLastStatus();
|
|
|
|
{
|
|
pfc::ptrholder_t<Graphics> target = new Graphics(resized.get_ptr());
|
|
EH << target->GetLastStatus();
|
|
EH << target->SetInterpolationMode(InterpolationModeHighQuality);
|
|
EH << target->Clear(Color(0,0,0,0));
|
|
EH << target->DrawImage(source.get_ptr(), Rect(0,0,size.cx,size.cy));
|
|
}
|
|
|
|
HICON icon = NULL;
|
|
EH << resized->GetHICON(&icon);
|
|
return icon;
|
|
} catch(...) {
|
|
PFC_ASSERT( !"Should not get here");
|
|
return NULL;
|
|
}
|
|
}
|
|
static HICON GdiplusLoadPNGIcon(UINT id, CSize size) {return GdiplusLoadIcon(id, _T("PNG"), size);}
|
|
|
|
static HICON LoadPNGIcon(UINT id, CSize size) {
|
|
GdiplusScope scope;
|
|
return GdiplusLoadPNGIcon(id, size);
|
|
}
|
|
|
|
static void GdiplusLoadButtonPNG(CIcon & icon, HWND btn_, UINT image) {
|
|
CButton btn(btn_);
|
|
if (icon == NULL) {
|
|
CRect client; WIN32_OP_D( btn.GetClientRect(client) );
|
|
CSize size = client.Size();
|
|
int v = MulDiv(pfc::min_t<int>(size.cx, size.cy), 3, 4);
|
|
if (v < 8) v = 8;
|
|
icon = GdiplusLoadPNGIcon(image, CSize(v,v));
|
|
}
|
|
btn.SetIcon(icon);
|
|
}
|
|
|
|
#pragma comment(lib, "gdiplus.lib")
|