CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303

    Unhappy detect if using Classic start menu

    i've searched and searched and can't find how to do this. i need to detect if the Classic start menu is being used, as opposed to the XP Style one. note that this is separate from whether or not the XP Visual Style is being used.

    all i can find info on is a registry key in the Policies section that forces the Classic Start menu and doens't allow users to change it back to XP Style. this is not what i'm looking for. i just want to detect what the current style is.

    i opened the Start Menu and Taskbar Properties screen and switched back and forth between styles while running Regmon and found nothing. i also exported two registry sections, the Policies "folder" and the Windows\Current Version\Explorer\Advanced folder, and compared the two under both circumstances and there's no changes there either.

    i thought maybe the registry setting gets saved when Explorer is closed during logoff/shutdown, but i logged off and back on, after changing it to Classic, and still couldn't find a difference.

    any ideas on where the setting could be?

  2. #2
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,283

    Re: detect if using Classic start menu

    I did a lot of research lately on the taskbar and its related registry values. These seem to be the 2 registry keys you'd need to look at :
    Code:
    Policy:
    
    [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\NoSimpleStartMenu]
    
    Shell State:
    [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer
    What you can do then is to use RegQueryValue and / or RegQueryValueEx to determine the current setting

  3. #3
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303

    Re: detect if using Classic start menu

    yeah, the policy setting isn't what i need (it only change when the policy is in place, not when you just change the Start menu style) but Shell State could be it. it's a long binary value that looks like mumbo jumbo to me, but i do see one of the number pairs changing.

    -edit-
    found more about shellstate on msdn:
    http://msdn2.microsoft.com/en-us/library/ms538317.aspx

    thanks for pointing me in the right direction
    Last edited by gnznroses; September 7th, 2007 at 05:11 PM.

  4. #4
    Join Date
    Aug 2007
    Location
    Illinois
    Posts
    164

    Re: detect if using Classic start menu

    I'm sure there are other API examples out there, but here is one that appears to work using the GetCurrentThemeName API. It's a French site, scroll down about 1/3 of the way til you see the code. It doesn't explicitly identify Windows Classic. But I think it would be safe to say that if the IsThemeActive call returns false, then classic is employed.
    Insomnia is a simple byproduct of "it can't be done"

  5. #5
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303

    Re: detect if using Classic start menu

    that's actually for the visual style, not the start menu style. you can actually have xp VS with classic start or classic VS with xp-style start.

    i thought i had figured it out, but i'm having no luck with SHGetSetSettings (returns 0 every time) or SHGetSettings (doesn't seem to support all of the values, including SSF_STARTPANELON).

    i thenh tried ditching that and just reading the registry data myself. but my registry query is failing. i have a registry module already that i use, and it supports DWORDs and REG_SZ, but not BINARY. so i looked at other registry modules and added in binary support to the one i use, and i'd swear i have it right but it's just not working.



    Code:
    Public Function regQuery_A_Key(ByVal lngRootKey As Long, _
                                   ByVal strRegKeyPath As String, _
                                   ByVal strRegSubKey As String) As Variant
        
    ' --------------------------------------------------------------
    ' Written by Kenneth Ives                     kenaso@home.com
    '
    ' Important:     If you treat all key data strings as being
    '                case sensitive, you should never have a problem.
    '                Always backup your registry files (System.dat
    '                and User.dat) before performing any type of
    '                modifications
    '
    ' Description:   Function for querying a sub key value.
    '
    ' Parameters:
    '           lngRootKey - HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,
    '                  HKEY_lOCAL_MACHINE, HKEY_USERS, etc
    '    strRegKeyPath - is name of the key path you wish to traverse.
    '     strRegSubKey - is the name of the key which will be queryed.
    '
    ' Syntax:
    '    strKeyQuery = regQuery_A_Key(HKEY_CURRENT_USER, _
    '                       "Software\AAA-Registry Test\Products", _
                            "StringTestData")
    '
    ' Returns the key value of "StringTestData"
    ' --------------------------------------------------------------
        
    ' --------------------------------------------------------------
    ' Define variables
    ' --------------------------------------------------------------
      Dim intPosition As Integer
      Dim lngKeyHandle As Long
      Dim lngDataType As Long
      Dim lngBufferSize As Long
      Dim lngBuffer As Long
      Dim strBuffer As String
    
    ' --------------------------------------------------------------
    ' Initialize variables
    ' --------------------------------------------------------------
      lngKeyHandle = 0
      lngBufferSize = 0
      
    ' --------------------------------------------------------------
    ' Query the key path
    ' --------------------------------------------------------------
      m_lngRetVal = RegOpenKey(lngRootKey, strRegKeyPath, lngKeyHandle)
      
    ' --------------------------------------------------------------
    ' If no key handle was found then there is no key.  Leave here.
    ' --------------------------------------------------------------
      If lngKeyHandle = 0 Then
          regQuery_A_Key = ""
          m_lngRetVal = RegCloseKey(lngKeyHandle)   ' always close the handle
          Exit Function
      End If
      
    ' --------------------------------------------------------------
    ' Query the registry and determine the data type.
    ' --------------------------------------------------------------
      m_lngRetVal = RegQueryValueEx(lngKeyHandle, strRegSubKey, 0&, _
                             lngDataType, ByVal 0&, lngBufferSize)
      
    ' --------------------------------------------------------------
    ' If no key handle was found then there is no key.  Leave.
    ' --------------------------------------------------------------
      If lngKeyHandle = 0 Then
          regQuery_A_Key = ""
          m_lngRetVal = RegCloseKey(lngKeyHandle)   ' always close the handle
          Exit Function
      End If
      
    ' --------------------------------------------------------------
    ' Make the API call to query the registry based on the type
    ' of data.
    ' --------------------------------------------------------------
      Select Case lngDataType
             Case REG_SZ, REG_EXPAND_SZ:      ' String data (most common)
                  ' Preload the receiving buffer area
                  strBuffer = Space(lngBufferSize)
          
                  m_lngRetVal = RegQueryValueEx(lngKeyHandle, strRegSubKey, 0&, 0&, _
                                         ByVal strBuffer, lngBufferSize)
                  
                  ' If NOT a successful call then leave
                  If m_lngRetVal <> ERROR_SUCCESS Then
                      regQuery_A_Key = ""
                  Else
                      ' Strip out the string data
                      intPosition = InStr(1, strBuffer, chr(0))  ' look for the first null char
                      If intPosition > 0 Then
                          ' if we found one, then save everything up to that point
                          regQuery_A_Key = Left(strBuffer, intPosition - 1)
                      Else
                          ' did not find one.  Save everything.
                          regQuery_A_Key = strBuffer
                      End If
                  End If
                  
             Case REG_DWORD:    ' Numeric data (Integer)
                  m_lngRetVal = RegQueryValueEx(lngKeyHandle, strRegSubKey, 0&, lngDataType, _
                                         lngBuffer, 4&)  ' 4& = 4-byte word (long integer)
                  ' If NOT a successful call then leave
                  If m_lngRetVal <> ERROR_SUCCESS Then
                      regQuery_A_Key = ""
                  Else
                      ' Save the captured data
                      regQuery_A_Key = lngBuffer
                  End If
                  
            Case REG_BINARY
                  m_lngRetVal = RegQueryValueEx(lngKeyHandle, strRegSubKey, 0&, lngDataType, _
                                         lngBuffer, 2&)
                  ' If NOT a successful call then leave
                  If m_lngRetVal <> ERROR_SUCCESS Then
                      regQuery_A_Key = ""
                  Else
                      ' Save the captured data
                      regQuery_A_Key = lngBuffer
                  End If
             
             Case Else:    ' unknown
                  regQuery_A_Key = ""
      End Select
      
      If m_lngRetVal = ERROR_ACCESS_DENIED Then
        frmError.Show vbModeless
        frmError.Label1.Caption = "Could not read from registry. Insufficient permissions."
      End If
      
    ' --------------------------------------------------------------
    ' Always close the handle in the registry.  We do not want to
    ' corrupt these files.
    ' --------------------------------------------------------------
      m_lngRetVal = RegCloseKey(lngKeyHandle)
    
    End Function

    for the buffer size, i tried lngBufferSize, i tried 2, and i tried 16. lngBufferSize just crashes vb6 entirely, the other two just return an error code as the return value.

  6. #6
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,283

    Re: detect if using Classic start menu

    The setting for Policy will be affected upon creating a New User account ( and you've selected "Classic Start Menu" for that user account ) - so, technically, it's still needed

    ShellState is the way to go. By you seeing the values change, it means it has changed.

    Classic Start Menu has this setting ( for ShellState ) :
    Code:
    24 00 00 00 31 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 0D 00 00 00 00 00 00 00 00 00 00 00
    XP Start Menu has this setting ( for ShellState ) :
    Code:
    24 00 00 00 31 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 0D 00 00 00 00 00 00 00 02 00 00 00
    As you can see there is only one small change. Just do not play around too much with those "mumbo jumbo ( as you call it )" hex values there, because a setting such as :
    Code:
    24 00 00 00 37 88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 0D 00 00 00 00 00 00 00 01 00 00 00
    In HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellState

    Will Turn off the recycle bin delete confirmation!
    Last edited by HanneSThEGreaT; September 8th, 2007 at 05:05 AM.

  7. #7
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303

    Re: detect if using Classic start menu

    yeah, i've got it all sorted now
    finally got some code working to read binary registry values and return it as a byte array, then i pluck the 32nd value or whatever.

  8. #8
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,283

    Re: detect if using Classic start menu

    Quote Originally Posted by gnznroses
    yeah, i've got it all sorted now
    That's good news !
    Quote Originally Posted by gnznroses
    finally got some code working to read binary registry values and return it as a byte array, then i pluck the 32nd value or whatever.
    Mind sharing this, I'd be interested to see what you've done ¿

  9. #9
    Join Date
    May 2002
    Location
    Huntington, WV
    Posts
    303

    Re: detect if using Classic start menu

    i didn't include the whole thing cause it's pretty long. it's a module i borrowed from somewhere - don't remember where. then i found the binary-reading code from some website and modified it to fit with the rest of the code that read strings and dwords.

    Code:
      Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _
                (ByVal lngRootKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _
                 lpType As Long, lpData As Any, lpcbData As Long) As Long
    
    Private Declare Function RegQueryValueExByte Lib "advapi32" Alias "RegQueryValueExA" _
      (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _
       ByRef lpType As Long, szData As Byte, ByRef lpcbData As Long) As Long


    Code:
    Public Function regQuery_A_Key(ByVal lngRootKey As Long, _
                                   ByVal strRegKeyPath As String, _
                                   ByVal strRegSubKey As String) As Variant
        
    ' --------------------------------------------------------------
    ' Written by Kenneth Ives                     kenaso@home.com
    '
    ' Important:     If you treat all key data strings as being
    '                case sensitive, you should never have a problem.
    '                Always backup your registry files (System.dat
    '                and User.dat) before performing any type of
    '                modifications
    '
    ' Description:   Function for querying a sub key value.
    '
    ' Parameters:
    '           lngRootKey - HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,
    '                  HKEY_lOCAL_MACHINE, HKEY_USERS, etc
    '    strRegKeyPath - is name of the key path you wish to traverse.
    '     strRegSubKey - is the name of the key which will be queryed.
    '
    ' Syntax:
    '    strKeyQuery = regQuery_A_Key(HKEY_CURRENT_USER, _
    '                       "Software\AAA-Registry Test\Products", _
                            "StringTestData")
    '
    ' Returns the key value of "StringTestData"
    ' --------------------------------------------------------------
        
    ' --------------------------------------------------------------
    ' Define variables
    ' --------------------------------------------------------------
      Dim intPosition As Integer
      Dim lngKeyHandle As Long
      Dim lngDataType As Long
      Dim lngBufferSize As Long
      Dim lngBuffer As Long
      Dim strBuffer As String
    
    ' --------------------------------------------------------------
    ' Initialize variables
    ' --------------------------------------------------------------
      lngKeyHandle = 0
      lngBufferSize = 0
      
    ' --------------------------------------------------------------
    ' Query the key path
    ' --------------------------------------------------------------
      m_lngRetVal = RegOpenKey(lngRootKey, strRegKeyPath, lngKeyHandle)
      
    ' --------------------------------------------------------------
    ' If no key handle was found then there is no key.  Leave here.
    ' --------------------------------------------------------------
      If lngKeyHandle = 0 Then
          regQuery_A_Key = ""
          m_lngRetVal = RegCloseKey(lngKeyHandle)   ' always close the handle
          Exit Function
      End If
      
    ' --------------------------------------------------------------
    ' Query the registry and determine the data type.
    ' --------------------------------------------------------------
      m_lngRetVal = RegQueryValueEx(lngKeyHandle, strRegSubKey, 0&, _
                             lngDataType, ByVal 0&, lngBufferSize)
      
    ' --------------------------------------------------------------
    ' If no key handle was found then there is no key.  Leave.
    ' --------------------------------------------------------------
      If lngKeyHandle = 0 Then
          regQuery_A_Key = ""
          m_lngRetVal = RegCloseKey(lngKeyHandle)   ' always close the handle
          Exit Function
      End If
      
    ' --------------------------------------------------------------
    ' Make the API call to query the registry based on the type
    ' of data.
    ' --------------------------------------------------------------
      Select Case lngDataType
             Case REG_SZ, REG_EXPAND_SZ:      ' String data (most common)
                  ' Preload the receiving buffer area
                  strBuffer = Space(lngBufferSize)
          
                  m_lngRetVal = RegQueryValueEx(lngKeyHandle, strRegSubKey, 0&, 0&, _
                                         ByVal strBuffer, lngBufferSize)
                  
                  ' If NOT a successful call then leave
                  If m_lngRetVal <> ERROR_SUCCESS Then
                      regQuery_A_Key = ""
                  Else
                      ' Strip out the string data
                      intPosition = InStr(1, strBuffer, chr(0))  ' look for the first null char
                      If intPosition > 0 Then
                          ' if we found one, then save everything up to that point
                          regQuery_A_Key = Left(strBuffer, intPosition - 1)
                      Else
                          ' did not find one.  Save everything.
                          regQuery_A_Key = strBuffer
                      End If
                  End If
                  
             Case REG_DWORD:    ' Numeric data (Integer)
                  m_lngRetVal = RegQueryValueEx(lngKeyHandle, strRegSubKey, 0&, lngDataType, _
                                         lngBuffer, 4&)  ' 4& = 4-byte word (long integer)
                  ' If NOT a successful call then leave
                  If m_lngRetVal <> ERROR_SUCCESS Then
                      regQuery_A_Key = ""
                  Else
                      ' Save the captured data
                      regQuery_A_Key = lngBuffer
                  End If
                  
            Case REG_BINARY
      '              m_lngRetVal = RegQueryValueEx(lngKeyHandle, strRegSubKey, 0&, lngDataType, _
    '                                     lngBuffer, 2&)
                    Dim abData() As Byte
                    ReDim abData(lngBufferSize)
                    m_lngRetVal = RegQueryValueExByte(lngKeyHandle, strRegSubKey, 0&, _
                                            lngDataType, abData(0), lngBufferSize)
                    Dim vR As Variant
                    vR = abData
    
                  ' If NOT a successful call then leave
                  If m_lngRetVal <> ERROR_SUCCESS Then
                      regQuery_A_Key = 0
                  Else
                      ' Save the captured data
                      'regQuery_A_Key = lngBuffer
                      Dim iByte As Long
                        For iByte = LBound(abData) To UBound(abData)
                            'regQuery_A_Key = regQuery_A_Key & "&H"
                            If (iByte < &H10) Then
                                regQuery_A_Key = regQuery_A_Key & "0"
                            End If
                            regQuery_A_Key = regQuery_A_Key & Hex$(vR(iByte)) & " "
                        Next iByte
                  End If
                  
                  'specific to checking Start menu status
                    Dim tmparray() As String
                    tmparray = Split(regQuery_A_Key, " ")
                    regQuery_A_Key = tmparray(32)
                  'Debug.Print regQuery_A_Key
    
             
             Case Else:    ' unknown
                  regQuery_A_Key = ""
      End Select
        
    ' --------------------------------------------------------------
    ' Always close the handle in the registry.  We do not want to
    ' corrupt these files.
    ' --------------------------------------------------------------
      m_lngRetVal = RegCloseKey(lngKeyHandle)
    End Function

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

Featured