-
Notifications
You must be signed in to change notification settings - Fork 686
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
Any chance to get a tutorial how to apply it to MFC app ? #7786
Comments
Truthfully, it isn't that different to doing this with UWP Xaml with WinUI 2.
and
These are the interfaces needed to host Xaml content in MFC, but notice how they have the experimental attribute? The WinUI 3 Xaml islands are not classed as ready for general usage right now. If you have no issues with experimenting with experimental features, it takes a little more work, but it is still easy to get it to work. The biggest thing you need in addition is a class that derives from Microsoft.UI.Xaml.Application and implements IMetadataProvider. Although the metadata provider can be much simpler than a full Xaml application. It only needs to provide metadata for existing components, meaning you can just pass the metadata provider through. If you want an example, I have no issues providing a fairly minimal Windows API example. It is easy enough to adapt that when you have all of the pieces. |
Hello, Thank you for hints. I wanted to start with a simple setup. I followed that tutorial, trying to rework it with WinUI. I forked repo to:
Note: Currently app must be switched to x86 before compilation. Currently there are such issues:
Summing up, hard way to start without a decent tutorial. |
Okay. This sample uses a Windows API window. It should be fairly easy to transfer the required parts into an MFC application. The important parts are the IslandApplication component and some method for getting the DesktopWindowXamlSource to filter any messages. |
Thank you for this one. When I try to build it I get: I installed the stuff from beneath link and have experimental projects available when trying to add a new Project, but obviously I miss something. |
That is interesting. The only thing I can think of is that there is something with the version of MIDL you are using. What version of the Windows SDK is being used? It was building, and succeeding, with the Windows 11 22H2 (10.0.22621.0) version of the SDK. IIRC, the project was set to use the latest version 10 SDK installed on the system. |
Thank you for further help. I've machine with win10, was wondering it I can install SDK 10.0.22621.0 on it, tried and installation was fine,. Then it compiled. At the startup I got: Do you want to install a compatible Windows App Runtime now?' So I installed it. Now it's crashing at startup: D:\a_work\1\s\dev\DynamicDependency\API\WinRTInprocModule.h(55)\Microsoft.WindowsAppRuntime.dll!7950A005: (caller: 79509AEE) Exception(1) tid(1eb8) 80004002 No such interface supported So I suppose maybe win10 is not capable of running it. |
The output for these projects is problematic since the Windows App SDK doesn't hesitate to use exceptions internally.
For a successful run. I have the AcrylicBrush exception as well as two others (AnimatedIcon and CommandBarFlyout). So that isn't the issue. But after looking through the code again, I did find the issue. I did originally use it to test a couple of extra things, but I stripped them out. I missed one. If you open mainwindow.cpp and check lines 87 and 88, you should find:
This attribute is only available on Windows 11 21H2 and newer. For Windows 10, it would fail. It doesn't do anything for the application. My apologies about this. Edit... I have removed everything else that I could see that was unneeded for the demonstration of the Xaml Island. My apologies for this. This project was originally testing a few other things. Mica and Desktop Acrylic being one of them as well as figuring out a bug where the Xaml loader wouldn't recognise a property of the Acrylic brush. |
Thank you, now it compiles and runs. Now I grabbed the idl code you provided above for DesktopWindowXamlSource put it into idl file in the project. Added a reference to the C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.22621.0\Windows.winmd Now it compiles for a while and gives: |
That is why, if you check the sample project that I gave, there is no extra reference to the Windows metadata. |
Without adding that reference when trying to compile idl files I get: Severity Code Description Project File Line Suppression State |
Ok, in wanting to solve the midl error, I didn't read your post fully. This is verifiable. If you set the Visual Studio build log to diagnostic, you can find the midl command line. The command line contains the name of the response (.rsp) file. This is the path on my system. It is relative to where the file is stored. This response file contains all of the references that midl uses. For my system, this file starts off as:
Where Microsoft.UI.Xaml.winmd is quite high up. The response file is used because of the Windows command line limit, so it is better to use a response file to pass in lots of command line options if the executable looks out for it. But it is equivalent to passing all of these options on the command line. I showed the runtime class definitions above to illustrate their presence, but it would be rare to want to use the in idl form. The idl definitions were extracted from the generated files, so they were incomplete. C++/WinRT is the expected way to use WinRT these days, and midl references the metadata directly, so you don't need to have separate idl files to use the Xaml Island classes and interfaces in your own components. As an example, if the IslandApplication runtime class is modified as follows:
then this idl file will compile with a warning. The warning is that since you are using an experimental type in a runtime class, the runtime class itself must be marked as experimental.
That was actually the reason why I used IClosable there. The only useful operation on WindowsXamlManager is Close, InitializeForCurrentThread is a static and is used to create the instance. This means that the runtime class can reference IClosable and not require the experimental attribute. Obviously, doing this will require modifications to the IslandApplication.h and IslandApplication.cpp files. C++/WinRT picks these classes up too. If you look at the Microsoft.UI.Xaml.Hosting.h file that C++/WinRT generates (it is under (project root)(platform)(configuration)\Generated Files, where project root is the directory where the .vcxproj is, you will find that C++/WinRT has generated wrappers for the runtime classes and interfaces there. The sample uses these particular classes directly. IslandApplication.h has a variable named m_xamlmanager of type winrt::Microsoft::UI::Xaml::Hosting::WindowsXamlManager. Using these types with C++/WinRT and the Windows App SDK packages doesn't require much else. If you were trying to use the idl definitions because it wasn't clear that you didn't need to use them, then you don't need to use them. As mentioned, Visual Studio will reference the correct .winmd file automatically meaning midl and C++/WinRT will just automatically use them. |
Thank you. Then I reviewed properties of MFC project against XamlIslandTest3, did a few changes, but the error still remains. I also compared "Generated Files" folders and they differ a bit - but why - I do not know. |
As I said previously, Xaml Islands are currently an experimental feature. This means that they are only in experimental versions of the Windows App SDK. For 1.2, this means 1.2.220727.1-experimental1 and 1.2.220909.2-experimental2 only. If it is just intellisense errors, then just force Visual Studio to rescan the solution. Selecting Rescan Solution will cause Visual Studio to dump all intellisense information and then rebuild it from the solution. |
Yes, I noticed that but did not update the post. I changed it to be 1.2.220909.2-experimental2, but still not helped.
Sorry I did not provided exact error, no it's not intellisense , it's a compiler error: Here is the solution you provided with that MFC project added:
Thank you, I did not know the trick, might be handy. |
Putting aside MFC example I tried to host User Control in this XamlIslandTest3 project. So I did (added parts bolded): `winrt::Microsoft::UI::Xaml::Hosting::DesktopWindowXamlSource _desktopWindowXamlSource{ nullptr }; _desktopWindowXamlSource = winrt::Microsoft::UI::Xaml::Hosting::DesktopWindowXamlSource(); At this point app started. Then I added to the solution a project WinUIComponentCs created as described at: and tried this: App is crashing with: Original Walkthrough witn WinUI example has such point:
I'm wondering if that also is relevant in this case, the change was in Package.appxmanifest which win32 app is not having? |
Well, for the entire MFC thing. I didn't have a clue. Notice the colouring on TRY there? That means it is a definition of some kind, and in this case, it is a macro defined by MFC. So, I disabled precompiled headers for the MFC project, moved the C++/WinRT headers out of pch.h and into a separate header, then I included that into IslandApplication.cpp, replacing pch.h in that file. It compiled fine. This is a simple case of the macros defined by MFC interfering with the C++/WinRT headers. For the second case, try looking at this. |
Here is the project. |
Well, after having a little look at various pieces of documentation and inferring from there, it wasn't that hard to get it working.
more specifically, the file name. Using:
as the registration free WinRT registration allows the component to load successfully. There is still a couple of things that I need to do to get things working again properly, but that is what normally happens when you have to reinstall Windows. ---Edit--- Well, after a little more work: I am able to load the control and create a new Xaml source for it. |
That is curious. Well, this is also one of the annoyances of working with code that you didn't write, also the sample was only ever written to show the initialisation of Xaml Islands. Anyway, getting things in the right place is key. If you don't do that, and especially don't clean things up properly after you then it does get rather crashy. I guess this is still one of the reasons why Xaml Islands is considered experimental. |
Thx again I think we are close to resolve it. I took the XamlIslandTest3.zip you posted 8 days ago and somehow the button created in the main_window::on_create is not visible in the main window. |
I have the impression it due to the fact I'm using Win10. |
Well, without knowing what you have and have not done then it is tough to say. Since I am technically on holiday now, I'll give you a bit of a run through about how bad the entire situation is in general. There is no really good source of information for Xaml Islands in general. The UWP Xaml Islands samples, which was the starting point of this work, are terrible. After a bit of looking around, I found reference to the XamlApplication class in the Microsoft Community Toolkit. This is what IslandApplication is based upon. But this was one of the requirements to get WinUI loaded. Interestingly, this class also had its own problems. When I was originally figuring things out, I was working with composition in the same application. The XamlApplication class was actually using the presence of a DispatcherQueue to determine if the application was a desktop or UWP application. The WinUI 3 work ended up being figuring out any differences between WinUI 2 and WinUI 3 and then changing the namespaces. There were some requirement differences. WinUI 2 needed to be loaded using the Dynamic Dependency API, the resources needed to be merged into the main resources.pri and there was also an interface difference. But this actually made working with WinUI 3 a bit easier. While I was at it, I also ended up running into a few bugs too. For example, the Dynamic Dependency API included with the Windows App SDK has an issue where if you try to use the registry or a file to control the lifetime of the dependency, it throws an exception. This works fine with the Windows 11 built in API though. So obviously I had to report this. Another bug that I ended up running into is in DesktopWindowXamlSource itself. There is an event named GotFocus which is documented to fire when the source receives focus. This never fires. Anyway, I finally managed to get the time to update the project and upload it to GitHub. The repository is here. But be warned, I ran across another bug, this time it is in the WinUI 3 DesktopWindowXamlHost. The TakeFocusRequested event isn't firing, so this won't allow you to navigate out of a xaml source. This was part of the reason why I took so long to reply, I was also getting the original WinUI 2 sample into a form that could be used to show that the bug exists. |
At my pc that middle button is not visible: After forcing styles it's working a bit - sometimes is visible , sometimes disappears (if I click it). I'm going to wait for a official release from Microsoft, currently there is too much effort needed, and to much low level windows messaging related code involved. Talking about examples quality that repo (subfolder XamlIslands-master\1903_Samples\CppWinRT_Win32_App) has a code that tries to create a User Control with a different approach - it's created inside Windows Runtime Component. Yet, app is crashing at the startup. |
As a proof if that is a win10/11 issue I tried to compile it on win11 machine but got: Severity Code Description Project File Line Suppression State Also tried a hint from https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/experimental-channel
but it's still not compiling. |
From the XamlIslandTest3 build output with the log file set to Diagnostic on Windows 11:
There is a few more using that library, but it is loading and using the pri tasks library without issue. So, are you sure this is a Windows problem? Both versions of Windows 11 (initial release and 22H2) have no issue building here at all. I also don't have a particularly complex Visual Studio install either. |
I might not described problems precisely. So there are two separate problems:
There are some 'No such interface supported' messages in the output, maybe they are saying it's basically not meant to be run on win10.
|
I finally got it working on Win11. Initially I did not have that Experimental Windows App SDK. Summing up (to get idea without reading the whole thread):
|
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 5 days. |
Tried again with [Windows App SDK, looks like it could work but there is strange exception, code at: https://github.com/microsoft/WindowsAppSDK-Samples/issues/328 |
How apply it to MFC app ?
There is a similar tutorial at:
https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/host-custom-control-with-xaml-islands-cpp
But that was UWP so some details are not applicable here.
The text was updated successfully, but these errors were encountered: