How to center a modeless .Net Form in ArcMap

1771
5
06-09-2010 02:58 PM
EricPaitz
Esri Contributor
I am able to setup the owner of the form so that the modeless dialog will minimize with ArcMap and stay ontop of ONLY ArcMap but I am unable to get a modeless dialog to center on ArcMap even when I have its StartupPosition set to CenterParent. I have tried the following:

public override void onCreate(object hook) {
     m_pApplication = hook as IApplication
}

public override void OnClick() {
     IntPtr pIntPtr = new IntPtr(m_pApplication.hWnd);
     MyForm pMyForm = new MyForm();
     pMyForm.Show((System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(pIntPrt);
}


Maybe the CenterParent property does not apply to a Modeless Form?

Thanks,
   -eric
0 Kudos
5 Replies
RuchiraWelikala
Occasional Contributor
I am able to setup the owner of the form so that the modeless dialog will minimize with ArcMap and stay ontop of ONLY ArcMap but I am unable to get a modeless dialog to center on ArcMap even when I have its StartupPosition set to CenterParent. I have tried the following:

public override void onCreate(object hook) {
     m_pApplication = hook as IApplication
}

public override void OnClick() {
     IntPtr pIntPtr = new IntPtr(m_pApplication.hWnd);
     MyForm pMyForm = new MyForm();
     pMyForm.Show((System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(pIntPrt);
}


Maybe the CenterParent property does not apply to a Modeless Form?

Thanks,
   -eric


In your form properties, try setting the StartPositon to CenterScreen.
0 Kudos
NeilClemmons
Regular Contributor III
Eric, if you follow the link in my signature to our company blog you'll find an entry that addresses the issue of showing modeless dialogs using .NET.  I'm not sure if it will correct the issue with centering the dialog so let me know how it goes.
0 Kudos
KenBuja
MVP Esteemed Contributor
When I call my modeless form, I initialize its position to the center of the ArcMap window with the following code.


  Dim InitializeForm As New myProject.Processing
  InitializeForm.Form_Initialize(m_application)
  InitializeForm.Show(New Win32HWNDWrapper(m_application.hWnd))

the following is the code for the form

Public Class Processing

  Friend Sub Form_Initialize(ByVal m_Application As ESRI.ArcGIS.Framework.IApplication)

    Dim pWinPos As ESRI.ArcGIS.Framework.IWindowPosition
    Dim CenterX As Short
    Dim CenterY As Short

    pWinPos = m_Application
    CenterX = (pWinPos.Width / 2) + pWinPos.Left
    CenterY = (pWinPos.Height / 2) + pWinPos.Top

    Me.Left = CenterX - Me.Width / 2
    Me.Top = CenterY - Me.Height / 2

  End Sub

End Class

the following is the code for the class Win32HWNDWrapper

Public Class Win32HWNDWrapper
  Implements System.Windows.Forms.IWin32Window
  Private _hwnd As System.IntPtr

  Public ReadOnly Property Handle() As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
    Get
      Return _hwnd
    End Get
  End Property

  Public Sub New(ByVal Handle As System.IntPtr)
    _hwnd = Handle
  End Sub
End Class
0 Kudos
EricPaitz
Esri Contributor
Thanks everyone! Based on all the comments these are the two small classes I came up with. The first is just a way to wrap the IApplication and expose its Handle as a IWin32Window. This class can be used as the owner of the Show() method on a Form. That will deal with being ontop of the ArcMap application (only) and to minimize, maximize and restore with the ArcMap application too. The second class is a base class that any of my modeless forms can inherit from. Thanks again! 🙂

public class IApplicationWrapper : System.Windows.Forms.IWin32Window {
 System.IntPtr m_pIntPtr;

 public IApplicationWrapper(IApplication pApplication) {
  m_pIntPtr = new IntPtr(pApplication.hWnd);
 }
 public IApplicationWrapper(SystemIntPtr pIntPtr) {
  m_pIntPtr = pIntPtr;
 }
 IntPtr System.Windows.Forms.IWin32Windwo.Handle {
  Get { return m_pIntPtr; }
 }
}

public class BaseForm : System.Windows.Forms.Form {
 private IApplication m_pApplication = null;
 
 ~BaseForm() {
  ESRI.ArcGIS.ADF.ComRelease.ReleaseCOMObject(m_pApplication);
 }

 protected override void OnLoad(EventArgs e) {
  if (m_pApplication != null) {
   this.Left = (((((IWindowPosition)m_pApplication).Width / 2) + ((IWindowPosition)m_pApplication).Left) �?? (this.Width / 2));
   this.Top = (((((IWindowPosition)m_pApplication).Height / 2) + ((IWindowPosition)m_pApplication).Top) �?? (this.Height / 2));
  }
  base.OnLoad(e);
 }
 public void Show(IApplication pApplication) {
  m_pApplication = pApplication
  this.Show(new IApplicationWrapper(pApplication));
 }
}
0 Kudos
RichardColeman
New Contributor III
I've been trying to display a modeless form with the parent ArcMap form as the parent.

This code works, but only the first time.

IntPtr pPtr = new IntPtr(_application.hWnd);
_parentWindow = (System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(pPtr);
this.Show(_parentWindow);

Where _application is a valid reference to the current IApplication ArcMap object

If I close the dialog box and try to open it a second time, _parentWindow is always null.  Even though _application.hWnd > 0.

Is there any reason why this only works once?

How can I create a modeless dialog in ArcMap (C#) that the user can open and close and will always have ArcMap as the parent?

Thanks,

rick.
0 Kudos