In meiner WPF-Anwendung hostet ich Win32-Inhalt mithilfe von HwndHost. Das Erstellen eines HwndHost erstellt jedoch nicht das systemeigene Fenster. Dies geschieht vielmehr in der überschriebenen Methode BuildWindowCore()
, die irgendwann später von WPF aufgerufen wird.Erzwingen der Initialisierung eines HwndHost
Mein gehosteter Inhalt benötigt das Fensterhandle des nativen Fensters für seine eigene Initialisierung. Unglücklicherweise kann ich die Erstellung des Fensters nicht erzwingen (d. H., WPF ruft den BuildWindowCore auf), also habe ich einen zweiten Thread, der den HwndHost abfragt, bis er initialisiert wurde. In .NET 4.0/WPF 4.0 wurde eine neue Methode WindowInteropHelper.EnsureHandle()
hinzugefügt. Ich hatte gehofft, dass dies die Situation lösen würde, aber es funktioniert nur für ein Fenster, nicht für einen HwndHost (der nicht von Window abgeleitet ist). Hast du einen Vorschlag, was ich stattdessen tun könnte?
EDIT:
Ich habe vergessen, einige weitere Einschränkungen für eine mögliche Lösung hinzuzufügen:
- Die HwndHost in einer Kontrolle gestellt wird, die je nach Benutzereinstellungen, Haupt ein Kind der Anwendung sein kann Fenster oder kann in einem neuen Fenster (über einen Docking-Manager eines Drittanbieters) platziert werden. Dies bedeutet, dass ich während der Erstellung des Fensters nicht sicher weiß, was das übergeordnete Fenster (und somit seine hWnd) sein wird.
- Während der native Code die hWnd während seiner Initialisierung benötigt, wird das Fenster nur angezeigt, wenn der Benutzer anfordert, es anzuzeigen (d. H. Es ist zunächst unsichtbar). Das Fenster zu zeigen, nur um es sofort wieder zu verstecken, sollte möglichst vermieden werden.
Es gibt zwei Probleme: 1) Ich kenne den übergeordneten hWnd nicht, da das Steuerelement später von einem Docking-Manager eines Drittanbieters positioniert wird und die gespeicherten Benutzereinstellungen bestimmen, ob es alleine oder als " Kind "des Hauptfensters. 2) Die Steuerung mit dem HwndHost wird anfangs möglicherweise überhaupt nicht angezeigt (abhängig wiederum von den gespeicherten Benutzereinstellungen), aber beim Start benötigt der alte Code den hWnd. –
Sie sollten in der Lage sein, sich in das Loaded-Ereignis auf Ihrem Steuerelement einzuloggen und dort alle Initialisierungen vorzunehmen: http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.loaded.aspx. Wenn der Legacy-Code das hwnd benötigt, dann müssen Sie nur etwas mit dem Legacy-Code machen, bis das hwnd fertig ist (was ich tun musste). –
Zitat aus dem Link: "Tritt auf, wenn das Element ausgelegt, gerendert und bereit für die Interaktion ist." Wenn ich das Steuerelement nicht zeige, wird Loaded nicht ausgelöst. –