-
Notifications
You must be signed in to change notification settings - Fork 198
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
Initial commit of WinUI3 Shell32 Controls, Services, Helper <WIP> #494
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a stub actually.
More coming soon.
Hello, @dahall I'm working on the When enumerating some special folders, the Code involved at
...
The folders that don't work are virtual ones: You can (hopefully) build the branch involved from this: You can see the result here: Any ideas? Didn't debug into your code, cause I'm not privileged enough to understand it 🤣 Keep in mind, that there are no icons involved, no navigation is working ⚒ Any thoughts on this? Thank you very much, |
You don't have to care. I'm bringing in Unit-Tests for this Issue, to track it down... My 1st Unit Testing 👅 🥇 |
Hello, @dahall I've made some progress with the Shell controls for WinUI the last weeks. I will update this pull request soon, I guess. In the meantime, a made a little class diagram from what I've got so far: As one can see, It's the same class hierarchy native There is one difference though: I'm using abstract classes for what represents a single shell Item. namespace electrifier.Controls.Vanara.Contracts;
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public abstract class AbstractBrowserItem<T>(bool isFolder, List<AbstractBrowserItem<T>>? childItems)
{
public readonly bool IsFolder = isFolder; // WARN: TODO: Check this. If unknown, then find it out! ... edit: or use virtual function for this!
public readonly List<AbstractBrowserItem<T>> ChildItems = childItems ?? [];
public SoftwareBitmapSource SoftwareBitmapSource = isFolder
? IShellNamespaceService.FolderBitmapSource
: IShellNamespaceService.DocumentBitmapSource;
public new string ToString() => $"AbstractBrowserItem(<{typeof(T)}>(isFolder {isFolder}, childItems {childItems})";
}
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public abstract class AbstractBrowserItemCollection<T> : IEnumerable<AbstractBrowserItem<T>>, IList<AbstractBrowserItem<T>>
{
//protected readonly ShellItem? _parentOwnerItem;
protected readonly IList<AbstractBrowserItem<T>> Collection = [];
AbstractBrowserItem<T> IList<AbstractBrowserItem<T>>.this[int index] { get => Collection[index]; set => Collection[index] = value; }
int ICollection<AbstractBrowserItem<T>>.Count => Collection.Count;
bool ICollection<AbstractBrowserItem<T>>.IsReadOnly => false;
void ICollection<AbstractBrowserItem<T>>.Add(AbstractBrowserItem<T> item) => Collection.Add(item);
void ICollection<AbstractBrowserItem<T>>.Clear() => Collection.Clear();
bool ICollection<AbstractBrowserItem<T>>.Contains(AbstractBrowserItem<T> item) => Collection.Contains(item);
void ICollection<AbstractBrowserItem<T>>.CopyTo(AbstractBrowserItem<T>[] array, int arrayIndex) => Collection.CopyTo(array, arrayIndex);
IEnumerator<AbstractBrowserItem<T>> IEnumerable<AbstractBrowserItem<T>>.GetEnumerator() => Collection.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Collection.GetEnumerator();
int IList<AbstractBrowserItem<T>>.IndexOf(AbstractBrowserItem<T> item) => Collection.IndexOf(item);
void IList<AbstractBrowserItem<T>>.Insert(int index, AbstractBrowserItem<T> item) => Collection.Insert(index, item);
bool ICollection<AbstractBrowserItem<T>>.Remove(AbstractBrowserItem<T> item) => Collection.Remove(item);
void IList<AbstractBrowserItem<T>>.RemoveAt(int index) => Collection.RemoveAt(index);
public new string ToString() => $"AbstractBrowserItemCollection(<{typeof(T)}>(number of child items: {Collection.Count})";
} This actually leads to the following (wip) descent public class BrowserItem(Shell32.PIDL pidl, bool isFolder, List<AbstractBrowserItem<ShellItem>>? childItems = default)
: AbstractBrowserItem<ShellItem>(isFolder, childItems), INotifyPropertyChanged
{
public readonly Shell32.PIDL PIDL = new(pidl);
public string DisplayName => ShellItem.GetDisplayName(ShellItemDisplayString.NormalDisplay) ?? ShellItem.ToString();
public ShellItem ShellItem = new(pidl);
public new ObservableCollection<BrowserItem> ChildItems = [];
public static BrowserItem FromPIDL(Shell32.PIDL pidl) => new(pidl, false);
public static BrowserItem FromShellFolder(ShellFolder shellFolder) => new(shellFolder.PIDL, true);
public static BrowserItem FromKnownFolderId(Shell32.KNOWNFOLDERID knownItemId) => new(new ShellFolder(knownItemId).PIDL, true);
public Task<int> Enumerate() {}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { }
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null) { }
} As one can see, it's pretty straightforward. However, I'm not sure how massive the impact of using @dahall: But, in my humble opinion, there should be none, what're your ideas on this? I'm writing things down so no one is wondering why I'm using such an approach. That is, cause i hope to get things abstract enough to have a generic platform for any structured content, like databases etc. pp. Regards and thanks for readings, tajbender |
Moin, @dahall: an initial Version of
So, after your next official Release I'd finally try to merge my stuff for an upcoming Release. @dahall Do you agree? 😁 Regards,
|
@tajbender That's awesome! Thanks for all your work on this. Let me know as you get closer so I can plan for the release. |
I must thank you, @dahall. Without your work I'd never have managed to get so far 👅 To be honest, the hardest Issue I had was #499, so I must tribute @zhuxb711 👍 - A lot of functionality has been removed in the meantime to track THIS single nasty 😿 beast down. However, things still on the Bucket List:
To be honest, I don't have a Win 10 Machine lying around, so it's only tested on Windows 11 '24h2. That's why I look for feedback to get it as bullet proof as it can be. As you may know, the 🍰 is a lie... So, yes, as soon as there is something that fits together (again), I'll let you know. Thank you very much for your endless support. Have a good time, |
Moin @dahall I made a short video, to check performance and memory footprint. That's because I've trying to implemented a simple Cache for folder enumeration results. It may be deactivated in the future, but I was wondering how the memory footprint and CPU utilization are impacting the machine. Look for yourself, but it's not that high. That is, however, what I've been expected, cause only PIDL and Attributes are cached in a simple array for each of the Items: Regards, |
It is performing really well. Congratulations. |
I hate slow programs 👿 Maybe because of my age, my little remaining lifetime 🧓 - and finally, that's the reason I never used WPF nor UWP. Let's finally see the difference when extracting icons and thumbnails edit: Oh, another question: Would the requirement of .net 8 for the WinUI3 package be a showstopper for you? Beside the 3rd Party Community Toolkit that is used? |
.NET 8 is supported, but so are all versions back to 4.5. We can use compiler conditions though to limit this control to the .NET 8 or greater builds. |
@tajbender Should I hold up the 4.5.0 release to include this? I'm planning to push it out this weekend. If so, I'll have you delete the changes to the .csproj and the workflows and just submit the changes to |
Also, what is the difference between this and #493? If one is redundant or expired, will you please remove it? Thanks! |
Hi, David, sorry for confusion, I try to clear things up:
Thanks. When I was starting using WinUI3, I learned to need at least .net 6 for using Windows App SDK - at least for the beta releases then. There are warnings, however, I may or even should use .net 8 cause of Issues with the Runtime Wrapper RTW. These are currently *warnings* as said, some came and disappeared then and when making slight changes. I didn't dig further as of now, but I guess .net 6 is an official requirement. My short research didn't dig up further details, cause NuGet at least is somehow quiet on this topic: Dependencies: No Dependencies 🍭 However, my conclusion: I'll try to revert the current mess, and restart a clean, somehow tested on Win11 Release of my work, since there have been many changes and rewrites in the last weeks. For Win 10 I'll test in a VM with the lowest Win10 release i can make it to work with. However, on my bucket list this has low priority currently. No stable version makes tests on lower versions useless at the moment. If you like or even need to, you my close both Issues / PRs. Then, I will re-submit my final version, including Unit Tests and docs. I guess that would be the best way to clear things up. Thanks for patience, and sorry for confusion. Regards, |
Initial commit of WinUI3 Shell32 helpers.
For Reference only.