ui/winui/icons.cpp

branch
newapi
changeset 216
391c2c723029
parent 215
1bd5534c395d
child 217
b9798109c7d2
--- 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 <Windows.h>
+#include <Shellapi.h>
+
+
 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<std::string, Symbol> 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;
+}

mercurial