¿Crea una ventana flotante (no acoplable) en ArcMap usando ArcObjects?

9

Estoy buscando una manera de crear una ventana flotante en ArcMap. Para dar un ejemplo, solo mira la ventana de la herramienta Identificar.

Flotante significa que permanece delante del documento de mapa en todo momento y que el usuario puede continuar trabajando con ArcMap. Sé que la interfaz IDockableWindowDef se puede usar para crear ventanas acoplables que también pueden flotar, pero no quiero que se acoplen . Que yo sepa, no es posible evitar que los formularios creados por IDockableWindowManager se acoplen, por ejemplo, si el usuario los empuja hasta el borde de la ventana de ArcMap.

¿Algunas ideas?


La solución fue buscar palabras clave como ventana secundaria y MDI. HTH

La solución del problema parece ser tan fácil como la respuesta de @ llcf :

MyForm form = new MyForm();
form.Show(NativeWindow.FromHandle(new IntPtr(m_application.hWnd)));
Y uno
fuente
Me gusta esta forma de NativeWindow, muy limpia.
Vidar

Respuestas:

7

Si en .net, creo que los ejemplos que he visto usan una clase auxiliar como se muestra a continuación:

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;
  }

fuente
¡Si! En lugar de su contenedor, utilicé NativeWindow.FromHandle () que hace exactamente lo mismo. Funciona y parece más elegante que la solución con user32.dll, en mi opinión. Gracias.
AndOne
3

Encontré la respuesta a este problema con la ayuda de los foros de ESRI más antiguos. Solo había usado las palabras clave incorrectas hasta ahora: / La solución está en 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);
    }
}

No estoy muy seguro de si la compatibilidad de 64 bits se implementa correctamente porque se supone que SetWindowLongPtr () reemplaza a SetWindowLong () pero no pude hacer que funcione en mi máquina de 64 bits. Siempre tengo una EntryPointNotFoundException. Pero al menos esto funciona con mi configuración de desarrollo.

Y uno
fuente
0

Si está utilizando .NET, la mejor opción es crear un formulario de Windows sin modo y establecer la propiedad TopMost en verdadero. También querrá establecer la propiedad principal del formulario en la aplicación 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
fuente
1
Gracias, pero desafortunadamente esto no se comporta como se solicitó. Dado que TopMost es cierto, el formulario permanece delante de todas las demás ventanas incluso cuando ArcMap está minimizado. Si se establece en falso, el formulario se ocultará detrás de la ventana de ArcMap.
AndOne