Page 2 of 2 FirstFirst 12
Results 41 to 56 of 56

Thread: Subclassing At Its Simplest

  1. #41
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,939

    Wink Re: Subclassing At Its Simplest

    Quote Originally Posted by nebeln View Post
    All subclassing goes to hell of you press the "STOP" button if you choose to subclass in the IDE mode and unsubclass in IDE mode!!
    Only way to not get this is to to make the subclassing in runtime outside the IDE!!
    It doesn't matter how or else...just don't subclass in IDE!! and not unsubclass in IDE!!
    Yeah I guess people were just wasting their time in this thread. I've just posted a very simple example in post #32 where you can absolutely press "Stop" and also move the execution pointer in debug mode to skip any errors while subclassing and everything works just fine.

    Both TheTrick and wqweto have more complicated examples that allow you to press the "End" button without crashing not just skip past the offending code. Feel free to test before making assumptions.

  2. #42
    Fanatic Member
    Join Date
    Mar 2023
    Posts
    834

    Re: Subclassing At Its Simplest

    And why will you and want you subclass in IDE? In my world this is left out.

  3. #43
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,939

    Wink Re: Subclassing At Its Simplest

    Pretty sure you can answer this one yourself but I think it's mainly for the same reason we don't write our code in Notepad and compile from the command line like the true legends.

  4. #44
    Fanatic Member
    Join Date
    Mar 2023
    Posts
    834

    Re: Subclassing At Its Simplest

    Probably I'm a legend then...I took up VB6 again in old days...how old are you WanGogh?

  5. #45
    Fanatic Member
    Join Date
    Mar 2023
    Posts
    834

    Re: Subclassing At Its Simplest

    When I wrote scripts for DC++ I wrote them in Notepad and executed them freehand..

  6. #46
    Fanatic Member
    Join Date
    Mar 2023
    Posts
    834

    Re: Subclassing At Its Simplest

    This was about 2003-2004 era if I'm not wrong

  7. #47

  8. #48
    Fanatic Member
    Join Date
    Mar 2023
    Posts
    834

    Re: Subclassing At Its Simplest

    Aha you think so cool indeed
    I had a preconcieved opionin that some was about 25 years stuggs

  9. #49

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,481

    Re: Subclassing At Its Simplest

    Ok, this is my thread, so y'all please stay at least somewhat on topic.

    And yes, there are several ways to do subclassing with the IDE completely protected.

    Why do we want to subclass in the IDE? Same reason we want to subclass at all, so we can do/change things that we can't otherwise do/change ... and we'd like to test all of that in the IDE. If we don't want to do that, why don't we just eliminate running our code in the IDE altogether?

    ----------------

    But again, if you're not talking about the details of subclassing, please bite your tongue, or, as it were, keep your fingers off the keyboard.

    Thank You.

    Ohhh, and here's a place you can post anything you like.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  10. #50

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,481

    Re: Subclassing At Its Simplest

    Subclassing to detect when a form is moving. Similar to Form_Resize, except for when the form is being drug by the TitleBar.

    Must be inserted into the code posted in the OP to use it.

    Code:
    
    Public Sub SubclassFormForMoving(frm As VB.Form)
        '
        ' On this one, we use dwRefData to save the ObjPtr(SomeForm) of the form that we're tracking.
        ' Called as follows:  SubclassSomeWindow Me.hWnd, AddressOf Moving_Proc, ObjPtr(Me)
        ' This can simultaneously be used by as many forms as will need it, but it should only be done once per form.
        '
        SubclassSomeWindow frm.hWnd, AddressOf Moving_Proc, ObjPtr(frm)
    End Sub
    
    Private Function Moving_Proc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
        Const WM_DESTROY As Long = &H2&
        If uMsg = WM_DESTROY Then
            UnSubclassSomeWindow hWnd, AddressOf_Moving_Proc, uIdSubclass
            Moving_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
            Exit Function
        End If
        If Not ProgramIsRunning Then ' Protect the IDE.  Don't execute any specific stuff if we're stopping.  We may run into COM objects or other variables that no longer exist.
            ToSeeMessages_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
            Exit Function
        End If
        '
        Dim frm As VB.Form
        Const WM_MOVING As Long = &H216&
        '
        If uMsg = WM_MOVING Then
            Set frm = FormObjectFromPtr(dwRefData)
            On Error Resume Next            ' Error trapping, in case we don't have Moving procedures.
                frm.Moving      ' MUST be Public (not Friend) to find it from here (as we're late-bound).
            On Error GoTo 0
        End If
        '
        ' Give control to other procs, if they exist.
        Moving_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
    End Function
    
    Private Function AddressOf_Moving_Proc() As Long
        AddressOf_Moving_Proc = ProcedureAddress(AddressOf Moving_Proc)
    End Function
    
    
    And these must be woven in as well:

    Code:
    
    Private Declare Function vbaObjSetAddref Lib "msvbvm60" Alias "__vbaObjSetAddref" (ByRef dstObject As Any, ByRef srcObjPtr As Any) As Long
    
    Public Function FormObjectFromPtr(ByVal Ptr As Long) As VB.Form
        ' Ideas for these were initially shown to me by The Trick.
        ' This uses the pointer to an existing (instantiated) COM/Form object and makes another reference to it.
        ' This reference is handled completely correctly in that Addref is performed for it.
        ' Usage: Set FormAlias = FormObjectFromPtr(ObjPtr(FormOriginal))
        vbaObjSetAddref FormObjectFromPtr, ByVal Ptr
    End Function
    
    
    Last edited by Elroy; May 28th, 2024 at 09:38 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  11. #51

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,481

    Re: Subclassing At Its Simplest

    This one is to detect when a form in our project has lost focus, but not to another form within the project, but rather to a form in another project entirely. It's often useful to know when our entire project has lost focus.

    Must be inserted into the code posted in the OP to use it.

    Code:
    
    Public Sub SubclassFormForGotLostFocus(frm As VB.Form)
        '
        ' On this one, we use dwRefData to save the ObjPtr(SomeForm) of the form that we're tracking.
        ' Called as follows:  SubclassSomeWindow Me.hWnd, AddressOf GotLostFocus_Proc, ObjPtr(Me)
        ' This can simultaneously be used by as many forms as will need it, but it should only be done once per form.
        '
        SubclassSomeWindow frm.hWnd, AddressOf GotLostFocus_Proc, ObjPtr(frm)
    End Sub
    
    Private Function GotLostFocus_Proc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
        Const WM_DESTROY As Long = &H2&
        If uMsg = WM_DESTROY Then
            UnSubclassSomeWindow hWnd, AddressOf_GotLostFocus_Proc, uIdSubclass
            GotLostFocus_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
            Exit Function
        End If
        If Not ProgramIsRunning Then ' Protect the IDE.  Don't execute any specific stuff if we're stopping.  We may run into COM objects or other variables that no longer exist.
            ToSeeMessages_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
            Exit Function
        End If
        '
        Dim frm As VB.Form
        Const WM_ACTIVATE As Long = &H6&
        '
        If uMsg = WM_ACTIVATE Then
            Set frm = FormObjectFromPtr(dwRefData)
            On Error Resume Next            ' Error trapping, in case we don't have LostGlobalFocus and/or GotGlobalFocus procedures.
                If (wParam And &HFFFF&) = 0& Then
                    frm.LostGlobalFocus     ' MUST be Public (not Friend) to find it from here.
                Else
                    frm.GotGlobalFocus      ' MUST be Public (not Friend) to find it from here.
                End If
            On Error GoTo 0
        End If
        '
        ' Give control to other procs, if they exist.
        GotLostFocus_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
    End Function
    
    Private Function AddressOf_GotLostFocus_Proc() As Long
        AddressOf_GotLostFocus_Proc = ProcedureAddress(AddressOf GotLostFocus_Proc)
    End Function
    
    
    And these must be woven in as well:

    Code:
    
    Private Declare Function vbaObjSetAddref Lib "msvbvm60" Alias "__vbaObjSetAddref" (ByRef dstObject As Any, ByRef srcObjPtr As Any) As Long
    
    Public Function FormObjectFromPtr(ByVal Ptr As Long) As VB.Form
        ' Ideas for these were initially shown to me by The Trick.
        ' This uses the pointer to an existing (instantiated) COM/Form object and makes another reference to it.
        ' This reference is handled completely correctly in that Addref is performed for it.
        ' Usage: Set FormAlias = FormObjectFromPtr(ObjPtr(FormOriginal))
        vbaObjSetAddref FormObjectFromPtr, ByVal Ptr
    End Function
    
    
    Last edited by Elroy; May 28th, 2024 at 09:38 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  12. #52

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,481

    Re: Subclassing At Its Simplest

    And here's an interesting one that occasionally comes in handy, a "keep form at bottom of zorder". This is the zorder for all desktop windows, not just the application (which is all the Me.ZOrder works with).

    Must be inserted into the code posted in the OP to use it.

    Code:
    
    Public Sub SubclassFormAlwaysOnBottom(frm As VB.Form)
        SubclassSomeWindow frm.hWnd, AddressOf AlwaysOnBottom_Proc, ObjPtr(frm)
    End Sub
    
    Private Function AlwaysOnBottom_Proc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
        Const WM_WINDOWPOSCHANGING  As Long = &H46&
        Const HWND_BOTTOM           As Long = 1&
        Const SIGN_BIT              As Long = &H80000000
        Const WM_DESTROY            As Long = &H2&
        '
        If uMsg = WM_DESTROY Then
            UnSubclassSomeWindow hWnd, AddressOf_AlwaysOnBottom_Proc, uIdSubclass
            AlwaysOnBottom_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
            Exit Function
        End If
        If Not ProgramIsRunning Then ' Protect the IDE.  Don't execute any specific stuff if we're stopping.  We may run into COM objects or other variables that no longer exist.
            ToSeeMessages_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
            Exit Function
        End If
        '
        If uMsg = WM_WINDOWPOSCHANGING Then
            PutMem4 ByVal (lParam Xor SIGN_BIT) + 4& Xor SIGN_BIT, ByVal HWND_BOTTOM      ' WINDOWPOS.hWndInsertAfter = HWND_BOTTOM
            Exit Function
        End If
        '
        AlwaysOnBottom_Proc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
    End Function
    
    Private Function AddressOf_AlwaysOnBottom_Proc() As Long
        AddressOf_AlwaysOnBottom_Proc = ProcedureAddress(AddressOf AlwaysOnBottom_Proc)
    End Function
    
    
    And this is also called, and must be placed at the top of your subclassing module to use this one:

    Code:
    
    Public Declare Sub PutMem4 Lib "msvbvm60" (ByRef Ptr As Any, ByRef Value As Any)
    
    
    Last edited by Elroy; May 28th, 2024 at 09:38 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  13. #53
    Member
    Join Date
    Apr 2014
    Posts
    39

    Re: Subclassing At Its Simplest

    Does anyone have any advice for VBA users? (32x/64x) for OCX made with VB6, addin, hooked dialogbox and used in Word/Excel ???

  14. #54

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,481

    Re: Subclassing At Its Simplest

    Quote Originally Posted by Thierry76 View Post
    Does anyone have any advice for VBA users? (32x/64x) for OCX made with VB6, addin, hooked dialogbox and used in Word/Excel ???
    I'm very confused as to what this question has to do with this thread. Also, why wouldn't you post this here?
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  15. #55
    Member
    Join Date
    Apr 2014
    Posts
    39

    Re: Subclassing At Its Simplest

    sorry, you are right...please excuse me

  16. #56
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,939

    Talking Re: Subclassing At Its Simplest

    Quote Originally Posted by Elroy View Post
    VanGogh: Did you test the "Stop" button while a MsgBox was on the screen? And also while a second vbModal form was on the screen? Those are the only conditions that give me problems.
    Yes, I've just posted an example with this subclassing approach. You can click "Stop" or "End" wherever you want, even when a modal form is on screen!

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width