Autor Wątek: Raw input  (Przeczytany 2009 razy)

Offline ShadowDancer

  • Redaktor

# Luty 16, 2013, 17:06:04
W mojej apce potrzebuje użycia wielu myszy (fizycznie podpiętych do komputera). Niestety jest to xna, z klasą game (czyli nie mam WinForma, nie mogę po prostu podmienić procedury okna). Poległem na przechwytywaniu wiadomości z mojego okna. Generalnie mam coś takiego:

      IntPtr hHook;
        IntPtr hWnd;
        Win32.WndProcDelegate wndProcDelegate;

// Init
     public void Init()
     {
            this.hWnd = Game.Instance.Window.Handle;

            wndProcDelegate = WndProcHook;

            uint threadId = Win32.GetWindowThreadProcessId(hWnd, IntPtr.Zero);

            // Win32 wywołuje funkcje winapi przez pinvoke
            hHook = Win32.SetWindowsHookEx(Win32.HookType.WH_CALLWNDPROC, wndProcDelegate, IntPtr.Zero, threadId);
}
        private int WndProcHook(int nCode, IntPtr wParam, ref Win32.Message lParam)
        {
            if (nCode >= 0)
            {
                Win32.TranslateMessage(ref lParam);
                WndProc(ref lParam);
            }
            return Win32.CallNextHookEx(hHook, nCode, wParam, ref lParam);
        }

// Struktura komunikatu
public struct Win32.Message
            {
                public IntPtr hWnd;
                public uint msg;
                public IntPtr wparam;
                public IntPtr lparam;
               
            }

void WndProc(ref Win32.Message message)
        {
// Tu próbuję przechwycić message.msg == WM_INPUT
        }


Niestety zamiast poprawnych komunikatów dostaje jakieś śmieci (typu 0, 0, 1, 2, 2, 1, 349143 ...). Nie wiem czy gdzieś mam tu błąd, czy jednak xna nie pozwala na takie zabawy.

---------------------------------------------------------------------------
Edit:
Dorzucam mój libek do obsługi wielu myszy i klawiatur
https://dl.dropbox.com/u/12185236/c%23%20raw%20input.7z
---------------------------------------------------------------------------
« Ostatnia zmiana: Luty 17, 2013, 16:49:25 wysłana przez ShadowDancer »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Pawelx156

  • Użytkownik

# Luty 16, 2013, 17:30:28
Hmm akurat tak się składa ze klasa Game posiada pole Window i jest to System.Windows.Forms.Form.

Ja u siebie mam edytor in game i potrzebuje ukrywać itp oryginalne okno XNA.

A robię to tak:

public  System.Windows.Forms.Form GameWindow; - moje okno gry

i mam funkcję która zamienia mi okno XNA na  pierwotną winform.

public  System.Windows.Forms.Form ConvertGameWindowToForm(Game game)
       {
           System.Windows.Forms.Control fr = System.Windows.Forms.Control.FromHandle(game.Window.Handle);       
           return (System.Windows.Forms.Form)fr;       
       }

Dzięki temu mam dostęp do pełnej zawartości okna XNA. Która normalnie nie jest udostępniona.

Czyli obsługiwać myszkę mogę  np tak :

GameWindow.MouseClick += new System.Windows.Forms.MouseEventHandler(GameWindow_MouseClick);
           GameWindow.MouseMove += new System.Windows.Forms.MouseEventHandler(GameWindow_MouseMove);

  void GameWindow_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
       {
          GameWindow.Text = "X: " + e.X.ToString() + " Y: " + e.Y.ToString();
       }

        void GameWindow_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
       {
           System.Windows.Forms.MessageBox.Show("kliknieto" + e.X.ToString() + " " + e.Y.ToString());
       }

Offline ShadowDancer

  • Redaktor

# Luty 16, 2013, 19:38:01
Ty po prostu dajesz formie callbacki, a ja potrzebuję zoverride'ować jej procedurę obsługi komunikatów (ew. PreprocessMessages) - czyli muszę mieć definicję forma. Z samym handle to mogę co najwyżej próbować zakładać hooki (co z jakiegoś powodu nie działa).

Rozwiązaniem byłoby utworzenie osobnego winforma i rendrowanie w nim, ale tego wolałbym uniknąć z różnych powodów (np. fullscreen).

Offline karol57

  • Użytkownik

# Luty 16, 2013, 21:17:55
Z góry zaznaczam, że nie mam pojęcia czy to zadziała. A jak byś pobrał procedurę okna używając GetWindowLongPtr, a potem podmienił na swoją (SetWindowLongPtr)?

Offline ShadowDancer

  • Redaktor

# Luty 17, 2013, 16:56:01
Dobry pomysł, sam nawet o tym nie pomyślałem, jednak moja procedura okna jest w kodzie zarządzanym i tu znowu są problemy - nie będę drążył tego rozwiązania. Widocznie muszę spiąć Game do WindowsForma, inaczej tego nie zrobię.

Jeśli komuś miałby się przydać to tu jest mój libek (razem z przykładem) do obsługi wielu myszy i klawiatur pod winforms
https://dl.dropbox.com/u/12185236/c%23%20raw%20input.7z