Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. How to get address of a function or method

How to get address of a function or method

Scheduled Pinned Locked Moved Visual Basic
helpvisual-studiotutorialcsharp
15 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    treddie
    wrote on last edited by
    #1

    Hi. I think an answer to this problem lies in the use of delegates and marshaling, but if so, I cannot figure this one out. In vb6, you could use the AddressOf method to get the address of a function. vb.Net no longer allows such a simple idea. Some have even suggested that you do not need to get the address of a function. Apparently they do not use API functions, where getting the address of a function is essential. Now, in vb.Net, if you attempt to use AddressOf(SomeFunction), as in:

    lPrevWndProc = SetWindowLong(hControl, GWL_WNDPROC, AddressOf WindowProc)

    You get the following error:

    'addressof' expression cannot be converted to 'IntPtr' because 'IntPtr' is not a delegate type

    MSDN is as obtuse as ever when describing this problem where a simple example of how to replace the as-simple-as-it-gets vb6 "AddressOf" method with a vb.Net method would have been the obvious thing to do. I reference: http://msdn.microsoft.com/en-us/library/ms184628%28v=vs.90%29.aspx[^] which explains no more than the IDE message does in that respect, so they might as well have not even created that link. They offer other links to study which venture off into space because...All they needed to do was offer a simple comparison of how to do in vb.Net, to what was done in vb6. I have searched high and low for an answer and all I have found is frustration. Any help would be greatly appreciated. HELP! SOS!

    T B Richard DeemingR 3 Replies Last reply
    0
    • T treddie

      Hi. I think an answer to this problem lies in the use of delegates and marshaling, but if so, I cannot figure this one out. In vb6, you could use the AddressOf method to get the address of a function. vb.Net no longer allows such a simple idea. Some have even suggested that you do not need to get the address of a function. Apparently they do not use API functions, where getting the address of a function is essential. Now, in vb.Net, if you attempt to use AddressOf(SomeFunction), as in:

      lPrevWndProc = SetWindowLong(hControl, GWL_WNDPROC, AddressOf WindowProc)

      You get the following error:

      'addressof' expression cannot be converted to 'IntPtr' because 'IntPtr' is not a delegate type

      MSDN is as obtuse as ever when describing this problem where a simple example of how to replace the as-simple-as-it-gets vb6 "AddressOf" method with a vb.Net method would have been the obvious thing to do. I reference: http://msdn.microsoft.com/en-us/library/ms184628%28v=vs.90%29.aspx[^] which explains no more than the IDE message does in that respect, so they might as well have not even created that link. They offer other links to study which venture off into space because...All they needed to do was offer a simple comparison of how to do in vb.Net, to what was done in vb6. I have searched high and low for an answer and all I have found is frustration. Any help would be greatly appreciated. HELP! SOS!

      T Offline
      T Offline
      TnTinMn
      wrote on last edited by
      #2

      There is an example here[^] in c#. Just run the code through an online coverter. You may need to touch up a few lines after converting.

      T 1 Reply Last reply
      0
      • T treddie

        Hi. I think an answer to this problem lies in the use of delegates and marshaling, but if so, I cannot figure this one out. In vb6, you could use the AddressOf method to get the address of a function. vb.Net no longer allows such a simple idea. Some have even suggested that you do not need to get the address of a function. Apparently they do not use API functions, where getting the address of a function is essential. Now, in vb.Net, if you attempt to use AddressOf(SomeFunction), as in:

        lPrevWndProc = SetWindowLong(hControl, GWL_WNDPROC, AddressOf WindowProc)

        You get the following error:

        'addressof' expression cannot be converted to 'IntPtr' because 'IntPtr' is not a delegate type

        MSDN is as obtuse as ever when describing this problem where a simple example of how to replace the as-simple-as-it-gets vb6 "AddressOf" method with a vb.Net method would have been the obvious thing to do. I reference: http://msdn.microsoft.com/en-us/library/ms184628%28v=vs.90%29.aspx[^] which explains no more than the IDE message does in that respect, so they might as well have not even created that link. They offer other links to study which venture off into space because...All they needed to do was offer a simple comparison of how to do in vb.Net, to what was done in vb6. I have searched high and low for an answer and all I have found is frustration. Any help would be greatly appreciated. HELP! SOS!

        B Offline
        B Offline
        Bernhard Hiller
        wrote on last edited by
        #3

        See this example: http://www.pinvoke.net/default.aspx/user32.setwindowlong[^]

        T 1 Reply Last reply
        0
        • T treddie

          Hi. I think an answer to this problem lies in the use of delegates and marshaling, but if so, I cannot figure this one out. In vb6, you could use the AddressOf method to get the address of a function. vb.Net no longer allows such a simple idea. Some have even suggested that you do not need to get the address of a function. Apparently they do not use API functions, where getting the address of a function is essential. Now, in vb.Net, if you attempt to use AddressOf(SomeFunction), as in:

          lPrevWndProc = SetWindowLong(hControl, GWL_WNDPROC, AddressOf WindowProc)

          You get the following error:

          'addressof' expression cannot be converted to 'IntPtr' because 'IntPtr' is not a delegate type

          MSDN is as obtuse as ever when describing this problem where a simple example of how to replace the as-simple-as-it-gets vb6 "AddressOf" method with a vb.Net method would have been the obvious thing to do. I reference: http://msdn.microsoft.com/en-us/library/ms184628%28v=vs.90%29.aspx[^] which explains no more than the IDE message does in that respect, so they might as well have not even created that link. They offer other links to study which venture off into space because...All they needed to do was offer a simple comparison of how to do in vb.Net, to what was done in vb6. I have searched high and low for an answer and all I have found is frustration. Any help would be greatly appreciated. HELP! SOS!

          Richard DeemingR Online
          Richard DeemingR Online
          Richard Deeming
          wrote on last edited by
          #4

          The AddressOf is fine; it's the P/Invoke declaration which is wrong. You're trying to pass a delegate to a parameter which is declared as taking an IntPtr. In unmanaged code, this would be fine, but in managed code, the parameter types need to match. To call this method, you would need to declare an overload of the SetWindowLong method with the dwNewLong parameter declared as a WndProc delegate. However, .NET offers much easier ways to accomplish the same thing. For example, in Windows Forms, you just need to override the WndProc method[^].


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

          T 2 Replies Last reply
          0
          • T TnTinMn

            There is an example here[^] in c#. Just run the code through an online coverter. You may need to touch up a few lines after converting.

            T Offline
            T Offline
            treddie
            wrote on last edited by
            #5

            Thanks for the link! I tried it and it does not work, yet. I am assuming that WindowProc is constantly listening for events, so that no button-click handler is required (which would defeat the purpose of using the API, anyway). But as it it is written now, I think it is deaf! :)

            Public Class Form1

            'A delegate that matches Win32 WNDPROC:
            Public Delegate Function Win32WndProc(ByVal hWnd As IntPtr, \_
                                                  ByVal Msg As Integer, \_
                                                  ByVal wParam As Integer, \_
                                                  ByVal lParam As Integer) As Integer
            

            '-----------------------------------------------------------------------------------------
            '-----------------------------------------------------------------------------------------
            'Win32 API functions:

            Private Declare Function SetWindowLong Lib "user32" (ByVal hWnd As IntPtr, \_
                                                                 ByVal nIndex As Integer, \_
                                                                 ByVal newProc As Win32WndProc) \_
                                                                 As IntPtr
                ''Aother version of SetWindowLong that takes 2 pointers:
                'Private Declare Function SetWindowLong Lib "user32" (ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As IntPtr) As IntPtr
                    ''And call it like this:
                    'Dim MyAddress As IntPtr
                    'MyAddress = SetWindowLong(hWnd, GWL\_WNDPROC, oldWndProc)
            
            Private Declare Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, \_
                                                                  ByVal hWnd As IntPtr, \_
                                                                  ByVal Msg As Integer, \_
                                                                  ByVal wParam As Integer, \_
                                                                  ByVal lParam As Integer) \_
                                                                  As Integer
            
            Private Const GWL\_WNDPROC As Integer = -4
            
            Private Const WM\_LBUTTONDOWN As Integer = 513
            

            '--------------------------------------------------------------------------------------------------------
            '--------------------------------------------------------------------------------------------------------

            'Program variables:
            Private oldWndProc As IntPtr = IntPtr.Zero
            
            Private newWndProc As Win32WndProc = Nothing
            
            Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
            
            T 1 Reply Last reply
            0
            • B Bernhard Hiller

              See this example: http://www.pinvoke.net/default.aspx/user32.setwindowlong[^]

              T Offline
              T Offline
              treddie
              wrote on last edited by
              #6

              Thank you, Bernhard! I am testing it now.

              T 1 Reply Last reply
              0
              • Richard DeemingR Richard Deeming

                The AddressOf is fine; it's the P/Invoke declaration which is wrong. You're trying to pass a delegate to a parameter which is declared as taking an IntPtr. In unmanaged code, this would be fine, but in managed code, the parameter types need to match. To call this method, you would need to declare an overload of the SetWindowLong method with the dwNewLong parameter declared as a WndProc delegate. However, .NET offers much easier ways to accomplish the same thing. For example, in Windows Forms, you just need to override the WndProc method[^].


                "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                T Offline
                T Offline
                treddie
                wrote on last edited by
                #7

                Thanks Richard! I am trying out all three suggestions to see what happens!

                1 Reply Last reply
                0
                • T treddie

                  Thanks for the link! I tried it and it does not work, yet. I am assuming that WindowProc is constantly listening for events, so that no button-click handler is required (which would defeat the purpose of using the API, anyway). But as it it is written now, I think it is deaf! :)

                  Public Class Form1

                  'A delegate that matches Win32 WNDPROC:
                  Public Delegate Function Win32WndProc(ByVal hWnd As IntPtr, \_
                                                        ByVal Msg As Integer, \_
                                                        ByVal wParam As Integer, \_
                                                        ByVal lParam As Integer) As Integer
                  

                  '-----------------------------------------------------------------------------------------
                  '-----------------------------------------------------------------------------------------
                  'Win32 API functions:

                  Private Declare Function SetWindowLong Lib "user32" (ByVal hWnd As IntPtr, \_
                                                                       ByVal nIndex As Integer, \_
                                                                       ByVal newProc As Win32WndProc) \_
                                                                       As IntPtr
                      ''Aother version of SetWindowLong that takes 2 pointers:
                      'Private Declare Function SetWindowLong Lib "user32" (ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As IntPtr) As IntPtr
                          ''And call it like this:
                          'Dim MyAddress As IntPtr
                          'MyAddress = SetWindowLong(hWnd, GWL\_WNDPROC, oldWndProc)
                  
                  Private Declare Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, \_
                                                                        ByVal hWnd As IntPtr, \_
                                                                        ByVal Msg As Integer, \_
                                                                        ByVal wParam As Integer, \_
                                                                        ByVal lParam As Integer) \_
                                                                        As Integer
                  
                  Private Const GWL\_WNDPROC As Integer = -4
                  
                  Private Const WM\_LBUTTONDOWN As Integer = 513
                  

                  '--------------------------------------------------------------------------------------------------------
                  '--------------------------------------------------------------------------------------------------------

                  'Program variables:
                  Private oldWndProc As IntPtr = IntPtr.Zero
                  
                  Private newWndProc As Win32WndProc = Nothing
                  
                  Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
                  
                  T Offline
                  T Offline
                  TnTinMn
                  wrote on last edited by
                  #8

                  What is that you want to accomplish? The code I referenced will work, but is restricted to re-assigning windows owned by the process that invokes it. This is a restriction imposed by the SetWindowLong function (see: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx[^]; for the doc on GWL_WNDPROC). Here is a version that works for a TextBox on the form.

                  Imports System.Runtime.InteropServices

                  Public Class Form1

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

                  ' Win32 API needed
                  <DllImport("user32")> _
                  Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As Win32WndProc) As IntPtr
                  End Function
                  <DllImport("user32")> _
                  Private Shared Function CallWindowProc(ByVal lpPrevWndFunc As IntPtr, ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
                  End Function

                  ' A delegate that matches Win32 WNDPROC:
                  Private Delegate Function Win32WndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

                  ' from winuser.h:
                  Private Const GWL_WNDPROC As Integer = -4
                  Private Const WM_LBUTTONDOWN As Integer = &H201

                  ' program variables
                  Private oldWndProc As IntPtr = IntPtr.Zero
                  Private newWndProc As Win32WndProc = Nothing

                  Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
                  ' hWnd is the window you want to subclass..., create a new
                  ' delegate for the new wndproc
                  newWndProc = New Win32WndProc(AddressOf MyWndProc)
                  ' subclass
                  oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc)
                  End Sub

                  ' this is the new wndproc, just show a messagebox on left button down:
                  Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
                  Select Case Msg
                  Case WM_LBUTTONDOWN
                  MessageBox.Show("Clicked")
                  Return 0
                  Case Else

                          Exit Select
                    End Select
                  
                    Return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam)
                  

                  End Function

                  '==================================

                  T 1 Reply Last reply
                  0
                  • Richard DeemingR Richard Deeming

                    The AddressOf is fine; it's the P/Invoke declaration which is wrong. You're trying to pass a delegate to a parameter which is declared as taking an IntPtr. In unmanaged code, this would be fine, but in managed code, the parameter types need to match. To call this method, you would need to declare an overload of the SetWindowLong method with the dwNewLong parameter declared as a WndProc delegate. However, .NET offers much easier ways to accomplish the same thing. For example, in Windows Forms, you just need to override the WndProc method[^].


                    "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                    T Offline
                    T Offline
                    treddie
                    wrote on last edited by
                    #9

                    That's what I couldn't understand, was how to get the address out of the delegate. But one of the things I still get caught up with is that the documented data types for API functions are apparently not sacrosanct. I guess there is some leeway via overloading (which seems hard to find info on in the official sources). In that regard, is overloading the same as subclassing?

                    Richard DeemingR 1 Reply Last reply
                    0
                    • T treddie

                      Thank you, Bernhard! I am testing it now.

                      T Offline
                      T Offline
                      treddie
                      wrote on last edited by
                      #10

                      That is the function, but the problem is the last argument, dwNewLong. In vb6, you could just use AddressOf dwNewLong and the world was happy. But in vb.Net you can't do that because its AddressOf() does not return an address, but a delegate object.

                      1 Reply Last reply
                      0
                      • T TnTinMn

                        What is that you want to accomplish? The code I referenced will work, but is restricted to re-assigning windows owned by the process that invokes it. This is a restriction imposed by the SetWindowLong function (see: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx[^]; for the doc on GWL_WNDPROC). Here is a version that works for a TextBox on the form.

                        Imports System.Runtime.InteropServices

                        Public Class Form1

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

                        ' Win32 API needed
                        <DllImport("user32")> _
                        Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As Win32WndProc) As IntPtr
                        End Function
                        <DllImport("user32")> _
                        Private Shared Function CallWindowProc(ByVal lpPrevWndFunc As IntPtr, ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
                        End Function

                        ' A delegate that matches Win32 WNDPROC:
                        Private Delegate Function Win32WndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

                        ' from winuser.h:
                        Private Const GWL_WNDPROC As Integer = -4
                        Private Const WM_LBUTTONDOWN As Integer = &H201

                        ' program variables
                        Private oldWndProc As IntPtr = IntPtr.Zero
                        Private newWndProc As Win32WndProc = Nothing

                        Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
                        ' hWnd is the window you want to subclass..., create a new
                        ' delegate for the new wndproc
                        newWndProc = New Win32WndProc(AddressOf MyWndProc)
                        ' subclass
                        oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc)
                        End Sub

                        ' this is the new wndproc, just show a messagebox on left button down:
                        Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
                        Select Case Msg
                        Case WM_LBUTTONDOWN
                        MessageBox.Show("Clicked")
                        Return 0
                        Case Else

                                Exit Select
                          End Select
                        
                          Return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam)
                        

                        End Function

                        '==================================

                        T Offline
                        T Offline
                        treddie
                        wrote on last edited by
                        #11

                        Gawd I'm so stupid sometimes. I was driving home from the store today, and realized I hadn't started the listening process during form load. My version works now...You're version worked perfectly from the get-go. But furthermore, to get mine to work, I had to change the function declarations to the "other" style. From:

                        Private Declare Function SetWindowLong Lib "user32" (ByVal hWnd As IntPtr, \_
                                                                             ByVal nIndex As Integer, \_
                                                                             ByVal newProc As Win32WndProc) As IntPtr
                        
                        Private Declare Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, \_
                                                                              ByVal hWnd As IntPtr, \_
                                                                              ByVal Msg As Integer, \_
                                                                              ByVal wParam As Integer, \_
                                                                              ByVal lParam As Integer) As Integer
                        

                        To:

                        \_
                        

                        Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, _
                        ByVal nIndex As Integer,
                        ByVal newProc As Win32WndProc) As IntPtr
                        End Function

                        \_
                        

                        Private Shared Function CallWindowProc(ByVal lpPrevWndFunc As IntPtr, _
                        ByVal hWnd As IntPtr, _
                        ByVal Msg As Integer, _
                        ByVal wParam As Integer, _
                        ByVal lParam As Integer) As Integer
                        End Function

                        Why is one different than the other? I notice that the first is not shared and the second one is. But I have never encountered any problems before using the first syntax.

                        T 1 Reply Last reply
                        0
                        • T treddie

                          That's what I couldn't understand, was how to get the address out of the delegate. But one of the things I still get caught up with is that the documented data types for API functions are apparently not sacrosanct. I guess there is some leeway via overloading (which seems hard to find info on in the official sources). In that regard, is overloading the same as subclassing?

                          Richard DeemingR Online
                          Richard DeemingR Online
                          Richard Deeming
                          wrote on last edited by
                          #12

                          treddie wrote:

                          is overloading the same as subclassing?

                          Overloading[^] means creating two or more methods with the same name but different signatures. Subclassing[^], in this context, usually means replacing the window procedure of an existing control to extend or alter its behaviour. pinvoke.net[^] is usually a good place to start when you're looking to call an unmanaged Windows API.


                          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                          T 1 Reply Last reply
                          0
                          • T treddie

                            Gawd I'm so stupid sometimes. I was driving home from the store today, and realized I hadn't started the listening process during form load. My version works now...You're version worked perfectly from the get-go. But furthermore, to get mine to work, I had to change the function declarations to the "other" style. From:

                            Private Declare Function SetWindowLong Lib "user32" (ByVal hWnd As IntPtr, \_
                                                                                 ByVal nIndex As Integer, \_
                                                                                 ByVal newProc As Win32WndProc) As IntPtr
                            
                            Private Declare Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, \_
                                                                                  ByVal hWnd As IntPtr, \_
                                                                                  ByVal Msg As Integer, \_
                                                                                  ByVal wParam As Integer, \_
                                                                                  ByVal lParam As Integer) As Integer
                            

                            To:

                            \_
                            

                            Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, _
                            ByVal nIndex As Integer,
                            ByVal newProc As Win32WndProc) As IntPtr
                            End Function

                            \_
                            

                            Private Shared Function CallWindowProc(ByVal lpPrevWndFunc As IntPtr, _
                            ByVal hWnd As IntPtr, _
                            ByVal Msg As Integer, _
                            ByVal wParam As Integer, _
                            ByVal lParam As Integer) As Integer
                            End Function

                            Why is one different than the other? I notice that the first is not shared and the second one is. But I have never encountered any problems before using the first syntax.

                            T Offline
                            T Offline
                            TnTinMn
                            wrote on last edited by
                            #13

                            When using the "Declare" keyword, the default characterset modifier is ANSI. From the documentation for Declare[^]

                            Quote:

                            Character Sets. You can specify in charsetmodifier how Visual Basic should marshal strings when it calls the external procedure. The Ansi modifier directs Visual Basic to marshal all strings to ANSI values, and the Unicode modifier directs it to marshal all strings to Unicode values. The Auto modifier directs Visual Basic to marshal strings according to .NET Framework rules based on the external reference name, or aliasname if specified. The default value is Ansi. charsetmodifier also specifies how Visual Basic should look up the external procedure within its external file. Ansi and Unicode both direct Visual Basic to look it up without modifying its name during the search. Auto directs Visual Basic to determine the base character set of the run-time platform and possibly modify the external procedure name, as follows: On an ANSI platform, such as Windows 95, Windows 98, or Windows Millennium Edition, first look up the external procedure with no name modification. If that fails, append "A" to the end of the external procedure name and look it up again. On a Unicode platform, such as Windows NT, Windows 2000, or Windows XP, first look up the external procedure with no name modification. If that fails, append "W" to the end of the external procedure name and look it up again.

                            The error message you should have received was: Unable to find an entry point named 'SetWindowLong' in DLL 'user32.dll'. You could correct this like this:

                            Private Declare Auto Function SetWindowLong Lib "user32.dll" (ByVal hWnd As IntPtr, _
                            ByVal nIndex As Int16, _
                            ByVal newProc As Win32WndProc) As IntPtr

                            Private Declare Auto Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, _
                            ByVal hWnd As IntPtr, _
                            ByVal Msg As Integer, _
                            ByVal wParam As Integer, _
                            ByVal lParam As Integer) As Integer

                            T 1 Reply Last reply
                            0
                            • T TnTinMn

                              When using the "Declare" keyword, the default characterset modifier is ANSI. From the documentation for Declare[^]

                              Quote:

                              Character Sets. You can specify in charsetmodifier how Visual Basic should marshal strings when it calls the external procedure. The Ansi modifier directs Visual Basic to marshal all strings to ANSI values, and the Unicode modifier directs it to marshal all strings to Unicode values. The Auto modifier directs Visual Basic to marshal strings according to .NET Framework rules based on the external reference name, or aliasname if specified. The default value is Ansi. charsetmodifier also specifies how Visual Basic should look up the external procedure within its external file. Ansi and Unicode both direct Visual Basic to look it up without modifying its name during the search. Auto directs Visual Basic to determine the base character set of the run-time platform and possibly modify the external procedure name, as follows: On an ANSI platform, such as Windows 95, Windows 98, or Windows Millennium Edition, first look up the external procedure with no name modification. If that fails, append "A" to the end of the external procedure name and look it up again. On a Unicode platform, such as Windows NT, Windows 2000, or Windows XP, first look up the external procedure with no name modification. If that fails, append "W" to the end of the external procedure name and look it up again.

                              The error message you should have received was: Unable to find an entry point named 'SetWindowLong' in DLL 'user32.dll'. You could correct this like this:

                              Private Declare Auto Function SetWindowLong Lib "user32.dll" (ByVal hWnd As IntPtr, _
                              ByVal nIndex As Int16, _
                              ByVal newProc As Win32WndProc) As IntPtr

                              Private Declare Auto Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, _
                              ByVal hWnd As IntPtr, _
                              ByVal Msg As Integer, _
                              ByVal wParam As Integer, _
                              ByVal lParam As Integer) As Integer

                              T Offline
                              T Offline
                              treddie
                              wrote on last edited by
                              #14

                              Thanks for the clarification, TnTinMan. Much obliged. So much to learn...So little time! :)

                              1 Reply Last reply
                              0
                              • Richard DeemingR Richard Deeming

                                treddie wrote:

                                is overloading the same as subclassing?

                                Overloading[^] means creating two or more methods with the same name but different signatures. Subclassing[^], in this context, usually means replacing the window procedure of an existing control to extend or alter its behaviour. pinvoke.net[^] is usually a good place to start when you're looking to call an unmanaged Windows API.


                                "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                                T Offline
                                T Offline
                                treddie
                                wrote on last edited by
                                #15

                                DoH!...I should have known better, but I forgot...Many years ago, I first learned about subclassing to solve a graphics issue, and should have recalled that subclasssing is, in a way, a sort of "hijacking", in that you make Windows THINK you are using a standard WindowProc(), when in fact you have redirected execution to a function of your own making. That way, Windows is satisfied, and you get to do neat stuff as a result.

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • World
                                • Users
                                • Groups