2017-03-29 2 views
0

Je développe une application dans WPF qui héberge une application Unity. Cet hébergement est réglé en utilisant une classe HwndHost (parce que la façon d'unité avec l'argument _hwndparent semble don (travail t).Unity3D intégré dans l'application WPF -> Problèmes SetWindowLong

Dans le BuilWindowCore de ma classe HwndHost, je dois changer le style de l'enfant de fenêtre à l'aide GetWindowLong et SetWindowLong .

Toutes ces œuvres parfaitement sur mon ordinateur développer. Mais je ne peux pas utiliser l'application sur un autre ordinateur.

Quand je viens de mettre en valeur WS_CCHILD (sans récupérer le style en utilisant GetWindowLong) est ther tombe pas en panne sur tous les ordinateurs, mais l'application enfant n'est pas apparue correctement (Maximisée etc.). C'est pourquoi je pense que le problème concerne la fenêtre enfant de style. partie.

Il est mon code de classe HwndHost:

public class UnityHwndHost : HwndHost 
{ 
    private Process _process; 
    private HandleRef _hwnd; 
    private IntPtr _unityHWND; // = IntPtr.Zero; 

    private const int GWL_STYLE = -16; 

    // Window Styles 
    const UInt32 WS_OVERLAPPED = 0; 
    const UInt32 WS_POPUP = 0x80000000; 
    const UInt32 WS_CHILD = 0x40000000; 
    const UInt32 WS_MINIMIZE = 0x20000000; 
    const UInt32 WS_VISIBLE = 0x10000000; 
    const UInt32 WS_DISABLED = 0x8000000; 
    const UInt32 WS_CLIPSIBLINGS = 0x4000000; 
    const UInt32 WS_CLIPCHILDREN = 0x2000000; 
    const UInt32 WS_MAXIMIZE = 0x1000000; 
    const UInt32 WS_CAPTION = 0xC00000;  // WS_BORDER or WS_DLGFRAME 
    const UInt32 WS_BORDER = 0x800000; 
    const UInt32 WS_DLGFRAME = 0x400000; 
    const UInt32 WS_VSCROLL = 0x200000; 
    const UInt32 WS_HSCROLL = 0x100000; 
    const UInt32 WS_SYSMENU = 0x80000; 
    const UInt32 WS_THICKFRAME = 0x40000; 
    const UInt32 WS_GROUP = 0x20000; 
    const UInt32 WS_TABSTOP = 0x10000; 
    const UInt32 WS_MINIMIZEBOX = 0x20000; 
    const UInt32 WS_MAXIMIZEBOX = 0x10000; 
    const UInt32 WS_TILED = WS_OVERLAPPED; 
    const UInt32 WS_ICONIC = WS_MINIMIZE; 
    const UInt32 WS_SIZEBOX = WS_THICKFRAME; 

    // Extended Window Styles 
    const UInt32 WS_EX_DLGMODALFRAME = 0x0001; 
    const UInt32 WS_EX_NOPARENTNOTIFY = 0x0004; 
    const UInt32 WS_EX_TOPMOST = 0x0008; 
    const UInt32 WS_EX_ACCEPTFILES = 0x0010; 
    const UInt32 WS_EX_TRANSPARENT = 0x0020; 
    const UInt32 WS_EX_MDICHILD = 0x0040; 
    const UInt32 WS_EX_TOOLWINDOW = 0x0080; 
    const UInt32 WS_EX_WINDOWEDGE = 0x0100; 
    const UInt32 WS_EX_CLIENTEDGE = 0x0200; 
    const UInt32 WS_EX_CONTEXTHELP = 0x0400; 
    const UInt32 WS_EX_RIGHT = 0x1000; 
    const UInt32 WS_EX_LEFT = 0x0000; 
    const UInt32 WS_EX_RTLREADING = 0x2000; 
    const UInt32 WS_EX_LTRREADING = 0x0000; 
    const UInt32 WS_EX_LEFTSCROLLBAR = 0x4000; 
    const UInt32 WS_EX_RIGHTSCROLLBAR = 0x0000; 
    const UInt32 WS_EX_CONTROLPARENT = 0x10000; 
    const UInt32 WS_EX_STATICEDGE = 0x20000; 
    const UInt32 WS_EX_APPWINDOW = 0x40000; 
    const UInt32 WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); 
    const UInt32 WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST); 
    const UInt32 WS_EX_LAYERED = 0x00080000; 
    const UInt32 WS_EX_NOINHERITLAYOUT = 0x00100000; // Disable inheritence of mirroring by children 
    const UInt32 WS_EX_LAYOUTRTL = 0x00400000; // Right to left mirroring 
    const UInt32 WS_EX_COMPOSITED = 0x02000000; 
    const UInt32 WS_EX_NOACTIVATE = 0x08000000; 


    private const int WM_ACTIVATE = 0x0006; 
    private readonly IntPtr WA_ACTIVE = new IntPtr(1); 
    private readonly IntPtr WA_INACTIVE = new IntPtr(0); 

    [DllImport("user32.dll")] 
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, UInt32 dwNewLong); 

    [DllImport("user32.dll", SetLastError = true)] 
    private static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex); 

    [DllImport("user32")] 
    private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent); 

    internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam); 
    [DllImport("user32.dll")] 
    internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam); 

    [DllImport("user32.dll")] 
    static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 

    [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] 
    public static extern bool IsWindow(IntPtr hWnd); 

    #region CONSTRUCTORS 
    #endregion 

    #region METHODS 
    protected override HandleRef BuildWindowCore(HandleRef hwndParent) 
    { 
     var context = DataContext as UltrasoundVM; 
     var psi = new ProcessStartInfo("UnityStandAlone.exe"); 

     psi.Arguments = "\"" + context.Workspace.Replace('\\', '/') + "\" " + context.SelectedFlexible; 
     LoggerHelper.Write(GetType().FullName + "." + new StackTrace().GetFrame(0).GetMethod().Name + " : " + psi.Arguments, EventLogEntryType.Information); 
     psi.WindowStyle = ProcessWindowStyle.Minimized; 

     _process = Process.Start(psi); 
     _process.WaitForInputIdle(); 
     while (_process.MainWindowHandle == IntPtr.Zero || !IsWindow(_process.MainWindowHandle)) 
     { 
      Thread.Yield(); 
     } 
     _unityHWND = _process.MainWindowHandle; 
     SetParent(_unityHWND, hwndParent.Handle); 

     var style = GetWindowLong(_unityHWND, GWL_STYLE); 
     style = style & ~WS_CAPTION & ~WS_THICKFRAME; // Removes Caption bar and the sizing border 
     style |= (WS_CHILD); // Must be a child window to be hosted 
     SetWindowLong(_unityHWND, GWL_STYLE, style); 

     SetWindowLong(_unityHWND, GWL_STYLE, WS_CHILD | WS_MAXIMIZE); 

     SendMessage(_unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero); 

     _hwnd = new HandleRef(this, _unityHWND); 
     return _hwnd; 
    } 

    protected override void DestroyWindowCore(HandleRef hwnd) 
    { 
     SendMessage(_hwnd.Handle, WM_ACTIVATE, WA_INACTIVE, IntPtr.Zero); 

     _process.CloseMainWindow(); 

     _process.WaitForExit(5000); 

     if (_process.HasExited == false) 
     { 
      _process.Kill(); 
     } 

     _process.Close(); 
     _process.Dispose(); 
     _process = null; 
    } 
    #endregion 
} 

Notes:

DEVELOPPER Computer
- OS: Windows 10 Édition Familiale - Unité édition gratuite 3D 5.5.2.f.1

Tests des ordinateurs - Système d'exploitation: Windows 10 (Édition familiale & Édition Pro)

Bien sûr, j'ai essayé de construire l'application de l'unité avec différents paramètres, la même chose avec mon application parente.

+0

_ "parce que le chemin de l'unité avec l'argument _hwparparent semble ne pas fonctionner" _ ... C'est ainsi que ça fonctionne.Il permet de gérer la fenêtre de l'enfant Unity ... sans cet argument, il jettera des exceptions et ne se comportera pas –

+0

Avez-vous un échantillon de travail? Parce que l'échantillon de l'unité officielle (celui avec le cube) ne fonctionne pas ... – Yokaichan

+0

il suffit d'ajouter '-parentHWND ' à vos paramètres ... Après cela, tout devrait fonctionner comme –

Répondre

0

OK

Il semble que le problème vient de mon unité autonome qui ne fut pas le même entre mes sources et mon dossier de débogage.