Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use native Win32 Shell ImageList in WinUI3 - Implementing ExplorerBrowser for WinUI3 #444

Open
tajbender opened this issue Mar 10, 2024 · 16 comments

Comments

@tajbender
Copy link
Contributor

Is your feature request related to a problem? Please describe

I'm using WinAppSDK for some months now.
I wonder how to use a native System Win32 API ImageList in UWP / WinUI?
No changes to Vanara needed, i guess.

Any Idea, David? Thx.

Describe the additions or enhancements you'd like

// convert system wide shellItemList into xaml based type
var winUIxamlObject = Vanara.*.SysImageList as || .SomeConversion()

@dahall
Copy link
Owner

dahall commented Mar 28, 2024

@tajbender I haven't done much with WinUI. There is a package called Vanara.WinUI.Extensions where we can land anything you want to add. Right now, that assembly is pretty light. I'll accept any PR you post.

@tajbender
Copy link
Contributor Author

@dahall Thank you very much. I really appreciate this.

I thought about aligning the interfaces of the WinUI3 ExplorerBrowser aka ShellListView / ShellTreeView that I'll implement the next days to those of Vanaras Win32 Ones.

That way Migrating that stuff from there to the WinUI-Version within Vanara would just be a piece of cake.

I'll let you know as soon there's something to talk about.

Have a nice Easter!

@dahall
Copy link
Owner

dahall commented Mar 29, 2024

Cool! Thanks. Happy Easter to you too!

@tajbender
Copy link
Contributor Author

@tajbender I haven't done much with WinUI.

btw, they have done an excellent job with WinUI3, in my humble opinion.

I've never worked with WPF and UWP before, but WinUI3 is straightforward as soon you get the point. They generate code-behind for the UI while compiling, this way, the UI-stuff is amazingly fast.

They also use DirectX / DirectDraw for rendering stuff. On the other side, you can use WinRT for the abstraction layer to OS for DOS, manipulating HWND settings / Messaging and so on: 🍔

👍

@tajbender
Copy link
Contributor Author

Done so far.

@tajbender
Copy link
Contributor Author

@tajbender
Copy link
Contributor Author

addendum: This should do it, for single images:

    Bitmap bitmap1 = Bitmap.FromHicon(SystemIcons.Hand.Handle);
    Graphics formGraphics = this.CreateGraphics();
    GraphicsUnit units = GraphicsUnit.Point;

    RectangleF bmpRectangleF = bitmap1.GetBounds(ref units);
    Rectangle bmpRectangle = Rectangle.Round(bmpRectangleF);
    formGraphics.DrawRectangle(Pens.Blue, bmpRectangle);
    formGraphics.Dispose();

https://learn.microsoft.com/en-us/dotnet/api/system.drawing.systemicons?view=windowsdesktop-3.1

@dahall
Copy link
Owner

dahall commented May 28, 2024

@tajbender What type(s) do you want converted from and to? I don't have a SysImageList class. Do you mean a native image list handle (HIMAGELIST)? What is the output type under WinUI3?

@tajbender
Copy link
Contributor Author

tajbender commented May 29, 2024

@tajbender What type(s) do you want converted from and to? I don't have a SysImageList class. Do you mean a native image list handle (HIMAGELIST)? What is the output type under WinUI3?

@dahall Thanks for Reply, but you don't have to care about the Notes above.
I just wrote down what I've found so far, so they're just a reminder for myself 🧷

You're right, with SysImageList I refer to the Win32 - HIMAGELIST handle, you could get with SHGFI_SYSICONINDEX flag, which returns the Index to the Shell Icon you're looking for.

Using Win32 you can pass this Handle to your ListView or TreeView controls directly, to avoid copying the images around from System space to your own Heap.

Anyway, you don't have to care about these comments, these are reminders for myself.

Sorry for confusion and bothering, anyways Thank you very much,
regards,
tajbender

@dahall dahall reopened this May 29, 2024
@dahall
Copy link
Owner

dahall commented May 29, 2024

I think you may be able to use Vanara.Windows.Shell.ShellImageList (in Vanara.Windows.Shell.Common) to expose the SafeHICON of system files or folders and wrap that into a class the derives from IconSource to provide the converted icon handle to a bitmap.

@tajbender
Copy link
Contributor Author

I think you may be able to use Vanara.Windows.Shell.ShellImageList (in Vanara.Windows.Shell.Common) to expose the SafeHICON of system files or folders and wrap that into a class the derives from IconSource to provide the converted icon handle to a bitmap.

public static ImageSource ToImageSource(this Icon icon)
{
    ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(
        icon.Handle,
        Int32Rect.Empty,
        BitmapSizeOptions.FromEmptyOptions());
    return imageSource;
}

That's what Copilot says 👌

I'll try this asap. Thank you very much 👍

@tajbender
Copy link
Contributor Author

@dahall: I uploaded an YouTube-Video

That's the current state of the WinUI3 Shell - Components I'm working on, using Vanara.

  • There's no optimization done yet, and no Unit-Tests done so far
  • Shell Images are default embedded Icon Resources, so no Vanara.Windows.Shell.ShellImageList in use
  • Enumeration is done using Vanara, respectively
Screenshot 2024-06-04 101413

You may look at the current branch here.

I still may need your help on some occasions, but I'm satisfied for now 😀

Just for your Info, regards, tajbender

