trouble using delegate in WndProc

when i use delegate like this:


-----------------
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{

delegate_ReplyFromDataProcess = new PrepareDelegate_ReplyFromDataProcess(ReplyFromDataProcess);
delegate_ReplyFromDataProcess.BeginInvoke(m, null, null);

}

delegate void PrepareDelegate_ReplyFromDataProcess(Message m);
private void ReplyFromDataProcess(Message m)
{
IntPtr pnt = dp.OnReply(UInt32.Parse(m.WParam.ToString()), Int32.Parse(m.LParam.ToString()));
}

-----------------

i met the error:
*********

{"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}

*********


but if i changed the code like this:

--------------
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
IntPtr pnt = dp.OnReply(UInt32.Parse(m.WParam.ToString()), Int32.Parse(m.LParam.ToString()));
}
--------------

everything is ok,so why and how i can handle this,thanks




Answer this question

trouble using delegate in WndProc

  • Michael Zilberstein

    i changed the code like this:

    delegate void Delegate_ReplyFromDataProcess(ref Message m);
    private void ReplyFromDataProcess(ref Message m)
    {
    IntPtr pnt = dp.OnReply(UInt32.Parse(m.WParam.ToString()), Int32.Parse(m.LParam.ToString()));
    }


    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    protected override void WndProc(ref Message m)
    {

    Delegate_ReplyFromDataProcess d = new Delegate_ReplyFromDataProcess(ReplyFromDataProcess);
    d.BeginInvoke(ref m,null,null);

    }

    and the error didn't change



  • Gombly

    .toint32() didn't change the trouble to me

    and the "SCHead" in the c++.net is like:

    struct SCHead {
    UInt16 m_nType;
    char m_cStatus;
    long m_lIndex;
    };

    and i compare the m.Msg with nReplyMsg_g to determine what message to cast

    -----------
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    protected override void WndProc(ref Message m)
    {

    if (m.Msg == nReplyMsg_g && Drvloaded)
    {
    Delegate_ReplyFromDataProcess d = new Delegate_ReplyFromDataProcess(ReplyFromDataProcess);
    d.BeginInvoke(m,null,null);
    }

    base.WndProc(ref m);

    }
    --------------


    and the "nReplyMsg_g" is from:

    nReplyMsg_g = RegisterWindowMessage("SCDemo Reply Message");



  • rodan_be

    i've included it like this

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    protected override void WndProc(ref Message m)
    {

    delegate_ReplyFromDataProcess = new repareDelegate_ReplyFromDataProcess(ReplyFromDataProcess);
    delegate_ReplyFromDataProcess.BeginInvoke(m, null, null);

    base.WndProc(ref m);

    }

    but the error is the same



  • JudgeDredd

    the exception triggered in the dp.OnReply() method

    ----
    delegate void Delegate_ReplyFromDataProcess(Message m);
    private void ReplyFromDataProcess(Message m)
    {
    IntPtr pnt = dp.OnReply(UInt32.Parse(m.WParam.ToString()), Int32.Parse(m.LParam.ToString()));
    }

    ----

    the position where exception happened:


    ------------------------
    IntPtr DataProcess::OnReply(WPARAM wParam, LPARAM lParam)
    {

    SCHead *pHead = (SCHead *)lParam;

    if ( pHead->m_cStatus == 0 ) //exception triggered on this line
    {
    ....
    }

    }

    --------------------------

    ps:this is the clr project,and c# add the c++.net project as a reference



  • Jomo Fisher MSFT

    Have you tried it only to solve your problem now

    Otherwise you have to make your delegate method thread-safe.



  • Roland Weiss

    Hi,

    I have created a little project sending the message pointer using an async delegate and a direct call and works fine.

    The only difference is how I pass the parameters, instead "UInt32.Parse(m.WParam.ToString()), " that I find quite ackward I use "m.WParam.ToInt32()", as WPARAM is published by .NET as int (LONG_PTR in C is 32bits).

    I also wonder what are you casting "SCHead *pHead = (SCHead *)lParam; ", it means that you are casting a parameter address to the "SCHead" address.

    You can debug your application (just trap one message) and check if the params have values greater than 0. If you want the address of your parameter you can change the definition to IntPtr or void* and then use "m.WParam.ToPointer()".

    Regards

     



  • Anoop PS

    Hi,

    OK, try this, create a new windows application project, add the following code:

    delegate void TestDel(Message m);

    /// <summary>
    /// Windows procedure override
    /// </summary>
    /// <param name="m"></param>
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    protected override void WndProc(ref Message m)
    {
    TestDel MyDelegate =
    new TestDel(YourCallback);
    MyDelegate .BeginInvoke(m,
    null, null);
    base.WndProc (ref m);
    }

    private void YourCallback(Message m)
    {
    Debug.WriteLine(m.ToString());
    }

    Check if you receive the error, what I am trying to check is the restrictions of your current application or at User/Machine level that maybe generates the exception. This code works for me on 1.1 and 2.0

    Also, where is the exception triggered If you debug your code it is raised when BeginInvoke

    If you can post what are you doing on your callback function also can help us to check where is the error.

    Best regards



  • ubercoder

    The BeginInvoke is a little bit nasty there imho. Because you can get a lot of messages you can better use a blocking method, like Invoke.


  • kerber

    Hi,

    I think what is happening is that the WndPrc is giving you a reference of the Message object (the address) and not the object itself. What I think is happening is that when you send the Message to the Callback is moving the message to a different memory location, then, when you try to send it to your C++ code you are expecting the memory address of the object what you don't have!, that is why is pointer to other place in memory and because the OS works in protected mode does not allow you to access it.

    Try to modify the the delegate to accept a reference of the message instead:

    private delegate YourDelegate(ref Message);

    And try again. Please let me know if this works.

    Regards



  • Kevin POCHAT

    Hi,

    Make sure that at some point you dispatch the messages to the Control using base.WndProc(ref m) otherwise you will get nasty exceptions because not even the windows handle can be created.

    If you include it it works fine, I have just tested it on .NET 1.1 and .NET 2.0 and they work fine.

    Regards



  • tribal

    Hi,

    Cool, now I can reproduce the error, the delegate is changing the address of the param (as I was suspecting!), therefore a direct call works but when it executes the async function it changes the reference! (Bloody .net moving things around!) Let me see if I can find a workaround.

    cheers



  • goelectric

    rsm1235, please try a blocking whay or make it thread safe.

    How often do you invoke the delegate


  • Mike Woods

    for the invoke method is inefficient and not suitable for users

  • Laurentiu Cristofor

    Again, why do you use BeginInvoke and not the blocking Invoke method


  • trouble using delegate in WndProc