Création d'une fenêtre flottante uniquement (non ancrable) dans ArcMap à l'aide d'ArcObjects?

9

Je cherche un moyen de créer une fenêtre flottante dans ArcMap. Pour donner un exemple, regardez simplement la fenêtre de l'outil Identifier.

Flottant signifie qu'il reste en permanence devant le document ArcMap et que l'utilisateur peut continuer à travailler avec ArcMap. Je sais que l'interface IDockableWindowDef peut être utilisée pour créer des fenêtres ancrables qui peuvent également flotter, mais je ne veux pas qu'elles soient ancrées . À ma connaissance, il n'est pas possible d'empêcher les formulaires créés par IDockableWindowManager de s'arrimer si, par exemple, l'utilisateur les pousse vers la bordure de la fenêtre ArcMap.

Des idées?


La solution consistait à rechercher des mots clés comme fenêtre enfant et MDI. HTH

La solution du problème semble être aussi simple que la réponse de @ llcf :

MyForm form = new MyForm();
form.Show(NativeWindow.FromHandle(new IntPtr(m_application.hWnd)));
Et une
la source
J'aime cette façon NativeWindow - très propre.
Vidar

Réponses:

7

Si en .net, je pense que les exemples que j'ai vus utilisent une classe d'assistance comme ci-dessous:

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

la source
Oui! Au lieu de votre wrapper, j'ai utilisé NativeWindow.FromHandle () qui fait exactement la même chose. Cela fonctionne et semble plus élégant que la solution avec user32.dll, à mon avis. Merci.
AndOne
3

J'ai trouvé la réponse à ce problème à l'aide des anciens forums ESRI. Je venais d'utiliser les mauvais mots clés jusqu'à présent: / La solution réside dans 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);
    }
}

Je ne suis pas sûr que la compatibilité 64 bits soit correctement implémentée car SetWindowLongPtr () est censé remplacer SetWindowLong () mais je n'ai pas pu le faire fonctionner sur ma machine 64 bits. Toujours obtenu une EntryPointNotFoundException. Mais au moins cela fonctionne avec ma configuration de développement.

Et une
la source
0

Si vous utilisez .NET, la création d'un formulaire Windows non modal et la définition de la propriété TopMost sur true est la meilleure solution. Vous souhaiterez également définir la propriété Parent du formulaire sur l'application 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
la source
1
Merci, mais malheureusement, cela ne se comporte pas comme demandé. Avec TopMost étant vrai, le formulaire reste devant toutes les autres fenêtres même lorsque ArcMap est minimisé. S'il est défini sur false, le formulaire sera masqué derrière la fenêtre ArcMap.
AndOne