Page 1 of 2 12 LastLast
Results 1 to 40 of 52

Thread: [vb6]Common Dialog Class (Yet Another One)

  1. #1

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    [vb6]Common Dialog Class (Yet Another One)

    Then enclosed class combines the Windows XP/Win2000 Open/Save dialog that uses APIs to generate the dialog with the IFileDialog interface used in Vista and higher. Basically, the class is a unicode-friendly dialog option as a drop-in, self-contained class. Do note that the class has been hard-coded to not run on any O/S less than XP/Win2000. Also included in the class is the old-style "Browse for Folder" dialog. The class can get all dialogs to callback to itself and forward you the events.

    Though the class makes heavy use of calling to interfaces not known to VB, it does not use type libraries (TLBs). However, I have made every effort to make it compatible to TLBs you may be using in your project. In other words, objects returned by this class through its events or functions should be 100% compatible with a TLB that defines interfaces that this class is using. Anything less would be an oversight by me and considered a "bug report".

    This class has absolutely no real benefit over existing code you may already be using unless you want more advanced options. Some of those options include:

    - XP/Win2000. APIs used to display the dialogs
    -- class-generated thunks for hooking the dialog. Those thunks result in raised events from the class to its host, i.e., form, usercontrol, other class, etc.
    -- auto-sizing buffer for multi-selection to prevent the ugly 'buffer too small' error and forcing users to go back and try again

    - Vista and higher. IFileDialog interface used to display the dialogs
    -- Customize by adding additional controls to the dialog and receive events for those controls
    -- Add a read-only checkbox back to the dialog that populates the common OFN_ReadOnly flag
    -- Interact with the dialog via class-generated thunks that raise events from the class to its host
    -- Use embedded custom configurations. There are currently 7 of those.
    1. Browse for Folders while showing file names too
    2. Navigate into compressed folders (zips) while being able to select the zip itself or one of its contained files or any other file
    3. Show both files and folders and be able to select either folders or files or both
    4. Four "basket mode" settings which allows selecting files/folders across multiple directories. Similar to "Add to my Cart" button.
    -- All custom mode button captions can be assigned by you or default to locale-aware captions (see screenshot below)

    Nearly all of the advanced Vista+ options are incorporated into this class, but not all. If you find you need anything more that is not offered, modify as needed.

    If you just want a simple Open/Save dialog where the filter is: All Files, the code needed for the dialog is as simple as:
    Code:
        Dim cBrowser As CmnDialogEx
        Set cBrowser = New CmnDialogEx
        If cBrowser.ShowOpen(Me.hWnd) = True Then
            MsgBox "File Selected: " & cBrowser.FileName
        End If
    Want to add the "Read-Only" checkbox back to the dialog?
    Code:
        Dim cBrowser As CmnDialogEx
        Set cBrowser = New CmnDialogEx
        cBrowser.Controls_AddReadOnlyOption 100    ' << user-defined Control ID
        If cBrowser.ShowOpen(Me.hWnd) = True Then
            MsgBox "File Selected and Read-Only opted for: " & CBool(cBrowser.Flags And Dlg_ReadOnly)
        End If
    Want a "Browse for Folder" like dialog that also shows files (not doable with newer dialog using standard options)?
    Code:
        Dim cBrowser As CmnDialogEx
        Set cBrowser = New CmnDialogEx
        cBrowser.Controls_SetCustomMode cm_BrowseFoldersShowFiles
        If cBrowser.ShowOpen(Me.hWnd) = True Then
            MsgBox "Selected Folder: " & cBrowser.FileName
        End If
    The screenshot below highlights locale-aware captions. The only one I haven't been able to find is a locale-aware caption like: All Files. That would be a nice-touch.
    Edited: Found it in shell32.dll ID: 34193 for Vista+. XP/Win2K will still use hard-coded value as needed
    Name:  Dialog.jpg
