Complemento ArcGIS 10: traiga la ventana acoplable al frente

8

Tengo un complemento ArcGIS 10 ArcMap escrito en C # .NET 3.5 que implementa un ESRI.ArcGIS.Desktop.AddIns.DockableWindow(que también se hereda de UserControl) y un ESRI.ArcGIS.Desktop.AddIns.Toolque cuando se hace clic en el mapa actualiza la ventana acoplable.

Me gustaría llevar la ventana acoplable al frente del orden Z en el OnMouseDown()método de la herramienta (cuando está en modo desacoplado). Actualmente, si el usuario abre otra ventana acoplable, la coloca encima de la mía y hace clic con la herramienta, la ventana se actualiza pero no se muestra al frente. Ya estoy llamando IDockableWindow.Show(true)para asegurarme de que la ventana esté visible después de hacer clic con la herramienta. También lo he intentado UserControl.BringToFront()pero no tiene ningún efecto.

La mejor solución que tengo actualmente es llamar IDockableWindow.Show(false)seguido IDockableWindow.Show(true), sin embargo, esto no es ideal ya que es discordante que la ventana desaparezca y vuelva a aparecer, así como que tenga que volver a pintar por completo, lo que lleva una cantidad considerable de tiempo.

La ventana de identificación incorporada no tiene este problema y se coloca en la parte superior cada vez que se usa la herramienta de identificación, por lo que claramente hay una manera de hacerlo.

¿Alguien sabe de una mejor solución para esto? ¡Gracias!

Editar: Aquí está el código que terminé usando para resolver esto. Gracias Kirk y Petr!

public static void BringDockableWindowToFront(IDockableWindow dockableWindow, IntPtr dockableWindowControlHandle)
/// <summary>
/// Workaround for bringing a dockable window to the top of the Z order.
/// dockableWindowControlHandle is the Handle property of the UserControl implemented by the dockable window
/// </summary>
{
    IWindowPosition windowPos = dockableWindow as IWindowPosition;
    IntPtr parentHwnd = GetParent(dockableWindowControlHandle); // Get parent window handle
    switch (windowPos.State)
    {
        case esriWindowState.esriWSFloating:
            IntPtr grandParentHwnd = GetParent(parentHwnd); // Get grandparent window handle
            SetActiveWindow(grandParentHwnd);  // Activate grandparent window when in floating (undocked) mode
            break;
        //case esriWindowState.esriWSMaximize: // Mode not yet implemented in ArcGIS 10, check at 10.1
        //case esriWindowState.esriWSMinimize: // Mode not yet implemented in ArcGIS 10, check at 10.1
        case esriWindowState.esriWSNormal:
            SetActiveWindow(parentHwnd); // Activate parent window when in normal (docked) mode
            break;
    }
    SetFocus(dockableWindowControlHandle); // Set keyboard focus to the dockable window
}

// Retrieves a handle to the specified window's parent or owner.
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetParent(IntPtr hWnd);

// Sets the keyboard focus to the specified window.
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr SetFocus(IntPtr hWnd);

// Activates a window.
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr SetActiveWindow(IntPtr hWnd);
blah238
fuente
¿me pueden enviar / publicar la muestra para agregar en la ventana de acoplamiento?

Respuestas:

6

Intente usar la llamada winapi SetWindowPos con el hWnd del control de ventana acoplable (o tal vez sea el control de contenedor principal o abuelo) con el indicador HWND_TOP.

Kirk Kuykendall
fuente
Gracias Kirk, en realidad solo intenté exactamente eso, pero no tuvo ningún efecto. La ventana acoplable no tiene control principal, pero sus propiedades Izquierda y Superior son 0, por lo que supongo que realmente tiene una ventana principal (que no sea la aplicación ArcMap). Realmente odio que no haya una manera más fácil de hacer esto que jugar con la API de Windows. ¿Has tenido suerte con esto tú mismo?
blah238
También es extraño, pero las propiedades Izquierda y Superior de la co-clase IWindowPosition son correctas, pero su método Move no tiene ningún efecto.
blah238
2
Usando spy ++, y mirando una ventana desacoplada, veo que su gran abuelo es arcmap. Entonces me imagino que el zorder lo establecería el abuelo de la ventana acoplable. Tienes razón: seguro que parece que habría una manera más fácil.
Kirk Kuykendall
2
De hecho, es la ventana de los abuelos. Sin embargo, confiar en esta estructura no es ideal, ya que puede romperse fácilmente en futuras versiones de ArcMap. ESRI realmente debería proporcionar alguna interfaz para hacer esto.
Petr Krebs
Gracias a todos, fue un poco difícil pero pude hacerlo funcionar. Editó la pregunta con la solución codificada.
blah238