Created
March 31, 2018 19:42
-
-
Save JSandusky/c2276330cdd33c7a31430dcc65efb2f3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Urho3D/Resource/Image.h> | |
#include <vector> | |
#include <set> | |
#include <windows.h> | |
#include <shlobj.h> | |
#include <Urho3D/DebugNew.h> | |
std::set<std::string> os_ThumbnailTried; | |
std::vector<unsigned char> HBitmapToPixels(HBITMAP bitmapHandle, int& width, int& height) | |
{ | |
BITMAP bmp = { 0 }; | |
BITMAPINFO bmpInfo = { 0 }; | |
HDC dc = CreateCompatibleDC(NULL); | |
std::memset(&bmpInfo, 0, sizeof(BITMAPINFO)); //not necessary really.. | |
HBITMAP oldBitmap = (HBITMAP)SelectObject(dc, bitmapHandle); | |
GetObject(bitmapHandle, sizeof(BITMAP), &bmp); | |
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
bmpInfo.bmiHeader.biWidth = width = bmp.bmWidth; | |
bmpInfo.bmiHeader.biHeight = height = bmp.bmHeight; | |
bmpInfo.bmiHeader.biPlanes = 1; | |
bmpInfo.bmiHeader.biBitCount = 32; | |
bmpInfo.bmiHeader.biCompression = BI_RGB; | |
bmpInfo.bmiHeader.biSizeImage = ((width * bmp.bmBitsPixel + 31) / 32) * 4 * height; | |
std::vector<unsigned char> pixelData = std::vector<unsigned char>(); | |
pixelData.resize(bmpInfo.bmiHeader.biSizeImage); | |
GetDIBits(dc, bitmapHandle, 0, height, pixelData.data(), &bmpInfo, DIB_RGB_COLORS); | |
SelectObject(dc, oldBitmap); | |
height = std::abs(height); | |
DeleteDC(dc); | |
for (size_t i = 0; i < pixelData.size(); i += 4) | |
std::swap(pixelData[i], pixelData[i + 2]); | |
return pixelData; | |
} | |
std::wstring MultiByteToWideString(const std::string &str) | |
{ | |
if (str.empty()) return std::wstring(); | |
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); | |
std::wstring wstrTo(size_needed, 0); | |
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); | |
return wstrTo; | |
} | |
Urho3D::SharedPtr<Urho3D::Texture2D> CreateThumbnail(Urho3D::Context* ctx, const Urho3D::String& path, unsigned size) | |
{ | |
Urho3D::SharedPtr<Urho3D::Texture2D> ret; | |
// Check if this thumbnail has been attempted, if so then early ut | |
// issue: previews that invalidate with file changes | |
// issue: cache outside of here, not just in resource cache (GetResource is slow for constant calling) | |
// issue: do any recognition of 'singular' icon outside of here (ie. *.xml files all using the same icon) | |
if (os_ThumbnailTried.find(path.CString()) != os_ThumbnailTried.end()) | |
return ret; | |
os_ThumbnailTried.insert(path.CString()); | |
IShellItem *shellItem; | |
WCHAR wideStr[MAX_PATH]; | |
memset(wideStr, 0, sizeof(WCHAR) * MAX_PATH); | |
MultiByteToWideChar(CP_UTF8, MB_COMPOSITE, path.CString(), path.Length(), wideStr, MAX_PATH); | |
auto wStr = MultiByteToWideString(path.CString()); | |
HRESULT hr = SHCreateItemFromParsingName(wStr.c_str(), NULL, IID_PPV_ARGS(&shellItem)); | |
if (SUCCEEDED(hr)) | |
{ | |
IShellItemImageFactory* imageFactory; | |
hr = SHCreateItemFromParsingName(wStr.c_str(), NULL, IID_PPV_ARGS(&imageFactory)); | |
if (SUCCEEDED(hr)) | |
{ | |
SIZE iconSize = { size, size }; | |
HBITMAP thumbnail; | |
hr = imageFactory->GetImage(iconSize, SIIGBF_BIGGERSIZEOK, &thumbnail); | |
if (SUCCEEDED(hr)) | |
{ | |
int w = size, h = size; | |
auto pixelData = HBitmapToPixels(thumbnail, w, h); | |
if (w > 0 && h > 0) | |
{ | |
Urho3D::UniquePtr<Urho3D::Image> img(new Urho3D::Image(ctx)); | |
img->SetSize(w, h, 4); | |
memcpy(img->GetData(), pixelData.data(), pixelData.size()); | |
ret = new Urho3D::Texture2D(ctx); | |
ret->SetData(img.Get(), true); | |
} | |
DeleteObject(thumbnail); | |
} | |
imageFactory->Release(); | |
} | |
} | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Code snippet for loading windows thumbnails into an Urho3D texture/image.