-
-
Notifications
You must be signed in to change notification settings - Fork 957
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
[WIP] Embedding Game in WPF and WinForms #1474
base: master
Are you sure you want to change the base?
Conversation
Nice one, I wonder whether we can introduce the parent window idea to the platform-independent |
Would be absolutely awesome if the sample would consist of three projects, for WPF, WinUI3 and WinForms. For WinUI3 I would just try and start with a MAUI app and see if appropriate use of See Retrieve a window handle (HWND) - Windows apps | Microsoft Docs |
I added a WinForms sample. It works, but user input is not quite working. Specifically, the right side arrows don't respond to mouse clicks. It's also sluggish, but I figured it was worthwhile to show something partially working. |
For Windforms there is another context, that also uses the winforms message loop. That might fix the issues. https://github.com/stride3d/stride/blob/master/sources/engine/Stride.Games/GameContextWinforms.cs |
Its not sluggish on my machine. Maybe thats much better if you build in Release.
Interesting though that right now this WinForms project is the only one not affected by the freezing while dragging. |
I experimented with this and running the WPF game loop in a task and it accomplished the same thing. It even shows the same behavior on failing to register clicks the right arrows. However, what is interesting is that after you resize the window that problem goes away. I tried forcing a refresh after starting the game loop but it didn't help. It is a clue though and may help figure out what is happening on the WinForms side as well. |
Would this also address support for winui3? |
Maybe change the title to include WinForms, Win32 (if that is what Particles.Windows is) and WinUI3 once its in? |
…g them from preferred values.
I at least figured a workaround for the game not responding to mouse clicks until resized. Basically, the game did not have the correct values set for width and height of the render area. I'm still trying to work my way through the generic classes (e.g. GameWindow) to see if there is a way to encapsulate this in a platform independent way. I'm not having a great deal of luck however. That may be a task better suited to someone more familiar with Stride. @SoggyBottomBoy I may try to add something for winui3. I'm not sure how much will have to be added since the WPF example makes use of the already existing GameEngineHost. @ericwj I probably should adjust the title. I don't believe Particles.Windows was modified in this PR. |
No indeed. The point would be to have people find this searching for Win32. But on second thought its only a temporary advantage; people won't normally find the PR once its merged. Particles should eventually be listed in the docs with these terms instead. |
Forget about WPF. Both WinUI3 and WPF have XAML but technically WPF is special. I think you should look at the Windows project to figure out how it'd work with WinUI3. |
var wndClass = new NativeMethods.WndClassEx(); | ||
wndClass.cbSize = (uint)Marshal.SizeOf(wndClass); | ||
wndClass.hInstance = NativeMethods.GetModuleHandle(null); | ||
wndClass.lpfnWndProc = NativeMethods.DefaultWindowProc; |
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.
I think this causes the problems with resizing and dragging. It shouldn't be needed to run the rendering in a task, either.
Take a look at this window procedure and then add to that a handler for WM_PAINT
which doesn't use BeginPaint
, EndPaint
, but calls into the rendering instead. You can see how it is done in C++ in the DirectX samples here.
The way to get WndProc
to be called for a specific window instance is by forwarding like it is done here. Notice the [UnmanagedCallersOnly]
and the use in there of CREATESTRUCTW
to carry a GCHandle
which targets the Window itself.
Updates Window so that it will accept a parent HWND and create a child in which to render.
Description
This is a Windows (OS) specific update. By passing in the parent window, using SDL CreateWindowFrom(), and some calls to native windows code I was able to host a Game inside WPF and WinForms. I used the Particles Sample project to create example implementations: ParticlesSample.Wpf and ParticlesSample.WinForms.
The WPF example makes use of GameEngineHost while the WinForms example doesn't need it. Both make use of SDL.Window which has been modifed to create child windows when passed a parent HWND. There is also an update to GameBase that prevents the PreferredBackBufferWidth and PreferredBackBufferHeight from overriding the Context RequestedWidth and RequestedHeight.
I'm not sure how you would go about doing something similar in Avalonia Given but how similar it is to WPF it may not be too difficult, although I suspect an equivalent class to GameEngineHost would need to be created.
Related Issue
#870
#1315
Motivation and Context
I would like to use Stride as a visualization tool inside an existing WPF application.
Types of changes
Checklist