Views: 7643
Size:  28.4 KB

    The sample project offers examples of several dialog variations. The class itself is heavily commented.
    Code:
    Update History
    5 Aug 18 - Massive changes see post #13 for  details
    28 May 18 - Enhancements & altered format of FileName property return value 
            when multiple files selected
    23 Jan 18 - Minor fixes
            Fixed a couple locale-aware captions being retrieved from common dlls
            Addressed case where Windows can convert "Open" button to unexpected split-button
    21 Jan 18 - initial release
    FYI: If you are using any previous version, do not simply replace it with the one in the zip below. So many changes were made to this version that it is not compatible with previous ones. To ensure no confusion between versions, the class name was also changed from OSDialogEx to CmnDialogEx.

    Minor fix to be applied after downloading. Next time zip is uploaded, fix will be applied and this paragraph will be removed. Test code left as-was by mistake.
    Code:
    - Routine: InitDir property Let
    - Action:
    
    relocate this line: If Len(Value) = 0& Then Exit Property relocate to immediately above this line: If InStr(Value, ":") Then
    - Reason: can't reset InitDir to null otherwise, without calling the Clear method
    Attached Files Attached Files
    Last edited by LaVolpe; Aug 11th, 2018 at 10:14 AM. Reason: Updated Version
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  2. #2

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Tips, Tricks, Notes...

    Notes. For those of you not yet using a real Vista+ dialog, there are several new flags made available. And some of those flags conflict with previous version of the dialog. Here's a couple of those changes. See this MSDN link for a complete list, also commented in the class.

    ForceFileSystem. Display only true files, not virtual files
    AllNonStorageItems. Allows you to navigate into non-system folders and zip files. AllNonStorageItems & ForceFileSystem are mutually exclusive. One or the other.
    PickFolders. Enables the new basic "Browse for Folder" dialog.
    Previous version flag OFN_ENABLEHOOK. Not supported because same value as new PickFolders constant. For pre-Vista users, the ShowOpen & ShowSave functions have an optional parameter to hook the dialog and pass events to you instead.

    All public enumerations in the class have been made unique so that they don't conflict with any similar enumerations you may already have. So, the class isn't truly plug & play with your existing dialog code, but very little effort is required. Typically, you may only need to change your Flags enumeration values from FOS_[xxxx] or OFN_[xxx] values to the class' DLG_[xxx] & DLGex_[xxx] values.
    Tip. DLG_ prefix is for all systems, DLGex_ prefix is for Vista and above DLGXP_ is for XP/Win2K

    Another major change is the heavy usage of IShellItem and IShellItemArray interfaces. Though for basic usage, interacting with those interfaces is not absolutely needed. The class does offer some 'courtesy' functions to query most of those interface methods.

    For those of you still quite comfortable with VB's common dialog or other classes designed to use GetOpenFileName and GetSaveFileName APIs, this class was designed around that structure. But the newer Vista+ dialog offers much more. The class offers many additional properties/methods to address those. All methods and properties in the class, except a few, are valid for the Vista+ dialog. Those few are silently ignored. Many of those others are not valid for the older XP/Win2K dialog. There are comments for each method/property. Those not applicable for the older dialog should be clearly stated.

    Tip. Any additional controls/containers you add to the dialog are assigned a user-defined numeric ID. That ID allows you to call the Controls_PropertyGet/Set functions to get/set properties before the dialog is displayed, while displayed, or after it closes. No ID can be duplicated and the IDs can range from 1 to 268435455 (&H1 to &HFFFFFFF)

    Tip. The FileName property contains the selected item(s) from the dialog. This property is different than other dialogs you have used when multiple files are selected. Because Vista+ can allow selection of files from different folders (items in a Library for example), each selected file includes the file's path. Previous versions included the path then a vbNullChar-delimited list of file titles which no longer can be enforced with Vista+. As was before, testing for a vbNullChar in the FileName property can be used to determine if multiple items were selected by the user.
    Note: If you allow non-system folders to be browsed/selected from within (AllNonStorageItems flag), then it is possible you will get a virtual path/file.

    Tip. The ShowOpen/ShowSave functions have an optional parameter to pass a stdole.IUnknown reference. This reference will contain an IShellItem or IShellItemArray (multiple selected items) on return. That reference can be passed to the modern IFileOperation interface which supersedes the SHFileOperation API (Win2K/XP). This class does not expose the IFileOperation interface. A TLB or custom solution is required.

    Tip. This class appears to work just fine in MS Office (at least Access), even with the thunks and subclassing in play. However, you will need to change some vartypes. Access does not recognize CheckBoxConstants used in public event: DialogCheckBoxChanged. Change that to Long or Boolean. It also does not recognize the vbCFFiles constant used in pvGetDisplayName. Change that constant to: 15.

    Tip. Though the dialog can be displayed without a passed owner hWnd, you should avoid this unless absolutely needed. Without that hWnd, the dialog is modal only to the line of code that called it, not the form that called it. That means your form is not 'disabled' while the dialog is displayed. It also means the user can close your form/project while the dialog is running. When they eventually close the dialog, your code continues to run which may lead to reloading your form/project, hidden to the user. In any case, the dialog does not disable the entire project (multiple forms displayed), only the form that called it when you also pass the form's hWnd as the owner hWnd. If this doesn't work for you, the easy workaround is: Before calling the dialog, disable all forms but the calling form, call the dialog, and when it closed, re-enable those forms.

    Tip. The old-style "Browse For Folder" dialog modality is same as the file dialog.

    Tip. For Vista+ and asking for events, you can change the folder view (list, tiles, small icons, etc) of the dialog via the IFileDialog_SetViewMode method.

    Tip. Use client GUIDs to have Windows save some of your dialog's last settings, i.e., position, size, last folder visited and a bit more. See CreateClientDataGUID & ShowOpen function comments for details.
    Last edited by LaVolpe; Aug 6th, 2018 at 06:29 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3
    Fanatic Member
    Join Date
    Jul 2007
    Location
    Essex, UK.
    Posts
    578

    Re: [vb6]Common Dialog Class (Yet Another One)

    This is excellent until I needed to dump some files to my 'F:\' drive. It wouldn't select the drive root with browseforfolder! Or am I doing something wrong

  4. #4

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by Steve Grant View Post
    This is excellent until I needed to dump some files to my 'F:\' drive. It wouldn't select the drive root with browseforfolder! Or am I doing something wrong
    I'm not sure what you mean by "wouldn't select". Are you saying it wouldn't navigate to F root?

    Can you be more specific and maybe also include the options you used? Maybe my logic in the subclassing for a custom mode you might have been using has a logic flaw?

    Edited: Yep, a logic flaw in the sample project, but not the dialog class.
    The dialog returns the root folder, but the looping I used in the sample failed...
    Code:
    ...
                sPath = cBrowser.FilePath & "\"
                sItems() = Split(Mid$(cBrowser.FileName, Len(sPath) + 1&), vbNullChar)
    sPath length is 3 since root folder selected. So the split is trying to split on Mid$(Path, 4). When I get a chance I'll update the sample project. If you actually look at cBrowser.FilePath or .FileName, you should see your folder selected.

    However, if multi-selecting root folders using "Browse for Folders", the class does have a logic flaw. I didn't take that into consideration and assumed multi-selection (non-basket mode) would all be in the same parent folder, i.e., same root path. Roots don't quite fit that failed logic. I'll need to tweak that & post the update this weekend.
    Last edited by LaVolpe; Feb 9th, 2018 at 04:29 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5
    Fanatic Member
    Join Date
    Jul 2007
    Location
    Essex, UK.
    Posts
    578

    Re: [vb6]Common Dialog Class (Yet Another One)

    You are so right. Thank you.

    Code:
            If UBound(sItems) > -1 Then
                For lItem = 0 To UBound(sItems)
                    lstEvents.AddItem "    Selected: " & sPath & sItems(lItem), lItem + 1&
                Next
            Else
                lstEvents.AddItem "    Selected: " & sPath
            End If

  6. #6
    Lively Member
    Join Date
    Jan 2010
    Posts
    117

    Re: [vb6]Common Dialog Class (Yet Another One)

    Is it possible to hide/remove Help button in Vista style dialog?

  7. #7

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    If it's an actual window, I would think you can use FindWindow/FindWindowEx to locate it an hide it, but don't know if you can remove it resulting in the other buttons shifting to fill the empty space. That is not an option that is made available by the IFileDialog or its related interfaces. At least not that I know of. Clicking on that help button does not raise an event in the IFileDialog.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  8. #8
    Lively Member
    Join Date
    Jan 2010
    Posts
    117

    Re: [vb6]Common Dialog Class (Yet Another One)

    Yes, I can find that button, it is called "&Help". Given that IModalWindow::Show is a blocking call, it would be complicated to use ShowWindow API to hide it. I was hoping to use IFileDialogCustomize interface to remove it.

  9. #9

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by riov View Post
    Yes, I can find that button, it is called "&Help". Given that IModalWindow::Show is a blocking call, it would be complicated to use ShowWindow API to hide it. I was hoping to use IFileDialogCustomize interface to remove it.
    If on Vista and higher and using this class, you can opt for events. One of the events is the DialogOnInit event. That event contains the dialog hWnd. Within any event, you can call the class IFileDialog_GetHwnd function. Events are not blocked
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10
    Lively Member
    Join Date
    Jan 2010
    Posts
    117

    Re: [vb6]Common Dialog Class (Yet Another One)

    Unfortunately, under further investigation it looks like it is impossible to hide that Help button. The reason is that it has no hwnd as it is drawn by DirectUIHWND. I can get a list of its properties, but I have not found a way to change them.


  11. #11

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Dialog class and sample project updated. List of primary changes follows:

    1. Changed format of FileName property when multiple files/folders selected.
    Instead of old format: Path vbNullChar FileName1 vbNullChar FileName2 etc
    Changed to: Path\FileName1 vbNullChar Path\FileName2 etc
    Reason: Vista+ allows selection of files from different paths, i.e., Library items. Since each selected item can be at a different path, the previous method of identifying just one path for all selected files no longer applies. Though pre-Vista still restricts multiple selections from same path, this new format is used whether the dialog is being displayed pre-Vista or Vista+

    2. Exposed IFolderView2 which can be used to change display of the dialog: details, list, small icon, etc
    - Added functions to get/set the folder's display mode
    IFileDialog_IFolderView2 retrieves interface
    IFileDialog_GetViewMode returns current folder's display mode
    IFileDialog_SetViewMode sets current folder's display mode
    - Added new enum to support above functions: IShellViewModeEnum

    3. Changed Controls_AddReadOnlyOption method to default Read-Only option to False vs. True
    - if checkbox style: checkbox is unchecked by default
    - if split-button style: "Open" button defaults to not open as read only

    4. Added locale-aware 'All Files' filter item when default filter used. Applies to Vista+
    Name:  Untitled.jpg
