HowTo: Synchronize settings of an IE plug-in

Nearly every software program has some settings. An Internet Explorer plug-in is not an exception. The IE add-on settings can be stored either in a file or in a registry branch, all is simple and transparent about this. But how to ensure the settings synchronization for all active instances of the IE plug-in in all running Internet Explorer processes? By using the AddinExpress.IE.ADXIESharedMemory class.

Well, here goes! Let’s create a new IE plug-in project using the “ADX IE Bar” wizard, populate our IEBarModule with a group box that has 3 radio buttons, add a couple of checkboxes, a combo box and text box. Ergo, we need to store and synchronize 5 values, Integer as index for RadioButtons, two Boolean values as CheckBox states, another Integer as index for ComboBox and String for TextBox. Now, add to the project your own class, a descendent of ADXIESharedMemory, by using “ADX IE Shared Data” wizard and modify the GlobalData class, which is present in every IE plug-in project.

Here is a list of private variables needed:


Private lastOutputPath As String
Private optionPageData As MySharedData

Private Const FILE_LOCKED As Integer = 0
Private Const RADIO_OPTION As Integer = 1
Private Const CHECK_OPTION_1 As Integer = 2
Private Const CHECK_OPTION_2 As Integer = 3
Private Const LIST_OPTION As Integer = 4
Private Const STRING_OPTION As Integer = 5

Modified constructor:


Public Sub New()
    MyBase.New()
    'System.Diagnostics.Debugger.Break()
    Dim outputPath As String = _
        Path.Combine(Environment.GetFolderPath( _
        Environment.SpecialFolder.InternetCache), "Low")
    outputPath = Path.Combine(outputPath, "MyIEOptionPage")
    If Not Directory.Exists(outputPath) Then
        Directory.CreateDirectory(outputPath)
    End If
    Me.lastOutputPath = outputPath
    Me.optionPageData = New MySharedData( _
        "MyIEOptionPage", 512, 10)

    Me.optionPageData(FILE_LOCKED) = 0
    Me.optionPageData(RADIO_OPTION) = 0
    Me.optionPageData(CHECK_OPTION_1) = False
    Me.optionPageData(CHECK_OPTION_2) = False
    Me.optionPageData(LIST_OPTION) = 0
    Me.optionPageData(STRING_OPTION) = "Default"
End Sub

Added methods:


Public Sub LoadOptions()
    If CInt(Me.optionPageData(FILE_LOCKED)) = 0 Then
        Me.optionPageData(FILE_LOCKED) = 1
        Try
            Dim outputFile As String = _
                Path.Combine(lastOutputPath, "myoptions.cfg")
            If File.Exists(outputFile) Then
                Using sr As New StreamReader(outputFile)
                    Dim line As String
                    line = sr.ReadLine()
                    Me.optionPageData(RADIO_OPTION) = _
                      Convert.ToInt32(line.Trim())
                    line = sr.ReadLine()
                    Me.optionPageData(CHECK_OPTION_1) = _
                      Convert.ToBoolean(line.Trim())
                    line = sr.ReadLine()
                    Me.optionPageData(CHECK_OPTION_2) = _
                      Convert.ToBoolean(line.Trim())
                    line = sr.ReadLine()
                    Me.optionPageData(LIST_OPTION) = _
                      Convert.ToInt32(line.Trim())
                    line = sr.ReadLine()
                    Me.optionPageData(STRING_OPTION) = _
                      line.Trim()
                End Using
            End If
        Finally
            Me.optionPageData(FILE_LOCKED) = 0
        End Try
    End If
End Sub

Private Sub SaveOptions()
    If CInt(Me.optionPageData(FILE_LOCKED)) = 0 Then
        Me.optionPageData(FILE_LOCKED) = 1
        Try
            Dim outputFile As String = _
                Path.Combine(lastOutputPath, "myoptions.cfg")
            Using sw As New StreamWriter(outputFile, False)
                sw.Write(Me.optionPageData(RADIO_OPTION))
                sw.Write(sw.NewLine)
                sw.Write(Me.optionPageData(CHECK_OPTION_1))
                sw.Write(sw.NewLine)
                sw.Write(Me.optionPageData(CHECK_OPTION_2))
                sw.Write(sw.NewLine)
                sw.Write(Me.optionPageData(LIST_OPTION))
                sw.Write(sw.NewLine)
                sw.Write(Me.optionPageData(STRING_OPTION))
            End Using
        Finally
            Me.optionPageData(FILE_LOCKED) = 0
        End Try
    End If
End Sub

