Avatar of Delta526
Delta526

asked on 

'AddressOf' expression cannot be converted to 'Integer' because 'Integer' is not a delegate type

This was marked in my code.
Public Function EnumCallback(ByVal Handle As Integer, ByRef wins() As WinLabel) As Integer
end function

Public Function ListWindows(ByRef wins() As WinLabel, Optional ByRef hwnd As Integer = 0) As Integer
Dim res As Integer
If hwnd Then
'UPGRADE_WARNING: Add a delegate for AddressOf EnumCallback
res = EnumChildWindows(hwnd, AddressOf EnumCallback, wins)
end if
end function

This is the ERROR
'AddressOf' expression cannot be converted to 'Integer' because 'Integer' is not a delegate type.
What is a delegate type and why is this a problem? EnumCallback is already an integer.
Visual Basic.NET

Avatar of undefined
Last Comment
Delta526
ASKER CERTIFIED SOLUTION
Avatar of graye
graye
Flag of United States of America image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Wow, thanks Mike for giving me the props ;)

Bob
My pleasure Bob!  Give credit, where credit is due....

By the way, you have a "real" job yet?   ;)
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

No, but I am trying desperately to start my .NET certification training.

Bob
Avatar of Delta526
Delta526

ASKER

Grave,

I'm not sure what you mean by "before the the EnumCallback is defined"? I put your function in the Declarations is that what you mean?
Delegate Function EnumCallback(ByVal Handle As Integer, ByRef wins() As WinLabel) As Integer
The error has not gone away.
Avatar of Delta526
Delta526

ASKER

This is my function, where do I put the Delegate function?

Public Function EnumCallback(ByVal Handle As Integer, ByRef wins() As WinLabel) As Integer
' for use with ListWindows() and API EnumWindows. See ListWindows()
      
Dim index As Integer
Static count As Byte
            
' possible test for uninitialized dynamic array
'if runtime error 9, redim your array with an element before passing it
index = UBound(wins)
EnumCallback = Handle
If Handle Then
inc(count)
wins(index).Handle = Handle
wins(index).Caption = WindowTextFromHnd(Handle)
wins(index).Class_Renamed = WindowClassFromHnd(Handle)
wins(index).hParent = GetParent(Handle)
wins(index).ThreadID = GetWinThrdProcID(Handle, wins(index).ProcID)
ReDim Preserve wins(index + 1)
If (count Mod 10) = False Then
System.Windows.Forms.Application.DoEvents()
count = 0
End If
End If
End Function
Avatar of Delta526
Delta526

ASKER

I'm not quite sure I understand delegates but I need to reframe the question.
Avatar of graye
graye
Flag of United States of America image

Just put the Delegate line at the beginning of the file, that will do nicely.

Explaining Delegates is a bit tough...  So, let me start at the beginning.

What are they for?   Delegates are used primarily in API calls as a way to "customize" an API to do something that the author of the API couldn't possibily do in advance.   Let me explain using a simple analogy...   Let's say that I wrote an program (an API-style DLL) that waited for an alarm and then did something.   Since I'm writing this program for others to use, I can't possibiliy know what you might want to do when the alarm goes off.  So, I write my program to use a delegate.   That way others who use my program can just "plug in" anything they want into my program.   For example, if you wanted to ring a bell when the alarm goes off, you could write a delegate called "RingBell" and plug it into my program.   This technique makes it easy for an API programmer, since he doesn't have to predict in advance the actual use of the API by others.

Why would I write a program that required Delegates?   You probably wouldn't...  in fact, I'd say that the only time you'd use a delegate is when you're using somebody else's code (an API-style DLL).

How do I make it work?   Well, there are three parts to the puzzle.  

1)  The 1st part is kinda simple... it's just a single line of code using the "Delegate" keyword.  This declaration looks a lot like a normal function, but without a "body" and no "End Function".   This tells the compiler to create a "signature" that will be used later on when calling the delegate.  The signature consists of the number and type of the arguments, plus the return type.

2) The 2nd part is the actual function that will be called (when the alarm goes off).  It must match the "signature" given in the Delegate line (meaning it has to have the same number of arguments, of the same type, and same return type).   This is where you write the code that does the work (rings a bell, in my silly example).

3) The 3rd part is the AddressOf operator.  This is how you plug your function into the API.  Typically, you'd pass the "address of" your function (the code you wrote in part 2) as a parameter to the API function call

There are probably a lot better explainations out there on the web...    Take a look at any one of the following:
http://www.google.com/search?q=delegate+addressof&rls=com.microsoft:en-us&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1
Avatar of Delta526
Delta526

ASKER

Actually that was very nice work. I do in fact understand what a delegate is and how it works. Just let me make sure I know what you mean by putting the:

Delegate Function EnumCallback(ByVal Handle As Integer, ByRef wins() As WinLabel) As Integer

In the right place. I put it with my declares the actual function is however not an API but a function. All of the arguments are the same.

When I try to build the application it still comes back with the error:
'AddressOf' expression cannot be converted to 'Integer' because 'Integer' is not a delegate type.

Am I missing something? VB.Net won’t even let me step through the code until this error is fixed.
Avatar of graye
graye
Flag of United States of America image

let's go back to the 1st chunk of code that you posted

     res = EnumChildWindows(hwnd, AddressOf EnumCallback, wins)

That's not gonna work by itself, because that's just the "Part 3" of the puzzle.

Now, let's take a look at the 2nd chunk of code you posted

    Public Function EnumCallback(ByVal Handle As Integer, ByRef wins() As WinLabel) As Integer
            ....
    End Function

That's not gonna work by itself, because that's just the "Part 2" of the puzzle.

So, where is the "Part 1" of the puzzle?

Yes, EnumChildWindows is indeed an API call.... and the 2nd parameter to that API call is a Delegate.   So, that means that you'll need to create the delegate "signature" before you delcare the EnumChildWindows in your code.    I'd expect it to look something like this:

    Delegate Function EnumCallBackDelegate(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Integer
    Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent as IntPtr, ByVal lpEnumFunc As EnumCallBackDelegate, ByVal lParam As Integer) As Integer
                                                                                                                                                                     ^^^^^^^^^^^^^^^

OK, now you've got all three parts... and it should work!
Avatar of graye
graye
Flag of United States of America image

Hummm... I just now noticed that your "Part 2" function doesn't match the required "signature" of the Delegate.   You can get the required signature from the API documentation.  In the case of the EnumChildWindows API, the delegate signature must be similar to the example above.   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/enumchildproc.asp

... or did you mix examples on me?
Avatar of Delta526
Delta526

ASKER

Grave,

I think I'm missing an understanding of the signature too, please move this conversation over to:
https://www.experts-exchange.com/questions/22417841/How-to-define-a-delegate-to-a-function.html?cid=239&anchorAnswerId=18623053#a18623053

So that I can get you points for the extra information.
Visual Basic.NET
Visual Basic.NET

Visual Basic .NET (VB.NET) is an object-oriented programming language implemented on the .NET framework, but also supported on other platforms such as Mono and Silverlight. Microsoft launched VB.NET as the successor to the Visual Basic language. Though it is similar in syntax to Visual Basic pre-2002, it is not the same technology,

96K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo