Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Go Back  Xtreme Visual Basic Talk > > > Save Dialog using GetSaveFileName API


Reply
 
Thread Tools Display Modes
  #1  
Old 09-01-2016, 07:46 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,859
Default Save Dialog using GetSaveFileName API


Now I am trying to add the Windows SAVE Dialog in my app.

I am trying to set the functionality up like Excel, whereas, when the dialog opens,
Book1.xls is filled in and highlighted (DefaultName.txt in my code below).

The code seems to work, however the line
MsgBox "{" & ofn.lpstrFile & "}"
only shows {C:\Users\Admin\De} when executed (obviously not complete)

Also, after the app is run, and the project is closed with X, and the VB is closed with X,
VB crashes with message box "Visual Basic has stopped working..."

As usual, I need some help...

This is my complete code:
Code:
Option Explicit


Private Declare Function GetSaveFileName Lib "comdlg32.dll" Alias _
    "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Long


Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    iFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type


Private Const OFN_OVERWRITEPROMPT = &H2


Private Function ShowSaveFileDialog() As String
    
    Dim ofn As OPENFILENAME
    On Error Resume Next

    Dim sBuffer As String * 255

    ' set the values for the OPENFILENAME struct
    ofn.lStructSize = Len(ofn)
    ofn.hwndOwner = Me.hWnd
    ofn.hInstance = 0
    ofn.lpstrFilter = "Text Files (*.txt)" & Chr$(0) & "*.txt" & Chr$(0)
    ofn.nMaxFile = 255
    ofn.lpstrFile = "DefaultName.txt" & vbNullChar & vbNullChar
    ofn.lpstrFileTitle = sBuffer
    ofn.nMaxFileTitle = 255
    ofn.lpstrInitialDir = App.Path & "\Subfolder"
    ofn.lpstrDefExt = "txt"
    ofn.flags = OFN_OVERWRITEPROMPT

    Dim lRet As Long
    lRet = GetSaveFileName(ofn)

    If lRet <> 0 Then
        
        'user specified a file name and clicked the OK button and the function is successful
        MsgBox "SUCCESS"
        
        ' set function return
        ShowSaveFileDialog = ofn.lpstrFile


        'save the file
        'Open ofn.lpstrFile For Output As #1
        'Print #1, "abcd"
        'Close #1
     
    ElseIf lRet = 0 Then
        
        'user canceled or closed the Save dialog box or an error occured
        MsgBox "FAIL"
        
        ' set function return
        ShowSaveFileDialog = ""

    End If
    
    
    MsgBox "{" & ofn.lpstrFile & "}"
 
End Function


Private Sub Command1_Click()
    
    'let user select a file to Save As
    
    Dim sRet As String
    sRet = ShowSaveFileDialog()
    MsgBox sRet
    
End Sub
Reply With Quote
  #2  
Old 09-06-2016, 10:41 PM
OnErr0r's Avatar
OnErr0rSave Dialog using GetSaveFileName API OnErr0r is offline
Obsessive OPtimizer

Administrator
* Guru *
 
Join Date: Jun 2002
Location: Debug Window
Posts: 13,774
Default

You're buffering lpStrFile with "DefaultName.txt" and two null characters, which is exactly the number of characters you're getting back. Windows is then writing the rest of the information in whatever address is next and causing the exception. You'll need to properly buffer the string before calling the function. You should also be checking the windows version because NT 5 and greater has 3 more fields in the structure.
__________________
Quis custodiet ipsos custodues.
Reply With Quote
  #3  
Old 09-07-2016, 12:32 PM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,859
Default

OK thanks!

I thought I was creating the proper buffer size with this line
ofn.nMaxFile = 255
I guess not
I will play with the buffer
Reply With Quote
  #4  
Old 09-10-2016, 11:00 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,859
Default

GOT IT!

Changed to this
Code:
    ' set the values for the OPENFILENAME struct
    ofn.lStructSize = Len(ofn)
    ofn.hwndOwner = Me.hWnd
    ofn.hInstance = 0
    ofn.lpstrFilter = "Text Files (*.txt)" & Chr$(0) & "*.txt" & Chr$(0)
    ofn.nMaxFile = 255
    ofn.lpstrFile = "DefaultName.txt" & vbNullChar & vbNullChar
    ofn.lpstrFileTitle = sBuffer
    ofn.nMaxFileTitle = 255
    ofn.lpstrInitialDir = App.Path & "\Subfolder"
    ofn.lpstrDefExt = "txt"
    ofn.flags = OFN_OVERWRITEPROMPT
to this
Code:
    ' set the values for the OPENFILENAME struct
    ofn.lStructSize = Len(ofn)
    ofn.hwndOwner = Form1.hWnd
    ofn.hInstance = App.hInstance
    ofn.lpstrFilter = "Text Files (*.txt)" & Chr$(0) & "*.txt" & Chr$(0)
    'ofn.iFilterIndex = 1
    ofn.lpstrFile = "DefaultFile.txt" & String(257 - Len("DefaultFile.txt"), 0)
    ofn.nMaxFile = Len(ofn.lpstrFile) - 1
    ofn.lpstrFileTitle = ofn.lpstrFile
    ofn.nMaxFileTitle = ofn.nMaxFile
    ofn.lpstrInitialDir = App.Path & "\Subfolder"
    ofn.lpstrTitle = "Save As"
    ofn.lpstrDefExt = ".txt"    
    ofn.Flags = OFN_OVERWRITEPROMPT
I got rid of
& vbNullChar & vbNullChar

Not sure what they did anyways.
Do I need them?

With regards to checking Windows version, I am running Windows7, and this code works without the extra fields.

I don't know how to incorporate the IF in the OPENFILENAME structure in VB
I searched online for an example, but could find nothing.
Could you point me to an example?

Last edited by mms; 09-10-2016 at 11:15 AM.
Reply With Quote
  #5  
Old 09-11-2016, 11:19 AM
Cerian Knight's Avatar
Cerian KnightSave Dialog using GetSaveFileName API Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,193
Default

String(..., 0) supplies the required vbNullChar (Chr$(0)) termination in addition to the required buffer padding. If padding the buffer were not a requirement... I'm not sure why you were using two vbNullChar, as LenB(vbNullChar) = 2 (two zeros), which is sufficient.

I'm sure that old Type legacy code is well supported (without structure change), but the question is: Do YOU want to support the new Vista+ dialog style? Obviously recommended to do so for user interface consistency within the OS, since XP- is becoming a less likely target for deployment.

If so, for VB6, just create two different Type structures (new, without C-style #IF, and old) and be prepared to fill/pass the new Type to NT5+, once determined, otherwise fill/pass the old. Give that a try... unless someone knows of another way to implement conditional structs.

If not, then just use the old Type structure.
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').

Last edited by Cerian Knight; 09-11-2016 at 11:47 AM. Reason: clarification
Reply With Quote
  #6  
Old 09-14-2016, 10:41 PM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,859
Default

OK thanks for your reply.
I can try your suggestion about using two different Type structures.

I don't understand however, by using a different Type structure, a different
dialog style will be displayed.

Also I'm not sure what you mean by this question.
Do YOU want to support the new Vista+ dialog style?
Reply With Quote
  #7  
Old 09-15-2016, 11:34 AM
Cerian Knight's Avatar
Cerian KnightSave Dialog using GetSaveFileName API Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,193
Default

Sorry if I over-stated the differences and the implications. In any case, this is what Microsoft says about the additional relevant flag in the new structure:

FlagsEx
Type: DWORD
A set of bit flags you can use to initialize the dialog box. Currently, this member can be zero or the following flag.

Value
OFN_EX_NOPLACESBAR
0x00000001

Meaning
If this flag is set, the places bar is not displayed. If this flag is not set, Explorer-style dialog boxes include a places bar containing icons for commonly-used folders, such as Favorites and Desktop.
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #8  
Old 09-16-2016, 03:24 PM
fafalone fafalone is offline
Freshman
 
Join Date: May 2010
Posts: 37
Default

To support the *new* dialog styles, features, and customizations you can't use this API at all; you need to use the IFileDialog (IFileOpenDialog/IFileSaveDialog) interfaces. They support all sorts of neat customizations like adding all sorts of controls, adding custom entries to the places list, getting callbacks in VB for any events, and tons of other things. Honestly it's easier to use too.
Reply With Quote
  #9  
Old 09-16-2016, 09:32 PM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,859
Default

I'd be willing to try if you'd like to share some VB code to get me started.
Reply With Quote
  #10  
Old 09-16-2016, 11:50 PM
fafalone fafalone is offline
Freshman
 
Join Date: May 2010
Posts: 37
Default

Follow the link in the post, it's to a demo I made of using it.
Reply With Quote
  #11  
Old 09-18-2016, 01:00 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,859
Default

OK thanks.

I've only ever tried COM with the CoreAudio APIs a year or two ago.
Got most working, but a lot of work to set things up.

Just curios. Why are certain APIs set up this way, instead of the traditional
way in which we are used to?
Reply With Quote
  #12  
Old 09-29-2016, 06:59 PM
fafalone fafalone is offline
Freshman
 
Join Date: May 2010
Posts: 37
Default

Because MS rejected the traditional "if it ain't broke, don't fix it" for the much more modern, interoperable, cross-platform, synergistic "if it ain't broke, keep trashing it and replacing it entirely until you find something that is broke"
Reply With Quote
Reply

Tags
string, function, save, private, ofn.lpstrfile, msgbox, openfilename, dim, dialog, set, lret, showsavefiledialog, user, closed, file, code, sret, integer, error, box, chr$0, type, sbuffer, vbnullchar, ofn_overwriteprompt


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
 
Save Dialog using GetSaveFileName API
Save Dialog using GetSaveFileName API
 
-->