|
-
Sep 25th, 2009, 05:00 AM
#1
Thread Starter
Frenzied Member
[RESOLVED] Return Selected Filter with GetSaveFileName API
Ok, I have a File Save dialog for a while, through the GetSaveFileName API.
However, now I need to determine which Filter the user has selected.
i.e .jpeg, .bmp, .gif etc...
Code:
Private Declare Function GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameW" (pOpenfilename As OPENFILENAME) As Long
Private Type OPENFILENAME
lStructSize As Long 'Length of structure, in bytes
hWndOwner As Long 'Window that owns the dialog, or NULL
hInstance As Long 'Handle of mem object containing template (not used)
lpstrFilter As Long 'File types/descriptions, delimited with vbnullchar, ends with 2xvbnullchar
lpstrCustomFilter As Long 'Filters typed in by user
nMaxCustFilter As Long 'Length of CustomFilter, min 40x chars
nFilterIndex As Long 'Filter Index to use (1,2,etc) or 0 for custom
lpstrFile As Long 'Initial file/returned file(s), delimited with vbnullchar for multi files
nMaxFile As Long 'Size of Initial File long , min 256
lpstrFileTitle As Long 'File.ext excluding path
nMaxFileTitle As Long 'Length of FileTitle
lpstrInitialDir As Long 'Initial file dir, null for current dir
lpstrTitle As Long 'Title bar of dialog
flags As Long 'See OFN_Flags
nFileOffset As Integer 'Offset to file name in full path, 0-based
nFileExtension As Integer 'Offset to file ext in full path, 0-based (excl '.')
lpstrDefExt As Long 'Default ext appended, excl '.', max 3 chars
lCustData As Long 'Appl defined data for lpfnHook
lpfnHook As Long 'Pointer to hook procedure
lpTemplateName As Long 'Template Name (not used)
pvReserved As Long 'new Win2000 / WinXP members
dwReserved As Long 'new Win2000 / WinXP members
FlagsEx As Long 'new Win2000 / WinXP members
End Type
Public Function cFileSave(ByVal InitialDir As String, _
ByVal DialogTitle As String, ByVal Filter As String, _
ByVal FrmhWnd As Long, Optional FileTitle As String = vbNullString, _
Optional ByRef rtnFilter As Long) As String
Dim OpenFile As OPENFILENAME
Dim lReturn As Long
Dim FileFilter As String
Dim strFile As String
strFile = String$(512, 0)
If Not FileTitle = vbNullString Then
strFile = FileTitle & strFile
End If
OpenFile.lStructSize = Len(OpenFile)
OpenFile.hWndOwner = FrmhWnd
OpenFile.hInstance = App.hInstance
FileFilter = Replace$(Filter, "|", vbNullChar)
If AscW(Right$(FileFilter, 1)) <> 0& Then FileFilter = FileFilter & vbNullChar
OpenFile.lpstrFilter = StrPtr(FileFilter)
OpenFile.nFilterIndex = 1
OpenFile.lpstrFile = StrPtr(strFile)
OpenFile.nMaxFile = Len(strFile) - 1
OpenFile.lpstrFileTitle = StrPtr(OpenFile.lpstrFile)
OpenFile.nMaxFileTitle = StrPtr(OpenFile.nMaxFile)
OpenFile.lpstrInitialDir = StrPtr(InitialDir)
OpenFile.lpstrTitle = StrPtr(DialogTitle)
OpenFile.flags = 0
lReturn = GetSaveFileName(OpenFile)
If lReturn = 0 Then
'Cancel Button Pressed
Else
cFileSave = Left$(strFile, InStr(strFile, vbNullChar) - 1)
rtnFilter = OpenFile.lpstrFile
End If
End Function
Currently it returns a LONG number,
How do i convert this to the relevant String format ?
_____________________________________________________________________
----If this post has helped you. Please take time to Rate it.
----If you've solved your problem, then please mark it as RESOLVED from Thread Tools.

