9

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?


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

The problem's solution seems to be as easy as @llcf's answer:

MyForm form = new MyForm();
form.Show(NativeWindow.FromHandle(new IntPtr(m_application.hWnd)));
asked Oct 21, 2010 at 19:46
1
  • I like this NativeWindow way - very clean. Commented Mar 2, 2012 at 8:07

3 Answers 3

7

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;
 }
answered Oct 22, 2010 at 15:42
1
  • 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. Commented Oct 22, 2010 at 16:20
3

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.

answered Oct 22, 2010 at 12:47
0

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;
 }
}
answered Oct 21, 2010 at 22:32
1
  • 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. Commented Oct 22, 2010 at 12:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.