jamirokwai wrote:as the snippet above is not Unicode-safe, I added a compiler-directive:
You are right: my code example above does not work if you compile a
Unicode program by selecting "Compiler/Compiler Options..." in the IDE
menu and enable "Create unicode executable". The explanation is simple:
The tags are always 4 characters which are stored in ASCII mode as a long
integer (4 Bytes). Due to the little-endian format in which Intel processors
store values in memory, the characters are stored in reversed order:
Code: Select all
PropertyCreator.L = 'PURE'
Debug PeekS(@PropertyCreator, 4) ; Displays "ERUP"
When trying to compile the above code (or my previous code example) with
the option "Create unicode executable" you obtain this error message:
PureBasic wrote:Line 1: Overflow error: a 'long' value (.l) must be between
-2147483648 and +4294967295.
In unicode mode each character takes two bytes, so 4x2 are 8 bytes which
don't fit into a long integer (4 bytes). If you declare PropertyCreator as a
quad value (PropertyCreator.Q) then the above code snippet will again work
correctly. But the utilized API functions await long integers, so this is no
solution. Therefore jamirokwai's approach is the correct one if you need
code that has to work in ASCII and Unicode mode: instead of using a string
of 4 characters simply use the resulting long integer value. And you even
don't need to work with CompilerIf because the usage of a long integer
works in ASCII and Unicode mode.
I therefore adapted my previous code example in this way and as a further
goodie added the possibility to switch the current word wrap mode during
runtime:
Code: Select all
; ----- Works in ASCII and Unicode mode!
ImportC ""
GetControlProperty(ControlRef, PropertyCreator, PropertyTag, BufferSize, *ActualSize, *PropertyBuffer)
TXNGetTXNObjectControls(TXNObject, ArrayItemCount, ControlTagsArray, ControlDataArray)
TXNSetTXNObjectControls(TXNObject, ClearAll, ArrayItemCount, ControlTagsArray, ControlDataArray)
EndImport
#kTXNWordWrapStateTag = 2004316787 ; 'wwrs'
Procedure ToggleWordWrapMode(EditorGadgetID)
Protected ControlRef
Protected TXNObject
Protected PropertyCreator = 1347768901 ; 'PURE'
Protected PropertyTag = 1415073602 ; 'TXOB'
Dim ControlTag(0)
Dim ControlData(0)
ControlRef = GadgetID(EditorGadgetID)
ControlTag(0) = #kTXNWordWrapStateTag
If GetControlProperty(GadgetID(EditorGadgetID), PropertyCreator, PropertyTag, 4, 0, @TXNObject) = 0
If TXNGetTXNObjectControls(TXNObject, 1, @ControlTag(0), @ControlData(0)) = 0
ControlData(0) ! 1
TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
EndIf
EndIf
EndProcedure
OpenWindow(0, 200, 100, 450, 100, "MacOS X Word Wrap Test", #PB_Window_SystemMenu)
EditorGadget(0, 10, 10, 430, 55)
ButtonGadget(1, 160, 70, 140, 20, "Toggle Word Wrap")
For i = 1 To 5
Text$ = Text$ + "This is a word wrap test - "
Next i
SetGadgetText(0, Text$)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventGadget() = 1
ToggleWordWrapMode(0)
EndIf
EndSelect
ForEver
For those using jamirokwai's above posted procedure in his previous posting:
The procedure won't work until you insert the following import statements
into your code
Code: Select all
ImportC ""
GetControlProperty(Control, PropertyCreator, PropertyTag, BufferSize, *ActualSize, *PropertyBuffer)
TXNSetTXNObjectControls(TXNObject, ClearAll, ControlCount, ControlTags, ControlData)
EndImport