Creazione di una finestra mobile (non ancorabile) in ArcMap usando ArcObjects?


9

Sto cercando un modo per creare una finestra mobile in ArcMap. Per fare un esempio, basta guardare la finestra dello strumento Identifica.

Mobile indica che rimane sempre davanti al documento della mappa e che l'utente può continuare a lavorare con ArcMap. So che l'interfaccia IDockableWindowDef può essere utilizzata per creare finestre agganciabili che possono anche galleggiare, ma non voglio che si ancorino . Per quanto ne sappia, non è possibile impedire l'ancoraggio dei moduli creati da IDockableWindowManager se, ad esempio, l'utente li spinge al bordo della finestra di ArcMap.

Qualche idea?


La soluzione era cercare parole chiave come finestra figlio e MDI. HTH

La soluzione del problema sembra essere facile come la risposta di @ llcf :

MyForm form = new MyForm();
form.Show(NativeWindow.FromHandle(new IntPtr(m_application.hWnd)));

Mi piace questo modo NativeWindow - molto pulito.
Vidar

Risposte:


7

Se in .net penso che gli esempi che ho visto utilizzino una classe helper come di seguito:

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

Sì! Invece del tuo wrapper ho usato NativeWindow.FromHandle () che fa esattamente lo stesso. A mio avviso, funziona e sembra più elegante della soluzione con user32.dll. Grazie.
AndOne,

3

Ho trovato la risposta a questo problema con l'aiuto dei precedenti forum ESRI. Finora avevo usato solo le parole chiave sbagliate: / La soluzione sta in 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);
    }
}

Non sono del tutto sicuro se la compatibilità a 64 bit sia implementata correttamente perché SetWindowLongPtr () dovrebbe sostituire SetWindowLong () ma non sono riuscito a farlo funzionare sul mio computer a 64 bit. Ho sempre ricevuto un EntryPointNotFoundException. Ma almeno questo funziona con la mia configurazione di sviluppo.


0

Se stai usando .NET, la scelta migliore è creare un Windows Form non modale e impostare la proprietà TopMost su true. Ti consigliamo inoltre di impostare la proprietà Parent del form sull'applicazione 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;
    }
}

1
Grazie, ma sfortunatamente questo non si comporta come richiesto. Con TopMost vero, il modulo rimane davanti a tutte le altre finestre anche quando ArcMap è ridotto a icona. Se impostato su false, il modulo verrà nascosto dietro la finestra di ArcMap.
AndOne,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.