VB.NET中使用委托(Delegate)来注册回调(callback)函数

前些日子捣鼓了下VFW,里面注册回调(callback)函数是通过sendmessage函数实现的,也就是把回调函数的指针作为参数发送给hWnd即可。折腾了不少时间,下面是代码

这是C/C++代码

typedef struct videohdr_tag {
LPBYTE      lpData;
DWORD       dwBufferLength;
DWORD       dwBytesUsed;
DWORD       dwTimeCaptured;
DWORD       dwUser;
DWORD       dwFlags;
DWORD       dwReserved[4];
} VIDEOHDR, *PVIDEOHDR, *LPVIDEOHDR;

#define capSetCallbackOnVideoStream(handle, callback) 
 (safeSendMessage (handle, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, callback))

capSetCallbackOnVideoStream(mhwnd, VideoCallback);

LRESULT CALLBACK VDCaptureDriverVFW::VideoCallback(HWND hwnd, LPVIDEOHDR lpVHdr) {
VDCaptureDriverVFW *pThis = (VDCaptureDriverVFW *)capGetUserData(hwnd);

if (pThis->mpCB && !pThis->mbBlockVideoFrames) {
    DO SOMETHING……
    }
    return 0;
}

下面是VB.NET的代码,因为.NET里不允许使用指针,就必须使用委托(Delegate)来实现

    Structure LPVIDEOHDR
            Public lpData As IntPtr            'point to the buffer
            Public dwBufferLength As UInt32     'length of buffer
            Public dwBytesUsed As UInt32        'buffer's Byte
            Public dwTimeCaptured As UInt32     'time:ms
            Public dwUser As UInt64             '
            Public dwFlags As UInt32            '
            Public dwReserved() As UInt64      'Reserved for driver.
            Public Sub New(ByVal Size As UShort) '
                dwReserved = New UInt64(Size) {}
            End Sub
    End Structure

Public lpVHdr As LPVIDEOHDR = New LPVIDEOHDR(4)

 Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (
                                                                        ByVal hWnd As Integer,
                                                                        ByVal wMsg As Integer,
                                                                        ByVal wParam As Integer,
                                                                        ByVal IParam As callback)


Public Delegate Function callback(ByVal whnd As IntPtr, ByVal lpVhdr As IntPtr)   '


Dim a1 As callback = Function(ByVal whnd As IntPtr, ByVal lpVhdr As IntPtr)
                         If count < 30 Then
                             Clipboard.GetImage.Save("D:\" & count & ".bmp")
                             count = count + 1
                         End If
                         Return True
                     End Function

Public Function fuckcallback(ByVal whnd As IntPtr, ByVal FramePoint As IntPtr) As Boolean
    DO SOMETHING
    Return True
End Function

Dim a2 As callback = AddressOf fuckcallback

Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        'SendMessage(hwnd, Cam.WM_CAP_SET_CALLBACK_FRAME, 0, a2)
        'SendMessage(hwnd, Cam.WM_CAP_SET_CALLBACK_FRAME, 0, a1)
        'SendMessage(hwnd, Cam.WM_CAP_SET_CALLBACK_FRAME, 0, AddressOf fuckcallback)
        '上面3个都行
End Sub

这样其实是有问题的,排查了半天,才发现是声明委托的时候,漏了函数返回值
Public Delegate Function callback(ByVal whnd As IntPtr, ByVal lpVhdr As IntPtr) 改成
Public Delegate Function callback(ByVal whnd As IntPtr, ByVal lpVhdr As IntPtr) as integer 即可 。

PS:以后可能不会再用VB.NET了,这篇文章算是个终了吧。

你可能感兴趣的:(VB-NET,MFC)