locked
System tray problem RRS feed

  • Question

  • Hi guys

    I have difficulty to fix my system tray problem. I want the form to run to the registry and read my application to see if 0 or 1 is to show or not show the system tray icon on my taskbar corner on the next software start. I have placed the registry code and the public click code on my form, the system tray enable or disable are working when I select on the menu item Show\disable but when I save one of them into the registry like disable the tray and when I run on the next software start it still showing the icon on my system tray. I don't know what went wrong, here is the code and I hope you can take a look!!!!!!!




    Code Block

        Private Declare Function RegCloseKey Lib "advapi32" (ByVal hKey As Integer) As Integer
        'UPGRADE_WARNING: Structure SECURITY_ATTRIBUTES may require marshalling attributes to be passed as an argument in this Declare statement. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="C429C3A5-5D47-4CD9-8F51-74A1616405DC"'
        Private Declare Function RegCreateKeyEx Lib "advapi32" Alias "RegCreateKeyExA" (ByVal hKey As Integer, ByVal lpSubKey As String, ByVal Reserved As Integer, ByVal lpClass As String, ByVal dwOptions As Integer, ByVal samDesired As Integer, ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, ByRef phkResult As Integer, ByRef lpdwDisposition As Integer) As Integer
        Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" (ByVal hKey As Integer, ByVal lpSubKey As String, ByVal ulOptions As Integer, ByVal samDesired As Integer, ByRef phkResult As Integer) As Integer
        Private Declare Function RegQueryValueEx Lib "advapi32" Alias "RegQueryValueExA" (ByVal hKey As Integer, ByVal lpValueName As String, ByVal lpReserved As Integer, ByRef lpType As Integer, ByVal lpData As String, ByRef lpcbData As Integer) As Integer
        Private Declare Function RegSetValueEx Lib "advapi32" Alias "RegSetValueExA" (ByVal hKey As Integer, ByVal lpValueName As String, ByVal Reserved As Integer, ByVal dwType As Integer, ByVal lpData As String, ByVal cbData As Integer) As Integer

        '---------------------------------------------------------------
        '- Registry Api Constants...
        '---------------------------------------------------------------
        ' Reg Data Types...
        Const REG_SZ As Short = 1 ' Unicode nul terminated string
        Const REG_EXPAND_SZ As Short = 2 ' Unicode nul terminated string
        Const REG_DWORD As Short = 4 ' 32-bit number

        ' Reg Create Type Values...
        Const REG_OPTION_NON_VOLATILE As Short = 0 ' Key is preserved when system is rebooted

        ' Reg Key Security Options...
        Const READ_CONTROL As Integer = &H20000
        Const KEY_QUERY_VALUE As Short = &H1S
        Const KEY_SET_VALUE As Short = &H2S
        Const KEY_CREATE_SUB_KEY As Short = &H4S
        Const KEY_ENUMERATE_SUB_KEYS As Short = &H8S
        Const KEY_NOTIFY As Short = &H10S
        Const KEY_CREATE_LINK As Short = &H20S
        Const KEY_READ As Single = KEY_QUERY_VALUE + KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + READ_CONTROL
        Const KEY_WRITE As Decimal = KEY_SET_VALUE + KEY_CREATE_SUB_KEY + READ_CONTROL
        Const KEY_EXECUTE As Object = KEY_READ
        Const KEY_ALL_ACCESS As Double = KEY_QUERY_VALUE + KEY_SET_VALUE + KEY_CREATE_SUB_KEY + KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + KEY_CREATE_LINK + READ_CONTROL

        ' Reg Key ROOT Types...
        Const HKEY_CLASSES_ROOT As Integer = &H80000000
        Const HKEY_CURRENT_USER As Integer = &H80000001
        Const HKEY_LOCAL_MACHINE As Integer = &H80000002
        Const HKEY_USERS As Integer = &H80000003
        Const HKEY_PERFORMANCE_DATA As Integer = &H80000004

        ' Return Value...
        Const ERROR_NONE As Short = 0
        Const ERROR_BADKEY As Short = 2
        Const ERROR_ACCESS_DENIED As Short = 8
        Const ERROR_SUCCESS As Short = 0

        '---------------------------------------------------------------
        '- Registry Security Attributes TYPE...
        '---------------------------------------------------------------
        Private Structure SECURITY_ATTRIBUTES
            Dim nLength As Integer
            Dim lpSecurityDescriptor As Integer
            Dim bInheritHandle As Boolean
        End Structure

        ' The resource string will be loaded into a control's property as follows:
        ' Object      Property
        ' Form        Caption
        ' Menu        Caption
        ' TabStrip    Caption, ToolTipText
        ' Toolbar     ToolTipText
        ' ListView    ColumnHeader.Text

        Sub LoadResStrings(ByRef frm As System.Windows.Forms.Form)
            On Error Resume Next
            Dim ctl As System.Windows.Forms.Control
            Dim obj As Object = Nothing
            Dim fnt As System.Drawing.Font
            Dim sCtlType As String
            Dim nVal As Short
            Dim sKeyVal As Short
            Dim sFullName As String

            ' Set the form's caption.
            frm.Text = obj.GetResourceString(CShort(frm.Tag))
            ' Set the font.
            Dim FontName As String, FontSize As Double
            FontName = obj.GetResourceString(20)
            FontSize = CShort(obj.GetResourceString(21))
            frm.Font = New System.Drawing.Font(FontName, FontSize)

            ' Set the controls' captions using the caption
            ' property for menu items and the Tag property
            ' for all other controls.
            For Each ctl In frm.Controls
                sCtlType = TypeName(ctl)
                If sCtlType = "Label" Then
                    ctl.Text = obj.GetResourceString(CShort(ctl.Tag))
                ElseIf sCtlType = "AxTabStrip" Then
                    For Each obj In CObj(ctl).Tabs
                        obj.Caption = obj.GetResourceString(CInt(ctl.Tag))
                        obj.ToolTipText = obj.GetResourceString(CShort(obj.ToolTipText))
                    Next obj
                ElseIf sCtlType = "AxToolbar" Then
                    For Each obj In CObj(ctl).Buttons
                        obj.ToolTipText = obj.GetResourceString(CShort(obj.ToolTipText))
                    Next obj
                ElseIf sCtlType = "AxListView" Then
                    For Each obj In CObj(ctl).ColumnHeaders
                        obj.Text = obj.GetResourceString(CShort(obj.Tag))
                    Next obj
                Else
                    nVal = 0
                    nVal = Val(ctl.Tag)
                    If nVal > 0 Then ctl.Text = obj.GetResourceString(nVal)
                    nVal = 0
                    nVal = Val(CObj(frm).ToolTip1.GetToolTip(ctl))
                    If nVal > 0 Then
                        CObj(frm).ToolTip1.SetToolTip(ctl, obj.GetResourceString(nVal))
                    End If
                End If
            Next ctl

        End Sub

        '-------------------------------------------------------------------------------------------------
        'sample usage - Debug.Print UpodateKey(HKEY_CLASSES_ROOT, "keyname", "newvalue")
        '-------------------------------------------------------------------------------------------------
        Public Function UpdateKey(ByRef KeyRoot As Integer, ByRef KeyName As String, ByRef SubKeyName As String, ByRef SubKeyValue As String) As Boolean
            Dim rc As Integer ' Return Code
            Dim hKey As Integer ' Handle To A Registry Key
            Dim hDepth As Integer '
            Dim lpAttr As SECURITY_ATTRIBUTES ' Registry Security Type

            lpAttr.nLength = 50 ' Set Security Attributes To Defaults...
            lpAttr.lpSecurityDescriptor = 0 ' ...
            lpAttr.bInheritHandle = True ' ...

            '------------------------------------------------------------
            '- Create/Open Registry Key...
            '------------------------------------------------------------
            rc = RegCreateKeyEx(KeyRoot, KeyName, 0, CStr(REG_SZ), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, lpAttr, hKey, hDepth) ' Create/Open //KeyRoot//KeyName

            If (rc <> ERROR_SUCCESS) Then GoTo CreateKeyError ' Handle Errors...

            '------------------------------------------------------------
            '- Create/Modify Key Value...
            '------------------------------------------------------------
            If (SubKeyValue = "") Then SubKeyValue = " " ' A Space Is Needed For RegSetValueEx() To Work...

            ' Create/Modify Key Value
            'UPGRADE_ISSUE: Constant vbFromUnicode was not upgraded. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="55B59875-9A95-4B71-9D6A-7C294BF7139D"'
            'UPGRADE_ISSUE: LenB function is not supported. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"'
            rc = RegSetValueEx(hKey, SubKeyName, 0, REG_SZ, SubKeyValue, Len(SubKeyValue.Length * 2))

            If (rc <> ERROR_SUCCESS) Then GoTo CreateKeyError ' Handle Error
            '------------------------------------------------------------
            '- Close Registry Key...
            '------------------------------------------------------------
            rc = RegCloseKey(hKey) ' Close Key

            UpdateKey = True ' Return Success
            Exit Function ' Exit
    CreateKeyError:
            UpdateKey = False ' Set Error Return Code
            rc = RegCloseKey(hKey) ' Attempt To Close Key
        End Function

        '-------------------------------------------------------------------------------------------------
        'sample usage - Debug.Print GetKeyValue(HKEY_CLASSES_ROOT, "COMCTL.ListviewCtrl.1\CLSID", "")
        '-------------------------------------------------------------------------------------------------
        Public Function GetKeyValue(ByRef KeyRoot As Integer, ByRef KeyName As String, ByRef SubKeyRef As String) As String
            Dim i As Integer ' Loop Counter
            Dim rc As Integer ' Return Code
            Dim hKey As Integer ' Handle To An Open Registry Key
            Dim sKeyVal As String = Nothing
            Dim lKeyValType As Integer ' Data Type Of A Registry Key
            Dim tmpVal As String ' Tempory Storage For A Registry Key Value
            Dim KeyValSize As Integer ' Size Of Registry Key Variable

            ' Open RegKey Under KeyRoot {HKEY_LOCAL_MACHINE...}
            '------------------------------------------------------------
            rc = RegOpenKeyEx(KeyRoot, KeyName, 0, KEY_ALL_ACCESS, hKey) ' Open Registry Key

            If (rc <> ERROR_SUCCESS) Then GoTo GetKeyError ' Handle Error...

            tmpVal = New String(Chr(0), 1024) ' Allocate Variable Space
            KeyValSize = 1024 ' Mark Variable Size

            '------------------------------------------------------------
            ' Retrieve Registry Key Value...
            '------------------------------------------------------------
            rc = RegQueryValueEx(hKey, SubKeyRef, 0, lKeyValType, tmpVal, KeyValSize) ' Get/Create Key Value

            If (rc <> ERROR_SUCCESS) Then GoTo GetKeyError ' Handle Errors

            Dim Text As String = Microsoft.VisualBasic.Left(tmpVal, InStr(tmpVal, Chr(0)) - 1)

            '------------------------------------------------------------
            ' Determine Key Value Type For Conversion...
            '------------------------------------------------------------
            Select Case lKeyValType ' Search Data Types...
                Case REG_SZ, REG_EXPAND_SZ ' String Registry Key Data Type
                    sKeyVal = tmpVal ' Copy String Value
                Case REG_DWORD ' Double Word Registry Key Data Type
                    For i = Len(tmpVal) To 1 Step -1 ' Convert Each Bit
                        sKeyVal = sKeyVal + Hex(Asc(Mid(tmpVal, i, 1))) ' Build Value Char. By Char.
                    Next
                    sKeyVal = Format$("&h" + sKeyVal) ' Convert Double Word To String
            End Select

            GetKeyValue = sKeyVal
            rc = RegCloseKey(hKey)
            Exit Function
    GetKeyError:  ' Cleanup After An Error Has Occured
            GetKeyValue = vbNullString
            rc = RegCloseKey(hKey)
        End Function

        Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
            Dim a As String = Nothing
            Timer1.Enabled = True
            Me.Show() 'form must be fully visible
            Me.Refresh()
            a = GetKeyValue(HKEY_LOCAL_MACHINE, "SOFTWARE\YourApp", "TrayEnabled")
            If a = vbNullString Then
                Me.NotifyIcon1.Visible = True
            ElseIf a = "0" Then
                SystemTray.Checked = False
                Me.NotifyIcon1.Visible = False
            End If
        End Sub

        Public Sub muExit_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles muExit.Click
            Me.Close()
        End Sub

        Public Sub PopExit_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles PopExit.Click
            Me.Close()
        End Sub

        Private Sub Form1_FormClosed(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
            Timer1.Enabled = False
        End Sub

        Private T As Boolean
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
            If T = False Then
                NotifyIcon1.Icon = New System.Drawing.Icon(Application.StartupPath & "\")
                T = True
            Else
                NotifyIcon1.Icon = New System.Drawing.Icon(Application.StartupPath & "\")
                T = False
            End If
            Timer1.Enabled = False
            Timer1.Enabled = True
        End Sub

        Public Sub SystemTray_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles SystemTray.Click
            If SystemTray.Checked = True Then
                Me.NotifyIcon1.Visible = False
                SystemTray.Checked = False
                UpdateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\YourApp", "TrayEnabled", "0")
            Else
                Me.NotifyIcon1.Visible = True
                SystemTray.Checked = True
                UpdateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\YourApp", "TrayEnabled", "1")
            End If
        End Sub






    I might have problem read\write on the registry but I'm not really sure what went wrong??



    Please advance guys!!!

    Thanks,
    Mark
    Wednesday, December 26, 2007 12:14 AM

Answers

  • I'm not experienced with registry issues but I'd suggest that you may be getting a false return value from your UpdateKey call -- but you wouldn't know because you let it slide by silently.  Also, I would wrap it in a Try...Catch block to catch the possible exception (though this is not likely your current problem).  Place this in your SystemTrayIcon_Click event handler...

     

    Dim result As Boolean = False

    Try

    If SystemTray.Checked = True Then

    Me.NotifyIcon1.Visible = False

    SystemTray.Checked = False

    result = UpdateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\YourApp", "TrayEnabled", "0") = False

    Else

    Me.NotifyIcon1.Visible = True

    SystemTray.Checked = True

    result = UpdateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\YourApp", "TrayEnabled", "1")

    End If

    If Not result Then

    MessageBox.Show("The attempt to change the registry key failed.")

    End If

    Catch ex As Exception

    MessageBox.Show(ex.Message)

    End Try

     

     

    Now if you get a False return you can set breakpoints or step through the function call to see where the problem lies.

    Wednesday, December 26, 2007 8:03 PM

All replies

  • guys, please advance any idea how we can get this fix??



    Thanks,
    Mark
    Wednesday, December 26, 2007 5:16 PM
  • I'm not experienced with registry issues but I'd suggest that you may be getting a false return value from your UpdateKey call -- but you wouldn't know because you let it slide by silently.  Also, I would wrap it in a Try...Catch block to catch the possible exception (though this is not likely your current problem).  Place this in your SystemTrayIcon_Click event handler...

     

    Dim result As Boolean = False

    Try

    If SystemTray.Checked = True Then

    Me.NotifyIcon1.Visible = False

    SystemTray.Checked = False

    result = UpdateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\YourApp", "TrayEnabled", "0") = False

    Else

    Me.NotifyIcon1.Visible = True

    SystemTray.Checked = True

    result = UpdateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\YourApp", "TrayEnabled", "1")

    End If

    If Not result Then

    MessageBox.Show("The attempt to change the registry key failed.")

    End If

    Catch ex As Exception

    MessageBox.Show(ex.Message)

    End Try

     

     

    Now if you get a False return you can set breakpoints or step through the function call to see where the problem lies.

    Wednesday, December 26, 2007 8:03 PM
  • Thanks for that but it didn't save on the registry so what's wrong??  Something have go wrong and need to be fix. I hope it will save on the registry like E.G when I disable the system tray and on the next software start, it show no icon on the system tray. Also I need help with form load cos I need to make sure that the control have access to the registry and open the value to see if the icon need to load or not. If I save the value to 0 then on the next software start, the form should not run the icon on the system tray.




    Hope you can advise me with this.



    Thanks,
    Mark
    Thursday, December 27, 2007 12:23 AM