Embedding the whole Mapinfo application in a .Net form.


Not sure if I’ll ever have a need for this, but someone else may so I thought I would throw this up here, just in case.

A couple of days ago there was a question on MapInfo-l about embedding MapInfo into a .Net application(http://groups.google.com/group/mapinfo-l/browse_thread/thread/15dfc23ceff8ceef).
Embedding a map window into .Net is something that is covered in the Mapbasic manual however this is not what was needed, what was interesting was the person wanted to be able to embed the whole Mapinfo application menus and all into a .Net contol.

As I had not done this before or seen anyone else do it I thought it might be interesting to have a look into it, knowing also that by using Win32 libraries from .Net(eg User32.dll) you could do some cool stuff I figured why not?

The following code is what I managed to write that lets me embed the whole application into a .Net control(I let the code comments explain what is going on):

For this code to work you will need to create a .Net form with a picture box somewhere on it and a button that calls button1_click for it’s click handler, you will also need to reference Mapinfow.exe/Mapinfo COM server see https://woostuff.wordpress.com/2009/04/01/com-instance-mapinfo-main/ for details.

    public partial class Form1 : Form
    {
        // Sets the parent of a window.
        [DllImport("User32", CharSet = CharSet.Auto, ExactSpelling = true)]
        internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndParent);

        //Sets window attributes
        [DllImport("USER32.DLL")]
        public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        //Gets window attributes
        [DllImport("USER32.DLL")]
        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        //assorted constants needed
        public static int GWL_STYLE = -16;
        public static int WS_CHILD = 0x40000000; //child window
        public static int WS_BORDER = 0x00800000; //window with border
        public static int WS_DLGFRAME = 0x00400000; //window with double border but no title
        public static int WS_CAPTION= WS_BORDER | WS_DLGFRAME; //window with a title bar
        public static int WS_MAXIMIZE = 0x1000000;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Create a new instance of MapInfo.
            MapInfoApplication mapinfo = new MapInfoApplication();

            // Get the handle to the whole MapInfo application.
            // 9 = SYS_INFO_MAPINFOWND.
            string handle = mapinfo.Eval("SystemInfo(9)");

            // Convert the handle to an IntPtr type.
            IntPtr oldhandle = new IntPtr(Convert.ToInt32(handle));

            //Make mapinfo visible otherwise it won't show up in our control.
            mapinfo.Visible = true;

            //Set the parent of MapInfo to a picture box on the form.
            SetParent(oldhandle, this.pictureBox1.Handle);

            //Get current window style of MapInfo window
            int style = GetWindowLong(oldhandle, GWL_STYLE);

            //Take current window style and remove WS_CAPTION(title bar) from it
            SetWindowLong(oldhandle, GWL_STYLE, (style & ~WS_CAPTION));

            //Maximize MapInfo so that it fits into our control.
            mapinfo.Do("Set Window 1011 Max");
        }
    }

After the code is complied and run you should end up with a screen like this:
(Once the whole MapInfo application is embedded into our C# application, we can still do all the Do and Eval methods that we normally would when doing integrated Mapping)

Advertisements

3 thoughts on “Embedding the whole Mapinfo application in a .Net form.

  1. Imports System.Runtime.InteropServices
    Imports MapInfo

    Public Class Form1

    Inherits Form
    ‘ Sets the parent of a window.
    _
    Friend Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndParent As IntPtr) As IntPtr
    End Function

    ‘Sets window attributes
    _
    Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
    End Function

    ‘Gets window attributes
    _
    Public Shared Function GetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
    End Function
    ‘assorted constants needed
    Public Shared GWL_STYLE As Integer = -16
    Public Shared WS_CHILD As Integer = &H40000000
    ‘child window
    Public Shared WS_BORDER As Integer = &H800000
    ‘window with border
    Public Shared WS_DLGFRAME As Integer = &H400000
    ‘window with double border but no title
    Public Shared WS_CAPTION As Integer = WS_BORDER Or WS_DLGFRAME
    ‘window with a title bar
    Public Shared WS_MAXIMIZE As Integer = &H1000000
    ‘Public Sub New()
    ‘InitializeComponent()
    ‘End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    InitializeComponent()
    End Sub

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    ‘ Create a new instance of MapInfo.

    ‘ Dim mapinfo As New MapInfoApplication()

    Dim mapinfo As New Object

    mapinfo = CreateObject(“MapInfo.application”)

    ‘ Get the handle to the whole MapInfo application.
    ‘ 9 = SYS_INFO_MAPINFOWND.
    Dim handle As String = mapinfo.Eval(“SystemInfo(9)”)
    ‘ Convert the handle to an IntPtr type.
    Dim oldhandle As New IntPtr(Convert.ToInt32(handle))
    ‘Make mapinfo visible otherwise it won’t show up in our control.
    mapinfo.Visible = True
    ‘Set the parent of MapInfo to a picture box on the form.
    SetParent(oldhandle, Me.PictureBox1.Handle)
    ‘Get current window style of MapInfo window
    Dim style As Integer = GetWindowLong(oldhandle, GWL_STYLE)
    ‘Take current window style and remove WS_CAPTION(title bar) from it
    SetWindowLong(oldhandle, GWL_STYLE, (style And Not WS_CAPTION))
    ‘Maximize MapInfo so that it fits into our control.
    mapinfo.[Do](“Set Window 1011 Max”)
    End Sub
    End Class

    i converted it to vb.net but i can’t get it to work ;-(

  2. Hi!
    With your code above, I can embed the mapinfo in a .Net form, also I can operate the Do() and Eval() to get some infomation with the mapinfo object.
    However, when I use the Do() methods to update the table, I get some trouble.
    statement like ‘Update T1 Set Name = “WordPress”‘ seems not work, nothing change with my table.
    Have you got this before??

  3. this information is old and i got my software working post your code segment for you do statment and i will look at it, I also posted working code on the mapinfo group

    Evil G

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s