Jump to content

FileSaveDialog - How to get selected filter?


5t0n3r
 Share

Recommended Posts

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
Link to comment
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

Link to comment
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
Link to comment
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
Link to comment
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

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...