Answered by:
'AddressOf' expression cannot be converted to 'Long'

Question
-
I am getting this error with the following code ...
" 'AddressOf' expression cannot be converted to 'Long' because 'Long' is not a delegate type. "
I thought AddressOf returned a long value in vb6 but I found out it now returns a "delegate" type in VB10 ... I am new to VB 10 and can't seem to wrap my head around this new type. Can anyone help explain to me how I can to turn a "delegate" type to a long value to pass to the "user32" SetWindowLong funtion?
Private Const GWL_WNDPROC = -4
Private Const WM_GETMINMAXINFO = &H24
Public lpPrevWndProc As Long
Public gHW As Long
Public Structure POINTAPI
Dim x As Long
Dim y As Long
End Structure
Public Structure MINMAXINFO
Dim ptReserved As POINTAPI
Dim ptMaxSize As POINTAPI
Dim ptMaxPosition As POINTAPI
Dim ptMinTrackSize As POINTAPI
Dim ptMaxTrackSize As POINTAPI
End Structure
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Sub CopyMemoryToMinMaxInfo Lib "KERNEL32" Alias "RtlMoveMemory" (hpvDest As MINMAXINFO, ByVal hpvSource As Long, ByVal cbCopy As Long)
Private Declare Sub CopyMemoryFromMinMaxInfo Lib "KERNEL32" Alias "RtlMoveMemory" (ByVal hpvDest As Long, hpvSource As MINMAXINFO, ByVal cbCopy As Long)
Private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Sub Hook()
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub Unhook()
Dim temp As Long
temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub
Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim myScreens() As Screen = Screen.AllScreens
Dim MinMax As MINMAXINFO
If uMsg = WM_GETMINMAXINFO Then
CopyMemoryToMinMaxInfo(MinMax, lParam, Len(MinMax))
MinMax.ptMinTrackSize.x = 100
MinMax.ptMinTrackSize.y = 100
MinMax.ptMaxTrackSize.x = myScreens(0).Bounds.Height + 10
MinMax.ptMaxTrackSize.y = myScreens(0).Bounds.Width + 10
CopyMemoryFromMinMaxInfo(lParam, MinMax, Len(MinMax))
WindowProc = DefWindowProc(hw, uMsg, wParam, lParam)
Else
WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End If
End Function- Edited by rdaviddd Saturday, July 28, 2012 10:30 PM
Saturday, July 28, 2012 10:15 PM
Answers
-
Hi,
there's a forum about upgrading: http://social.msdn.microsoft.com/Forums/en-US/vbinterop/threads
Maybe a moderator can move it.
It would have helped if you had used the upgrade wizard so that at least some data types are matching. In general, if you want to translate, you should know both languages well before. Anyway, first step is changing Long to Integer. However, as VB6 didn't have a pointer type, Long was the replacment. In VB.Net, it is IntPtr now. So, wherever a pointer-size type is required, use IntPtr. Wherever a 32 bit size integer is required use Integer (or Int32).
I won't correct all API declarations now. Have a look at pInvoke.net and copy from there.
Regarding the question: SetWindowLong has been superseded by SetWindowLongPtr. The last parameter is IntPtr now or a delegate:
Private Delegate Function WndProcDelegate(ByVal hWnd As IntPtr, ByVal msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
That means, keep two declarations of SetWindowLongPtr: One with IntPtr and one with WndProcDelegate as the last parameter's type.
Then you also need to change:
Public lpPrevWndProc As IntPtr Public gHW As IntPtr Public Sub Hook() lpPrevWndProc = SetWindowLongPtr(gHW, GWL_WNDPROC, AddressOf WindowProc) End Sub Public Sub Unhook() Dim temp As IntPtr temp = SetWindowLongPtr(gHW, GWL_WNDPROC, lpPrevWndProc) End Sub
Function WindowProc(ByVal hw As IntPtr, ByVal uMsg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
'''' .....
End Function
Let me know if I forgot something.
Armin
- Edited by Armin Zingler Saturday, July 28, 2012 10:36 PM
- Proposed as answer by Paul IshakModerator Wednesday, August 1, 2012 2:55 PM
- Marked as answer by Youen ZenModerator Tuesday, August 7, 2012 8:13 AM
Saturday, July 28, 2012 10:36 PM
All replies
-
Hi,
there's a forum about upgrading: http://social.msdn.microsoft.com/Forums/en-US/vbinterop/threads
Maybe a moderator can move it.
It would have helped if you had used the upgrade wizard so that at least some data types are matching. In general, if you want to translate, you should know both languages well before. Anyway, first step is changing Long to Integer. However, as VB6 didn't have a pointer type, Long was the replacment. In VB.Net, it is IntPtr now. So, wherever a pointer-size type is required, use IntPtr. Wherever a 32 bit size integer is required use Integer (or Int32).
I won't correct all API declarations now. Have a look at pInvoke.net and copy from there.
Regarding the question: SetWindowLong has been superseded by SetWindowLongPtr. The last parameter is IntPtr now or a delegate:
Private Delegate Function WndProcDelegate(ByVal hWnd As IntPtr, ByVal msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
That means, keep two declarations of SetWindowLongPtr: One with IntPtr and one with WndProcDelegate as the last parameter's type.
Then you also need to change:
Public lpPrevWndProc As IntPtr Public gHW As IntPtr Public Sub Hook() lpPrevWndProc = SetWindowLongPtr(gHW, GWL_WNDPROC, AddressOf WindowProc) End Sub Public Sub Unhook() Dim temp As IntPtr temp = SetWindowLongPtr(gHW, GWL_WNDPROC, lpPrevWndProc) End Sub
Function WindowProc(ByVal hw As IntPtr, ByVal uMsg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
'''' .....
End Function
Let me know if I forgot something.
Armin
- Edited by Armin Zingler Saturday, July 28, 2012 10:36 PM
- Proposed as answer by Paul IshakModerator Wednesday, August 1, 2012 2:55 PM
- Marked as answer by Youen ZenModerator Tuesday, August 7, 2012 8:13 AM
Saturday, July 28, 2012 10:36 PM -
Iiin addition:
- The Len() function is not appropriate for calculating the size of an unmanaged structure because it calculates the size of the object if written to a file. That's not necessarily equal. Call System.Runtime.InteropServices.Marshal.SizeOf instead. So the
call would be:
RtlMoveMemory(MinMax, lParam, New IntPtr(Marshal.SizeOf(MinMax)))
- However, RtlMoveMemory can be replaced by Marshal.PtrToStructure resp. StructureToPtr:
MinMax = DirectCast(Marshal.PtrToStructure(lParam, GetType(MINMAXINFO)), MINMAXINFO)
'...
Marshal.StructureToPtr(MinMax, lParam, False)
Armin
- Edited by Armin Zingler Saturday, July 28, 2012 11:03 PM
Saturday, July 28, 2012 11:02 PM - The Len() function is not appropriate for calculating the size of an unmanaged structure because it calculates the size of the object if written to a file. That's not necessarily equal. Call System.Runtime.InteropServices.Marshal.SizeOf instead. So the
call would be: