Modify

Opened 7 years ago

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

Attachments (0)

Change History (2)

comment:1 Changed 7 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 7 years ago by Jpm (previous) (diff)

comment:2 Changed 7 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

Modify Ticket

Action
as closed The owner will remain Jpm.
Author


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

 
Note: See TracTickets for help on using tickets.