diff -r 1bd5534c395d -r 391c2c723029 ui/winui/icons.cpp --- a/ui/winui/icons.cpp Fri Oct 13 15:20:54 2023 +0200 +++ b/ui/winui/icons.cpp Fri Oct 13 19:53:21 2023 +0200 @@ -35,13 +35,24 @@ #include "util.h" +#include +#include + + using namespace winrt; using namespace Microsoft::UI::Xaml; using namespace Microsoft::UI::Xaml::Controls; using namespace Windows::UI::Xaml::Interop; using namespace winrt::Windows::Foundation; using namespace winrt::Microsoft::UI::Xaml::Controls::Primitives; +using namespace winrt::Microsoft::UI::Xaml::Media::Imaging; +//using namespace Windows::Storage::Streams; +static UiIcon* sys_folder_icon16; +static UiIcon* sys_file_icon16; + +static UiIcon* sys_folder_icon32; +static UiIcon* sys_file_icon32; std::unordered_map ui_symbol_icons = { {"Accept", Symbol::Accept }, @@ -283,6 +294,23 @@ winrt::Microsoft::UI::Xaml::Controls::IconElement UiImageIcon::getIcon() { BitmapIcon icon = BitmapIcon(); icon.UriSource(uri); + ImageIcon img = ImageIcon(); + img.Source(); + return icon; +} + +// bitmap icon implementation +UiBitmapIcon::UiBitmapIcon(winrt::Microsoft::UI::Xaml::Media::Imaging::BitmapSource bitmap) { + this->bitmap = bitmap; +} + +UiBitmapIcon::~UiBitmapIcon() { + +} + +winrt::Microsoft::UI::Xaml::Controls::IconElement UiBitmapIcon::getIcon() { + ImageIcon icon = ImageIcon(); + icon.Source(bitmap); return icon; } @@ -300,3 +328,87 @@ UIEXPORT void ui_icon_free(UiIcon* icon) { delete icon; } + + +struct __declspec(uuid("905a0fef-bc53-11df-8c49-001e4fc686da")) IBufferByteAccess : ::IUnknown +{ + virtual HRESULT __stdcall Buffer(uint8_t** value) = 0; +}; + + + +winrt::Microsoft::UI::Xaml::Media::Imaging::WriteableBitmap ui_dllicon2bitmap(const char* dll, int iconindex, bool large) { + WriteableBitmap wbitmap = { nullptr }; + + // get the icon from the dll + HICON hicon_small; + HICON hicon_large; + if (ExtractIconExA(dll, iconindex, &hicon_large, &hicon_small, 1) > 0) { + HICON hicon = large ? hicon_large : hicon_small; + + // convert icon to (gdi) bitmap + ICONINFO info; + if (GetIconInfo(hicon, &info)) { + BITMAP bitmap; + if (GetObjectW(info.hbmColor, sizeof(BITMAP), &bitmap) != 0) { + size_t bitmap_size = bitmap.bmWidthBytes * bitmap.bmHeight; + char *bitmap_data = (char*)malloc(bitmap_size); + + // get the pixel data + if (GetBitmapBits(info.hbmColor, bitmap_size, bitmap_data) != 0) { + WriteableBitmap wb = WriteableBitmap(bitmap.bmWidth, bitmap.bmHeight); + void *wb_data = wb.PixelBuffer().data(); + memcpy(wb_data, bitmap_data, bitmap_size); + wbitmap = wb; + } + DeleteObject(info.hbmColor); + free(bitmap_data); + } + } + DeleteObject(info.hbmMask); + + DestroyIcon(hicon_small); + DestroyIcon(hicon_large); + } + + return wbitmap; +} + +UiIcon* ui_dllicon(const char* dll, int iconindex, bool large) { + WriteableBitmap wbitmap = ui_dllicon2bitmap(dll, iconindex, large); + return new UiBitmapIcon(wbitmap); +} + +UIEXPORT UiIcon* ui_foldericon(size_t size) { + bool large = true; + UiIcon** sys_folder_icon = &sys_folder_icon32; + if (size <= 24) { + large = false; + sys_folder_icon = &sys_folder_icon16; + } + + if (*sys_folder_icon) { + return *sys_folder_icon; + } + + UiIcon* icon = ui_dllicon("shell32.dll", 3, large); + *sys_folder_icon = icon; + return icon; +} + +UIEXPORT UiIcon* ui_fileicon(size_t size) { + bool large = true; + UiIcon** sys_folder_icon = &sys_folder_icon32; + if (size <= 24) { + large = false; + sys_folder_icon = &sys_folder_icon16; + } + + if (*sys_folder_icon) { + return *sys_folder_icon; + } + + UiIcon* icon = ui_dllicon("shell32.dll", 0, large); + *sys_folder_icon = icon; + return icon; +}