Thanks rgb, that is a clean reproduction and I can confirm it is a bug in Objo, not in your code.
What is going on: in a Desktop project, assigning Text to a TextField is applied to the underlying control a moment later than a change to SelectionStart. When Me.SelectionStart = 5 runs, the field still holds its old (empty) text, so the position is clamped to 0, and then "Hello" arrives with the caret left at the start. SetFocus() is behaving correctly and is not part of the problem. The same ordering issue affects SearchField, and it is also why reading Me.Text immediately after assigning it can return the previous value. TextArea is not affected. It is not platform specific, so it behaves the same on macOS, Windows, and Linux.
I've logged it here: https://feedback.objo.dev/bug/1835
The fix is to apply Text immediately so that anything you do straight afterwards sees the new value. I will fix this in an upcoming release.
Workaround until then: move the caret placement into the FocusReceived event, which runs after the text has been applied:
Event Opening() # TextField1
Me.Text = "Hello"
Me.SetFocus()
End Event
Event FocusReceived() # TextField1
Me.SelectionStart = Me.Text.Length
End Event
Bear in mind that FocusReceived fires every time the field gains focus, so this will also move the caret to the end when you click or tab into the field. Treat it as a stopgap until the fix lands.