Suplemento do ArcGIS 10: coloque a janela acoplável para frente

8

Eu tenho um complemento ArcGIS 10 ArcMap escrito em C # .NET 3.5 que implementa um ESRI.ArcGIS.Desktop.AddIns.DockableWindow(que também herda de UserControl) e um ESRI.ArcGIS.Desktop.AddIns.Toolque, quando clicado no mapa, atualiza a janela encaixável.

Eu gostaria de trazer a janela encaixável para a frente da ordem Z no OnMouseDown()método da ferramenta (quando estiver no modo desencaixado). Atualmente, se o usuário abrir outra janela acoplável, colocá-la em cima da minha e clicar com a ferramenta, a janela será atualizada, mas não será trazida para a frente. Já estou ligando IDockableWindow.Show(true)para garantir que a janela fique visível depois de clicar com a ferramenta. Eu também tentei, UserControl.BringToFront()mas não tem nenhum efeito.

A melhor solução que eu tenho atualmente é chamar IDockableWindow.Show(false)seguido por IDockableWindow.Show(true), no entanto, isso não é ideal, pois é chocante fazer a janela desaparecer e reaparecer, além de precisar repintar completamente, o que leva uma quantidade substancial de tempo.

A janela interna do Identify não possui esse problema e é trazida para o topo toda vez que a ferramenta Identify é usada, portanto, claramente há uma maneira de fazer isso.

Alguém sabe de uma solução melhor para isso? Obrigado!

Edit: Aqui está o código que acabei usando para resolver isso. Obrigado Kirk e 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
fonte
você pode me enviar / postar a amostra do dockwindow add in?

Respostas:

6

Tente usar a chamada winapi SetWindowPos com o hWnd do controle de janela encaixável (ou talvez seja o controle de contêiner pai ou avô) com o sinalizador HWND_TOP.

Kirk Kuykendall
fonte
Obrigado Kirk, na verdade, tentei exatamente isso, mas não teve efeito. A janela encaixável não tem controle pai, mas suas propriedades Esquerda e Superior são 0, então suponho que isso significa que realmente possui uma janela pai (que não seja o aplicativo ArcMap). Eu realmente odeio que não haja uma maneira mais fácil de fazer isso do que mexer com a API do Windows. Você já teve alguma sorte com isso?
blah238
Também é estranho, mas as propriedades Left e Top da co-classe IWindowPosition estão corretas, mas seu método Move não tem efeito.
blah238
2
Usando o spy ++, e olhando para uma janela desencaixada, vejo que o bisavô é o arcmap. Então, eu imaginaria que o zorder seria definido pelo avô da janela encaixável. Você está certo - com certeza parece que haveria uma maneira mais fácil.
Kirk Kuykendall
2
É de fato a janela dos avós. Contar com essa estrutura não é ideal, pois pode ser facilmente interrompido em versões futuras do ArcMap. A ESRI realmente deve fornecer alguma interface para fazer isso.
Petr Krebs
Obrigado pessoal, foi um trabalho árduo, mas consegui fazê-lo funcionar. Editou a pergunta com a solução codificada.
Blah238