At 16:54 14.03.2006 +0100, Milo van der Linden wrote:
Hello Christian (list),

You answered my previous question on callbacks, so I hope you don't find it
rude that I ask you one more.

I have the callback up and running and manage to get the "click" event in
MapInfo into a msgbox. I am also able to show the statustext on the
statusbar. However,
When I store the returnd X and Y coordinates from the callback in a variable
and call another form with it, my newly opened form hangs. I have been
searching myself a roundtrip in the world of threading, invoke and
marshalling, but I cannot get it running.

Any ideas of how I can make the callback function end up in the same thread
as my main application?

Kind regards,

Milo van der Linden


Hello Milo,

with callback functions it is generally advisable to return control to
the caller (here the MapInfo COM/OLE object) immediately, i.e. without
potential delays caused by user interaction requests etc. The creation
of a new form from within the callback function should thus be avoided.

Instead the callback function could store the received parameters in
persistent variables, then trigger a user event with the "PostMessage"
API function and then return control to the caller. The event can then
be processed by the receiving window/form without blocking the OLE
server's thread.

The code sample given before requires the following extensions and
modifications:

At first you'll need some Win32 API InterOp declarations:

    Class Win32Api

        Public Const WM_USER As Int32 = &H400

        Public Declare Auto Function PostMessage Lib "user32.dll" _
             (ByVal hwnd As IntPtr, _
              ByVal wMsg As Int32, ByVal wParam As Int32, _
              ByRef lParam As IntPtr) As Int32

    End Class


The following class variables are persistent / "Shared" members of
the main window class (could as well be in a general app class etc.):

        Public Shared sLastUserEventX As String
        Public Shared sLastUserEventY As String
        Public Shared hwndMain As IntPtr


Within the constructor of the main window (form1.new()) the window
handle is saved permanently for later access from outside the form's
class:

        hwndMain = Me.Handle


Then the window procedure of the main form is customized so as to
react to the event triggered by the callback function and display a
second form:

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = Win32Api.WM_USER Then
            Dim myForm2 As New Form2()
            myForm2.Show()
        Else
            MyBase.WndProc(m)
        End If
    End Sub


The callback function parses the received string parameter and saves the
coordinate values into the public variables of the main window's class,
then triggers the WM_USER event and returns without delay:

    Public Sub SelectGeneric(ByVal str As String)
        Dim split As String() = str.Split(",")
        Form1.sLastUserEventX = split(0).Substring(3)
        Form1.sLastUserEventY = split(1)
        Win32Api.PostMessage(Form1.hwndMain, Win32Api.WM_USER, 0, 0)
    End Sub


The second form, intended to display the coordinate values, fetches these
values from the respective variables in the contstructor (new()) function
and puts these into two text boxes:

    TextBox1.Text = Form1.sLastUserEventX
    TextBox2.Text = Form1.sLastUserEventY


Does this solve your problem?

Regards,

Christian Singer





Ing.-Büro
Christian Singer
Singerhoffstr. 14
44225 Dortmund
Germany
E-mail:  [EMAIL PROTECTED]
WWW   :  www.icsinger.de
Phone :  +49 231 791464
Fax   :  +49 231 791460


_______________________________________________
MapInfo-L mailing list
[email protected]
http://www.directionsmag.com/mailman/listinfo/mapinfo-l

Reply via email to