Opened 9 years ago
Closed 9 years ago
#3087 closed Bug (Fixed)
UTF problem with _GUICtrlRichEdit_StreamFromFile in 3.3.14.0
Reported by: | mLipok | Owned by: | Jpm |
---|---|---|---|
Milestone: | 3.3.15.1 | Component: | Standard UDFs |
Version: | 3.3.15.0 | Severity: | None |
Keywords: | Cc: |
Description
Disscusion here:
https://www.autoitscript.com/forum/topic/173900-problem-with-_guictrlrichedit_streamfromfile-33140/
REPRO SCRIPT:
#include <GUIConstantsEx.au3> #include <GuiRichEdit.au3> #include <WindowsConstants.au3> Example() Func Example() Local $hGui, $iMsg, $idBtnNext, $iStep = 0, $idLblMsg, $hRichEdit $hGui = GUICreate("Example (" & StringTrimRight(@ScriptName, StringLen(".exe")) & ")", 320, 350, -1, -1) $hRichEdit = _GUICtrlRichEdit_Create($hGui, "This is a test.", 10, 10, 300, 220, _ BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL)) $idLblMsg = GUICtrlCreateLabel("", 10, 235, 300, 60) $idBtnNext = GUICtrlCreateButton("Next", 270, 310, 40, 30) GUISetState(@SW_SHOW) _GUICtrlRichEdit_StreamFromFile($hRichEdit, @ScriptDir & "\wzor.rtf") While True $iMsg = GUIGetMsg() Select Case $iMsg = $GUI_EVENT_CLOSE _GUICtrlRichEdit_Destroy($hRichEdit) ; needed unless script crashes ; GUIDelete() ; is OK too Exit EndSelect WEnd EndFunc ;==>Example
Please make some fix.
My proposal is to add new parameters for File enconding with default $FO_UTF8_NOBOM as it is default for new files in AutoIt 3.3.14.0+
Consider to make the relevant amendments also in:
_GUICtrlRichEdit_StreamToFile
Attachments (1)
Change History (7)
Changed 9 years ago by mLipok
comment:1 Changed 9 years ago by mLipok
comment:2 Changed 9 years ago by Jpm
Hi,
adding $FO_UTF8_NOBOM to your proposed repro script and using your proposed updated function lead to display Nothing
I supposed it was intended to display TEST as it appear when opening "wzor.rtf" with Office-Word
comment:3 Changed 9 years ago by mLipok
Yes. I see.
this was because $iFileEncoding should be used in two places, but I forget about:
$hFile = FileOpen($sFileSpec, $FO_READ + $iFileEncoding) ; reopen it at the start
I also check @error returning from _GUICtrlRichEdit_StreamFromFile()
and I always get 700
so I do deeper search:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb774302(v=vs.85).aspx
On output, the dwError member can contain a nonzero error code if an error occurred.
so this mean:
If $iError <> 0 Then SetError(700, $iError, False)
instead:
If $iError <> 1 Then SetError(700, $iError, False)
FINALLY:
Func _GUICtrlRichEdit_StreamFromFile($hWnd, $sFileSpec, $iFileEncoding = Default) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, False) Local $tEditStream = DllStructCreate($tagEDITSTREAM) DllStructSetData($tEditStream, "pfnCallback", DllCallbackGetPtr($__g_pGRC_StreamFromFileCallback)) Local $hFile If $iFileEncoding = Default Then $hFile = FileOpen($sFileSpec, $FO_READ) Else $hFile = FileOpen($sFileSpec, $FO_READ + $iFileEncoding) EndIf If $hFile = -1 Then Return SetError(1021, 0, False) Local $sBuf = FileRead($hFile, 5) FileClose($hFile) $hFile = FileOpen($sFileSpec, $FO_READ + $iFileEncoding) ; reopen it at the start DllStructSetData($tEditStream, "dwCookie", $hFile) ; -> Send handle to CallbackFunc Local $wParam = ($sBuf == "{\rtf" Or $sBuf == "{urtf") ? $SF_RTF : $SF_TEXT $wParam = BitOR($wParam, $SFF_SELECTION) If Not _GUICtrlRichEdit_IsTextSelected($hWnd) Then _GUICtrlRichEdit_SetText($hWnd, "") EndIf Local $iQchs = _SendMessage($hWnd, $EM_STREAMIN, $wParam, $tEditStream, 0, "wparam", "struct*") FileClose($hFile) Local $iError = DllStructGetData($tEditStream, "dwError") If $iError <> 0 Then SetError(700, $iError, False) If $iQchs = 0 Then If FileGetSize($sFileSpec) = 0 Then Return SetError(1022, 0, False) Return SetError(700, $iError, False) EndIf Return True EndFunc ;==>_GUICtrlRichEdit_StreamFromFile
comment:4 Changed 9 years ago by mLipok
btw.
Good in: _GUICtrlRichEdit_StreamToFile
If $iError <> 0 Then SetError(700, $iError, False)
but it should be:
If $iError <> 0 Then Return SetError(700, $iError, False)
and wrong in: _GUICtrlRichEdit_StreamFromVar
If $iError <> 1 Then Return SetError(700, $iError, False)
it als should be:
If $iError <> 0 Then Return SetError(700, $iError, False)
Finalizing:
in all this function there should be:
Local $iError = DllStructGetData($tEditStream, "dwError") If $iError <> 0 Then Return SetError(700, $iError, False)
Instead:
Local $iError = DllStructGetData($tEditStream, "dwError") If $iError <> 1 Then Return SetError(700, $iError, False)
comment:5 Changed 9 years ago by mLipok
and I think the last post:
all fixed functions:
; #FUNCTION# ==================================================================================================================== ; Authors........: Chris Haslam (c.haslam) ; Modified ......: mLipok ; =============================================================================================================================== Func _GUICtrlRichEdit_StreamFromFile($hWnd, $sFileSpec, $iFileEncoding = Default) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, False) Local $tEditStream = DllStructCreate($tagEDITSTREAM) DllStructSetData($tEditStream, "pfnCallback", DllCallbackGetPtr($__g_pGRC_StreamFromFileCallback)) Local $hFile If $iFileEncoding = Default Then $hFile = FileOpen($sFileSpec, $FO_READ) Else $hFile = FileOpen($sFileSpec, $FO_READ + $iFileEncoding) EndIf If $hFile = -1 Then Return SetError(1021, 0, False) Local $sBuf = FileRead($hFile, 5) FileClose($hFile) $hFile = FileOpen($sFileSpec, $FO_READ + $iFileEncoding) ; reopen it at the start DllStructSetData($tEditStream, "dwCookie", $hFile) ; -> Send handle to CallbackFunc Local $wParam = ($sBuf == "{\rtf" Or $sBuf == "{urtf") ? $SF_RTF : $SF_TEXT $wParam = BitOR($wParam, $SFF_SELECTION) If Not _GUICtrlRichEdit_IsTextSelected($hWnd) Then _GUICtrlRichEdit_SetText($hWnd, "") EndIf Local $iQchs = _SendMessage($hWnd, $EM_STREAMIN, $wParam, $tEditStream, 0, "wparam", "struct*") FileClose($hFile) Local $iError = DllStructGetData($tEditStream, "dwError") If $iError <> 0 Then Return SetError(700, $iError, False) If $iQchs = 0 Then If FileGetSize($sFileSpec) = 0 Then Return SetError(1022, 0, False) Return SetError(700, $iError, False) EndIf Return True EndFunc ;==>_GUICtrlRichEdit_StreamFromFile ; #FUNCTION# ==================================================================================================================== ; Authors........: Chris Haslam (c.haslam) ; Modified ......: mLipok ; =============================================================================================================================== Func _GUICtrlRichEdit_StreamFromVar($hWnd, $sVar) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, False) Local $tEditStream = DllStructCreate($tagEDITSTREAM) DllStructSetData($tEditStream, "pfnCallback", DllCallbackGetPtr($__g_pGRC_StreamFromVarCallback)) $__g_pGRC_sStreamVar = $sVar Local $s = StringLeft($sVar, 5) Local $wParam = ($s == "{\rtf" Or $s == "{urtf") ? $SF_RTF : $SF_TEXT $wParam = BitOR($wParam, $SFF_SELECTION) If Not _GUICtrlRichEdit_IsTextSelected($hWnd) Then _GUICtrlRichEdit_SetText($hWnd, "") EndIf _SendMessage($hWnd, $EM_STREAMIN, $wParam, $tEditStream, 0, "wparam", "struct*") Local $iError = DllStructGetData($tEditStream, "dwError") If $iError <> 0 Then Return SetError(700, $iError, False) Return True EndFunc ;==>_GUICtrlRichEdit_StreamFromVar ; #FUNCTION# ==================================================================================================================== ; Authors........: Chris Haslam (c.haslam) ; Modified ......: mLipok ; =============================================================================================================================== Func _GUICtrlRichEdit_StreamToFile($hWnd, $sFileSpec, $bIncludeCOM = True, $iOpts = 0, $iCodePage = 0, $iFileEncoding = Default) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, False) Local $wParam If StringRight($sFileSpec, 4) = ".rtf" Then $wParam = ($bIncludeCOM ? $SF_RTF : $SF_RTFNOOBJS) Else $wParam = ($bIncludeCOM ? $SF_TEXTIZED : $SF_TEXT) If BitAND($iOpts, $SFF_PLAINRTF) Then Return SetError(1041, 0, False) EndIf ; only opts are $SFF_PLAINRTF and $SF_UNICODE If BitAND($iOpts, BitNOT(BitOR($SFF_PLAINRTF, $SF_UNICODE))) Then Return SetError(1042, 0, False) If BitAND($iOpts, $SF_UNICODE) Then If Not BitAND($wParam, $SF_TEXT) Then Return SetError(1043, 0, False) EndIf If _GUICtrlRichEdit_IsTextSelected($hWnd) Then $wParam = BitOR($wParam, $SFF_SELECTION) $wParam = BitOR($wParam, $iOpts) If $iCodePage <> 0 Then $wParam = BitOR($wParam, $SF_USECODEPAGE, BitShift($iCodePage, -16)) EndIf Local $tEditStream = DllStructCreate($tagEDITSTREAM) DllStructSetData($tEditStream, "pfnCallback", DllCallbackGetPtr($__g_pGRC_StreamToFileCallback)) Local $hFile If $iFileEncoding = Default Then $hFile = FileOpen($sFileSpec, $FO_OVERWRITE) Else $hFile = FileOpen($sFileSpec, $FO_OVERWRITE + $iFileEncoding) EndIf If $hFile = -1 Then Return SetError(102, 0, False) DllStructSetData($tEditStream, "dwCookie", $hFile) ; -> Send handle to CallbackFunc _SendMessage($hWnd, $EM_STREAMOUT, $wParam, $tEditStream, 0, "wparam", "struct*") FileClose($hFile) Local $iError = DllStructGetData($tEditStream, "dwError") If $iError <> 0 Then SetError(700, $iError, False) Return True EndFunc ;==>_GUICtrlRichEdit_StreamToFile ; #FUNCTION# ==================================================================================================================== ; Authors........: Chris Haslam (c.haslam) ; Modified ......: mLipok ; =============================================================================================================================== Func _GUICtrlRichEdit_StreamToVar($hWnd, $bRtf = True, $bIncludeCOM = True, $iOpts = 0, $iCodePage = 0) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, "") Local $wParam If $bRtf Then $wParam = ($bIncludeCOM ? $SF_RTF : $SF_RTFNOOBJS) Else $wParam = ($bIncludeCOM ? $SF_TEXTIZED : $SF_TEXT) If BitAND($iOpts, $SFF_PLAINRTF) Then Return SetError(1041, 0, "") EndIf ; only opts are $SFF_PLAINRTF and $SF_UNICODE If BitAND($iOpts, BitNOT(BitOR($SFF_PLAINRTF, $SF_UNICODE))) Then Return SetError(1042, 0, "") If BitAND($iOpts, $SF_UNICODE) Then If Not BitAND($wParam, $SF_TEXT) Then Return SetError(1043, 0, "") EndIf If _GUICtrlRichEdit_IsTextSelected($hWnd) Then $wParam = BitOR($wParam, $SFF_SELECTION) $wParam = BitOR($wParam, $iOpts) If $iCodePage <> 0 Then $wParam = BitOR($wParam, $SF_USECODEPAGE, BitShift($iCodePage, -16)) EndIf Local $tEditStream = DllStructCreate($tagEDITSTREAM) DllStructSetData($tEditStream, "pfnCallback", DllCallbackGetPtr($__g_pGRC_StreamToVarCallback)) $__g_pGRC_sStreamVar = "" _SendMessage($hWnd, $EM_STREAMOUT, $wParam, $tEditStream, 0, "wparam", "struct*") Local $iError = DllStructGetData($tEditStream, "dwError") If $iError <> 0 Then Return SetError(700, $iError, "") Return $__g_pGRC_sStreamVar EndFunc ;==>_GUICtrlRichEdit_StreamToVar
Just for copy/paste
comment:6 Changed 9 years ago by Jpm
- Milestone set to 3.3.15.1
- Owner set to Jpm
- Resolution set to Fixed
- Status changed from new to closed
Fixed by revision [11499] in version: 3.3.15.1
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.
Here are proposals: