Jump to content

Detecting Cancel in _WinAPI_GetSaveFileName


Recommended Posts

I am trying to detect when the use clicks the Cancel button in _WinAPI_GetSaveFileName , however when passing values for the DefaultFile and DefaultExt the function always seems to return valid Array values, so I have not been able to distinquish between the user selecting Save or Cancel.

Any idea I how work around this ?

Stewart

Edited by StewartWilkinson
Link to comment
Share on other sites

If $aRet[0] = 0 Then Error

As the documentation says

Failure - Array of 1 item set to 0

Edited by PhoenixXL

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

#include <WinAPI.au3>

$ExportFileTypes = "Amateur Data Interchange Format (*.adi;*.adif)"
$Path = "C:\Test\"
$sDefFile = "Test.adif"

$flags = BitOR(0, $OFN_PATHMUSTEXIST, $OFN_OVERWRITEPROMPT)
$aRet = _WinAPI_GetSaveFileName("Export log entries to :", $ExportFileTypes, $Path, $sDefFile, "adif", 0, $flags)
If ($aRet[0] = 0) Then
  $sError = _WinAPI_CommDlgExtendedError()
  ConsoleWrite( "Cancelled" & @CRLF )
Else
  For $N = 0 To $aRet[0]
    ConsoleWrite( "aRet[" & $N & "] : " & $aRet[$N] & @CRLF )
  Next
EndIf

When I click save I get the expected result, but not when I click Cancel.

(on Windows7 64bit and Windows XP)

Edited by StewartWilkinson
Link to comment
Share on other sites

There seems to be a bug in _WinAPI_GetSaveFileName(), the result of the Api call to GetSaveFileNameW seems not to be evaluated at all. See attached correction lines #1 & #2, I'll post a bug report on this.

#include <WinAPI.au3>

$ExportFileTypes = "Amateur Data Interchange Format (*.adi;*.adif)"
$Path = "C:\Test\"
$sDefFile = "Test.adif"

$flags = BitOR(0, $OFN_PATHMUSTEXIST, $OFN_OVERWRITEPROMPT)
$aRet = _WinAPI_GetSaveFileName_Ex("Export log entries to :", $ExportFileTypes, $Path, $sDefFile, "adif", 0, $flags)
ConsoleWrite(@error & @CRLF)
If ($aRet[0] = 0) Then
    $sError = _WinAPI_CommDlgExtendedError()
    ConsoleWrite("Cancelled" & @CRLF)
Else
    For $N = 0 To $aRet[0]
        ConsoleWrite("aRet[" & $N & "] : " & $aRet[$N] & @CRLF)
    Next
EndIf


Func _WinAPI_GetSaveFileName_Ex($sTitle = "", $sFilter = "All files (*.*)", $sInitalDir = ".", $sDefaultFile = "", $sDefaultExt = "", $iFilterIndex = 1, $iFlags = 0, $iFlagsEx = 0, $hwndOwner = 0)
    Local $iPathLen = 4096 ; Max chars in returned string
    Local $tOFN = DllStructCreate($tagOPENFILENAME)
    Local $aFiles[1] = [0]

    Local $iFlag = $iFlags

    ; Filter string to array conversion
    Local $asFLines = StringSplit($sFilter, "|")
    Local $asFilter[$asFLines[0] * 2 + 1]
    Local $iStart, $iFinal, $stFilter
    $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)
        $stFilter &= "wchar[" & StringLen($asFilter[$i * 2 - 1]) + 1 & "];wchar[" & StringLen($asFilter[$i * 2]) + 1 & "];"
    Next

    Local $tTitle = DllStructCreate("wchar Title[" & StringLen($sTitle) + 1 & "]")
    Local $tInitialDir = DllStructCreate("wchar InitDir[" & StringLen($sInitalDir) + 1 & "]")
    Local $tFilter = DllStructCreate($stFilter & "wchar")
    Local $tPath = DllStructCreate("wchar Path[" & $iPathLen & "]")
    Local $tExtn = DllStructCreate("wchar Extension[" & StringLen($sDefaultExt) + 1 & "]")
    For $i = 1 To $asFilter[0]
        DllStructSetData($tFilter, $i, $asFilter[$i])
    Next

    ; Set Data of API structures
    DllStructSetData($tTitle, "Title", $sTitle)
    DllStructSetData($tInitialDir, "InitDir", $sInitalDir)
    DllStructSetData($tPath, "Path", $sDefaultFile)
    DllStructSetData($tExtn, "Extension", $sDefaultExt)

    DllStructSetData($tOFN, "StructSize", DllStructGetSize($tOFN))
    DllStructSetData($tOFN, "hwndOwner", $hwndOwner)
    DllStructSetData($tOFN, "lpstrFilter", DllStructGetPtr($tFilter))
    DllStructSetData($tOFN, "nFilterIndex", $iFilterIndex)
    DllStructSetData($tOFN, "lpstrFile", DllStructGetPtr($tPath))
    DllStructSetData($tOFN, "nMaxFile", $iPathLen)
    DllStructSetData($tOFN, "lpstrInitialDir", DllStructGetPtr($tInitialDir))
    DllStructSetData($tOFN, "lpstrTitle", DllStructGetPtr($tTitle))
    DllStructSetData($tOFN, "Flags", $iFlag)
    DllStructSetData($tOFN, "lpstrDefExt", DllStructGetPtr($tExtn))
    DllStructSetData($tOFN, "FlagsEx", $iFlagsEx)
    Local $iRes = DllCall("comdlg32.dll", "bool", "GetSaveFileNameW", "struct*", $tOFN) ; Correction #1 - Added "Local $iRes ="
    If Not $iRes[0] Then Return SetError(1, _WinAPI_CommDlgExtendedError(), $aFiles) ; Correction #2 - Added whole line
    If @error Then Return SetError(@error, @extended, $aFiles)
    Return __WinAPI_ParseFileDialogPath(DllStructGetData($tPath, "Path"))
