Results 1 to 2 of 2

Thread: VB.NET delegates for callback.

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Oct 1999
    Posts
    23

    VB.NET delegates for callback.

    I am required to secure the handle of a window and read all its child windows. The only way I think is to use EnumChildWindows API of win32. The API implements a callback function. Since my application is VB.NET, I am trying to implement the callback function as a delegate. However I am getting the following error message on the line where the EnumChildWindows API is called.

    An unhandled exception of type 'System.NullReferenceException' occurred in WinAPI.exe
    Additional information: Object reference not set to an instance of an object.


    I tried handling this exception but with no positive results. I guess my implementation of delegates is incorrect. Please guide me.

    [COLOR=dark-blue]
    Option Strict Off
    Imports System
    Imports System.Runtime.InteropServices
    Imports Microsoft.VisualBasic

    Public Class Form1
    Inherits System.Windows.Forms.Form

    <DllImport("user32.dll")> Public Shared Function _
    EnumChildWindows(ByVal hWndParent As Long, ByRef lpEnumFunc As EnumChildGetValueDelegate, ByVal lParam As Long) As Boolean
    End Function

    Delegate Function EnumChildGetValueDelegate(ByVal hWnd As Long, ByVal lParam As Long) As Boolean

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

    Public Function EnumChildGetValue(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
    Dim slength As Long
    Dim retval As Long
    Dim iRet As Integer = 0
    Dim CurClass As String = ""
    Dim strGetValue As String = ""
    Dim lpClassName As String
    Dim strSetValueNew As String
    Const WM_GETTEXTLENGTH = &HE
    Const WM_GETTEXT = &HD
    MsgBox("HELLO!")
    iRet = Win32.GetClassName(hWnd, lpClassName, 50)
    If iRet <> 0 Then
    lpClassName = Trim$(lpClassName)
    If InStr(lpClassName, Chr(0)) > 0 Then _
    CurClass = Microsoft.VisualBasic.Left(lpClassName, InStr(lpClassName, Chr(0)) - 1)
    If CurClass = "Edit" Then
    slength = Win32.SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1
    strGetValue = Space(slength)
    retval = Win32.SendMessage(hWnd, WM_GETTEXT, slength, strGetValue)
    strGetValue = Microsoft.VisualBasic.Left(strGetValue, retval)
    strSetValueNew = strGetValue
    Return False
    Exit Function
    End If
    Return True
    End If
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim hWnd As Integer
    Const WM_GETTEXTLENGTH = &HE
    Const WM_CLOSE = &H10
    Const WM_GETTEXT = &HD
    Const WM_SETTEXT = &HC
    Dim slength As Long
    Dim retval As Long
    Dim strGetValue As String = " "
    Dim objNewDelegate As EnumChildGetValueDelegate
    objNewDelegate = New EnumChildGetValueDelegate(AddressOf EnumChildGetValue)
    hWnd = Win32.FindWindow(vbNullString, "Untitled - Notepad")
    slength = Win32.SendMessage(hWnd, WM_SETTEXT, 0, "Daljeet")
    slength = Win32.SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1
    retval = Win32.SendMessage(hWnd, WM_GETTEXT, 2000, strGetValue)

    If hWnd = 0 Then
    MsgBox("Window Not Open")
    Else
    MsgBox(Win32.GetClassName(hWnd, vbNullString, 50))
    MsgBox("Hi: " & Win32.GetWindow(hWnd, 5))
    MsgBox(Win32.GetClassName(hWnd, vbNullString, 50))
    End If
    End Sub
    End Class
    [/COLOR]

  2. #2
    Junior Member
    Join Date
    Sep 2002
    Posts
    23
    See GCHandle
    "This sample demonstrates how to pass a managed object to an unmanaged function that expects an LPARAM type. An LPARAM type is a pointer to an unmanaged parameter. The Microsoft .NET Framework SDK includes the complete Visual Basic .NET and C# versions of this sample in Samples\Technologies\Interop\Platform-Invoke.

    The GCHandle sample uses the following unmanaged function, shown with its original function declaration:

    EnumWindows exported from User32.dll.
    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    In this sample, the LibWrap class contains a managed prototype of the EnumWindows method. As its parameters, the managed method substitutes the CallBack delegate for the WNDENUMPROC function pointer and an IntPtr pointer for the LPARAM type.

    The App class creates a handle to the managed object using the GCHandle.Alloc method, which prevents the managed object from being collected. A call to the EnumWindows method passes the delegate and the managed object, casting the handle to an IntPtr. The unmanaged function passes the type back to the caller as a parameter of the callback function.

    Declaring Prototypes
    [Visual Basic]
    Public Delegate Function CallBack( ByVal handle As Integer, ByVal param _As IntPtr ) As Boolean

    Public Class LibWrap
    ' Pass a managed object instead of an LPARAM.
    ' Declare a managed prototype for the unmanaged function.
    Declare Function EnumWindows Lib "user32.dll" ( _
    ByVal cb As CallBack, ByVal param As IntPtr ) As Boolean
    End Class 'LibWrap
    [C#]
    public delegate bool CallBack( int handle, IntPtr param );

    public class LibWrap
    {
    // Pass a managed object as an LPARAM type.
    // Declare a managed prototype for the unmanaged function.
    [ DllImport( "user32.dll" )]
    public static extern bool EnumWindows( CallBack cb, IntPtr param );
    }
    Calling Functions
    [Visual Basic]
    Public Class App
    Public Shared Sub Main()
    Dim tw As TextWriter = System.Console.Out
    Dim gch As GCHandle = GCHandle.Alloc( tw )

    ' Platform invoke prevents the delegate from being garbage collected
    ' before the call ends.
    Dim cewp As CallBack
    cewp = AddressOf App.CaptureEnumWindowsProc
    LibWrap.EnumWindows( cewp, GCHandle.op_Explicit( gch ))
    gch.Free()
    End Sub 'Main

    Public Shared Function CaptureEnumWindowsProc( ByVal handle _
    As Integer, ByVal param As IntPtr ) As Boolean
    Dim gch As GCHandle = GCHandle.op_Explicit( param )
    Dim tw As TextWriter = CType( gch.Target, TextWriter )
    tw.WriteLine( handle )
    return True
    End Function 'CaptureEnumWindowsProc
    End Class 'App"

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width