-
Sep 25th, 2009, 07:35 AM
#2
Re: Return Selected Filter with GetSaveFileName API
Curious. You want the filter index, by you are looking at the .lpstrFile which is a Long string pointer. Wouldn't you want to look .nFilterIndex? Not sure if it gets updated, but easy enough to check.
Edited: I checked, it does get updated. So: rtnFilter = OpenFile.nFilterIndex
Last edited by LaVolpe; Sep 25th, 2009 at 08:16 AM.
-
Sep 25th, 2009, 08:05 AM
#3
Re: Return Selected Filter with GetSaveFileName API
the simple method is to change the type of the filter member of the type to string and remove the strptr when assigning the value
lpstrFilter As String 'File types/descriptions, delimited with vbnullchar, ends with 2xvbnullchar
OpenFile.lpstrFilter = FileFilter
same applies to other members of the type
an alternative
Code:
Private Type OPENFILENAME
lStructSize As Long ' Filled with UDT size
hwndOwner As Long ' Tied to Owner
hInstance As Long ' Ignored (used only by templates)
lpstrFilter As String ' Tied to Filter
lpstrCustomFilter As String ' Ignored
nMaxCustFilter As Long ' Ignored
nFilterIndex As Long ' Tied to FilterIndex
lpstrFile As String ' Tied to FileName
nMaxFile As Long ' Handled internally
lpstrFileTitle As String ' Tied to FileTitle
nMaxFileTitle As Long ' Handled internally
lpstrInitialDir As String ' Tied to InitDir
lpstrTitle As String ' Tied to DlgTitle
Flags As Long ' Tied to Flags
nFileOffset As Integer ' Ignored
nFileExtension As Integer ' Ignored
lpstrDefExt As String ' Tied to DefaultExt
lCustData As Long ' Ignored (needed for hooks)
lpfnHook As Long ' Ignored (good luck with hooks)
lpTemplateName As Long ' Ignored (good luck with templates)
End Type
Last edited by westconn1; Sep 25th, 2009 at 08:09 AM.
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
-
Sep 25th, 2009, 08:27 AM
#4
Re: Return Selected Filter with GetSaveFileName API
westconn1, one of the advantages of using StrPtr is that some1uk03 is supporting unicode filenames via the W API version. But using strings works as well, the only difference is that they need to be converted to unicode, i.e., StrConv(), or other workarounds, else VB will convert the strings to ANSI when it passes the UDT.
Edited: However, his code will fail on non-unicode systems (possibly WinME and below). But that may not be an issue?
Edited yet again. Personal preferences of mine are to use strings as you are describing and changing the declaration depending on whether A or W version API is called:
Code:
Private Declare Function GetSaveFileNameUnicode Lib "comdlg32.dll" Alias "GetSaveFileNameW" (ByVal pOpenfilename As Long) As Long
' ^^ sample call: lReturn = GetSaveFileNameUnicode(VarPtr(OPENFILE))
Private Declare Function GetSaveFileNameANSI Lib "comdlg32.dll" Alias "GetSaveFileNameA" (ByRef pOpenfilename As OPENFILENAME) As Long
' ^^ sample call: lReturn = GetSaveFileNameANSI(OPENFILE)
Last edited by LaVolpe; Sep 25th, 2009 at 08:46 AM.
-
Sep 25th, 2009, 10:15 AM
#5
Thread Starter
Frenzied Member
Re: Return Selected Filter with GetSaveFileName API
 Originally Posted by LaVolpe
Curious. You want the filter index, by you are looking at the .lpstrFile which is a Long string pointer. Wouldn't you want to look .nFilterIndex? Not sure if it gets updated, but easy enough to check.
Edited: I checked, it does get updated. So: rtnFilter = OpenFile.nFilterIndex
You've spotted it well LaVolpe... Nice 1..
I think haven't been careful with the spelling there and typed OpenFile.lpstrFile instead. 
Also with the UniCode version, yes I'm not supporting WinME and below, so that isn't an issue.
Thanks Guys
_____________________________________________________________________
----If this post has helped you. Please take time to Rate it.
----If you've solved your problem, then please mark it as RESOLVED from Thread Tools.

Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|