Создание плавающего (не закрепляемого) окна в ArcMap с использованием ArcObjects?

9

Я ищу способ создать плавающее окно в ArcMap. Чтобы привести пример, просто посмотрите на окно инструмента «Идентифицировать».

Плавающий означает, что он всегда находится перед документом карты и что пользователь может продолжать работать с ArcMap. Я знаю, что интерфейс IDockableWindowDef может быть использован для создания закрепляемых окон, которые также могут всплывать, но я не хочу, чтобы они состыковывались . Насколько мне известно, невозможно предотвратить стыковку форм, созданных IDockableWindowManager, если, например, пользователь перемещает их к границе окна ArcMap.

Любые идеи?


Решением был поиск ключевых слов, таких как дочернее окно и MDI. НТН

Решение проблемы кажется таким же простым, как и ответ @ llcf :

MyForm form = new MyForm();
form.Show(NativeWindow.FromHandle(new IntPtr(m_application.hWnd)));
И один
источник
Мне нравится этот способ NativeWindow - очень чистый.
Видар

Ответы:

7

Если в .net я думаю, что примеры, которые я видел, используют вспомогательный класс, как показано ниже:

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

источник
Да! Вместо вашей обертки я использовал NativeWindow.FromHandle (), который делает то же самое. На мой взгляд, он работает и выглядит более элегантно, чем решение с user32.dll. Спасибо.
AndOne 22.10.10
3

Я нашел ответ на эту проблему с помощью старых форумов ESRI. Только что использовал неправильные ключевые слова до сих пор: / Решение находится в 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);
    }
}

Я не совсем уверен, правильно ли реализована 64-битная совместимость, потому что SetWindowLongPtr () должен был заменить SetWindowLong (), но я не смог заставить его работать на моей 64-битной машине. Всегда получал EntryPointNotFoundException. Но по крайней мере это работает с моей установкой dev.

И один
источник
0

Если вы используете .NET, лучше всего создать немодальную форму Windows и установить для свойства TopMost значение true. Вы также захотите установить свойство Parent формы для приложения 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
Спасибо, но, к сожалению, это не так, как просили. Если TopMost имеет значение true, форма остается перед всеми другими окнами, даже если ArcMap свернут. Если установлено значение false, форма будет скрыта за окном ArcMap.
AndOne 22.10.10