Criando uma janela flutuante (não acoplável) no ArcMap usando o ArcObjects?

9

Estou procurando uma maneira de criar uma janela flutuante no ArcMap. Para dar um exemplo, basta olhar para a janela da ferramenta Identify.

Flutuar significa que ele fica sempre na frente do documento do mapa e que o usuário pode continuar trabalhando com o ArcMap. Sei que a interface IDockableWindowDef pode ser usada para criar janelas encaixáveis ​​que também podem flutuar, mas não quero que elas encaixem . Que eu saiba, não é possível impedir que os formulários criados pelo IDockableWindowManager sejam encaixados se, por exemplo, o usuário os empurrar para a borda da janela do ArcMap.

Alguma ideia?


A solução foi procurar palavras-chave como janela filho e MDI. HTH

A solução do problema parece ser tão fácil quanto a resposta do @ llcf :

MyForm form = new MyForm();
form.Show(NativeWindow.FromHandle(new IntPtr(m_application.hWnd)));
E um
fonte
Eu gosto desse modo NativeWindow - muito limpo.
Vidar

Respostas:

7

Se em .net eu acho que os exemplos que eu vi usam uma classe auxiliar como abaixo:

var form = new Form1();
form.Show(new WindowWrapper(_mxDocument.ActiveView.ScreenDisplay.hWnd));

public class WindowWrapper : System.Windows.Forms.IWin32Window
  {
    public WindowWrapper(IntPtr handle)
    {
      m_hwnd = handle;
    }
    public WindowWrapper(int handle)
    {
      m_hwnd = (IntPtr)handle;
    }
    public IntPtr Handle
    {
      get
      {
        return m_hwnd;
      }
    }
    private IntPtr m_hwnd;
  }

fonte
Sim! Em vez de seu invólucro, usei NativeWindow.FromHandle (), que faz exatamente o mesmo. Funciona e parece mais elegante que a solução com user32.dll, na minha opinião. Obrigado.
AndOne 22/10/10
3

Encontrei a resposta para esse problema com a ajuda dos fóruns antigos da ESRI. Só tinha usado as palavras-chave erradas até agora: / A solução está em SetWindowLong ():

// import external methods
[DllImport("user32.dll")]
static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll")]
static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
private int GWL_HWNDPARENT = -8;

public TestForm()
{
    InitializeComponent();

    IntPtr mxPtr = new IntPtr(GetApplicationReference().hWnd);
    if(IntPtr.Size == 8) { // needed for 64bit compatibility?
        SetWindowLongPtr(this.Handle, GWL_HWNDPARENT, mxPtr);
    } else {
        SetWindowLong(this.Handle, GWL_HWNDPARENT, mxPtr);
    }
}

Não tenho certeza se a compatibilidade de 64 bits foi implementada corretamente porque SetWindowLongPtr () supostamente substituiu SetWindowLong (), mas não consegui fazê-lo funcionar na minha máquina de 64 bits. Sempre obteve um EntryPointNotFoundException. Mas pelo menos isso funciona com minha configuração de desenvolvedor.

E um
fonte
0

Se você estiver usando o .NET, criar uma Formulário do Windows sem modelo e definir a propriedade TopMost como true é a melhor opção. Você também deseja definir a propriedade Parent do formulário como o aplicativo ArcMap.

sealed class MyForm : Form
{
    // ... other impl ...

    public void SetMxParent(IApplication app)
    {
        IntPtr mxPtr = new IntPtr(app.hWnd);
        this.Parent = Control.FromHandle(mxPtr);

        // optionally
        this.TopMost = true;
    }
}
Jim B
fonte
11
Obrigado, mas infelizmente isso não se comporta como solicitado. Com o TopMost sendo verdadeiro, o formulário permanece na frente de todas as outras janelas, mesmo quando o ArcMap é minimizado. Se estiver definido como false, o formulário ficará oculto atrás da janela do ArcMap.
AndOne 22/10/10