Views: 5098
Size:  8.0 KB

    5. Added option within Filter property to allow not showing the filter, if desired. In screenshot below, you can see the Filter in a typical dialog and then the dialog with the hidden filter. Tip: This is a nice alternative when the filter would just be All Files... Why show the filter if it really doesn't apply? Rhetorical.
    Name:  Untitled.jpg
Views: 5560
Size:  13.6 KB
    Last edited by LaVolpe; Jun 2nd, 2018 at 07:53 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  12. #12

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Here's a replacement for the pvProcessCustomMode routine in the class.

    Scenario: Using options to show both files and folders while browsing for folders. Since files are shown, then can be selected.

    Problem: Logic flaw. It is possible the user only selects files and selects no folders. The dialog would close when the "Select Folder" button is clicked. This resulted in dialog returning a true value (items selected) when none were actually selected. In this scenario, the parent folder should be returned.

    Solution: Test the count of actual folders that were selected and ignore button click if zero folders were selected. The existing code removed any files from the selection, but didn't recheck the count afterwards and simply closed the dialog in that case. If user selected only files, then the dialog will return the parent folder.

    Changes are bolded and in blue below. I'll include this patch the next time I update the zip in original post above. Will also look at preventing files from being clickable in this scenario.
    Code:
    Private Function pvProcessCustomMode() As Long
    
        ' this routine processes the subclassed "Open" button. User wants to select something
        ' applies only when Controls_SetCustomMode called and a subclass was created
        
        ' overriding default behavior is a bit complex
        
        Dim bCancel As Boolean, nrItems As Long
        Dim lAttrs As Long, oPtr As Long, aPtr As Long
        Dim lOptions As Long, n As Long, aData() As Long
        Dim IFolderView2 As stdole.IUnknown
        Const IfIFolderView2_GetSelection As Long = 32
        
        pvCallInterface ObjPtr(m_Dialog), ifFileDialog_GetOptions, VarPtr(lOptions)
        If (lOptions And DLG_AllowMultiSelect) Then
            ' see IFileDialog_GetCurrentSelection method for comments why we ask for multi-select items this way
            Set IFolderView2 = pvGetIFolderView2
            If Not IFolderView2 Is Nothing Then
                pvCallInterface ObjPtr(IFolderView2), IfIFolderView2_GetSelection, 0&, VarPtr(m_ModeResults)
                Set IFolderView2 = Nothing
            End If
        End If
        If m_ModeResults Is Nothing Then
            Set m_ModeResults = Me.IFileDialog_GetCurrentSelection(True, nrItems)
            If m_ModeResults Is Nothing Then Exit Function      ' no items selected
        Else
            pvCallInterface ObjPtr(m_ModeResults), ifShellItemArray_GetCount, VarPtr(nrItems)
        End If
        
        Select Case (m_StateFlags And emskCustMode)
         
         Case cm_BasketModeFilesOrFolders, cm_PickFilesOrFolders ' can select anything
             If (m_StateFlags And emskCustMode) = cm_BasketModeFilesOrFolders Then
                 RaiseEvent DialogAddBasketItem(m_ModeResults, bCancel)
             ElseIf (m_StateFlags And emskAllEvents) Then
                 RaiseEvent DialogOnFileOk(bCancel)
             End If
             If bCancel Then
                 Set m_ModeResults = Nothing ' function returns 0 to keep dialog open
             ElseIf (m_StateFlags And emskCustMode) = cm_PickFilesOrFolders Then
                 pvProcessCustomMode = True   ' closes dialog
             Else
                 pvUpdateBasket nrItems      ' dialog remains open
                 Set m_ModeResults = Nothing
             End If
             
         Case cm_BrowseFoldersShowFiles, cm_BasketModeFoldersOnlyShowFiles
             For n = 0& To nrItems - 1&                ' test attributes of each selected item
                 pvCallInterface ObjPtr(m_ModeResults), ifShellItemArray_GetItemAt, n, VarPtr(oPtr)
                 If oPtr Then
                     pvCallInterface oPtr, ifShellItem_GetAttributes, -1&, VarPtr(lAttrs)
                     pvCallInterface oPtr, ifUnknown_Release: oPtr = 0&
                     If (lAttrs And siAttr_FOLDER) = 0& Then Exit For    ' not a folder
                     If (lOptions And DLGex_AllNonStorageItems) = 0 Then ' only system folders (not zip content)?
                         If Not (lAttrs And (siAttr_FILESYSTEM Or siAttr_STREAM)) = siAttr_FILESYSTEM Then Exit For
                     End If
                 End If
             Next
             If n < nrItems Then                         ' at least one non-folder selected
                 If nrItems = 1& Then                    ' else multi-selection
                     nrItems = 0&
                 Else
                     ReDim aData(0 To nrItems - 1&)          ' loop again, keeping only valid items
                     For n = 0& To nrItems - 1&
                         pvCallInterface ObjPtr(m_ModeResults), ifShellItemArray_GetItemAt, n, VarPtr(oPtr)
                         If oPtr Then
                             pvCallInterface oPtr, ifShellItem_GetAttributes, -1&, VarPtr(lAttrs)
                             If (lAttrs And siAttr_FOLDER) Then
                                 SHGetIDListFromObject oPtr, aData(aPtr): aPtr = aPtr + 1&
                                 If (lOptions And DLGex_AllNonStorageItems) = 0 Then ' only system folders (not zip content)?
                                     If Not (lAttrs And (siAttr_FILESYSTEM Or siAttr_STREAM)) = siAttr_FILESYSTEM Then _
                                         aPtr = aPtr - 1&
                                 End If
                             End If
                             pvCallInterface oPtr, ifUnknown_Release: oPtr = 0&
                         End If
                     Next
                     Set m_ModeResults = Nothing: nrItems = aPtr
                     If nrItems > 0& Then                      ' rebuild results, skipping invalid selections
                        SHCreateShellItemArrayFromIDLists nrItems, VarPtr(aData(0)), m_ModeResults
                        For nrItems = 0& To nrItems - 1&
                            CoTaskMemFree aData(nrItems)
                        Next
                    End If
                End If
                If (m_StateFlags And emskCustMode) = cm_BrowseFoldersShowFiles And nrItems = 0& Then
                    ' only files were selected, choose the files folder & place into IShellItemArray
                    pvCallInterface ObjPtr(m_Dialog), ifFileDialog_GetFolder, VarPtr(m_ModeResults)
                    If Not m_ModeResults Is Nothing Then
                        SHGetIDListFromObject ObjPtr(m_ModeResults), aPtr
                        Set m_ModeResults = Nothing
                        If aPtr Then
                            SHCreateShellItemArrayFromIDLists 1&, VarPtr(aPtr), m_ModeResults
                            CoTaskMemFree aPtr: nrItems = 1&
                        End If
                    End If
                End If
             End If
             If nrItems < 1& Then
                bCancel = True
             ElseIf (m_StateFlags And emskCustMode) = cm_BasketModeFoldersOnlyShowFiles Then
                 RaiseEvent DialogAddBasketItem(m_ModeResults, bCancel)
             ElseIf (m_StateFlags And emskAllEvents) Then
                 RaiseEvent DialogOnFileOk(bCancel)
             End If
             If bCancel Then
                 Set m_ModeResults = Nothing     ' keep dialog open
             ElseIf (m_StateFlags And emskCustMode) = cm_BasketModeFoldersOnlyShowFiles Then
                 pvUpdateBasket nrItems          ' keep dialog open
                 Set m_ModeResults = Nothing
             Else
                 pvProcessCustomMode = True       ' close dialog
             End If
         
         Case cm_CompressedFolderPlusFiles, cm_BasketModeFilesOnly
             For n = 0& To nrItems - 1&
                 pvCallInterface ObjPtr(m_ModeResults), ifShellItemArray_GetItemAt, n, VarPtr(oPtr)
                 If oPtr Then
                     pvCallInterface oPtr, ifShellItem_GetAttributes, -1&, VarPtr(lAttrs)
                     pvCallInterface oPtr, ifUnknown_Release: oPtr = 0&
                     If (lAttrs And siAttr_FOLDER) Then
                         If Not (lAttrs And (siAttr_FILESYSTEM Or siAttr_STREAM)) = _
                             (siAttr_FILESYSTEM Or siAttr_STREAM) Then Exit For
                     End If
                 End If
             Next
             If n < nrItems Then
                 Set m_ModeResults = Nothing
             ElseIf (m_StateFlags And emskCustMode) = cm_BasketModeFilesOnly Then
                 pvUpdateBasket nrItems
                 Set m_ModeResults = Nothing
             Else
                 If (m_StateFlags And emskAllEvents) Then RaiseEvent DialogOnFileOk(bCancel)
                 If bCancel Then Set m_ModeResults = Nothing Else pvProcessCustomMode = True
             End If
             
        'Case cm_PickFilesOrFolders, cm_BasketModeFoldersOnly  ' these are not subclassed
             
        End Select
    
    End Function
    Upcoming enhancement: Inclusion of Vista+ SetClientGUID and ClearClientData options. SetClientGUID allows you to assign dialog-startup persisted information to a GUID. This is like having a configuration file for a dialog. You can have as many of these as you'd like, for example, one for a Open dialog, one for a Save dialog, etc. ClearClientData resets associated GUIDs. GUIDs are cached per application. See this for more info.
    By specifying a GUID, an application can have different persisted states (such as the last visited folder and the position and size of the dialog) for different versions of the dialog within the same application (for example, an import dialog and an open dialog).
    Considering other enhancements before the next update.
    Last edited by LaVolpe; Jun 2nd, 2018 at 02:55 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  13. #13

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Project updated ... massively.

    Important. The class in the zip file is no longer named the same, on purpose. So many changes were made that it could not be kept compatible with the previous version. Old name was OSDialogEx and new class name is CmnDialogEx. Here is a summary of the changes made:

    - Includes the old-style "Browse For Folder" dialog. It is likely many still use it. So, decided to include it with the class. Most of the class methods don't apply to that dialog. At top of the class, there are comments to which class methods do apply (about a dozen). This is biggest reason why class became incompatible with previous one. Also included several callback events.

    - Since the property Flags is no longer intuitive to which dialog it belongs to, we now have 3 Flags properties:
    FlagsDialog is the old Flags property and pertains to the file dialogs
    FlagsDialogEx is the old FlagsEx property and pertains to the file dialogs
    FlagsFolderBrowsing is a new property and only pertains the "Browse for Folder" dialog

    - InitDir, SetRootFolder, SetNavFolders, SetNavFoldersEx have been slightly modified to accept various forms of "folder" references to include: standard folder names, PIDLs, CSIDL constants, Vista+ KnownFolderIDs & control panel path GUIDs

    - Added ability to use client GUIDs with the Vista+ file dialog. See previous reply above for more info. Also to support this, included a custom class function to create these GUIDs for you, on demand. There's a bit more to this if you opt to use them and the class CreateClientGUID function is well commented about that. Tweaked the ShowOpen and ShowSave functions for client GUID use and added comments there too.

    - A few properties were removed: FileExtension, FilePath & MaxFileTitle. Another became read-only: FileTitle

    - Included all known CLSID values and Vista+ KnownFolderIDs to the class via enumerations so you don't have to go looking for them if needed. For example, returning a known folder ID:
    Code:
     ' cBrowser as been declared as CmdDialogEx
        Debug.Print cBrowser.GetKnownFolderGUID(eFOLDERID_ProgramFilesX64)
        ' following printed out: {6D809377-6AF0-444b-8957-A3773F02200E}
    - Minor bug fixes noted at top of the class comments

    - Also updated the sample project to include use of the "Browse for Folder" dialog
    Last edited by LaVolpe; Aug 6th, 2018 at 02:21 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  14. #14
    New Member
    Join Date
    Aug 2018
    Posts
    6

    Re: [vb6]Common Dialog Class (Yet Another One)

    Thanks very much for making this available. It looks really good and can do more than I need in a number of ways, but perhaps less than I need in another, and that has to do with messages shown to the user.

    Is there a way to have a custom message appear when using the Save As version and the file already exists? In many situations, the standard "already exists" message is usable, though not ideal. Using the old OCX, my program shows

    The file already exists!
    Do you want to replace it with a new file?
    If you answer 'Yes,' the previous contents of the file will be lost.


    But in a few cases, I need to offer the choice of adding new content to an existing file. In these cases, my program shows

    File: filename
    The file already exists!
    Do you want to add to the existing file?
    Choose 'Yes' to ADD this new report to the file.
    Choose 'No,' to have this new report REPLACE the previous contents of the file.
    Choose 'Cancel' to enter a DIFFERENT NAME for the new file.

    So I need three choices. They don't have to be worded exactly as above, and could use a dialog box with three options, the way Word does (I could accept Word's "merge" option, if a custom label wasn't possible).

    The way I handled these situations with the old OCX was to have it display the dialog box, retrieve the selected file name, see if it exists and if so give the appropriate message, then after the user makes their choice either close the dialog box and move on or return to it, if a new name is needed.

    I tried to find a place where I could do the same thing – check the file name while the dialogue is still shown – but wasn't successful. Is there such a place, or is there a way to tell it to offer three choices and change their labels?

    Thank you very much!

  15. #15
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [vb6]Common Dialog Class (Yet Another One)

    You can use the IFileDialog events for all those, I posted a more detailed comment in your original thread.

  16. #16
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,817

    Re: [vb6]Common Dialog Class (Yet Another One)

    Hi LaVolpe,

    I hate to use your new tool against you, but I found a doubly-naked Redim in this project. It's in the CmnDialogEx.cls module, the pvGetIFolderView2 procedure, and it's the aData(0 to 7) variable. Specifically, it's the following line:

    Code:
    
            ReDim aData(0 To 7) ' need to use 2 GUIDs (service GUID + IFolderView2 GUID)
    
    

    I just deleted the line, as I didn't see the aData array used in that pvGetIFolderView2 procedure. However, your comment on that line was a bit disconcerting to me.

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  17. #17

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    That line is basically dead code since it isn't used in that routine. Deleting it is just fine. Just FYI. Reason it's there is because of a copy & paste from another routine and forgot to clean it up. The comments are valid though. The 2 GUIDs are added to the aGuid() array, same routine, not the aData() array.

    Thanx. Once I get that project scanner done, maybe I'll go back and start looking at some of these older projects of mine and clean them up. That scanner would have found that mistake.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  18. #18
    Fanatic Member
    Join Date
    Apr 2015
    Posts
    524

    Re: [vb6]Common Dialog Class (Yet Another One)

    I need a custom button in a file dialog.
    No problem so far using this class.

    From this custom button, I want the dialog navigate to a determined folder.
    But I can't find the how to.

    Code:
    Private Sub cBrowser_DialogButtonClicked(ByVal ControlID As Long)
    
    'if ControlID = ...
    
    With cBrowser
        .DialogTitle = "CLICKED:" & CStr(Timer)
        .FileName = "C:\Windows"
    End With
    This all works flawless.
    How does the navigation work?

    Thanks
    Karl

  19. #19
    Fanatic Member
    Join Date
    Apr 2015
    Posts
    524

    Re: [vb6]Common Dialog Class (Yet Another One)

    No idea reg. post #18?

  20. #20

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Karl,

    Before the dialog displays, you can set the FileName property to the complete path & file name of the target file or set the InitDir property to the folder to start the dialog with. But I think you know that. There is no method that I provided that will allow you to navigate, change folders, while the dialog is open. Here is how it can be done rather easily...

    All of the following apply to Vista+

    1. Use the SetNavFolders or SetNavFoldersEx function for the folder(s) you want a user to be able to navigate to easily. This creates a list of those "links" in the navigation pane (left side) of the browser. See the notes in those routines.

    2. Dynamically...

    a. Create a button or some other control, i.e., a combobox or custom button with menus, for a user to choose different paths. Looks like you were attempting that already.

    b. Add the following new routine to the class and call it from the appropriate event, i.e., DialogButtonClicked. Pass folders only, no file names. Afterwards, you can set the FileName property separately if desired.

    Code:
    Public Function NavigateTo(Destination As Variant) As Boolean
    
        If m_StateFlags < 0& Then                   ' else dialog not running or pre-Vista
            Dim oItem As stdole.IUnknown
            Set oItem = pvGetIShellItem(Destination) ' see comments in routine
            NavigateTo = (pvCallInterface(ObjPtr(m_Dialog), ifFileDialog_SetFolder, ObjPtr(oItem)) = 0) 
            Set oItem = Nothing
        End If
    
    End Function
    Note: In another thread, one user experienced problems in Win7 displaying the dialog -- it errored; the system would not create it. May want to add this as a safety check.
    - replace existing Class_Initialize with this:
    Code:
    Private Sub Class_Initialize()
    
        Dim osv As OSVERSIONINFO
        Dim aGuid(0 To 7) As Long, tDialog As stdole.IUnknown
        
        osv.dwOSVersionInfoSize = Len(osv)
        GetVersionEx osv
        Select Case osv.dwMajorVersion
        Case Is < 5     ' less than Win2K/XP
        Case 5          ' Win2K or XP
            m_StateFlags = 5
        Case Else       ' Vista or better
            CLSIDFromString StrPtr(CLSID_FileOpenDialog), VarPtr(aGuid(0))
            IIDFromString StrPtr(IID_IFileOpenDialog), VarPtr(aGuid(4))
            If CoCreateInstance(VarPtr(aGuid(0)), 0&, CLSCTX_INPROC_SERVER, VarPtr(aGuid(4)), tDialog) = 0& Then
                Set tDialog = Nothing
                m_StateFlags = osv.dwMinorVersion + osv.dwMajorVersion
            Else
                m_StateFlags = 5
            End If
        End Select
        
    '     m_StateFlags = 5  ' <<< un-rem to pretend system is pre-Vista
    
    End Sub
    Last edited by LaVolpe; Dec 12th, 2018 at 03:33 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  21. #21
    Fanatic Member
    Join Date
    Apr 2015
    Posts
    524

    Re: [vb6]Common Dialog Class (Yet Another One)

    Code:
    Public Function NavigateTo(Destination As Variant) As Boolean
    
        If m_StateFlags < 0& Then                   ' else dialog not running or pre-Vista
            Dim oItem As stdole.IUnknown
            Set oItem = pvGetIShellItem(Destination) ' see comments in routine
            NavigateTo = (pvCallInterface(ObjPtr(m_Dialog), ifFileDialog_SetFolder, ObjPtr(oItem)) = 0) 
            Set oItem = Nothing
        End If
    
    End Function
    Thank you LaVolpe.
    NavigateTo works exactly as expected.
    Great!

  22. #22
    Junior Member
    Join Date
    Sep 2017
    Posts
    17

    Re: [vb6]Common Dialog Class (Yet Another One)

    Hard to believe... VB6 folks still alive, and being rolled over by latest """updates""" of Win10 (aka VISTA II)
    This seems like a VERY comprehensive project.

    First question:
    Will all this work under the latest cruel Win10 "updates", which seem to kill right and left many VB6 calls and traditional controls?

    Second question:
    GetVersionEx on one of my win7 machine return 5, hence most options disabled.
    No idea why (Win10 returns 6).

    3rd question:
    We just need no-frills "Open" and "Save" options, with fixed hard-coded filter, and NO other options from the multitude you provide.
    We wish to have only the new style Vista+.
    It seems that we need only fraction of the code.
    Do you happen to have a more timid version with less code to follow?

    Thanks.

  23. #23
    Junior Member
    Join Date
    Sep 2017
    Posts
    17

    Re: [vb6]Common Dialog Class (Yet Another One)

    Hard to believe... VB6 folks still alive, and being rolled over by latest """updates""" of Win10 (aka VISTA II)
    This seems like a VERY comprehensive project.

    First question:
    Will all this work under the latest cruel Win10 "updates", which seem to kill right and left many VB6 calls and traditional controls?

    Second question:
    GetVersionEx on one of my win7 machine return 5, hence most options disabled.
    No idea why (Win10 returns 6).

    3rd question:
    We just need no-frills "Open" and "Save" options, with fixed hard-coded filter, and NO other options from the multitude you provide.
    We wish to have only the new style Vista+.
    It seems that we need only fraction of the code.
    Do you happen to have a more timid version with less code to follow?

    Thanks.

  24. #24
    Fanatic Member
    Join Date
    Apr 2015
    Posts
    524

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by DerWeise View Post
    Will all this work under the latest cruel Win10 "updates"
    Yes, it works.
    What is so cruel?

    which seem to kill right and left many VB6 calls and traditional controls?
    Hmm?
    What exactly is killed?

  25. #25
    Addicted Member gilman's Avatar
    Join Date
    Jan 2017
    Location
    Bilbao
    Posts
    173

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by DerWeise View Post
    Second question:
    GetVersionEx on one of my win7 machine return 5, hence most options disabled.
    No idea why (Win10 returns 6).

    Thanks.
    I have the same issue, but only in IDE, when I compile and run the exe program runs OK and the major version in exe version is 6.
    I'm used Win7 64b

  26. #26
    Fanatic Member
    Join Date
    Apr 2015
    Posts
    524

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by gilman View Post
    I have the same issue, but only in IDE, when I compile and run the exe program runs OK and the major version in exe version is 6.
    I'm used Win7 64b
    Can it be that you have set the version to report in the VB6.EXE compatibility settings?

  27. #27

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by DerWeise View Post
    First question:
    Will all this work under the latest cruel Win10 "updates", which seem to kill right and left many VB6 calls and traditional controls?
    The easy answer is yes. The real answer is: who knows? Since it uses Windows interfaces and APIs, see no reason why it should fail

    Second question:
    GetVersionEx on one of my win7 machine return 5, hence most options disabled.
    No idea why (Win10 returns 6).
    Not sure why Win7 should return 5. Any application that does not run identifying itself compatible with Win8.1 and/or above via a manifest, will report as running in lower compatibility mode when O/S is higher than 8. You might want to open TaskManager and in the Details tab, add the "Operating System Context" column and see what Windows is reporting. That does affect the how windows 'lies' to your app.

    3rd question:
    We just need no-frills "Open" and "Save" options, with fixed hard-coded filter, and NO other options from the multitude you provide.
    Plenty of examples on this site using the APIs GetOpenFileName & GetSaveFileName. That's what you are looking for then

    In any case, any version of 6+ allows usage of the newer Vista+ dialogs. Version 7+ may be needed for custom portions of the class. Windows dictates what dialog options are available per version. And a manifest can resolve most of the problems if the app is reported to Windows as supporting its current O/S.

    Per MSDN
    With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version. The value returned by the GetVersionEx function now depends on how the application is manifested.

    Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2). Once an application is manifested for a given operating system version, GetVersionEx will always return the version that the application is manifested for in future releases.
    Last edited by LaVolpe; Mar 23rd, 2019 at 10:39 AM. Reason: added quote
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  28. #28

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by gilman View Post
    I have the same issue, but only in IDE, when I compile and run the exe program runs OK and the major version in exe version is 6.
    I'm used Win7 64b
    See my reply to DerWeise above regarding manifests. My VB6.exe is manifested to be recognized as compatible up to Win10. I have no problems, otherwise, version 6 would be reported too
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  29. #29
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,817

    Re: [vb6]Common Dialog Class (Yet Another One)

    Say Keith,

    Would you mind showing us the .manifest you're using for your VB6.exe program?

    Thanks,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  30. #30

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by Elroy View Post
    Would you mind showing us the .manifest you're using for your VB6.exe program?
    Shown at bottom of post. Save to file alongside vb6.exe and name this file: vb6.exe.manifest

    Getting it activated on modern O/S can be difficult at times. If never having one before, may just need to close VB (if opened) and restart it. Otherwise, try a reboot.

    Now, if you make changes to it down the road, sometimes, you need to "touch" vb6.exe, meaning change its file creation time, using APIs or other means. Even this can fail for me at times and is quite annoying to change due to Windows caching of manifests. As a last resort, I'll tweak a registry setting, restart, undo the registry setting. Here's a post from another thread of mine
    If you want your VB6.exe to use an external manifest, unless you plan on using some 3rd party software to embed one into the exe (and hope it doesn't corrupt it), some annoyances are expected. Simply adding an external manifest along side of VB6.exe doesn't guarantee it will be used. You may very well need to change a registry setting to make it happen. After you are sure your manifest is being recognized, you will likely want to go and restore the setting:
    Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide
    Value: PreferExternalManifest
    Data: 1 = prefer, 0 = don't prefer
    After making the change and manifest still appears to not take effect, reboot. It is getting harder and harder to use external manifests within Windows -- and that's probably not a bad thing.
    Code:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
    	<assemblyIdentity name="Microsoft.Visual.Basic" version="6.00.9782.0" type="win32" processorArchitecture="x86"/>
    	<description>VB6</description>
    	<dependency>
    		<dependentAssembly>
    			<assemblyIdentity name="Microsoft.Windows.Common-Controls" version="6.0.0.0" type="win32" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"/>
    		</dependentAssembly>
    	</dependency>
    	<dependency>
    		<dependentAssembly>
    			<assemblyIdentity name="Microsoft.Windows.GdiPlus" version="1.1.0.0" type="win32" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"/>
    		</dependentAssembly>
    	</dependency>
    	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    		<security>
    			<requestedPrivileges>
    				<requestedExecutionLevel level="highestAvailable" uiAccess="false"/>
    			</requestedPrivileges>
    		</security>
    	</trustInfo>
    	<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    		<application>
    			<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
    			<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
    			<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
    			<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
    	 		<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
    
    		</application>
    	</compatibility>
    	<application xmlns="urn:schemas-microsoft-com:asm.v3">
    		<windowsSettings>
    			<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    			<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">system</dpiAwareness>
    		</windowsSettings>
    	</application>
    </assembly>
    Note: GDI+ inclusion shouldn't be necessary any longer on Win8 and above. Maybe Win7? Don't recall which OS version changed to defaulting to GDI+ v1.1 versus v1.0. Definitely exclude it on XP systems.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  31. #31
    Junior Member
    Join Date
    Sep 2017
    Posts
    17

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by Karl77 View Post
    Yes, it works.
    What is so cruel?


    Hmm?
    What exactly is killed?
    Well, we developed industrial software in VB6 over 20 years ago, and sold it to hundreds of customers worldwide. It runs in German, Chinese, Japanese and English all over.
    In the XP years it was proven to be robust and stable. It was running nicely on 32 AND ON 64.
    When VISTA came along the problems started. Namely, "it was working yesterday and now it crash".
    The first control to suffer was COMDLG32, of course, which, as you state in your code, went through "all new" revolution.
    We could not make it work, we had dozens of customers worldwide reporting crash / hang on ShowSave.
    We fought it for 3 years until MS themselves understood VISTA is a disaster, but we already suffered damage of trust (who would believe US saying VISTA is crap?)
    The second control to go wild was MSXML6 and its frequent variations, and the third was MSCOMCT32 and his 'brothers'.
    Endless issues and hangs, UNTIL WIn10 came along, with its "update-or-die" brutal way, and shot us out the water completely,
    We run as add-on inside SOLIDWORKS using their VBA API. Many users of EXCEL worldwide, not just US, now say "it worked yesterday".
    Sometimes MS themselves say specifically as notes to an "update" something like "It affects MSXML6 but we are working on providing a solution", etc. Yeah? And what should we tell our industrial customers, that MS promised to solve it?
    I don't really want to get started on this. I started before DOS an saw all the revolutions until the whole world was left with ONE TYRANNIC dictator who is able to put things INTO YOUR OWN COMPUTER against your will.
    The subject now is how to build alternative to COMDLG32 that will survive latest WIN10 updates including 1809, which we now try to do with the help of your code.
    Everything we do we immediately check on 5 PC here, two Win7 and 3 Win10 (Chinese, Japanese and English) in USER or ADMIN accounts.
    MS "updates" are NOT identical in those cases. For example, ShowSave can crash in Japanese USER but work on English ADMIN, but few days later it is different. There is no end for this. We also check remote computers in Australia and Japan on different accounts.
    All I can say FOR SURE, that since about mid 2018, VB6 suffered many attacks which practically shut us down.
    BTW, with the code I adopted form you we now see crash of DUser.DLL , never seen this before using your code. It only crash on Save but not on Open. We implemented a very small portion of the code, per your examples "Standard Open" and "Standard Save".
    The latest crash es happen so far on Win7 (latest updates few days ago) but not yet on Win10 latest (probably will join in few days).

    I hope it answers.
    (I have decades of VB on me. since BASIC on mainframes in 1979, through all the variations of VB except NET.). I still maintain it is the quickest and most efficient high-level language with the fastest road to market).

  32. #32
    Fanatic Member
    Join Date
    Apr 2015
    Posts
    524

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by DerWeise View Post
    Well, we developed industrial software in VB6 over 20 years ago, and sold it to hundreds of customers worldwide. It runs in German, Chinese, Japanese and English all over.
    In the XP years it was proven to be robust and stable. It was running nicely on 32 AND ON 64.
    When VISTA came along the problems started. Namely, "it was working yesterday and now it crash".
    The first control to suffer was COMDLG32, of course, which, as you state in your code, went through "all new" revolution.
    We could not make it work, we had dozens of customers worldwide reporting crash / hang on ShowSave.
    We fought it for 3 years until MS themselves understood VISTA is a disaster, but we already suffered damage of trust (who would believe US saying VISTA is crap?)
    The second control to go wild was MSXML6 and its frequent variations, and the third was MSCOMCT32 and his 'brothers'.
    Endless issues and hangs, UNTIL WIn10 came along, with its "update-or-die" brutal way, and shot us out the water completely,
    We run as add-on inside SOLIDWORKS using their VBA API. Many users of EXCEL worldwide, not just US, now say "it worked yesterday".
    Sometimes MS themselves say specifically as notes to an "update" something like "It affects MSXML6 but we are working on providing a solution", etc. Yeah? And what should we tell our industrial customers, that MS promised to solve it?
    I don't really want to get started on this. I started before DOS an saw all the revolutions until the whole world was left with ONE TYRANNIC dictator who is able to put things INTO YOUR OWN COMPUTER against your will.
    The subject now is how to build alternative to COMDLG32 that will survive latest WIN10 updates including 1809, which we now try to do with the help of your code.
    Everything we do we immediately check on 5 PC here, two Win7 and 3 Win10 (Chinese, Japanese and English) in USER or ADMIN accounts.
    MS "updates" are NOT identical in those cases. For example, ShowSave can crash in Japanese USER but work on English ADMIN, but few days later it is different. There is no end for this. We also check remote computers in Australia and Japan on different accounts.
    All I can say FOR SURE, that since about mid 2018, VB6 suffered many attacks which practically shut us down.
    BTW, with the code I adopted form you we now see crash of DUser.DLL , never seen this before using your code. It only crash on Save but not on Open. We implemented a very small portion of the code, per your examples "Standard Open" and "Standard Save".
    The latest crash es happen so far on Win7 (latest updates few days ago) but not yet on Win10 latest (probably will join in few days).

    I hope it answers.
    (I have decades of VB on me. since BASIC on mainframes in 1979, through all the variations of VB except NET.). I still maintain it is the quickest and most efficient high-level language with the fastest road to market).
    While my story is quite similar, I had more luck.
    Trouble with COMDLG32.OCX in the VB3 times, so we used a class using the DLL directly.
    And no problems since then, on every OS including Vista, except XP64.
    Also we never used MSCOMCTL.OCX.

    Could you post a snippet around your ShowSave that crashes?
    As a simple demo?
    Perhaps it helps us to not fall into the same traps as you.
    In our tests here in Win7s, all VMs, we don't find a problem, that's why I ask.

  33. #33
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,817

    Re: [vb6]Common Dialog Class (Yet Another One)

    Truth be told, DerWeise's story about problems was a bit puzzling to me.

    I suppose my story is also rather similar, but I also didn't have those kinds of problems.

    However, early on, I implemented a SxS approach for all my OCX dependencies, and I very rarely update those. Also, through the years, I've managed to cut out a couple of those dependencies. Here's the complete list I currently use:

    • mscomct2.ocx 6.1.98.16
    • mscomctl.ocx 6.1.98.39
    • msflxgrd.ocx 6.1.98.14
    • richtx32.ocx 6.1.98.16
    • tabctl32.ocx 6.1.98.16

    I've often thought of cutting those out, and using Krool's and Eduardo's alternatives, but that comes down to priorities. Also, I have a rather strong "if it ain't broke, don't fix it" attitude about many things. But I am being asked to consider language translations, which is pushing me into Unicode considerations. So, who knows what the future will bring.

    Also, LaVolpe, I apologize if this is hijacking your thread too much. DerWeise, if you'd like to continue this discussion, we should probably move over to the regular Q&A section with a new thread. @Moderators: You may want to do that anyway, starting with post #31.

    Y'all Take Care,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  34. #34
    Junior Member
    Join Date
    Sep 2017
    Posts
    17

    Re: [vb6]Common Dialog Class (Yet Another One)

    I implemented the sample code, and have a hysterical bug. Took months to isolate, but not yet to solve.
    ShowSave crash bigtime in CERTAIN cases (lots off crunching away from the SAVE code).
    Once ".Filter =" is specified - it crashes for sure. The line ".Filter = " omitted - open like charm.

    Hint: It almost always happen when the filter is two-letter, not three. (e,g, "LK|*.LK" crash, "LKA|*LKA" works).
    Tried with and without EXT, same results.

    (in your sample it never happens).

    Any clue?
    Thanks.

  35. #35

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    @DerWise. With the sample project, this doesn't happen, correct? But it happens with your project?

    Can you post your code where you are setting the dialog properties along with the actual call to ShowSave?
    Also which Windows version are your running? Does it happen when the dialog is attempting to display or after you close it?

    P.S. A bug does exist in the Filter Get routine & isn't related to length of extension. Extra vbNullChar is wrong
    this line: n = InStrRev(ofn.lpstrFilter, vbNullChar & vbNullChar)
    needs changing to: n = InStrRev(ofn.lpstrFilter, vbNullChar)
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  36. #36
    Junior Member
    Join Date
    Sep 2017
    Posts
    17

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by LaVolpe View Post
    @DerWise. With the sample project, this doesn't happen, correct? But it happens with your project?

    Can you post your code where you are setting the dialog properties along with the actual call to ShowSave?
    Also which Windows version are your running? Does it happen when the dialog is attempting to display or after you close it?

    P.S. A bug does exist in the Filter Get routine & isn't related to length of extension. Extra vbNullChar is wrong
    this line: n = InStrRev(ofn.lpstrFilter, vbNullChar & vbNullChar)
    needs changing to: n = InStrRev(ofn.lpstrFilter, vbNullChar)
    Thanks.

    Here is the code in the form:

    Public Sub exec(ByVal Fl As String, ByVal Extn As String, ByVal ind As String, ByVal Mds As String)
    Set cBrowser = New CmnDialogEx

    With cBrowser
    .Filter = Fl
    .DefaultExt = Extn
    .InitDir = ind
    Select Case Mds
    Case "OPEN"
    bReturn = cBrowser.ShowOpen(Me.hWnd, 0)
    Case "SAVE"
    bReturn = cBrowser.ShowSave(Me.hWnd, 0)
    Case "FOLDER"
    .FlagsDialog = DLG__BaseOpenDialogFlags Or DLGex_PickFolders
    .InitDir = ind
    bReturn = cBrowser.ShowOpen(Me.hWnd, 0)

    End Select
    End With

    Set cBrowser = Nothing

    End Sub


    I added the fix but it didn't solve it.
    It happens in Win7 in the IDE (I know now that whatever crash in my IDE will crash on Win10 in EXE...) It also happens to our users in US and Japan on Win7 and 10 as EXE.
    When it crash you get white screen (when it gets to the line:
    lReturn = pvCallInterface(ObjPtr(m_Dialog), ifModalWindow_Show, ownerHwnd)

    Then any click just gets PING, need to close VB6 and the running app by Task Manager.
    Usually the Fault module Name is DUser.dll, exception 5 at offset 2cf1

    If I comment the line .Filter = fl above, [B]IT DOESN'T CRASH[B] the form opens OK, but then it shows all extensions.

    Many thanks.

  37. #37

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    @DerWise. I think I may have it but am not sure.

    In your copy of the class, can you make the following changes, for testing only. We are going to take the sItems() array out of pvInitStructure and move it to the declarations section:

    1. Add this at top of declarations section: Private sItems() As String
    2. In pvInitStructure method...
    a. remove sItems from the DIM statements
    b. remove the line: Erase sItems()

    Now try it.
    Last edited by LaVolpe; Jun 9th, 2019 at 03:22 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  38. #38
    Junior Member
    Join Date
    Sep 2017
    Posts
    17

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by LaVolpe View Post
    @DerWise. I think I may have it but am not sure.

    In your copy of the class, can you make the following changes, for testing only. We are going to take the sItems() array out of pvInitStructure and move it to the declarations section:

    1. Add this at top of declarations section: Private sItems() As String
    2. In pvInitStructure method...
    a. remove sItems from the DIM statements
    b. remove the line: Erase sItems()

    Now try it.
    Sorry, still hangs but slightly differently.
    1. It now takes about 1 second after I click SAVE before the hang
    2. The Fault Module shown is propsys.dll

    One more question:
    We use MANY absolute variables declared in several modules.
    I didn't see any in your code.
    Still is there a chance we step on something of yours?
    (I found one, pIndex, and changed it to be safe, but there can be many others.

    Thanks!

  39. #39

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [vb6]Common Dialog Class (Yet Another One)

    Quote Originally Posted by DerWeise View Post
    Still is there a chance we step on something of yours?
    Absolutely not. In a VB class, variables referenced are those in the procedure first, class declarations second, then global ones (not applicable here).

    One thing has me confused still. You said that the sample project that came with the zip did not crash? Even if you go and change the filter in the sample code?

    Grasping at straws here. If you set the Flags property to DLG__BaseSaveDialogFlags any change? Another question, is this only with the Save dialog or the Open dialog also, when using the same filter?

    And finally, do you have the most recent Win7 service pack installed? I can find many hits on the web for SetFileTypes (filter) crashing Win7, but am not finding anything that looks like it applies to the class I wrote. Your description sounds almost like the Dialog is trying to access some variable after it closes, after the class released and cleared all of its variables. To test that idea, simply do not set the class to nothing and see if the error continues.
    Last edited by LaVolpe; Jun 10th, 2019 at 08:30 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    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} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  40. #40
    Junior Member
    Join Date
    Sep 2017
    Posts
    17

    Re: [vb6]Common Dialog Class (Yet Another One)

    I'm trying to answer, but by the time I finish the answer it shows me logged out and all my writing is gone....
    I can show you everything and discuss it seriously if you skype me.
    How can I write you my contact not public?
    Thanks.

Page 1 of 2 12 LastLast

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