Public Sub UpdateOptions(ByVal [module] As IEBarModule)
    SyncLock Instance
        Me.optionPageData(RADIO_OPTION) = [module].RadioOptions
        Me.optionPageData(CHECK_OPTION_1) = [module].CheckOption1
        Me.optionPageData(CHECK_OPTION_2) = [module].CheckOption2
        Me.optionPageData(LIST_OPTION) = [module].ListOption
        Me.optionPageData(STRING_OPTION) = [module].StringOption
        SaveOptions()
    End SyncLock
End Sub

Public Sub RefreshOptions(ByVal [module] As IEBarModule)
    SyncLock Instance
        [module].RadioOptions = _
          CInt(Me.optionPageData(RADIO_OPTION))
        [module].CheckOption1 = _
          CBool(Me.optionPageData(CHECK_OPTION_1))
        [module].CheckOption2 = _
          CBool(Me.optionPageData(CHECK_OPTION_2))
        [module].ListOption = _
          CInt(Me.optionPageData(LIST_OPTION))
        [module].StringOption = _
          DirectCast(Me.optionPageData(STRING_OPTION), String)
    End SyncLock
End Sub

Public Sub CloseOptions()
    SyncLock Instance
        If Me.optionPageData IsNot Nothing Then
            Try
                SaveOptions()
            Finally
                Me.optionPageData.Dispose()
                Me.optionPageData = Nothing
            End Try
        End If
    End SyncLock
End Sub

Now let’s go back to IEBarModule and add Load, OnConnect, OnDisconnect, OnSendMessage and two button Click event handlers (one to apply settings, and another to cancel them):


Private startMode As Boolean = True
Private Const WM_UPDATE_OPTIONS As Integer = (&H400 + 3000)

Private Sub IEBarModule_Load( _
    ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles MyBase.Load

    Try
        GlobalData.Instance.LoadOptions()
    Catch err As Exception
        MessageBox.Show(err.Message, Me.Title, _
          MessageBoxButtons.OK, MessageBoxIcon.[Error])
    End Try
End Sub

Private Sub IEBarModule_OnConnect( _
    ByVal sender As System.Object, _
    ByVal threadId As System.Int32) Handles MyBase.OnConnect

    comboBox1.SelectedIndex = 0
    SendMessageToAll(WM_UPDATE_OPTIONS, IntPtr.Zero, IntPtr.Zero)
    startMode = False
End Sub

Private Sub IEBarModule_OnDisconnect( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.OnDisconnect

    Try
        GlobalData.Instance.CloseOptions()
    Catch err As Exception
        MessageBox.Show(err.Message, Me.Title, _
          MessageBoxButtons.OK, MessageBoxIcon.[Error])
    End Try
End Sub

Private Sub IEBarModule_OnSendMessage( _
    ByVal e As AddinExpress.IE.ADXIESendMessageEventArgs) _
    Handles MyBase.OnSendMessage

    Select Case e.Message
        Case WM_UPDATE_OPTIONS
            If True Then
                startMode = True
                Try
                    GlobalData.Instance.RefreshOptions(Me)
                Finally
                    startMode = False
                End Try
            End If
            Exit Select
    End Select
End Sub

Private Sub buttonApply_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles buttonApply.Click

    Try
        GlobalData.Instance.UpdateOptions(Me)
        SendMessageToAll(WM_UPDATE_OPTIONS, IntPtr.Zero, _
            IntPtr.Zero)
    Finally
        buttonApply.Enabled = False
        buttonCancel.Enabled = False
    End Try
End Sub

Private Sub buttonCancel_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles buttonCancel.Click

    Try
        GlobalData.Instance.RefreshOptions(Me)
    Finally
        buttonApply.Enabled = False
        buttonCancel.Enabled = False
    End Try
End Sub

So, now we have all the settings stored in the myoptions.cfg file. Once the settings are changed, all active instances of the IE plug-in in all running Internet Explorer processes learn the fact and get to know their new values.

That’s all for today.

You may also be interested in:

How to develop an add-on for IE6, IE7 and IE8
How to create a custom button for IE toolbar
How to build an Explorer bar and context menu

Available downloads:

This sample add-in was developed using Add-in Express 2009 for Internet Explorer and .net

C# sample IE plug-in for VS 2005
VB.NET sample IE plug-in for VS 2005

2 Comments

  • PB says:

    Hi,

    isn’t using Windows registry better solution? I had a lot of problems (not solved yet) in storing app data in Vista (I used standard C# Settings mechanism).

    Storing data in the registry works pretty well on every tested environment (XP, Vista, 2003 Server).

    Regards,
    PB

  • Dmitry Kostochko says:

    Sure, you can store your data in the Windows registry. I only possible problem that I foresee is that you will need somehow to delete the stored data when uninstalling the plug-in. Though, it may not be a problem.

Post a comment

Have any questions? Ask us right now!