|
-
Nov 1st, 2002, 01:31 AM
#1
Thread Starter
Junior Member
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]
-
Nov 2nd, 2002, 12:06 AM
#2
Junior Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|