@tajbender tajbender changed the title How to use native Win32 Shell ImageList in WinUI3 / UWP How to use native Win32 Shell ImageList in WinUI3 - Implementing ExplorerBrowser for WinUI3 Jun 4, 2024
@dahall
Copy link
Owner

dahall commented Jun 9, 2024

I just committed a class I'll use for this: Vanara.Windows.Shell.ShellIconExtractor

@tajbender
Copy link
Contributor Author

I just committed a class I'll use for this: Vanara.Windows.Shell.ShellIconExtractor

Thank you very much. This will help a lot. 🥇

@tajbender
Copy link
Contributor Author

Dear @dahall

Love 4 support 🧑‍⚕️

Currently, ⚽ European Championships take place in Germany, so no time no money 🍰

I used the new code already, it works stable 🥇

The next days, I will create a Pull Request for merging the stuff I have so far to Vanara. It still is WIP. But some review would help a lot.

Regards,

tajbender

@tajbender
Copy link
Contributor Author

I just committed a class I'll use for this: Vanara.Windows.Shell.ShellIconExtractor

Hi, @dahall

I used the ShellIconExtractor for some days now.

I'm new to that multithreading stuff, but anyway I get some strange behavior: Enumerating the same Folder again and again when navigating through the pages and views, ShellIconExtractor in my App may result in different findings:

08:40:10:034	'electrifier.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.19\System.Private.CoreLib.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:10:389	'electrifier.exe' (CoreCLR: clrhost): Loaded 'Snippets'. 
08:40:10:892	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\runtimes\win\lib\net7.0\System.Diagnostics.EventLog.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:10:892	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\Vanara.Windows.Shell.Common.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:10:892	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\Vanara.PInvoke.Ole.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:10:892	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\Vanara.PInvoke.Shell32.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:10:892	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\Vanara.PInvoke.Shared.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:11:883	Error: Converter failed to convert value of type 'Windows.Foundation.IReference`1<Microsoft.UI.Xaml.GridLength>' to type 'Double'; BindingExpression: Path='TemplateSettings.CompactPaneGridLength' DataItem='Microsoft.UI.Xaml.Controls.SplitView'; target element is 'Microsoft.UI.Xaml.Media.Animation.SplineDoubleKeyFrame' (Name='null'); target property is 'Value' (type 'Double'). 
08:40:14:383	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\Vanara.Core.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:14:631	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\Vanara.PInvoke.Gdi32.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:14:631	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\Vanara.Windows.Extensions.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:14:631	'electrifier.exe' (CoreCLR: clrhost): Loaded 'D:\gitHub\tajbender\electrifier.v1.24\src\electrifier\bin\x64\Debug\net7.0-windows10.0.19041.0\AppX\Vanara.PInvoke.User32.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:15:144	.IconExtOnComplete(): 63 items
08:40:15:144	.SetItemsSource(): `Desktop` 63 items.
08:40:16:630	.IconExtOnComplete(): 61 items
08:40:16:630	.SetItemsSource(): `Desktop` 61 items.
08:40:16:630	.GridViewVisibility = Visible
08:40:23:882	'electrifier.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.19\System.Reflection.Emit.Lightweight.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:23:882	'electrifier.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.19\System.Reflection.Emit.ILGeneration.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:23:882	'electrifier.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.19\System.Reflection.Primitives.dll'. Symbol loading disabled by Include/Exclude setting.
08:40:24:130	.IconExtOnComplete(): 64 items
08:40:24:130	.SetItemsSource(): `Desktop` 64 items.
08:40:27:631	.IconExtOnComplete(): 64 items
08:40:27:631	.SetItemsSource(): `Desktop` 64 items.
08:40:27:631	.GridViewVisibility = Visible
08:40:47:395	The thread '[Thread Destroyed]' (12448) has exited with code 0 (0x0).
08:40:47:645	The thread '[Thread Destroyed]' (27936) has exited with code 0 (0x0).
08:40:50:430	.IconExtOnComplete(): 63 items
08:40:50:430	.SetItemsSource(): `Desktop` 63 items.
08:40:52:736	.IconExtOnComplete(): 64 items
08:40:52:736	.SetItemsSource(): `Desktop` 64 items.
08:40:52:984	.GridViewVisibility = Visible
08:40:55:740	.IconExtOnComplete(): 64 items
08:40:55:740	.SetItemsSource(): `Desktop` 64 items.
08:40:57:780	.IconExtOnComplete(): 64 items
08:40:57:780	.SetItemsSource(): `Desktop` 64 items.
08:40:57:780	.GridViewVisibility = Visible
08:41:00:578	.IconExtOnComplete(): 64 items
08:41:00:578	.SetItemsSource(): `Desktop` 64 items.
08:41:03:657	.IconExtOnComplete(): 64 items
08:41:03:657	.SetItemsSource(): `Desktop` 64 items.
08:41:03:657	.GridViewVisibility = Visible
08:41:05:689	.IconExtOnComplete(): 62 items
08:41:05:689	.SetItemsSource(): `Desktop` 62 items.
08:41:25:456	The thread '[Thread Destroyed]' (8484) has exited with code 0 (0x0).
08:41:25:697	The thread '[Thread Destroyed]' (22372) has exited with code 0 (0x0).

Everytime .IconExtOnComplete(): has finished, my desktop folder has been enumerated. As you may see, I may get different number of items while doing so (62, 63, 64). 😒

In Fact, it should be 63 items... I'll investigate further 🤔 💭

Have a nice, sunny day 🌞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants