-
Mar 6th, 2024, 08:58 PM
#41
Re: Subclassing At Its Simplest
Originally Posted by nebeln
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.
-
Mar 6th, 2024, 09:12 PM
#42
Fanatic Member
Re: Subclassing At Its Simplest
And why will you and want you subclass in IDE? In my world this is left out.
-
Mar 6th, 2024, 09:17 PM
#43
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.
-
Mar 6th, 2024, 09:26 PM
#44
Fanatic Member
Re: Subclassing At Its Simplest
Probably I'm a legend then...I took up VB6 again in old days...how old are you WanGogh?
-
Mar 6th, 2024, 09:28 PM
#45
Fanatic Member
Re: Subclassing At Its Simplest
When I wrote scripts for DC++ I wrote them in Notepad and executed them freehand..
-
Mar 6th, 2024, 09:34 PM
#46
Fanatic Member
Re: Subclassing At Its Simplest
This was about 2003-2004 era if I'm not wrong
-
Mar 6th, 2024, 09:38 PM
#47
Re: Subclassing At Its Simplest
Everybody here is in the same age ballpark, except dilettante who's our granddaddy!
-
Mar 6th, 2024, 09:52 PM
#48
Fanatic Member
Re: Subclassing At Its Simplest
Aha you think so cool indeed
I had a preconcieved opionin that some was about 25 years stuggs
-
Mar 7th, 2024, 12:57 AM
#49
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.
-
May 9th, 2024, 10:46 AM
#50
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.
-
May 9th, 2024, 10:58 AM
#51
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.
-
May 10th, 2024, 09:59 AM
#52
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.
-
Jun 21st, 2024, 11:36 AM
#53
Member
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 ???
-
Jun 24th, 2024, 01:08 PM
#54
Re: Subclassing At Its Simplest
Originally Posted by Thierry76
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.
-
Jun 24th, 2024, 04:09 PM
#55
Member
Re: Subclassing At Its Simplest
sorry, you are right...please excuse me
-
Aug 28th, 2024, 11:04 AM
#56
Re: Subclassing At Its Simplest
Originally Posted by Elroy
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!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|