[VB6] API Open With Dialog with enhanced functionality-VBForums
Results 1 to 9 of 9

Thread: [VB6] API Open With Dialog with enhanced functionality

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    331

    [VB6] API Open With Dialog with enhanced functionality

    All the methods I've seen for bringing up the Open With dialog use rundll32. But Windows Vista and above has a better option: the SHOpenWithDialog API call. This allows a number of different options in addition to modality. After searching, it seems no one has posted a VB6 implementation yet, so I thought others might like the idea of using this as much as I did.

    *UPDATE: Flags were declared incorrectly; forgot &H.


    Requirements: The API call is only available on Vista or higher.

    Code:
    Option Explicit
    
    'Module: mOpenWith
    'Version: 0.1
    'Author: fafalone
    'Purpose: Vista and above provides an API call for the Open With dialog, which offers more options
    '         than the previous typical method of using rundll
    
    Public Declare Function SHOpenWithDialog Lib "shell32" (ByVal hWnd As Long, poainfo As OPENASINFO) As Long
    
    Public Enum OPEN_AS_INFO_FLAGS
        OAIF_ALLOW_REGISTRATION = &H1 'Enable the "always use this program" checkbox. If not passed, it will be disabled.
        OAIF_REGISTER_EXT = &H2 'Do the registration after the user hits the OK button.
        OAIF_EXEC = &H4 'Execute file after registering.
        OAIF_FORCE_REGISTRATION = &H8 'Force the Always use this program checkbox to be checked. Typically, you won't use the OAIF_ALLOW_REGISTRATION flag when you pass this value.
        OAIF_HIDE_REGISTRATION = &H20 'Introduced in Windows Vista. Hide the Always use this program checkbox. If this flag is specified, the OAIF_ALLOW_REGISTRATION and OAIF_FORCE_REGISTRATION flags will be ignored.
        OAIF_URL_PROTOCOL = &H40 'Introduced in Windows Vista. The value for the extension that is passed is actually a protocol, so the Open With dialog box should show applications that are registered as capable of handling that protocol.
        OAIF_FILE_IS_URI = &H80 'Introduced in Windows 8. The location pointed to by the pcszFile parameter is given as a URI.
    End Enum
    
    Public Type OPENASINFO
        pcszFile As Long
        pcszClass As Long 'file type description for registering the type with 'always open', if not set uses extension, as in 'XYZ File'
        oafInFlags As OPEN_AS_INFO_FLAGS
    End Type
    
    
    
    Public Function OpenWith(sFile As String, lFlags As OPEN_AS_INFO_FLAGS, Optional hWndParent As Long, Optional sClass As String) As Long
    Dim oai As OPENASINFO
    oai.pcszFile = StrPtr(sFile)
    oai.oafInFlags = lFlags
    If sClass <> "" Then oai.pcszClass = StrPtr(sClass)
    OpenWith = SHOpenWithDialog(hWndParent, oai)
    End Function
    The sample project attached contains a form that calls the OpenWith function.

    OpenWith(sFile As String, lFlags As OPEN_AS_INFO_FLAGS, Optional hWndParent As Long, Optional sClass As String)

    sFile - The file to be opened
    lFlags - See the descriptions in the BAS; you'll usually want to include OAIF_EXEC to open the file afterwards, and OAIF_ALLOW_REGISTRATION to enable the 'always use this program' box.
    hWndParent - You can specify an owner window (e.g. Form1.hWnd) and the dialog will be modal to that form (you can't click on anything on the form until the dialog closes).
    sClass - You can optionally specify a file type description for registering the type for always open. If not specified, the file extension would be used (e.g. XYZ File).

    Note: Since this is a Unicode function (it takes lpcwstr's, hence the need for strptr()), it should handle unicode file names and unicode path lengths without issue.
    Attached Files Attached Files
    Last edited by fafalone; Oct 23rd, 2014 at 05:05 PM.

  2. #2
    PowerPoster
    Join Date
    Feb 2006
    Posts
    11,738

    Re: [VB6] API Open With Dialog with enhanced functionality

    I'm not sure why a program would ever need to do this since it is part of the Shell UI meant to be driven by the end user. Even then it's only for advanced users since you can easily break file associations pretty seriously by innocently interacting with it.

    Your "implementation" appears to do nothing but call the function.

    What am I missing?

    What situations do you find this useful for?

  3. #3
    Hyperactive Member
    Join Date
    Jun 2012
    Posts
    275

    Re: [VB6] API Open With Dialog with enhanced functionality

    Quote Originally Posted by dilettante View Post
    I'm not sure why a program would ever need to do this since it is part of the Shell UI meant to be driven by the end user. Even then it's only for advanced users since you can easily break file associations pretty seriously by innocently interacting with it.
    On this function you can pass flags that the registration will not be touched. So no harms in that case.

  4. #4
    VBaholic & Loving It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    GetWindowRect()
    Posts
    12,818

    Re: [VB6] API Open With Dialog with enhanced functionality

    Quote Originally Posted by dilettante View Post
    What situations do you find this useful for?
    In some projects of mine, I use ShellExecute to try to open a file with registered association, if any. If that API fails, then I launch an "Open With" dialog via run32dll.
    Insomnia is just a byproduct of, "It can't be done"

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {GDI+ Classes/Samples} {Unicode Open/Save Dialog} {Icon Organizer/Extractor}
    {VBA Control Arrays} {XP/Vista Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    331

    Re: [VB6] API Open With Dialog with enhanced functionality

    Quote Originally Posted by dilettante View Post
    I'm not sure why a program would ever need to do this since it is part of the Shell UI meant to be driven by the end user. Even then it's only for advanced users since you can easily break file associations pretty seriously by innocently interacting with it.

    Your "implementation" appears to do nothing but call the function.

    What am I missing?

    What situations do you find this useful for?
    I despise the built-in file search, so I wrote my own search program. And sometimes I want to open a file with something other than the default program. Last night I was searching through the SDK for a particular IDL, and did the normal open, and realized VC 2010 had the default association whereas I wanted to open it with VC 2008 (I only have 2010 express, and 2008 is full edition) that particular time. Media files are another point. I almost always want the default associated player for MKV files; but for MKV's with untouched blurays I have to use a player I like less but can better handle a 30-40GB file. Regarding breaking things; that is why this method is superior: the rundll32 method not only has the box to permanently change the association enabled, but it's checked by default. The API allows it to be unchecked by default AND totally disabled or completely hidden.

    And I apologize if "implementation" is the wrong word for what my code does. why don't I just delete it if it's so terrible.
    Last edited by fafalone; Oct 13th, 2014 at 10:10 PM.

  6. #6
    Fanatic Member Elroy's Avatar
    Join Date
    Jun 2014
    Posts
    696

    Re: [VB6] API Open With Dialog with enhanced functionality

    Hey fafalone,

    I think it's a great little call. You should probably but something like a bFileExists check in it though. It crashes my IDE if I call it with a non-existent file. I still think it's cool and can see some uses for it. Specifically, I have an application that does a great deal of manipulation and moving around of PDF and Movie files. I have the MPUI (with portable SMPlayer) embedded in my app for playing the movies. But occasionally, they want to actually edit them rather than just play them. Or occasionally, someone will want to play them with Windows Media Player rather than the built-in MPUI player.

    In these cases, I usually pop out to a Windows Explorer that's already in the folder they're using (and there are 1000s of folders), and let them double-click whatever Movie they want. Or, some know how to right-click and then "Open With..." (possibly opening a movie with Camtasia or whatever). However, if I could pull that functionality back into my program (rather than opening Windows Explorer), they'd like it.

    So again, Cool Beans.

    EDIT: Just in case you'd like it, here's my bFileExists function:

    Code:
    Public Function bFileExists(fle As String) As Boolean
        On Error GoTo FileExistsError
        ' If no error then something existed.
        bFileExists = (GetAttr(fle) And vbDirectory) = 0
        Exit Function
    FileExistsError:
        bFileExists = False
        Exit Function
    End Function
    Last edited by Elroy; Oct 23rd, 2014 at 01:19 PM.

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    331

    Re: [VB6] API Open With Dialog with enhanced functionality

    I use the PathFileExistsW API; but my thinking was validating whether the file existed was something that would be done long before opening the dialog about it.

    If all you need is Open With then this will work- but you might want to look into IContextMenu, that lets you bring up the full Explorer right-click menu right in your application. It's pretty cool; it even sends a WM_MENUSELECT message and a GetCommandString function so you can show the tips like in Explorer.

    Last edited by fafalone; Oct 23rd, 2014 at 01:32 PM.

  8. #8
    VBaholic & Loving It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    GetWindowRect()
    Posts
    12,818

    Re: [VB6] API Open With Dialog with enhanced functionality

    kinda surprised it works a expected. Just looked at your constants and 3 of them are declared incorrectly. May be reason for crashing?

    As declared:
    Code:
        OAIF_HIDE_REGISTRATION = 20 
        OAIF_URL_PROTOCOL = 40 
        OAIF_FILE_IS_URI = 80
    Should be declared:
    Code:
        OAIF_HIDE_REGISTRATION = &H20 
        OAIF_URL_PROTOCOL = &H40 
        OAIF_FILE_IS_URI = &H80
    FYI: when you see constants declared like 0x######## that is in hex form, not decimal form
    Insomnia is just a byproduct of, "It can't be done"

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {GDI+ Classes/Samples} {Unicode Open/Save Dialog} {Icon Organizer/Extractor}
    {VBA Control Arrays} {XP/Vista Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  9. #9

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    331

    Re: [VB6] API Open With Dialog with enhanced functionality

    Well that's embarassing. Fixed... and I know 0x... is hex, just a typo, I'm not THAT bad at it

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.