# HG changeset patch # User Olaf Wintermann # Date 1697219601 -7200 # Node ID 391c2c7230299fd95a871a411861755364827740 # Parent 1bd5534c395da647e3824ba917d5073dd686edc7 add dll icon loader diff -r 1bd5534c395d -r 391c2c723029 make/vs/testapp/main.c --- a/make/vs/testapp/main.c Fri Oct 13 15:20:54 2023 +0200 +++ b/make/vs/testapp/main.c Fri Oct 13 19:53:21 2023 +0200 @@ -163,7 +163,8 @@ ui_list_append(wdata->list3, "test"); ui_list_append(wdata->list3, "dir"); - folder_icon = ui_icon("Folder", 32); + //folder_icon = ui_icon("Folder", 32); + folder_icon = ui_foldericon(16); TableData* td1 = malloc(sizeof(TableData)); TableData* td2 = malloc(sizeof(TableData)); diff -r 1bd5534c395d -r 391c2c723029 ui/ui/toolkit.h --- a/ui/ui/toolkit.h Fri Oct 13 15:20:54 2023 +0200 +++ b/ui/ui/toolkit.h Fri Oct 13 19:53:21 2023 +0200 @@ -440,6 +440,8 @@ UIEXPORT UiIcon* ui_imageicon(const char* file); UIEXPORT void ui_icon_free(UiIcon* icon); +UIEXPORT UiIcon* ui_foldericon(size_t size); +UIEXPORT UiIcon* ui_fileicon(size_t size); #ifdef __cplusplus } 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; +} diff -r 1bd5534c395d -r 391c2c723029 ui/winui/icons.h --- a/ui/winui/icons.h Fri Oct 13 15:20:54 2023 +0200 +++ b/ui/winui/icons.h Fri Oct 13 19:53:21 2023 +0200 @@ -58,5 +58,19 @@ winrt::Microsoft::UI::Xaml::Controls::IconElement getIcon(); }; +struct UiBitmapIcon : UiIcon { + winrt::Microsoft::UI::Xaml::Media::Imaging::BitmapSource bitmap{ nullptr }; + + UiBitmapIcon(winrt::Microsoft::UI::Xaml::Media::Imaging::BitmapSource bitmap); + + ~UiBitmapIcon(); + + winrt::Microsoft::UI::Xaml::Controls::IconElement getIcon(); +}; + winrt::Microsoft::UI::Xaml::Controls::IconElement ui_get_icon(const char* name); + +winrt::Microsoft::UI::Xaml::Media::Imaging::WriteableBitmap ui_dllicon2bitmap(const char* dll, int iconindex, bool large); + +UiIcon* ui_dllicon(const char* dll, int iconindex, bool large); diff -r 1bd5534c395d -r 391c2c723029 ui/winui/pch.h --- a/ui/winui/pch.h Fri Oct 13 15:20:54 2023 +0200 +++ b/ui/winui/pch.h Fri Oct 13 19:53:21 2023 +0200 @@ -22,8 +22,11 @@ #include #include #include +#include #include #include #include #include #include + +#include diff -r 1bd5534c395d -r 391c2c723029 ui/winui/table.cpp --- a/ui/winui/table.cpp Fri Oct 13 15:20:54 2023 +0200 +++ b/ui/winui/table.cpp Fri Oct 13 19:53:21 2023 +0200 @@ -320,13 +320,18 @@ // select everything between the first selection and the current row std::sort(selection.begin(), selection.end()); int first = selection.front(); + int last = row; + if (first > row) { + last = first; + first = row; + } // clear previous selection change_rows_bg(selection, defaultBrush, defaultBrush); // create new selection std::vector newselection; - for (int s = first; s <= row; s++) { + for (int s = first; s <= last; s++) { newselection.push_back(s); } selection = newselection; diff -r 1bd5534c395d -r 391c2c723029 ui/winui/winui.vcxproj --- a/ui/winui/winui.vcxproj Fri Oct 13 15:20:54 2023 +0200 +++ b/ui/winui/winui.vcxproj Fri Oct 13 19:53:21 2023 +0200 @@ -91,6 +91,9 @@ _DEBUG;DISABLE_XAML_GENERATED_MAIN__;UI_WINUI;UI_WINUI_PCH;%(PreprocessorDefinitions) $(SolutionDir)..\..\ucx;%(AdditionalIncludeDirectories) + + shell32.lib;gdi32.lib;%(AdditionalDependencies) +