Results 1 to 11 of 11

Thread: [RESOLVED] Design question

  1. #1

    Thread Starter
    Member
    Join Date
    May 2009
    Location
    Victoria, BC
    Posts
    36

    Resolved [RESOLVED] Design question

    I have to design a way to know what controls have been changed on our Settings Dialog. This dialog has every type of control you can think of on it.
    The reason for it, is the dialog has like 100 controls and when we hit save, it tries saving all settings to the registry, no matter if they have changed or not. It also will restart all of our threads, even if it doesn't need too.

    Does anyone have an idea of what I could possibly look into doing?

  2. #2
    Hyperactive Member deathfxu's Avatar
    Join Date
    Mar 2009
    Location
    USA
    Posts
    279

    Re: Design question

    Quote Originally Posted by Kruis View Post
    It also will restart all of our threads, even if it doesn't need too.
    What do you mean by this? For whatever reason this sentence is making no sense to me.

    btw, Welcome to VBForums !
    Last edited by deathfxu; May 27th, 2009 at 11:47 AM. Reason: clarification

  3. #3

    Thread Starter
    Member
    Join Date
    May 2009
    Location
    Victoria, BC
    Posts
    36

    Re: Design question

    Yes, not knowing our system makes it harder to explain.

    What I mean, is some setting in our settings dialog, if changed will need to restart some of our threads in our product. Some settings do not affect these threads, so they do not need to be restarted.
    Currently, if a user goes into the server settings for our product and make a minor change then hits 'Save'. It saves all of the settings, and restarts all of the server threads for our product.

    Does that make any more sense?

  4. #4
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Design question

    One way is to use the .Tag property of the controls.

    When you first load the data, store the values of each control to its own .Tag property too. When the save button is pressed, you can compare the value to the .Tag, and only save that item it has changed.

  5. #5
    Hyperactive Member deathfxu's Avatar
    Join Date
    Mar 2009
    Location
    USA
    Posts
    279

    Re: Design question

    Also, in the registry if you save "[objectname] [propertyname] [propertyvalue] " then you can use:

    vb Code:
    1. Private Sub SetObjProp(objName As String, objProp As String, objPropValue As String)
    2.  
    3. CallByName Me.Controls(objName), objProp, VbLet, objPropValue
    4.  
    5. End Sub

    So if you do:

    vb Code:
    1. Call SetObjProp("Text1", "Text", "It worked!")

    Then Text1.Text will equal "It worked!".

  6. #6

    Thread Starter
    Member
    Join Date
    May 2009
    Location
    Victoria, BC
    Posts
    36

    Re: Design question

    That's an excellent suggest! The one thing I did not explain, is that one control can be used for more than one item.
    Maybe the best way to explain this, is by drawing an image. On the left side of our settings dialog, we have a tree control with a list of items. When a user selects an items, the controls on the right side populate with the items details. Such as its name.
    The user can go in and change all the items names, and then save at the end.
    So the tag field wouldn't work in this instance, since the value for the control will change when the user selects different items.

    I have a feeling this way to confusing to explain.

  7. #7
    Hyperactive Member deathfxu's Avatar
    Join Date
    Mar 2009
    Location
    USA
    Posts
    279

    Re: Design question

    Quote Originally Posted by Kruis View Post
    That's an excellent suggest! The one thing I did not explain, is that one control can be used for more than one item.
    Maybe the best way to explain this, is by drawing an image. On the left side of our settings dialog, we have a tree control with a list of items. When a user selects an items, the controls on the right side populate with the items details. Such as its name.
    The user can go in and change all the items names, and then save at the end.
    So the tag field wouldn't work in this instance, since the value for the control will change when the user selects different items.
    Maybe then you can store the data in a manner like i listed in post #5 with all the default values. Then you can use:

    vb Code:
    1. CallByName Me.Controls(curObj), curProp, vbGet

    To check to see if the values are equal.

  8. #8
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Design question

    From your explanation it sounds like you must be storing somewhere (perhaps an array?) what the current values of each item are - so just store a duplicate version which contains the original version (or a boolean to say if it has changed), and check that before saving.

  9. #9

    Thread Starter
    Member
    Join Date
    May 2009
    Location
    Victoria, BC
    Posts
    36

    Re: Design question

    This is how it currently works for a simple field like a 'Name'.
    All the information is stored in an array, when it is saving we convert the array, to a string. ie.
    arrNames() = {"T1","T2","T3"} to sNames = "T1,T2,T3"
    Then we save this string into our 'Names' registry entry.

    I am not allowed to change how the string is saved in the registry because it would cause our end users to lose their current settings.

    This is the solution I have come up with. Being a bit of a kludge Lets talk about one control type. The TextBox as the Names field.
    - On the LostFocus for the TextBox, I will compare the current Reg data with the new text value.
    - If it has changed, I will save the control id, and index of the item into a new struct called, 'HasChanged'. Which is a list of changed items/fields.
    - When the user hits save, I loop through all 'HasChanged' to write the new values to the Reg, and I check to see what threads, if any need to be restarted. I find this out from the Tag property in the control. I am using the Tag to store a bitwise flag that tells me, if this control affects any threads in our product when changed.

    For instance, the 'Name' field can change, and we do not need to restart any threads. But if a different field changes. We might have to restart some of them.

  10. #10
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Design question

    I have a suggestion with some "cool" factor in it: what about listening GotFocus and LostFocus event of each of your controls and only checking there whether a property of a control has changed or not?

    Code:
    Option Explicit
    
    Private WithEvents Focus As FocusEvents
    
    Private m_Changed As Collection
    Private m_OriginalText As String
    Private m_OriginalValue As Variant
    
    Private Sub Command1_Click()
        Dim lngA As Long, strArray() As String
        ' display the changes that have been made
        If m_Changed.Count Then
            ReDim strArray(m_Changed.Count - 1)
            For lngA = 1 To m_Changed.Count
                strArray(lngA - 1) = m_Changed(lngA)
            Next lngA
            MsgBox Join(strArray, vbNewLine), vbInformation, "Changed!"
        End If
    End Sub
    
    Private Sub Focus_GotFocus(Control As Control)
        If TypeOf Control Is TextBox Then
            m_OriginalText = Control.Text
        Else
            m_OriginalValue = Control.Value
        End If
    End Sub
    
    Private Sub Focus_LostFocus(Control As Control)
        ' if value of a control has changed add it in to the collection of changed elements
        If TypeOf Control Is TextBox Then
            If m_OriginalText <> Control.Text Then
                On Error Resume Next
                m_Changed.Add Control.Name, Control.Name
                On Error GoTo 0
            End If
        Else
            If m_OriginalValue <> Control.Value Then
                On Error Resume Next
                m_Changed.Add Control.Name, Control.Name
                On Error GoTo 0
            End If
        End If
    End Sub
    
    Private Sub Form_Initialize()
        Dim Control As Control
        ' watch for controls that have properties Text and Value
        Set Focus = New FocusEvents
        For Each Control In Me.Controls
            ' see if it has Text property
            If Focus.Add(Control, "Text") = 0 Then
                ' it did not have, try Value
                Focus.Add Control, "Value"
            End If
        Next Control
        ' initialize collection that knows which elements have changed
        Set m_Changed = New Collection
    End Sub
    
    Private Sub Form_Terminate()
        Set Focus = Nothing
    End Sub
    The required FocusEvent.cls and FocusEvents.cls are attached (as is the whole demo project). Afaik using this would require minimal code changes to what you currently have.
    Attached Files Attached Files

  11. #11

    Thread Starter
    Member
    Join Date
    May 2009
    Location
    Victoria, BC
    Posts
    36

    Re: Design question

    This is totally Rad! Thank you Merri, this will save me a lot of extra code by not having to add a LostFocus to every control.

    Thank you everyone, this has been a big help in my design.

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