Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm looking for a way to create a floating window in ArcMap. To give an example just look at the window of the Identify tool.

Floating means that it stays in front of the map document at all times and that the user can continue to work with ArcMap. I know that the interface IDockableWindowDef can be used to create dockable windows which can also float, but I don't want them to dock. To my knowledge it's not possible to prevent forms created by IDockableWindowManager from docking if e.g. the user pushes them to the border of the ArcMap window.

Any ideas?

[edit] The solution was to search for keywords like child window and MDI. HTH

[edit2] The problem's solution seems to be as easy as this (see llcf's answer):

MyForm form = new MyForm();
form.Show(NativeWindow.FromHandle(new IntPtr(m_application.hWnd)));
share|improve this question
    
I like this NativeWindow way - very clean. –  Vidar Mar 2 '12 at 8:07
add comment

3 Answers 3

up vote 4 down vote accepted

If in .net I think the examples I have seen uses a helper class as below:

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;
  }
share|improve this answer
    
Yes! Instead of your wrapper I used NativeWindow.FromHandle() which does exactly the same. It works and seems more elegant than the solution with user32.dll, in my view. Thanks. –  AndOne Oct 22 '10 at 16:20
add comment

I found the answer to this problem with the help of the older ESRI forums. Just had used the wrong keywords until now :/ The solution lies 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);
    }
}

I'm not quite sure if the 64bit compatibility is implemented right because SetWindowLongPtr() is supposed to supersed SetWindowLong() but I wasn't able to get it to work on my 64bit machine. Always got an EntryPointNotFoundException. But at least this works with my dev setup.

share|improve this answer
add comment

If you're using .NET, creating a modeless Windows Form and setting the TopMost property to true is the best bet. You'll also want to set the Form's Parent property to the ArcMap application.

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;
    }
}
share|improve this answer
1  
Thanks, but unfortunately this doesn't behave like requested. With TopMost being true the form stays in front of all other windows even when ArcMap is minimized. If it is set to false, the form will be hidden behind the ArcMap window. –  AndOne Oct 22 '10 at 12:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.