Problem with accessing protected memory after creating delegate in VB.NET 2005

Posted on 2007-03-29
Last Modified: 2007-11-27
I have taken some sample code from an application written in VB6.  I used the upgrade wizard to upgrade it to VB 2005.  It told me I needed to add a delegate for AddressOf WindowProc.

I followed the example from the help file and got the program to compile.  It works fine for a while, then after a while (the time varies) I receive an error that it "Attempted to read or write protected memory."  Text from error is below the code.

I don't understand what is happening. I'm a novice programmer and this doesn't make sense to me.  

What the program is doing (as I understand it) is that it uses a .dll to query a server.  This server sends back packets to this program asynchronously.  The program then receives the data packet and determines what to do with it from there.

Any help you can give me will be greatly appreciated.

'++++++++++++++Excerpt from Module1:

Declare Function CallWindowProc Lib "user32"  Alias "CallWindowProcA"(ByVal lpPrevWndFunc As Integer, ByVal hwnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

    '----------------The following 3 lines were modified from the initial build to accomodate a delegate:
    'Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As SubClassProcDelegate) As Integer
    Delegate Function SubClassProcDelegate(ByVal hw As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
      Public Const GWL_WNDPROC As Short = -4
      Public lpPrevWndProc As Integer
      Public gHW As Integer
    Function WindowProc(ByVal hw As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

        Dim intErrCode As Short
        Dim strTime As New VB6.FixedLengthString(40)
        If (uMsg = WM_RTB_MESSAGE) Then
            ' We are receiving a message.
            ' wParam tells us what it is.  We will display some
            ' message according to it.
            Select Case wParam
                Case 1
                    HelloVB.lblStatus.Text = "Trying primary"
                Case 2
                    HelloVB.lblStatus.Text = "Trying secondary"
                Case 3
                    HelloVB.lblStatus.Text = "Logon Completed"
                Case 4
                Case 5
                    ' lParam is the DataPacket ID.
                    ' Get the time out of the data packet.

                    intErrCode = RTBDataGetString(lParam, 0, 0, strTime.Value, 40)
                    HelloVB.lblData.Text = "Hello World, it's " & strTime.Value & "!"

                    ' Free the data packet
                    intErrCode = RTBFreePacket(lParam)
            End Select
        End If
        WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
    End Function

'+++++++++++++Excerpt from Main Class Form

'UPGRADE_WARNING: Add a delegate for AddressOf WindowProc Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="E9E157F7-EF0C-4016-87B7-7D7FBBC6EE08"'
        lpPrevWndProc = SetWindowLong(Me.Handle.ToInt32, GWL_WNDPROC, AddressOf WindowProc)

        '-----------' Create the query

Error information
************** Exception Text **************
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
   at System.Windows.Forms.Form.DefWndProc(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ContainerControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WmSysCommand(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Question by:robbid
  • 2
  • 2

Author Comment

ID: 18817868
Here is some additional information about the error:

A callback was made on a garbage collected delegate of type 'Project1!Project1.Module1+SubClassProcDelegate::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.
LVL 41

Accepted Solution

graye earned 500 total points
ID: 18951740
Take a look at this introductory article about Delegates and the AddressOf operator...   It has some downloadable VB.Net source code examples that might be if help

Author Comment

ID: 19043439
This article helps me understand the process a little better.  I still don't understand why the delegate is being collected, though.  I think I might try re-writing the code myself (using information from the article you provided and some others) and see what happens.
LVL 41

Assisted Solution

graye earned 500 total points
ID: 19044339
I don't see where the value for lpPrevWndProc is originally set.   It appears to me that when SetWindowLong is first called from the "Main Class Form" there is no value for lpPrevWndProc.   It only get's set after SetWindowLong has completed.

But a break on this statement and see what the value of lpPrevWndProc is

        WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entering a date in Microsoft Access can be tricky. A typo can cause month and day to be shuffled, entering the day only causes an error, as does entering, say, day 31 in June. This article shows how an inputmask supported by code can help the user a…
Today, the web development industry is booming, and many people consider it to be their vocation. The question you may be asking yourself is – how do I become a web developer?
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

790 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question