Modify

Opened 11 years ago

Closed 11 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 11 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
Version 0, edited 11 years ago by Jpm (next)

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