Kann ich das Verhalten der Einstellung meiner WinForms Form des Eigentümers mit einem hwnd / Native bekommen?

StackOverflow https://stackoverflow.com/questions/213661

  •  03-07-2019
  •  | 
  •  

Frage

Meine Anwendung ist ein VB6 ausführbar, aber einige neuere Formen im System werden in C # geschrieben. Ich mag die C # Form Besitzer Eigenschaft mit einem Griff in die Hauptfenstern einstellen zu können, so dass die Dialoge auf oben bleiben, wenn hin und her zwischen meiner Anwendung und anderen Anwendungen Tabbing.

Ich kann die Hwnd des Hauptanwendungsfenster erhalten. Ich bin mir nicht sicher, was ich kann von dort tun?


UPDATE 20. Oktober '08 um 17:06 Uhr:

Scott,

Vielen Dank für die Antwort. Ich hatte übersehen, dass die Show / Showdialog-Methode Parameter nicht vom Typ Formular war. - Ich war nur auf der Owner-Eigenschaft suche

ich leicht modifiziert den Code, den ich aus der oben bin mit - wir haben eine Komponente, die unsere Formulare allgemein lädt und ruft Showdialog. Mein Code sieht wie folgt aus:

Form launchTarget = FormFactory.GetForm(xxx);  // psuedo-code for generic form loader
launchTarget.StartPosition = FormStartPosition.CenterParent;
IWin32Window parentWindow = GetWindowFromHwnd(hwnd);

launchTarget.ShowDialog(parentWindow);

GetWindowFromHwnd ist eine Methode, verpackte Version des Codes:

private IWin32Window GetWindowFromHost(int hwnd)
{
    IWin32Window window = null;
    IntPtr handle = new IntPtr(hwnd);

    try
    {
        NativeWindow nativeWindow = new NativeWindow();
        nativeWindow.AssignHandle(handle);
        window = nativeWindow;
    }
    finally
    {
        handle = IntPtr.Zero;
    }

    return window;
}

Leider ist dies nicht zu tun, was ich hatte gehofft. Die Form tut Display modal, aber es ist nicht in der richtigen Position zeigt sich noch ist es nach wie vor an der Spitze, wenn ich Registerkarte weg und zurück in das übergeordnete Fenster. Unsere modals zeigen keine Aufgabe in der Taskleiste, so dass das Fenster scheinbar „verschwindet“ (obwohl es noch in der Alt-Tab-Fenster Liste ist). Das zeigt mir, ich könnte nicht das Recht Hwnd haben. Wenn Sie noch andere Vorschläge obwohl haben, antworten Sie bitte zurück. Nochmals vielen Dank.


UPDATE 10. November '08 um 16:25 Uhr

Eine Bemerkung folgen - Wenn Sie es in einem Versuch in einen Methodenaufruf ausklammern / schließlich, wie in Scotts zweiten Beitrag, der Anruf in dem finally-Block sollte sein:

parentWindow.ReleaseHandle();
War es hilfreich?

Lösung

So haben Sie eine C # Windows Form-Klasse von VB6 anrufen, was bedeutet, dass Sie wahrscheinlich entweder Show() oder ShowDialog() verwenden, richtig? Diese beiden Methoden auch einen IWin32Window Parameter nehmen, die einfach ein Objekt definiert, die eine IntPtr Eigenschaft namens Handle zurück.

So ... Sie benötigen einen überladenen Konstruktor (oder Showdialog-Methode) für Ihr Windows hinzuzufügen Forms-Klassen, die ein long als Parameter, so dass Sie die VB6 Hwnd zum Formular passieren können. Einmal in der C # -Code, benötigen Sie einen IntPtr aus dem Hwnd erstellen und sie zu einem NativeWindow Objekt zuweisen und dann das passieren als Eigentümer.

So etwas wie dies sollte Arbeit, obwohl es nicht getestet:

public DialogResult ShowDialog(long hwnd)
{
   IntPtr handle = new IntPtr(hwnd);
   try
   {
      NativeWindow nativeWindow = new NativeWindow();

      nativeWindow.AssignHandle(handle);
      return this.ShowDialog(nativeWindow);
   }
   finally
   {
      handle = IntPtr.Zero;
   }
}

Andere Tipps

Das ist zu lange als Kommentar zu schreiben ...

Ich denke, das Problem, das Sie in laufen, ist die Art und Weise Sie den Code wickelte ich in der Showdialog Überlast dargestellt. Wenn Sie folgen, was Ihr GetWindowFromHost Code tut es geht durch die folgenden Schritte:

  1. Erstellt einen neuen IntPtr aus dem Hwnd gegeben.
  2. Erstellt ein neues Nativewindow-Objekt und weist es handhabt die IntPtr sein.
  3. Stellt die IntPtr (im finally-Block) sein IntPtr.Zero.

Ich denke, es ist der Block schließlich, dass Sie Probleme verursacht. In meinem Code würde der finally-Block nach dem Aufruf läuft fertig this.ShowDialog(nativeWindow). An diesem Punkt der Griff (IntPtr) war nicht mehr verwendet werden. In Ihrem Code, kehren Sie einen IWin32Window, die noch einen Verweis auf dieses IntPtr abhalten sollten, die zum Zeitpunkt des launchTarget.ShowDialog(parentWindow) nennt, sind IntPtr.Zero.

Versuchen Sie, Ihren Code zu ändern wie folgt aussehen:

private NativeWindow GetWindowFromHost(int hwnd)
{
   IntPtr handle = new IntPtr(hwnd);
   NativeWindow nativeWindow = new NativeWindow();
   nativeWindow.AssignHandle(handle);
   return window;
}

Und dann Ihre Berufung Code ändern wie folgt aussehen:

Form launchTarget = FormFactory.GetForm(xxx);  // psuedo-code for generic form 
loaderlaunchTarget.StartPosition = FormStartPosition.CenterParent;
NativeWindow parentWindow = GetWindowFromHwnd(hwnd);

try
{
   launchTarget.ShowDialog(parentWindow);
}
finally
{
   parentWindow.DestroyHandle();
}

Diese Änderungen sollten arbeiten, aber auch dies ist nicht getestet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top