Hallo liebe Community!
Folgenes Szenario: Ich habe mittles WPF ein Overlay erstellt, welches sich über das Spiel GTA IV legt. Das ganze funktioniert soweit auch wunderbar! Nur ich habe da ein Problem bei welchem ich Unterstützung brauche, undzwar kann ich mit keinem Control auf diesem Window interagieren, da GTA IV den Cursor versteckt und stattdessen seinen eigenen Cursor im Spiel malt.
Nun hatte ich folgende Idee: Wenn man die Windows Taste drückt um das Startmenü aufzurufen, dann kommt der standard Windows Cursor zurück mit dem ich wieder mit Controls auf diesem Window interagieren kann. Doch sobald ich wieder auf GTA IV klicke um es in den Vordergrund zubringen verschwindet dieser wieder.
Meine Frage: Kann ich das WPF Window vielleicht mittels pinvoke manuell den Fokus geben so das Windows wieder den standard Cursor wiederherstellt und so das GTA IV kein Maus/Tastertur Input mehr erhält?
SetFocus habe ich schon getestet, leider ohne Erfolg.
Das ganze wird übrigens nicht zum cheaten oder ähnlichen benutzt sondern soll ein cooles neues Feature für version 1.6 von meinem GTA IV Launcher werden.
Falls sich jemand fragt warum ich nicht gleich mit DirectX ein Overlay erstelle welches sich in GTA IV injected: Ich würde super gerne alle Features von WPF verwenden also ist dies keine Option für mich.
Wie es im Moment aussieht:
Diese Klasse verwende ich um das WPF Window über GTA IV anzeigen zu können
Spoiler anzeigen
Dies sind die XAML Settings für dieses Window falls notwending
Falls weitere Fragen bestehen einfach ein Kommentar schreiben!
Ich würde mich sehr über Vorschläge freuen!
Folgenes Szenario: Ich habe mittles WPF ein Overlay erstellt, welches sich über das Spiel GTA IV legt. Das ganze funktioniert soweit auch wunderbar! Nur ich habe da ein Problem bei welchem ich Unterstützung brauche, undzwar kann ich mit keinem Control auf diesem Window interagieren, da GTA IV den Cursor versteckt und stattdessen seinen eigenen Cursor im Spiel malt.
Nun hatte ich folgende Idee: Wenn man die Windows Taste drückt um das Startmenü aufzurufen, dann kommt der standard Windows Cursor zurück mit dem ich wieder mit Controls auf diesem Window interagieren kann. Doch sobald ich wieder auf GTA IV klicke um es in den Vordergrund zubringen verschwindet dieser wieder.
Meine Frage: Kann ich das WPF Window vielleicht mittels pinvoke manuell den Fokus geben so das Windows wieder den standard Cursor wiederherstellt und so das GTA IV kein Maus/Tastertur Input mehr erhält?
SetFocus habe ich schon getestet, leider ohne Erfolg.
Das ganze wird übrigens nicht zum cheaten oder ähnlichen benutzt sondern soll ein cooles neues Feature für version 1.6 von meinem GTA IV Launcher werden.
Falls sich jemand fragt warum ich nicht gleich mit DirectX ein Overlay erstelle welches sich in GTA IV injected: Ich würde super gerne alle Features von WPF verwenden also ist dies keine Option für mich.
Wie es im Moment aussieht:
Diese Klasse verwende ich um das WPF Window über GTA IV anzeigen zu können
C#-Quellcode
- public class WindowSinker {
- #region DLLImports
- [DllImport("user32.dll")]
- static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
- [DllImport("user32.dll")]
- static extern IntPtr SetFocus(IntPtr hWnd);
- [DllImport("user32.dll")]
- static extern IntPtr DeferWindowPos(IntPtr hWinPosInfo, IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
- [DllImport("user32.dll")]
- static extern IntPtr BeginDeferWindowPos(int nNumWindows);
- [DllImport("user32.dll")]
- static extern bool EndDeferWindowPos(IntPtr hWinPosInfo);
- #endregion
- #region Variables
- private static readonly IntPtr HWND_TOP = new IntPtr(0);
- private const UInt32 SWP_NOSIZE = 0x0001;
- private const UInt32 SWP_NOMOVE = 0x0002;
- private const UInt32 SWP_NOACTIVATE = 0x0010;
- private const UInt32 SWP_NOZORDER = 0x0004;
- private const int WM_ACTIVATEAPP = 0x001C;
- private const int WM_ACTIVATE = 0x0006;
- private const int WM_SETFOCUS = 0x0007;
- private const int WM_WINDOWPOSCHANGING = 0x0046;
- private WindowInteropHelper windowInteropHelper;
- private Window targetWindow;
- #endregion
- #region Events
- private void Window_Loaded(object sender, RoutedEventArgs e)
- {
- if (windowInteropHelper == null)
- return;
- if (windowInteropHelper.Handle == IntPtr.Zero)
- return;
- SetWindowPos(windowInteropHelper.Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- HwndSource Source = HwndSource.FromHwnd(windowInteropHelper.Handle);
- Source.AddHook(new HwndSourceHook(WndProc));
- }
- private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
- {
- if (windowInteropHelper == null)
- return;
- if (windowInteropHelper.Handle == IntPtr.Zero)
- return;
- HwndSource Source = HwndSource.FromHwnd(windowInteropHelper.Handle);
- Source.RemoveHook(new HwndSourceHook(WndProc));
- }
- #endregion
- #region Constructor
- public WindowSinker(Window window)
- {
- targetWindow = window;
- windowInteropHelper = new WindowInteropHelper(targetWindow);
- }
- #endregion
- #region Methods
- public void Sink()
- {
- targetWindow.Loaded += Window_Loaded;
- targetWindow.Closing += Window_Closing;
- }
- public void Unsink()
- {
- targetWindow.Loaded -= Window_Loaded;
- targetWindow.Closing -= Window_Closing;
- }
- #endregion
- #region Functions
- public IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
- {
- switch (msg) {
- case WM_SETFOCUS:
- hWnd = windowInteropHelper.Handle;
- SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- handled = true;
- break;
- }
- return IntPtr.Zero;
- }
- #endregion
- }
Dies sind die XAML Settings für dieses Window falls notwending
Falls weitere Fragen bestehen einfach ein Kommentar schreiben!
Ich würde mich sehr über Vorschläge freuen!
Wenn ich dir auf irgendeiner Art und Weise helfen konnte, drück doch bitte den "Hilfreich" Button
Für VB.NET Entwickler: Option Strict On nicht vergessen!
Für VB.NET Entwickler: Option Strict On nicht vergessen!