Hi,

I am programming an app that I will use to launch different applications depending on the file type specified.

I have found, and know how to use, ShellExecute from VB and all I now need to know is how to get the default action specified by the user when double-clicking on that file type. I.e. the default action when double-clicking a .mp3 file is Open but I want to use MY default action of Enqueue.

Does anyone know how to get this info from the computer?

Also, if you happen to know how to get a list of possible actions, similar to right-clicking the file, that would be a bonus.

Thanks

Yomet

Recommended Answers

All 7 Replies

Hi again,

I found out how to do it and it's very simple. Just set the Operation argument to vbNullString and ShellExecuteA will do the defult action... Oh well, who'd 'a thunk...

Now, if someone still wants to give me a hint about how to get a list of available actions I am all ears.

Thanks again

Yomet

what do you mean by a list of possible actions? Something like the "open with" menu, or something like the properties menu?

If, in Win XP or Win 2K, you right click a file you will have a few choices as the first two, three or four lines in the pop-up menu, just above the Open with... option. For example, if I right-click a .doc file I have:
Open
New
Print
Open with

These choices come from the Tools/Folder Options... menu in Explorer and then chosing the File Types tab. I have a bunch of custom choices for different files and I would like to reproduce them in my app.

I hope this makes sense.

Thx Comatose

Yomet

If You Are Wanting To Retrieve A List of those options, for a given file, you are going to need to know a lot about the registry (a lot more than I can explain here). If you are already registry proficient, then, for a .doc file, for example, you might start by looking at: HKEY_CLASSES_ROOT\.doc, the "default" value for that, is a pointer, to another key in HKCR, in my case, Word.Document.8. So, you would then have to navigate to: HKEY_CLASSES_ROOT\Word.Document.8, and then check out the "shell" key. At this point, you'll have to "enumerate" all of the subkeys of the shell subkey, to give you a list of menu options. If you open one of the subkeys, you'll see that the tree nests even further, and if you open, say "New" you'll see a "command" subkey, which will reference the path and EXE to the file to launch in case of a click to "New".

Truth is, it's a real pain to do this, mostly because of the enumeration of the registry. This isn't the easiest thing in the world to do, but you would need the API Calls:
RegEnumKey, RegEnumKeyEx, and RegEnumValue (For The Values In The Keys). You Might Need RegOpenKeyEx, and RegCloseKey Too (Since I Think They Have To Be Opened Before You Can Enumerate Them). I Wrote A Program That Does This As A Part of it's functionality, but the Project in it's entirety isn't fully functional, So I won't be posting it. Let me know if this helps any, though.

Comatose,

Thanks for the reply and, yes, it helps me a lot.

Now to say that I will go through all the trouble - I'm not so sure. But at least I know where to start and, thanks to you, how to go about digging through the registry.

For now I have almost everything I wanted by being able to launch with the default application and action but if I decide to do it and it works I'll make a stand-alone module and I'll send it to you... ;)

Thanks Again

Yomet

Aw Crap! Here's Part of it:

