RE: Mouse Events, Integrated Mapping w/ VB.NET VS2010, MapInfo Pro 11.5

1,183 views
Skip to first unread message

ICW Keith

unread,
Oct 24, 2012, 8:22:34 PM10/24/12
to mapi...@googlegroups.com
I have been programming in MapBasic for a long time but I am fairly new to using VB.NET.  I have been working on an integrated mapping application (The base was built from the Sample IntegratedMappingVB that comes with MapBasic Samples).  The basic components of the application consist of a Main Form, A Panel, A statusStrip, a ToolStrip with several tool buttons, which I added new, on the right side of the form.  Adding tool buttons for Zoom In, Zoom Out, Pan and Select were all relatively easy.  I have been able to make my own Change View form which allows the end user to change the map Distance Units and Map Zoom within one form (for anyone else considering doing this the Set Distance Units/SessionInfo(2-SESSION_INFO_DISTANCE_UNITS ) plays an important role.  I have a Ruler tool that I want to customize.  I have been able to show the MI Pro ruler window that shows the distance of the last line drawn as well as the cumulative length.  But Instead of using that particular Ruler Window, I would like to be able to show the ruler distance in a statusbar at the bottom of the form.  I have attempted to use the standard Mouse events that are events of the panel,  However once the MapInfo Window application fills the Panel I no longer get any Mouse events to fire from the panel.  I see that there are MapInfo Callback events, which are OnMenuItemClick, OnStatusBarTextChanged and OnWindowContentsChanged.  I see there are NO MapInfo Callbacks for Mouse Events.  I wonder why not?  This would certainly be helpful.
 
So all of that being said, my question to the MapInfo L community is how might one capture Mouse Events that occur in the Map Window that has a Panel as a Parent?  I would not have thought this was such a monumental task.  Perhaps I am looking the wrong way.  Any input would be appreciated.   Have a Great Day!

Evil "G"

unread,
Oct 24, 2012, 10:10:40 PM10/24/12
to mapi...@googlegroups.com
i have used vb.net  2010 and mapinfo 10 unless the example in the book has changed for 11.5 it will not work correctly
post your vb.net code on how you call mapinfo
 

ICW Keith

unread,
Oct 25, 2012, 11:48:09 AM10/25/12
to mapi...@googlegroups.com
Hopefully this will give you an idea of how I create the mapinfo object.  The map window is not created until a workspace is opened.  I open a workspace when the form is loaded.  The workspace will be specified prior to launching the application.  Upon opening a workspace the map window is created in a panel on a form.(see Screen Capture picture)
 
 
 
Evil "G" Some of your examples have been very helpful.  I was able to put the entire MapInfo application in a form, but I am attempting to model this particular app after an app we currently have in vb6 and mapx (4 or 5).
 
 

Implements

MapInfo.MiPro.Samples.IM.ICallbackNotify

' Strings displayed in a combobox, to let the user choose a map tool

Private _mapToolPan As String = "Pan"

   

   

' Id of the map window being reparented

Public _mapWindowId As String = ""

' HWND of the window being reparented

Private _hWnd As System.IntPtr

' Mapping of map tool names to tool command ids

Private _toolIdMap As Dictionary(Of String, Integer)

'ID of the custom OLE menu item on the map window's context menu

Private Const _customItemId As UInteger = 10000

' Reference to the callbackobject

Private _callbackObject As MapInfo.MiPro.Samples.IM.MapInfoCallBack

' Store a reference to MapInfo Professional's COM interface

Public _mapInfoApp As MapInfoApplication

Private Sub InitializeComObject()

Dim cmd As String = String.Format("Set Application Window {0}", Me.Handle)

' Create the MapInfo Professional object

_mapInfoApp =

New MapInfoApplication()

' Set parent window for MapInfo Professional dialogs

_mapInfoApp.Do(cmd)

' Create the callback object

_callbackObject =

New MapInfo.MiPro.Samples.IM.MapInfoCallBack(Me)

' Register the callback object with MapInfo Professional

_mapInfoApp.RegisterCallback(_callbackObject)

End Sub

 

Private

Sub MapForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

' Create an instance of MapInfo Professional, silently/hidden

InitializeComObject()

' Add a custom item to the map window's context menu

AddMapperShortcutMenuitem()

Dim WorkSpace1 As String = "D:\MapData\MyWorkSpace.WOR"

Dim cmd1 As String

cmd1 =

String.Format("Set application window {0}", Me.Handle)

MapInfoApp.Do(cmd1)

cmd1 =

String.Format("Set Next Document Parent {0} Style 1", Me.MapPanel.Handle)

MapInfoApp.Do(cmd1)

MapInfoApp.Do(

"Run application " & Chr(34) & WorkSpace1 & Chr(34))

'D:\MB115_NEW\HillsMapData\HILLS_AVL.WOR

_mapWindowId = MapInfoApp.Eval(

"WindowID(0)")

' MapInfoApp.Do("Run application " & Chr(34) & "D:\KEITHSOURCE\SAM_Sample\keithtest.mbx" & Chr(34))

' Call WindowInfo with 12 (WIN_INFO_WND) to get the Windows HWND.

' If the user resizes the form, we need the HWND to update the map size.

Dim hWnd As Long = Long.Parse(_mapInfoApp.Eval("WindowInfo(FrontWindow(),12)"))

_hWnd =

New System.IntPtr(hWnd)

End Sub

 

 

 
ScreenCapture.png

Evil "G"

unread,
Oct 25, 2012, 5:04:26 PM10/25/12
to mapi...@googlegroups.com
Keith
 
it would be easier to use a VB.net tool bar and call the mapinfo functions from their
the way your trying to do this will will be very hard.
 

ICW Keith

unread,
Oct 25, 2012, 6:39:40 PM10/25/12
to mapi...@googlegroups.com
VB.net and MapInfo Pro integration has proven to be quite demanding.
It is as if this type of integration really was not meant to be.
MapExtreme would probably be much better and MapX has been discontinued
in response to the toolbar.
 
Actually the buttons on the right side are a vb.net ToolStrip and ToolStripButtons(i had to make screen captures and clean up color for the images you see on the buttons).  I am making pretty good progress with the app.  I have had to press on about the ruler. However, I saw where someone said to get the ruler to appear is to make it the child of a newly added in form.  Actually that was not necessary, I actually did the following and when the user tabs from this app to another, the ruler window goes with it, where as before it was behaving like a totally separate app.  The code is as follows.
 

Dim cmd1 As String = String.Format("Run Menu Command {0}", commandId)

_mapInfoApp.Do(cmd1)

Dim msg As String

msg =

"Set Window Ruler Parent " & Me.MapPanel.Handle.ToString

_mapInfoApp.Do(msg)

Dim hwnd As Integer

hwnd = MapInfoApp.Eval(

"windowinfo(1007,12)")

SetParent(hwnd,

Me.MapPanel.Handle)  '<----This was the ticket for good behavior.(the mappanel is the container for the mapwindow)
 
 
  It seems as though MapInfo does a pretty good job of hiding the actual mouse clicks in their map window.  In MapBasic, if a person makes a custom tool using the DM_CUSTOM_POLYLINE the xy's and developing object can not be analyzed until the drawer has completed drawing the polyline.  It seems the only way to terminate this style tool is to double click at the end of drawing unlike the standard polyline tool.  
 
 

Include "icons.def"

Include "mapbasic.def"

Declare Sub Main

Declare Sub draw_via_button

Sub Main

Create ButtonPad "Custom" As

ToolButton

Icon MI_ICON_LINE

DrawMode DM_CUSTOM_POLYLINE

Cursor MI_CURSOR_CROSSHAIR

ModifierKeys On

Calling draw_via_button

HelpMsg "Draws a polyline on a Map window\nDraw Line"

Show

End Sub

Sub draw_via_button

Dim x1, y1,x2, y2 As Float

If WindowInfo(FrontWindow(),WIN_INFO_TYPE) <> WIN_MAPPER Then

Note "This tool may only be used on a Map window. Sorry!"

Exit Sub

End If

Dim Pobj1 as object

Pobj1=CommandInfo(CMD_INFO_CUSTOM_OBJ)

Dim Pobj2 as object

alter object Pobj1 info OBJ_INFO_PEN,MAKEPEN(2,255,3)

dim i as integer

for i =1 to objectinfo(Pobj1,obj_info_npnts)

print format$(objectnodeX(Pobj1,1,i),"00.000000")

print format$(objectnodeY(Pobj1,1,i),"00.000000")

insert into cosmetic1(obj) values (Createpoint(objectnodeX(Pobj1,1,i), objectnodeY(Pobj1,1,i)))

next

insert into cosmetic1(obj) values (Pobj1)

end sub

 

 

ICW Keith

unread,
Oct 25, 2012, 6:51:55 PM10/25/12
to mapi...@googlegroups.com
Actually one line should be
 
msg =

"Set Window Ruler Parent " & Me.Handle.ToString      (Me.MapPanel.Handle.ToString is incorrect)

_mapInfoApp.Do(msg)

 

ICW Keith

unread,
Oct 26, 2012, 4:24:03 PM10/26/12
to mapi...@googlegroups.com

It appears that parenting the ruler to a new form, the map window object, the mappanel or the main form still has not provided behavior identical to mapinfo pro.  This is proving to be quite the challenge.  I guess my expectation on this integrated mapping is too high.

 

 

Evil "G"

unread,
Oct 27, 2012, 1:12:54 PM10/27/12
to mapi...@googlegroups.com

you need to control mapinfo from VB.net the problem with integrated mapping is that windows 7 is a multi thread operation system and mapinfo is an outdated 32 bit windows App they just don't play nice

ICW Keith

unread,
Nov 1, 2012, 5:39:36 PM11/1/12
to mapi...@googlegroups.com
I have been using two different windows 7 machines one 64 and one 32.   Currently using the integrated mapping where I just use a map window from MI Pro. I can check to see if a particular layer is in the map, if not I see if it is on the hard drive, if not I create it.  Either way the window ID for the map window is used several times without issue.  As soon as I try to add the Layer to the Map window using (vb.net/mapbasic syntax Do and EVal of course) I get a COM/Hresult error complaining that it is the wrong Window ID.  This darn window id is used repeatedly prior to trying to add the layer.  I can even right click and add the newly created mappable table to the map window.  But programmatically MI Pro complains about the darn window ID.  I even tried using the Frontwindow() command to no avail.  I even copied the syntax for the statement to the mapbasic window with the full blown mi pro open and it worked.   Unbelievable.  I have not given up yet.  I will persist and the software will abide.
 
Evil "G" Have you used any MapExtreme and Vb.net?  MapX was a pretty good product.  I will be trying out MapExtreme soon.  I  am not sure about the pricing per license though. 

Evil "G"

unread,
Nov 1, 2012, 6:03:54 PM11/1/12
to mapi...@googlegroups.com
I feel your pain
 
send me an example VB.net program I will debug it for you
 
your using mapinfo 10 or higher correct?
 
 

ICW Keith

unread,
Nov 1, 2012, 6:28:21 PM11/1/12
to mapi...@googlegroups.com
In MapInfo Pro. If there is only one map window open.  I used the:
 
Works fine in MI Pro
 
Add map auto layer "MyLayer"
 
and it still complains the map window is the wrong window Id in the integrated mapping.
 
This must a be  NOT doable in the integrated mapping.  WTF? 
 
I guess after I create the table, I will ask the end user to place it in the map window through the layer control.  What nonsense.

ICW Keith

unread,
Nov 1, 2012, 6:47:12 PM11/1/12
to mapi...@googlegroups.com
 
 
Okay i got it to work by not subbing it out.  most of this all happens in the MapForm Load event(but i like to sub what I can).
 
basically as workspace is open first. then I sub out to determine if my crumbtrail table are in the workspace.
 
To check if the layers are there is subbed out, to build them on the fly it subbed out.  All of this is in a separate module.  so it seems that when that is the case I  pass the MapInfoApp object, the mapwindowID and the table name.  this is what did not work.
 
 

Public Sub AddMapLayer(ByVal MIobj1 As Object, ByVal TabLayer1 As String, ByVal MapWinID1 As Integer)

'I tried this

Dim cmd1 As String = "Add Map Auto Layer " + TabLayer1

and i tried this

cmd1 =

"Add Map Window " & MapWinID1.ToString & " Layer " + TabLayer1

MIobj1.do(cmd1)

End Sub

 
 

'This checks existence, opens if it does, creates it if it does not.

Call MakeCrumbTrail(MapInfoApp, WorPath1)

 

 

======This works in the form load event=====

_mapInfoApp.Do(

"Add Map Window " + _mapWindowId.ToString + " Layer crumbtrail")

and remmed out this

====this does not work in a call from the form load====

'Call AddMapLayer(MIObj1, CTTab1, mapwindid)

 Thanks for the offer Evil "G"
 
I really appreciate that it sounds like you have spent some time doing these kind of shenanigans.  I will persist.
And if it really gets bad I may just take you up on the offer if it still stands.
 
Rock on.
 

Evil "G"

unread,
Nov 2, 2012, 11:07:42 AM11/2/12
to mapi...@googlegroups.com
Public Function Create_Map_ScamCodes(ByVal tablename As String, ByVal filename As String) As Integer
        Dim MSG As String
        tablename = tablename.Replace(" ", "_")
        MSG = "Create Table " & Chr(34) & tablename & Chr(34) & " (Long Float,Lat Float,ScrambleCode Integer,Carrier Char(40),DeviceName Char(100)) file " _
            & Chr(34) & filename & Chr(34) & " TYPE NATIVE Charset " & Chr(34) & "WindowsLatin1" & Chr(34)
        mapinfo.do(MSG)
        MSG = "Create Map For " & tablename & " CoordSys Earth Projection 1, 0"
        mapinfo.do(MSG)
        MSG = "Map From " & tablename
        mapinfo.do(MSG)
        MSG = "Set Map Layer 1 Editable On"
        mapinfo.do(MSG)
        Return Val(mapinfo.eval("frontwindow()"))

           End Function
    
     Public Function Create_BCCH(ByVal row As Double, ByVal mapinfo_window_ID As Integer, ByVal tablename As String, ByVal pointcolor As Color, ByVal Code As Integer, ByVal count As Integer, ByVal other As Boolean) As Double
        Dim msg As String
        tablename = tablename.Replace(" ", "_")
        msg = "Set Style Font Makefont(""Arial"", 1, 30, " & pointcolor.ToArgb & "," & Color.White.ToArgb() & ") "
        mapinfo.do(msg)
        msg = "Insert Into " & tablename & "(obj) Values ( CreateText ( " & mapinfo_window_ID & ", -0.1," & row & "," & Chr(34) & Chr(149) & Chr(34) & ",0,5,0))"
        mapinfo.do(msg)
        msg = "Set Style Font Makefont(""Arial"", 1, 12, " & Color.Black.ToArgb() & "," & Color.White.ToArgb() & ") "
        mapinfo.do(msg)
        msg = "Insert Into " & tablename & "(obj) Values ( CreateText ( " & mapinfo_window_ID & ", -0.1," & row & "," & Chr(34) & Code & " BCCH    ( " & count & " )    " & Chr(34) & ",0,5,15))"
        mapinfo.do(msg)
        row = row - 0.1
        Return row
    End Function

ICW Keith

unread,
Nov 2, 2012, 11:39:17 AM11/2/12
to mapi...@googlegroups.com
the mapinfo object is defined on the main form.  I have added a module with multiple subs.  there is a timer with an ontimed event.  During the ontimedevent I attempt to insert something into mapinfo table, however I do not believe the OnTimedEvent knows what the MapInfoApp object is.  It is really not clear to me how one makes all public variables available for additional modules.  I suppose I could take the contents of the module and put in the code for the form.  That is a lot of code on one form.  Any thoughts would be appreciated.
      
      I did get the tables to build in a sub which is in the module.  The mapinfo object is actually included as an argument in the module sub.  So it knows the MapInfoApp object.  The OnTimedEvent does not afford additional Arguments and does not know the Mapinfo object from Adam.

Evil "G"

unread,
Nov 2, 2012, 12:03:23 PM11/2/12
to mapi...@googlegroups.com
make 1 form that handle all of you mapinfo controls trying to pass the mapinfo object will not work 

ICW Keith

unread,
Nov 2, 2012, 1:18:42 PM11/2/12
to mapi...@googlegroups.com
Thanks, will do, Be Well.

ICW Keith

unread,
Nov 5, 2012, 11:27:56 AM11/5/12
to mapi...@googlegroups.com
Okay that did the trick.  All of the code is now with the form code.  The mapinfo object is now well known through out.

Sokhona Cheikh

unread,
May 14, 2018, 6:03:36 AM5/14/18
to MapInfo-L
Hello,
I really need help.
I'm working on a VB.NET project I have to integrate map with mapinfo for two months I'm deadlocked.
first of all I would like to know how to run mapinfo in the background and display the map part in my VB.net Form.
Reply all
Reply to author
Forward
0 new messages