Uninstantiation working differently in IDE than compiled-VBForums
Results 1 to 25 of 25

Thread: Uninstantiation working differently in IDE than compiled

  1. #1

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

    Uninstantiation working differently in IDE than compiled

    Ok, here's one that just bit me in the derrière. Apparently, uninstantiation works differently for forms when compiled versus the IDE.

    I'd love for someone to explain to me why this code runs differently when compiled versus within the IDE:

    Some code for a Form1 (the startup form):

    Code:
    
    Option Explicit
    
    Private Sub Form_DblClick()
        Dim s As String
    
        Form2.ShowModal s
    
        MsgBox "Our string: """ & s & """"
    End Sub
    
    And, some code for a Form2:

    Code:
    
    Option Explicit
    '
    Dim ms As String
    '
    
    Friend Sub ShowModal(s As String)
        ms = s
        Me.Show vbModal
        s = ms
        'MsgBox "Return to caller"
    End Sub
    
    Private Sub cmdOK_Click()
        Unload Me
    End Sub
    
    Private Sub Form_DblClick()
        ms = "put something in string"
        Unload Me
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        'MsgBox "Unload"
        Set Form2 = Nothing
    End Sub
    
    For your convenience, I've also zipped and attached it.

    At first, I thought the event order was different between IDE-vs-compiled. However, that wasn't the case. What it appears to be is that, when compiled, the moment you execute a "Set Form2 = Nothing" all the module level variables are uninitialized. However, when in the IDE, apparently these module level variables aren't uninitialized until the very last occurrence of the COM object goes out of scope (i.e., COM's internal count goes to zero, including implicit references created by VB6). That's my best guess.

    I'll be interested in any other explanations. I didn't test it with CLS modules, but it wouldn't surprise me if they had the same discrepancy.

    Cheers,
    Elroy

    EDIT1: Basically, in the example, if I'm in the IDE, I get my string returned. However, if I'm compiled, I don't get the string back. I suppose I should have said that earlier.

    EDIT2: This makes the second IDE-vs-compiled discrepancy I've found. The first is when passing UDT arrays. Just an outright bug is that there's no type mismatch when the caller uses one UDT to make the array, and the called procedure "catches" the array but with it declared as another UDT type. Apparently Microsoft just missed checking types on this one.

    And then, the discrepancy is that when this happens, and when the UDTs aren't the same size, the compiler pads them in (between the two UDT types) entirely differently than the IDE (at runtime, of course).

    Interestingly, the "bug" can be used to pass around UDTs in a way that's not typically possible, so long as you're willing to "array" them (possibly with only one element).

    EDIT1: The custom icon on Form2 is now deleted, so that the form no longer needs its FRX piece (which wasn't, and still isn't provided).
    Attached Files Attached Files
    Last edited by Elroy; Dec 7th, 2017 at 03:49 PM.
    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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  2. #2
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,208

    Re: Uninstantiation working differently in IDE than compiled

    Quote Originally Posted by Elroy View Post
    ...the moment you execute a "Set Form2 = Nothing"
    Well, that's one of those lines, which should never be written by anybody ...
    especially not within the Form-definition itself - or (even worse) in the Form_Unload-Event.

    Here's adapted code, which does it correctly (using the "Prototype" with a dedicated instancing):

    Form1:
    Code:
    Option Explicit
    
    Private Sub Form_DblClick()
        Dim s As String
        
        With New Form2
          .ShowModal s
        End With
        MsgBox "Our string: """ & s & """"
    End Sub
    Form2:
    Code:
    Option Explicit
     
    Dim ms As String
     
    Friend Sub ShowModal(s As String)
        ms = s
        Me.Show vbModal
        s = ms
    End Sub
     
    Private Sub Form_DblClick()
        ms = "put something in string"
        Unload Me
    End Sub
    HTH

    Olaf

  3. #3
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,503

    Re: Uninstantiation working differently in IDE than compiled

    Given that the EXE and the IDE are not really doing the same thing to execute the application, you can expect gremlins like this to show up from time to time. It's never serious though. Usually only happens when you try to do weird things.

    Try this, compile the EXE to p-code instead of native code. See what happens. If the p-code EXE behaves like it does in the IDE then you found your gremlin. If not, then this is a true mystery.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  4. #4
    Fanatic Member
    Join Date
    Apr 2012
    Posts
    906

    Re: Uninstantiation working differently in IDE than compiled

    I agree with Olaf; Set Form2 = Nothing shouldn't be in the Form2's unload event handler...
    If you don't know where you're going, any road will take you there...

    My VB6 love-children: Vee-Hive and Vee-Launcher

  5. #5

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

    Re: Uninstantiation working differently in IDE than compiled

    @Olaf & Colin:

    Ok, what if we like using the PredeclaredId of forms, and, yes, I know there's substantial debate on this, but please, let's set that debate aside. We've got this PredeclaredId, so I'll never understand why we should be prohibited from using it.

    Ok, we're using the PredeclaredId, such as Form1 or Form2 (or the Properties Window name we've given to the form). When using that implicit object variable, how would you recommend un-instantiating the COM/code object when we're done with it? (And Olaf, note that you're leaving it instantiated.)



    @Niya: Good call. P-code compiled works the same as the IDE, not machine compiled.


    EDIT1: And BTW, I've fixed it. I was just making a note in these forums about this discrepancy. And here's how I fixed it:

    Modified Form2 code (from above):
    Code:
    
    Option Explicit
    '
    Dim ms As String
    '
    
    Friend Sub ShowModal(s As String)
        ms = s
        Me.Show vbModal
        s = ms
        'MsgBox "Return to caller"
        Set Form2 = Nothing     ' <--- Moved from Form_Unload to here.
    End Sub
    
    Private Sub cmdOK_Click()
        Unload Me
    End Sub
    
    Private Sub Form_DblClick()
        ms = "put something in string"
        Unload Me
    End Sub
    
    
    Last edited by Elroy; Dec 7th, 2017 at 09:40 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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  6. #6
    Fanatic Member
    Join Date
    Apr 2012
    Posts
    906

    Re: Uninstantiation working differently in IDE than compiled

    Quote Originally Posted by Elroy View Post

    Ok, we're using the PredeclaredId, such as Form1 or Form2 (or the Properties Window name we've given to the form). When using that implicit object variable, how would you recommend un-instantiating the COM/code object when we're done with it? (And Olaf, note that you're leaving it instantiated.)
    TBH, I've never used PredeclareID so I'm no expert but wouldn't it get uninstantiated when the app closes, since it a gobal instance?
    If you don't know where you're going, any road will take you there...

    My VB6 love-children: Vee-Hive and Vee-Launcher

  7. #7

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

    Re: Uninstantiation working differently in IDE than compiled

    Hi Colin,

    Sure it gets uninstantiated when the app closes, however, the main VBP of my project includes LOTS of forms, and that doesn't even count the many ActiveX.DLLs that are also a part of it. I do my best to try and keep memory cleaned up when I back out of certain program areas.

    Best Regards,
    Elroy
    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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  8. #8
    Fanatic Member
    Join Date
    Apr 2012
    Posts
    906

    Re: Uninstantiation working differently in IDE than compiled

    Not to ignite the debate you are trying to avoid with the whole PredeclareID thing, but can you explain, please, the benefit that accrues from using them in your scenario - just for my own educational purposes...
    If you don't know where you're going, any road will take you there...

    My VB6 love-children: Vee-Hive and Vee-Launcher

  9. #9
    Fanatic Member
    Join Date
    Feb 2017
    Posts
    623

    Re: Uninstantiation working differently in IDE than compiled

    Quote Originally Posted by Schmidt View Post
    Well, that's one of those lines, which should never be written by anybody ...
    especially not within the Form-definition itself - or (even worse) in the Form_Unload-Event.
    Quote Originally Posted by ColinE66 View Post
    I agree with Olaf; Set Form2 = Nothing shouldn't be in the Form2's unload event handler...
    I would like to ask why?

    I had a few cases in the past where, for example, I opened a form non modally, and I wanted only one instance for the whole application so I used the predefined one. But after it was finished used and unloaded, I wanted to go to the "default state" so I've put in the Unload event Set FormMane = Nothing.

    Of course I never attempted to use any variable that were the form after that.

    And it seems to work without problem, so I'm curious about why that "should never be written by anybody".

    TIA.
    MSDN online for VB6 - Language Reference - Controls Reference
    Download MSDN October 2001: disk 1, 2 and 3

  10. #10
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,503

    Re: Uninstantiation working differently in IDE than compiled

    Quote Originally Posted by Elroy View Post
    @Niya: Good call. P-code compiled works the same as the IDE, not machine compiled.
    I suspected as much. A p-code EXE executes the app the same way the IDE executes it.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  11. #11

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

    Re: Uninstantiation working differently in IDE than compiled

    Quote Originally Posted by ColinE66 View Post
    Not to ignite the debate you are trying to avoid with the whole PredeclareID thing, but can you explain, please, the benefit that accrues from using them in your scenario - just for my own educational purposes...
    Hi Colin,

    Ohhh, I wouldn't mind this debate. It'll be much more pleasant than the debate of copyright in another thread.

    As suggested by Eduardo, and myself, we've got these "global" object/form variables whether we want them or not, so I've just never seen the point of forbidding use of them. From my perspective, they actually promote encapsulation (the idea of keeping a code concept well encapsulated, without too many lines of external code). For instance, when we don't use these global variables, we've got to declare another variable (for our form object), instantiate it, use it to show the form, and then make sure we do appropriate clean-up.

    I know I'm (probably, somewhat) on the wrong side of yet another argument, but it's still something I just don't see any absolute reason to not do. I will grant that, before we use these PredeclaredId variables, we should develop a sound understanding of how they work. In fact, probably more than anything, that's what this thread is about.

    As we should know, a form has both a Window piece and a COM/code piece. That's reflected in the fact that we get both Form_Load/Form_Unload and Form_Initialize/Form_Terminate events. There's a Microsoft page somewhere that talks about how we can have either-or-both of these pieces loaded, and that's precisely what must be appropriately managed.

    Also, when dealing with VB6 COM/code objects, we must realize that VB6 will often create "temporary" references to that object that aren't represented in explicit VB6 variables. That's how a CLS module can de-reference every reference to itself, and still execute the code long enough to get a Class_Terminate executed.

    So long as our understanding of these things is clear, I see no problem with using these global PredeclaredId variables.

    What's interesting is that, when the last "explicit" reference to a particular COM object is de-referenced, apparently, in machine-compiled VB6 code, all the module level variables (and possibly any procedure statics as well) are immediately destroyed. Whereas, in the IDE, they're not destroyed until the COM object's code completes final execution.

    I'd bet that CLS modules behave in a similar fashion, and I may set up a test. If I do, I'll post the results.

    Best Regards,
    Elroy
    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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  12. #12
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,208

    Re: Uninstantiation working differently in IDE than compiled

    Quote Originally Posted by Elroy View Post
    Ok, what if we like using the PredeclaredId of forms, and, yes, I know there's substantial debate on this, but please, let's set that debate aside.
    We've got this PredeclaredId, so I'll never understand why we should be prohibited from using it.
    Yep, we've got it (by default for Forms) - and it is a convenience for simple scenarios.

    Quote Originally Posted by Elroy View Post
    Ok, we're using the PredeclaredId, such as Form1 or Form2 (or the Properties Window name we've given to the form).
    When using that implicit object variable, how would you recommend un-instantiating the COM/code object when we're done with it?
    I already wrote, that a line like "Set FormProtoTypeName=Nothing" should never be written" - period.

    And I've also already shown the proper way to do it, so why not adapting to it.

    Quote Originally Posted by Elroy View Post
    (And Olaf, note that you're leaving it instantiated.)
    That's just another one of your wrong assumptions Elroy -
    in my example I don't leave the Form-Instance alive -
    it dies properly and immediately at the point where you "run over" the 'End With' line.


    Quote Originally Posted by Elroy View Post
    Code:
    
    Dim ms As String
    '
    
    Friend Sub ShowModal(s As String)
        ms = s
        Me.Show vbModal
        s = ms
        'MsgBox "Return to caller"
        Set Form2 = Nothing     ' <--- Moved from Form_Unload to here.
    End Sub
    
    Yeah . stubborn ignorance as always.

    The above will fall apart when for example:
    - more than one instance of that form needs to be shown (because the Prototype exists only once)
    - or a developer decides to do it properly - instantiating (from) said Form2 in another, dedicated Variable F2, then calling F2.ShowModal (ms of F2 will not be cleaned up then)

    In short:
    Using the Prototype-Name of a given Form in the very same FormTypes (Class-)CodeModule is "as evil as using the End-statement".

    Olaf

  13. #13
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,208

    Re: Uninstantiation working differently in IDE than compiled

    Quote Originally Posted by Eduardo- View Post
    And it seems to work without problem, so I'm curious about why that "should never be written by anybody".
    I thought, that from Elroys Opener-Post, it was already a given, that stuff like that is far from "working without problems".

    You just don't use the Forms Prototype-Name in the Form-Class-Code -
    or - if you do, do it at "your own risk"...

    I mean, when you write "just a few Longs" at random Addresses into a given Process's Memory-Area,
    then there's also a good chance, that you will not crash, probably.

    Olaf

  14. #14

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

    Re: Uninstantiation working differently in IDE than compiled

    Hi Olaf,

    (First, if you wouldn't mind, please offer me a tad of common respect. I'll do my best to overlook what feels/seems like personal attacks.)

    Now, I did manage to overlook your "With New Form2" statement, so I'd agree that the COM object is being uninstantiated, because of the New statement. However, if we do something like the following, we see that it's not:

    Form1 code (with a couple of buttons):
    Code:
    
    Option Explicit
    
    Private Sub Command1_Click()
        Dim s As String
    
        Form2.ShowModal s
        MsgBox "Our string: """ & s & """"
    End Sub
    
    Private Sub Command2_Click()
        MsgBox "Our test: """ & Form2.Test & """"
    End Sub
    
    Form2 code:
    Code:
    
    Option Explicit
    
    Dim ms As String
    Dim msTest As String
    
    Friend Sub ShowModal(s As String)
        msTest = "test test test"
    
        ms = s
        Me.Show vbModal
        s = ms
    End Sub
    
    Private Sub Form_DblClick()
        ms = "put something in string"
        Unload Me
    End Sub
    
    Friend Property Get Test() As String
        Test = msTest
    End Property
    
    Quote Originally Posted by Schmidt View Post
    I already wrote, that a line like "Set FormProtoTypeName=Nothing" should never be written" - period.
    So, the fact that it was written by Olaf, means that it should never be questioned again, and accepted as the word of GOD? Olaf, what happened to the spirit of fully understanding things so that we could use them appropriately. In fact, I've seen the obstreperous Dilettante edit CLS modules, specifically to make use of their PredeclareID option. Is this to be forbidden as well? Just asking.

    Quote Originally Posted by Schmidt View Post
    more than one instance of that form needs to be shown (because the Prototype exists only once)
    Now that's actually a good point. It's not relevant to me because I virtually never load multiple instances of the same form, but others may. So it's an excellent point.

    Quote Originally Posted by Schmidt View Post
    when you write "just a few Longs" at random Addresses into a given Process's Memory-Area,
    then there's also a good chance, that you will not crash, probably.
    Are you suggesting that I'm doing that in my post #5? Or is that just ... erm ... dare I say ... ignorant speculation? Ok ok, I apologize for that one. I should be above tit-for-tat.

    Yet Again, Trying to Keep My Spirits Up, The Best to All,
    Elroy
    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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  15. #15
    Hyperactive Member
    Join Date
    May 2011
    Posts
    370

    Re: Uninstantiation working differently in IDE than compiled

    @Elroy: Form2.frx is missing -- apparently you like having custom icons on them forms.

    Just replacing `Form2.ShowModal s` with
    vb Code:
    1. With Form2
    2.     .ShowModal s
    3. End With
    . . . fixes the issue.

    We'll need trick's help to confirm if the problem is that on a line like `obj.method output_param` the compiler emits code that releases `obj` reference before processing `output_param` (no idea what processing is needed).

    This is total speculation on my part, root cause can be totally unrelated. Only the fix above is real :-))

    cheers,
    </wqw>

  16. #16

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

    Re: Uninstantiation working differently in IDE than compiled

    @wqweto: Ahhh, sorry. When I was running down the bug, I started out with a form from my primary project, which did have a custom icon. I thought I deleted the FRX and then test re-loaded it and it worked. But I must not have. Yeah, I'll check it and fix it.

    Best Regards,
    Elroy

    EDIT1: Yep, it loaded fine (which is all I did as a check), but it complained when executing. I've now fixed the attachment in the OP.

    EDIT2: WOW, that's really curious that your proposed fix works. Unless a "New" was included, I would have never thought that a simple "With" block would have fixed it. Yes, we may need to wait on The Trick. However, yes, as a guess, I'm thinking that the "With" block is creating another implicit object variable which is keeping the COM object instantiated just long enough to retrieve that module level variable out of Form2's code.

    In fact, that gives me more assurance that my code in post #5 is also working as expected. Both approaches are just delaying uninstantiation (or, more precisely, un-initialization of module variables) a bit.

    Best Regards,
    Elroy
    Last edited by Elroy; Dec 7th, 2017 at 03:57 PM.
    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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  17. #17
    Fanatic Member
    Join Date
    Apr 2012
    Posts
    906

    Re: Uninstantiation working differently in IDE than compiled

    Thanks for replying, Elroy. I'm reducing myself to 'interested spectator' at this point so as to learn from the current exchange of opinions. I should point out that my initial assertion was based upon it just feeling 'wrong' to set Form2 to Nothing from within its own code. Again, thanks for taking the time to respond...
    If you don't know where you're going, any road will take you there...

    My VB6 love-children: Vee-Hive and Vee-Launcher

  18. #18
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,208

    Re: Uninstantiation working differently in IDE than compiled

    Quote Originally Posted by Elroy View Post
    (First, if you wouldn't mind, please offer me a tad of common respect. I'll do my best to overlook what feels/seems like personal attacks.)
    Oh, then please do offer me the same -
    see, I've invested my time to show you a properly working example
    (using even a bit less code than what you've shown in your first post).

    You choose to "skip over it" - even making wrong statements about it.
    So, please allow me to show a bit of "frustration" about your missing
    respect in *that* (priorily happened) instance, if you don't mind.

    Quote Originally Posted by Elroy View Post
    ... However, if we do something like the following, ...
    And it continues,,,

    Elroy - again, modally shown Forms literally "cry" for being wrapped in a:
    With New ProtoTypeName
    '...
    End With
    Code-Block...

    but since you insist to deal with modal Forms using their Prototype-Autoinstance, ...
    Quote Originally Posted by Elroy View Post
    Form2 code:
    Code:
    
    Option Explicit
    
    Dim ms As String
    Dim msTest As String
    
    Friend Sub ShowModal(s As String)
        msTest = "test test test"
    
        ms = s
        Me.Show vbModal
        s = ms
    End Sub
    
    Private Sub Form_DblClick()
        ms = "put something in string"
        Unload Me
    End Sub
    
    Friend Property Get Test() As String
        Test = msTest
    End Property
    
    ...here is, how I'd rewrite your above given Form2:

    Code:
    Option Explicit
    
    Private Type tm
      s As String
      sTest As String
    End Type
    
    Private m As tm
    
    Friend Sub ShowModal(s As String)
        m.sTest = "test test test"
    
        m.s = s
          Show vbModal
        s = m.s
        mCleanup
    End Sub
    
    Private Function mCleanup() As tm
        m = mCleanup
    End Function
    
    Private Sub Form_DblClick()
        m.s = "put something in string"
        Unload Me
    End Sub
    
    Friend Property Get Test() As String
        Test = m.sTest
    End Property
    But if it's about "a lot of Parameter-Variables to pass into the Modal-Form",
    I'd probably re-write it this way (using a DataContainer-Class):

    Into a Class, named cModalData
    Code:
    Option Explicit
    
    Public s As String, sTest As String
    Into Form1
    Code:
    Option Explicit
     
    Private Sub Command1_Click()
        Dim D As New cModalData
            Form2.ShowModal D
        MsgBox "Our string: """ & D.s & """"
    End Sub
    
    Private Sub Command2_Click()
        MsgBox "Our test: """ & Form2.Test & """"
    End Sub
    Into Form2
    Code:
    Option Explicit
     
    Private mD As cModalData
    
    Friend Sub ShowModal(D As cModalData)
      Set mD = D
          mD.sTest = "test test test"
             Show vbModal
      Set mD = Nothing
    End Sub
     
    Private Sub Form_DblClick()
      mD.s = "put something in string"
      Unload Me
    End Sub
    
    Friend Property Get Test() As String
      If Not mD Is Nothing Then Test = mD.sTest
    End Property

    Quote Originally Posted by Elroy View Post
    So, the fact that it was written by Olaf, means that it should never be questioned again, ...
    Not at all - but where was your question to my first posting in #2 exactly?
    (the only one, who asked a concrete question about it, was Eduardo).

    Besides, I'm the only one in the VB6-community (AFAIK) who has written an (even DPI-aware) alternative
    to the original VB6-Form-Engine, so I guess you can safely assume that I know what I'm talking about...

    Quote Originally Posted by Elroy View Post
    [Random CopyMemory stuff]
    Are you suggesting that I'm doing that in my post #5?
    Well, I was trying to make a joke there - but you've described real problems in your post #1 -
    and I've mentioned a few more risks that could happen also by using your "revised stuff" in your post #5.

    How many times you think, do I have to point out "risky-stuff" you didn't think about,
    when you come up with your "next revision" of the "let's use the global AutoInstance in the Class-Module"-approach.

    Olaf

  19. #19

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

    Re: Uninstantiation working differently in IDE than compiled

    Olaf,

    Thank you for the thoughtful reply. And again, I'm sorry I missed your "With New Form2" (or, as pointed out by wqweto, "With Form2" does the same thing if not already instantiated). Until now, I've just never seen the need for a "With" statement when there's only one line of code to be placed in that "With" block.

    I'm still convinced that my "fix" in post #5 is quite adequate, but I'm hoping it's time to just move on.

    Peace (hopefully),
    Elroy
    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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  20. #20
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,605

    Re: Uninstantiation working differently in IDE than compiled

    you mentioned encapsulation, but referring to a global instance inside a generic instance's code without a reason doesn't just seem wrong - it seems to breaks the encapsulation paradigm. Not to mention the bugs you are going to get if you ever use a generic instance, vs the global one.

    At a minimum I would put this in the Initialize so it's only used a singleton...
    Code:
    Private Sub Form_Initialize()
        If Not Me Is Form2 Then Err.Raise 5, "Form2", "Youre doing it Wrong... Form2 Is a singleton." 'see ShowModal() for boobie trap
    End Sub
    Imagine what it would be like to set breakpoints in, or step through subclassing code;
    and then being able to hit stop/end/debug or continue, without crashing the IDE.

    VB6.tlb | Bulletproof Subclassing in the IDE (no thunks/assembly/DEP issues)

  21. #21

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

    Re: Uninstantiation working differently in IDE than compiled

    Hi Dex,

    Yeah, I woke up at 5am thinking about this encapsulation issue. I suppose, in my mind, there are two points of encapsulation: 1) trying our best to keep our variables as local as possible, 2) pushing code as far down in the call stack as we possibly can. Use of these PredeclaredId variables certainly violates my #1 point. However, they're there, and there's no way to get rid of them (other than totally ignore them, which is clearly what Olaf is suggesting).

    However, regarding my #2 point, IMHO, the following code ...

    Code:
    Form1.ShowModal [argument list]
    ... is more encapsulated than ...

    Code:
    With New Form1
        .ShowModal
    End With
    ... and that's even more encapsulated than ...

    Code:
    Dim frm As VB.Form
    Set frm = New Form1
    frm.ShowModal
    Set frm = Nothing
    I suppose, at the higher level (i.e., outside the form we're dealing with), I like the elegance of a single statement to get something done. In that vein, even doing something like the following, solves the problem I raised...

    Form1:
    Code:
    
    Option Explicit
    
    Private Sub Form_DblClick()
        Dim s As String
    
        Form2.ShowModal s
    
        MsgBox "Our string: """ & s & """"
    End Sub
    
    Form2:
    Code:
    
    Option Explicit
    '
    Dim ms As String
    '
    
    Friend Sub ShowModal(s As String)
        Dim frm As Form     ' <--- NEW
        Set frm = Me        ' <--- NEW (it may not seem like this is doing anything, but it's raising the COM alias count).
        '
        ms = s
        Me.Show vbModal
        s = ms
    End Sub
    
    Private Sub cmdOK_Click()
        Unload Me
    End Sub
    
    Private Sub Form_DblClick()
        ms = "put something in string"
        Unload Me
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        Set Form2 = Nothing
    End Sub
    
    IMHO, the problem is all about the COM's internal alias/reference count. Apparently, machine-compiled code is a bit more efficient with this count, getting it to zero a bit quicker than p-code, and therein lies the problem.

    Best Regards,
    Elroy
    Last edited by Elroy; Dec 8th, 2017 at 09:22 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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  22. #22
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,605

    Re: Uninstantiation working differently in IDE than compiled

    ah elroy! it you seem to have your own ideas about what encapsulation means. It's a little different in Computer Science, as these terms are pretty specific, and have nothing to do with the call stack or local variables, and everything to do with OOP.

    https://en.wikipedia.org/wiki/Encaps...r_programming)

    basically you see the real problem as the difference in compiled code vs going against established best practice.

    edit: why do you have Set Form2 = Nothing in there again?
    ShowModal uses it's own instance, but the unload zeros the global reference?
    why?
    Last edited by DEXWERX; Dec 8th, 2017 at 09:41 AM.
    Imagine what it would be like to set breakpoints in, or step through subclassing code;
    and then being able to hit stop/end/debug or continue, without crashing the IDE.

    VB6.tlb | Bulletproof Subclassing in the IDE (no thunks/assembly/DEP issues)

  23. #23
    Hyperactive Member
    Join Date
    May 2011
    Posts
    370

    Re: Uninstantiation working differently in IDE than compiled

    This looks like a compile time optimization, probably a single QI on `Form2` is saved in final compiled binary. There is no COM rule that demands AddRef'ing an interface before calling any of it's methods so `Form2.method` does not increase instance `ref_count` unless a hidden temporary QI is performed which is kept in a hidden local var that gets released before stepping to the next line (as one can speculate probably the IDE is doing).

    Another possibility is difference in how zombie instances get cleaned up by IDE and in compiled binary. Technically in your sample in `Form2.ShowModal` all the code past `Me.Show vbModal` gets executed on a zombie instance -- one that got it's `Form_Terminate` fired. The behavior of zombie objects is mostly undefined but getting member vars cleaned by the runtime is reasonable to occur somewhere after `Form_Terminate` and before object memory getting completely deallocated from heap.

    I'm really baffled how they managed to not get into AV exception on `s = ms` line -- accessing member var in a deallocated memory. Getting an empty output string is the least that could happen here. . .

    cheers,
    </wqw>

  24. #24

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

    Re: Uninstantiation working differently in IDE than compiled

    Hi Dex,

    Can I just concede the point, and still point out a couple of things? Who knows, maybe I'm just in a mood these days. If you don't mind, let me quote a bit from that Wikipedia page:

    A language mechanism for restricting direct access to some of the object's components.
    I read this as the #1 point I made, i.e., keeping variables as local as possible. Or at least that's part of it. And...

    A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.
    Now, I truly realize that's a "big" statement. And I "get" it. I have a procedure that uses quantile regression to calculate BMI (body mass index) percentiles based on published (public domain) CDC survey data. The procedure has an enormous amount of data "encapsulated" into it, but the function only takes four arguments (height, weight, age, gender) and returns only one (BMI percentile). IMHO, that's really what they're talking about. But, to my eyes, it could also be talking about writing things such that superfluous code isn't needed at higher levels to get things done. And, if more code is needed, push it down into the lower level procedures.

    Again, I take your point.

    Best Regards,
    Elroy

    EDIT1: For grins, here's a screenshot of that "encapsulated" CDC data. It goes on for pages and pages. It used to be in a file, but I now just keep it in a CLS module:
    Name:  cdc.png
Views: 35
Size:  161.7 KB
    (And just for anyone who's curious, I actually worked with Bernard Rosner to develop and debug these algorithms. Rosner was the lead investigator who worked with the CDC to collect these data.)
    Last edited by Elroy; Dec 8th, 2017 at 09:49 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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  25. #25
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,503

    Re: Uninstantiation working differently in IDE than compiled

    Encapsulation should be treated as more of a guiding principle than something concrete like language mechanisms, even though language mechanisms do help enforce adherence to its guidelines.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.