Sign in to follow this  
Followers 0
5t0n3r

FileSaveDialog - How to get selected filter?

11 posts in this topic

When I choose a filename, it doesn't put on the extension of the selected filter.

Any way I can find out the selected filter and write it to a variable?

Thanks in advance.

#include <GUIConstants.au3>

_file_save()
Func _file_save()


GUICreate(" Location", 387, 200, @DesktopWidth / 2 - 260, @DesktopHeight / 2 - 45)

GUICtrlCreateLabel("**Input Path**", 150, 35)
$path = GUICtrlCreateInput("",10,53,367,23)
$browse = GUICtrlCreateButton("Browse", 135, 81,100, 23)
GUICtrlCreateLabel("**Output Path**", 148, 111)
$output = GUICtrlCreateInput("",10, 128,367,23)

GUISetState()
$msg = 0

While $msg <> $GUI_EVENT_CLOSE
    $msg = GUIGetMsg()
    Select
        Case $msg = $browse
;           $ext1 = ".txt"
;           $ext2 = ".doc"
            $File2open = FileSaveDialog("Browse for save location", @DesktopDir, "Text Documents (*.txt)|Word Documents (*.doc)", 2) ;returns the file path
;            $File2open = FileSaveDialog ("Browse for save location", @DesktopDir, "Text Documents (*"& $ext1 & ")|Word Documents (*"& $ext2 & ")", 2) ;returns the file path

            GUICtrlSetData($path, $File2open)       ;set input data
            GUICtrlSetData($output, $File2open)     ;same as above
    EndSelect
WEnd
EndFunc

Share this post


Link to post
Share on other sites



This is an alternative (Manadar?) showed me a while ago. It doesn't return the file type, but makes sure its added. It is superior in most ways to the in built one.

Func _FileSaveDialog ($sTitle, $sInitDir, $sFilter = 'All (*.*)', $iOpt = 0, $sDefaultFile = "", $sDefaultExt = "", $mainGUI = 0)
   Local $iFileLen = 65536
   Local $iFlag = BitOR(BitShift(BitAND($iOpt, 2), -10), BitShift(BitAND($iOpt, 16), 3))
   Local $asFLines = StringSplit($sFilter, '|'), $asFilter[$asFLines[0] * 2 + 1]
   Local $i, $iStart, $iFinal, $suFilter = '', $ret

   $asFilter[0] = $asFLines[0] * 2
   For $i = 1 To $asFLines[0]
      $iStart = StringInStr($asFLines[$i], '(', 0, 1)
      $iFinal = StringInStr($asFLines[$i], ')', 0, -1)
      $asFilter[$i * 2 - 1] = StringStripWS(StringLeft($asFLines[$i], $iStart - 1), 3)
      $asFilter[$i * 2] = StringStripWS(StringTrimRight(StringTrimLeft($asFLines[$i], $iStart), StringLen($asFLines[$i]) - $iFinal + 1), 3)
      $suFilter = $suFilter & 'byte[' & StringLen($asFilter[$i * 2 - 1]) + 1 & '];byte[' & StringLen($asFilter[$i * 2]) + 1 & '];'
   Next
   Local $uOFN = DllStructCreate('dword;int;int;ptr;ptr;dword;dword;ptr;dword' & ';ptr;int;ptr;ptr;dword;short;short;ptr;ptr;ptr;ptr;ptr;dword;dword')
   Local $usTitle = DllStructCreate('byte[' & StringLen($sTitle) + 1 & ']')
   Local $usInitDir = DllStructCreate('byte[' & StringLen($sInitDir) + 1 & ']')
   Local $usFilter = DllStructCreate($suFilter & 'byte')
   Local $usFile = DllStructCreate('char[' & $iFileLen & ']')
   Local $usExtn = DllStructCreate('byte[' & StringLen($sDefaultExt) + 1 & ']')
   For $i = 1 To $asFilter[0]
      DllStructSetData($usFilter, $i, $asFilter[$i])
   Next
   DllStructSetData($usTitle, 1, $sTitle)
   DllStructSetData($usInitDir, 1, $sInitDir)
   DllStructSetData($usFile, 1, $sDefaultFile)
   DllStructSetData($usExtn, 1, $sDefaultExt)
   DllStructSetData($uOFN, 1, DllStructGetSize($uOFN))
   DllStructSetData($uOFN, 2, $mainGUI)
   DllStructSetData($uOFN, 4, DllStructGetPtr($usFilter))
   DllStructSetData($uOFN, 7, 1)
   DllStructSetData($uOFN, 8, DllStructGetPtr($usFile))
   DllStructSetData($uOFN, 9, $iFileLen)
   DllStructSetData($uOFN, 12, DllStructGetPtr($usInitDir))
   DllStructSetData($uOFN, 13, DllStructGetPtr($usTitle))
   DllStructSetData($uOFN, 14, $iFlag)
   DllStructSetData($uOFN, 17, DllStructGetPtr($usExtn))
   DllStructSetData($uOFN, 23, BitShift(BitAND($iOpt, 32), 5))
   $ret = DllCall('comdlg32.dll', 'int', 'GetSaveFileName', 'ptr', DllStructGetPtr($uOFN))
      If $ret[0] Then
         Return StringStripWS(DllStructGetData($usFile, 1), 3)
      Else
         SetError(1)
         Return ""
      EndIf