in a Module (you'll also need to declare the registry API's, But There Are Too many API'S in my project to sift through):

Public Const REG_SZ = 1
Public Const REG_EXPAND_SZ = 2
Public Const REG_BINARY = 3
Public Const REG_DWORD = 4
Public Const REG_MULTI_SZ = 7
Public Const ERROR_MORE_DATA = 234
Public Const KEY_READ = &H20019
Public Const HKEY_CLASSES_ROOT = &H80000000
Public Const HKEY_CURRENT_CONFIG = &H80000005
Public Const HKEY_CURRENT_USER = &H80000001
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const HKEY_USERS = &H80000003

public Function EnumRegistryKeys(ByVal hKey As Long, ByVal KeyName As String) As Collection
    Dim Handle As Long
    Dim length As Long
    Dim index As Long
    Dim subkeyName As String
    
    ' initialize the result collection
    Set EnumRegistryKeys = New Collection
    
    ' Open the key, exit if not found
    If Len(KeyName) Then
        If RegOpenKeyEx(hKey, KeyName, 0, KEY_READ, Handle) Then Exit Function
        ' in all case the subsequent functions use hKey
        hKey = Handle
    End If
    
    Do
        ' this is the max length for a key name
        length = 260
        subkeyName = Space$(length)
        ' get the N-th key, exit the loop if not found
        If RegEnumKey(hKey, index, subkeyName, length) Then Exit Do
        
        ' add to the result collection
        subkeyName = Left$(subkeyName, InStr(subkeyName, vbNullChar) - 1)
        EnumRegistryKeys.Add subkeyName, subkeyName
        ' prepare to query for next key
        index = index + 1
    Loop
   
    ' Close the key, if it was actually opened
    If Handle Then RegCloseKey Handle
        
End Function

Public Function EnumRegistryValues(ByVal hKey As Long, ByVal KeyName As String) As Collection

    Dim Handle As Long
    Dim index As Long
    Dim valueType As Long
    Dim name As String
    Dim nameLen As Long
    Dim resLong As Long
    Dim resString As String
    Dim dataLen As Long
    Dim valueInfo(0 To 1) As Variant
    Dim retVal As Long
    
    ' initialize the result
    Set EnumRegistryValues = New Collection
        
    ' Open the key, exit if not found.
    If Len(KeyName) Then
        If RegOpenKeyEx(hKey, KeyName, 0, KEY_READ, Handle) Then Exit Function
        ' in all cases, subsequent functions use hKey
        hKey = Handle
    End If
    
    Do
        ' this is the max length for a key name
        nameLen = 260
        name = Space$(nameLen)
        ' prepare the receiving buffer for the value
        dataLen = 4096
        ReDim resBinary(0 To dataLen - 1) As Byte
        
        ' read the value's name and data
        ' exit the loop if not found
        retVal = RegEnumValue(hKey, index, name, nameLen, ByVal 0&, valueType, _
            resBinary(0), dataLen)
        
        ' enlarge the buffer if you need more space
        If retVal = ERROR_MORE_DATA Then
            ReDim resBinary(0 To dataLen - 1) As Byte
            retVal = RegEnumValue(hKey, index, name, nameLen, ByVal 0&, _
                valueType, resBinary(0), dataLen)
        End If
        ' exit the loop if any other error (typically, no more values)
        If retVal Then Exit Do
        
        ' retrieve the value's name
        valueInfo(0) = Left$(name, nameLen)
        
        ' return a value corresponding to the value type
        Select Case valueType
            Case REG_DWORD
                CopyMemory resLong, resBinary(0), 4
                valueInfo(1) = resLong
            Case REG_SZ, REG_EXPAND_SZ
                ' copy everything but the trailing null char
                resString = Space$(dataLen - 1)
                CopyMemory ByVal resString, resBinary(0), dataLen - 1
                valueInfo(1) = resString
            Case REG_BINARY
                ' shrink the buffer if necessary
                If dataLen < UBound(resBinary) + 1 Then
                    ReDim Preserve resBinary(0 To dataLen - 1) As Byte
                End If
                valueInfo(1) = resBinary()
            Case REG_MULTI_SZ
                ' copy everything but the 2 trailing null chars
                resString = Space$(dataLen - 2)
                CopyMemory ByVal resString, resBinary(0), dataLen - 2
                valueInfo(1) = resString
            Case Else
                ' Unsupported value type - do nothing
        End Select
        
        ' add the array to the result collection
        ' the element's key is the value's name
        'EnumRegistryValues.Add valueInfo, valueInfo(0)
        EnumRegistryValues.Add valueInfo(0)
        EnumRegistryValues.Add valueInfo(1)
        
        index = index + 1
    Loop
   
    ' Close the key, if it was actually opened
    If Handle Then RegCloseKey Handle
      
End Function

As you can see, if you have all of the API's Needed Declared, These 2 functions return a collection (sort of like an array, but more like perl's associative array (hash)). You can loop through the collection (or enum each part of the collection in a loop, but then you'll have crazy nested collections and stuff, or an Array of Collections :eek: ). This, however, is how I call the functions:

Dim RetCol, TColl As New Collection
Set RetCol = EnumRegistryValues(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows\CurrentVersion\Run")

Here I used EnumRegistryValues, But It Is The Same Idea For Registry Keys. It's Uh, A Lot of code to be certain, and it's nothing trivial, but this way you at least have the functions, and can play with them if you decide to add it to your project. :)

Thanks a million Comatose,

Not only do you point me in the right direction - you give me code to, almost, solve my whole problem. Great!

Now I'll start looking through your code and how to incorporate it into my little app - I feel obliged to... ;)

Thanks again and I'll give you an update when I'm finished.

Yomet

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.