#pragma once #include #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 resource = LoadResourceEx(core_api::get_my_instance(),MAKEINTRESOURCE(id),resType); if (resource.is_empty()) throw pfc::exception_bug_check(); pfc::com_ptr_t stream; stream.attach( SHCreateMemStream((const BYTE*)resource->GetPointer(), resource->GetSize()) ); if ( stream.is_empty() ) throw std::bad_alloc(); GdiplusErrorHandler EH; pfc::ptrholder_t source = new Image(stream.get_ptr()); EH << source->GetLastStatus(); pfc::ptrholder_t resized = new Bitmap(size.cx, size.cy, PixelFormat32bppARGB); EH << resized->GetLastStatus(); { pfc::ptrholder_t 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 resource = LoadResourceEx(core_api::get_my_instance(),MAKEINTRESOURCE(id),resType); if (resource.is_empty()) throw pfc::exception_bug_check(); pfc::com_ptr_t stream; stream.attach( SHCreateMemStream((const BYTE*)resource->GetPointer(), resource->GetSize()) ); if (stream.is_empty()) throw std::bad_alloc(); GdiplusErrorHandler EH; pfc::ptrholder_t source = new Image(stream.get_ptr()); EH << source->GetLastStatus(); pfc::ptrholder_t resized = new Bitmap(size.cx, size.cy, PixelFormat32bppARGB); EH << resized->GetLastStatus(); { pfc::ptrholder_t 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(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")