EndFunc   ;==> _FileSaveDialog

Mat

Share this post


Link to post
Share on other sites

Holy Moly, that's bit much for this guy to grasp.

I'm a little unsure how to incorporate this into my script as I get an error when calling the function.

Share this post


Link to post
Share on other sites

Holy Moly, that's bit much for this guy to grasp.

I'm a little unsure how to incorporate this into my script as I get an error when calling the function.

:D, I don't even pretend to have the slightest clue whats going on there, but its dll stuff.

an error? I don't get any errors... try:

$sFile = _FileSaveDialog ("Test", @WorkingDir)

MsgBox (0, "test:", $sFile)

Func _FileSaveDialog ($sTitle, $sInitDir, $sFilter = 'All (*.*)', $iOpt = 0, $sDefaultFile = "", $sDefaultExt = "", $mainGUI = 0)
   Local $iFileLen = 65536
   Local $iFlag = BitOR(BitShift(BitAND($iOpt, 2), -10), BitShift(BitAND($iOpt, 16), 3))
   Local $asFLines = StringSplit($sFilter, '|'), $asFilter[$asFLines[0] * 2 + 1]
   Local $i, $iStart, $iFinal, $suFilter = '', $ret

   $asFilter[0] = $asFLines[0] * 2
   For $i = 1 To $asFLines[0]
      $iStart = StringInStr($asFLines[$i], '(', 0, 1)
      $iFinal = StringInStr($asFLines[$i], ')', 0, -1)
      $asFilter[$i * 2 - 1] = StringStripWS(StringLeft($asFLines[$i], $iStart - 1), 3)
      $asFilter[$i * 2] = StringStripWS(StringTrimRight(StringTrimLeft($asFLines[$i], $iStart), StringLen($asFLines[$i]) - $iFinal + 1), 3)
      $suFilter = $suFilter & 'byte[' & StringLen($asFilter[$i * 2 - 1]) + 1 & '];byte[' & StringLen($asFilter[$i * 2]) + 1 & '];'
   Next
   Local $uOFN = DllStructCreate('dword;int;int;ptr;ptr;dword;dword;ptr;dword' & ';ptr;int;ptr;ptr;dword;short;short;ptr;ptr;ptr;ptr;ptr;dword;dword')
   Local $usTitle = DllStructCreate('byte[' & StringLen($sTitle) + 1 & ']')
   Local $usInitDir = DllStructCreate('byte[' & StringLen($sInitDir) + 1 & ']')
   Local $usFilter = DllStructCreate($suFilter & 'byte')
   Local $usFile = DllStructCreate('char[' & $iFileLen & ']')
   Local $usExtn = DllStructCreate('byte[' & StringLen($sDefaultExt) + 1 & ']')
   For $i = 1 To $asFilter[0]
      DllStructSetData($usFilter, $i, $asFilter[$i])
   Next
   DllStructSetData($usTitle, 1, $sTitle)
   DllStructSetData($usInitDir, 1, $sInitDir)
   DllStructSetData($usFile, 1, $sDefaultFile)
   DllStructSetData($usExtn, 1, $sDefaultExt)
   DllStructSetData($uOFN, 1, DllStructGetSize($uOFN))
   DllStructSetData($uOFN, 2, $mainGUI)
   DllStructSetData($uOFN, 4, DllStructGetPtr($usFilter))
   DllStructSetData($uOFN, 7, 1)
   DllStructSetData($uOFN, 8, DllStructGetPtr($usFile))
   DllStructSetData($uOFN, 9, $iFileLen)
   DllStructSetData($uOFN, 12, DllStructGetPtr($usInitDir))
   DllStructSetData($uOFN, 13, DllStructGetPtr($usTitle))
   DllStructSetData($uOFN, 14, $iFlag)
   DllStructSetData($uOFN, 17, DllStructGetPtr($usExtn))
   DllStructSetData($uOFN, 23, BitShift(BitAND($iOpt, 32), 5))
   $ret = DllCall('comdlg32.dll', 'int', 'GetSaveFileName', 'ptr', DllStructGetPtr($uOFN))
      If $ret[0] Then
         Return StringStripWS(DllStructGetData($usFile, 1), 3)
      Else
         SetError(1)
         Return ""
      EndIf

EndFunc   ;==> _FileSaveDialog

Share this post


Link to post
Share on other sites

Works great, thanks!

Any idea how to get it to show the *.* for All? The dropdown menu for file types only shows "All", not "All (*.*)".

Share this post


Link to post
Share on other sites

Works great, thanks!

Any idea how to get it to show the *.* for All? The dropdown menu for file types only shows "All", not "All (*.*)".

Yes... Thats the one bit of the code I can understand! One line change with no dll work involved.

$sFile = _FileSaveDialog ("Test", @WorkingDir)

MsgBox (0, "test:", $sFile)

Func _FileSaveDialog ($sTitle, $sInitDir, $sFilter = 'All (*.*)', $iOpt = 0, $sDefaultFile = "", $sDefaultExt = "", $mainGUI = 0)
   Local $iFileLen = 65536
   Local $iFlag = BitOR(BitShift(BitAND($iOpt, 2), -10), BitShift(BitAND($iOpt, 16), 3))
   Local $asFLines = StringSplit($sFilter, '|'), $asFilter[$asFLines[0] * 2 + 1]
   Local $i, $iStart, $iFinal, $suFilter = '', $ret

   $asFilter[0] = $asFLines[0] * 2
   For $i = 1 To $asFLines[0]
      $iStart = StringInStr($asFLines[$i], '(', 0, 1)
      $iFinal = StringInStr($asFLines[$i], ')', 0, -1)
      ;$asFilter[$i * 2 - 1] = StringStripWS(StringLeft($asFLines[$i], $iStart - 1), 3)
      $asFilter[$i * 2 - 1] = $asFlines[$i]
      $asFilter[$i * 2] = StringStripWS(StringTrimRight(StringTrimLeft($asFLines[$i], $iStart), StringLen($asFLines[$i]) - $iFinal + 1), 3)
      $suFilter = $suFilter & 'byte[' & StringLen($asFilter[$i * 2 - 1]) + 1 & '];byte[' & StringLen($asFilter[$i * 2]) + 1 & '];'
   Next
   Local $uOFN = DllStructCreate('dword;int;int;ptr;ptr;dword;dword;ptr;dword' & ';ptr;int;ptr;ptr;dword;short;short;ptr;ptr;ptr;ptr;ptr;dword;dword')
   Local $usTitle = DllStructCreate('byte[' & StringLen($sTitle) + 1 & ']')
   Local $usInitDir = DllStructCreate('byte[' & StringLen($sInitDir) + 1 & ']')
   Local $usFilter = DllStructCreate($suFilter & 'byte')
   Local $usFile = DllStructCreate('char[' & $iFileLen & ']')
   Local $usExtn = DllStructCreate('byte[' & StringLen($sDefaultExt) + 1 & ']')
   For $i = 1 To $asFilter[0]
      DllStructSetData($usFilter, $i, $asFilter[$i])
   Next
   DllStructSetData($usTitle, 1, $sTitle)
   DllStructSetData($usInitDir, 1, $sInitDir)
   DllStructSetData($usFile, 1, $sDefaultFile)
   DllStructSetData($usExtn, 1, $sDefaultExt)
   DllStructSetData($uOFN, 1, DllStructGetSize($uOFN))
   DllStructSetData($uOFN, 2, $mainGUI)
   DllStructSetData($uOFN, 4, DllStructGetPtr($usFilter))
   DllStructSetData($uOFN, 7, 1)
   DllStructSetData($uOFN, 8, DllStructGetPtr($usFile))
   DllStructSetData($uOFN, 9, $iFileLen)
   DllStructSetData($uOFN, 12, DllStructGetPtr($usInitDir))
   DllStructSetData($uOFN, 13, DllStructGetPtr($usTitle))
   DllStructSetData($uOFN, 14, $iFlag)
   DllStructSetData($uOFN, 17, DllStructGetPtr($usExtn))
   DllStructSetData($uOFN, 23, BitShift(BitAND($iOpt, 32), 5))
   $ret = DllCall('comdlg32.dll', 'int', 'GetSaveFileName', 'ptr', DllStructGetPtr($uOFN))
      If $ret[0] Then
         Return StringStripWS(DllStructGetData($usFile, 1), 3)
      Else
         SetError(1)
         Return ""
      EndIf
EndFunc   ;==> _FileSaveDialog

Share this post


Link to post
Share on other sites

I don't see the problem with the OP's example code? I see the filters as expected and the file is added to the dialog correctly as well. Maybe I don't understand the OP's question/problem?

Share this post


Link to post
Share on other sites

That did it, thanks!

I appreciate all your help. :D

Share this post


Link to post
Share on other sites

The problem is in the return value. If you don't specify an extension, it doesn't add one. Usually you can check by seeing if the file name conatains an extension, and add one if its missing, but I had the problem a while ago when using multiple file extensions, and not knowing which one to add. I know about it becouse I have posted a similar question before. but that was when I was just getting started. Looking back at the code now, it actually begins to make sense, even if I don't know about the dll structs and calls.

type in the new file name without extension, and it won't add the default one. so you're left with a file and no extension, despite ".txt" being the filter. Mine still does it, but only for all files (*.*), when it does not have much choice.

ah well, I think that function resolves it.

MDiesel

Share this post


Link to post
Share on other sites

Gotcha.

Share this post


Link to post
Share on other sites

Yeah, it would be very nice if the built-in code could return the selected filter extension. It must know what it is, as it filters the view.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0