EndFunc   ;==>_WinAPI_GetSaveFileName_Ex
Link to comment
Share on other sites

  • 3 months later...

There seems to be a bug in _WinAPI_GetSaveFileName(), the result of the Api call to GetSaveFileNameW seems not to be evaluated at all. See attached correction lines #1 & #2, I'll post a bug report on this.

#include <WinAPI.au3>

$ExportFileTypes = "Amateur Data Interchange Format (*.adi;*.adif)"
$Path = "C:\Test\"
$sDefFile = "Test.adif"

$flags = BitOR(0, $OFN_PATHMUSTEXIST, $OFN_OVERWRITEPROMPT)
$aRet = _WinAPI_GetSaveFileName_Ex("Export log entries to :", $ExportFileTypes, $Path, $sDefFile, "adif", 0, $flags)
ConsoleWrite(@error & @CRLF)
If ($aRet[0] = 0) Then
    $sError = _WinAPI_CommDlgExtendedError()
    ConsoleWrite("Cancelled" & @CRLF)
Else
    For $N = 0 To $aRet[0]
        ConsoleWrite("aRet[" & $N & "] : " & $aRet[$N] & @CRLF)
    Next
EndIf


Func _WinAPI_GetSaveFileName_Ex($sTitle = "", $sFilter = "All files (*.*)", $sInitalDir = ".", $sDefaultFile = "", $sDefaultExt = "", $iFilterIndex = 1, $iFlags = 0, $iFlagsEx = 0, $hwndOwner = 0)
    Local $iPathLen = 4096 ; Max chars in returned string
    Local $tOFN = DllStructCreate($tagOPENFILENAME)
    Local $aFiles[1] = [0]

    Local $iFlag = $iFlags

    ; Filter string to array conversion
    Local $asFLines = StringSplit($sFilter, "|")
    Local $asFilter[$asFLines[0] * 2 + 1]
    Local $iStart, $iFinal, $stFilter
    $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)
        $stFilter &= "wchar[" & StringLen($asFilter[$i * 2 - 1]) + 1 & "];wchar[" & StringLen($asFilter[$i * 2]) + 1 & "];"
    Next

    Local $tTitle = DllStructCreate("wchar Title[" & StringLen($sTitle) + 1 & "]")
    Local $tInitialDir = DllStructCreate("wchar InitDir[" & StringLen($sInitalDir) + 1 & "]")
    Local $tFilter = DllStructCreate($stFilter & "wchar")
    Local $tPath = DllStructCreate("wchar Path[" & $iPathLen & "]")
    Local $tExtn = DllStructCreate("wchar Extension[" & StringLen($sDefaultExt) + 1 & "]")
    For $i = 1 To $asFilter[0]
        DllStructSetData($tFilter, $i, $asFilter[$i])
    Next

    ; Set Data of API structures
    DllStructSetData($tTitle, "Title", $sTitle)
    DllStructSetData($tInitialDir, "InitDir", $sInitalDir)
    DllStructSetData($tPath, "Path", $sDefaultFile)
    DllStructSetData($tExtn, "Extension", $sDefaultExt)

    DllStructSetData($tOFN, "StructSize", DllStructGetSize($tOFN))
    DllStructSetData($tOFN, "hwndOwner", $hwndOwner)
    DllStructSetData($tOFN, "lpstrFilter", DllStructGetPtr($tFilter))
    DllStructSetData($tOFN, "nFilterIndex", $iFilterIndex)
    DllStructSetData($tOFN, "lpstrFile", DllStructGetPtr($tPath))
    DllStructSetData($tOFN, "nMaxFile", $iPathLen)
    DllStructSetData($tOFN, "lpstrInitialDir", DllStructGetPtr($tInitialDir))
    DllStructSetData($tOFN, "lpstrTitle", DllStructGetPtr($tTitle))
    DllStructSetData($tOFN, "Flags", $iFlag)
    DllStructSetData($tOFN, "lpstrDefExt", DllStructGetPtr($tExtn))
    DllStructSetData($tOFN, "FlagsEx", $iFlagsEx)
    Local $iRes = DllCall("comdlg32.dll", "bool", "GetSaveFileNameW", "struct*", $tOFN) ; Correction #1 - Added "Local $iRes ="
    If Not $iRes[0] Then Return SetError(1, _WinAPI_CommDlgExtendedError(), $aFiles) ; Correction #2 - Added whole line
    If @error Then Return SetError(@error, @extended, $aFiles)
    Return __WinAPI_ParseFileDialogPath(DllStructGetData($tPath, "Path"))
EndFunc   ;==>_WinAPI_GetSaveFileName_Ex

.

maybe it would be a good idea to return an error array like the helpfile describes:

Failure: Array of 1 item set to 0

.

?

so already written scripts don't get broken ?

Edano

 

Edit: forget my request ;) i just realized that it already does it. so it's fine.

Edited by Edano

[color=rgb(255,0,0);][font="'comic sans ms', cursive;"]FukuLeaks[/color][/font]

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...