Modify

Opened 12 years ago

Closed 12 years ago

#2326 closed Bug (Fixed)

Cancel not detected in _WinAPI_GetSaveFileName()

Reported by: KaFu Owned by: Jpm
Milestone: 3.3.9.5 Component: Standard UDFs
Version: 3.3.8.1 Severity: None
Keywords: Cc:

Description

Cancel is not detected in _WinAPI_GetSaveFileName() because the results of the GetSaveFileNameW call are not evaluated. See attached corrected version example ("Correction 1" & "Correction 2")

#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

Change History (2)

comment:1 Changed 12 years ago by Jpm

In fact as string cannot be return in @extended

	Local $aRes = DllCall("comdlg32.dll", "bool", "GetSaveFileNameW", "struct*", $tOFN) ; Correction #1 - Added "Local $aRes ="
	If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, $aFiles) ; Correction 2

It will leave the caller script the decisio to call to_WinAPI_CommDlgExtendedError() as your reproscript is doing.

THe @error is also modified to allow checking only non zero @error if error occured

Last edited 12 years ago by Jpm (previous) (diff)

comment:2 Changed 12 years ago by Jpm

  • Milestone set to 3.3.9.5
  • Owner set to Jpm
  • Resolution set to Fixed
  • Status changed from new to closed

Fixed by revision [7686] in version: 3.3.9.5

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.