For simple tables cells are represented with tabs, and a table row is
ended at the end of the paragraph, so native richedit controls
substitute spaces for \tab and \par rich text format control words.
The values returned by EM_SETPARAFORMAT and EM_GETPARAFORMAT previously
indicated an error, and the included tests shows that Windows behaves as
documented.
The problem was that the paragraph format was being retrieved,
slightly modified and then used to set the paragraph format, without
limiting the mask to what was being set. The PFM_OFFSETINDENT mask flag
being valid meant that dxStartIndent specifies a relative offset, thus
dxStartIndent was doubled.
When the cursor is moved over the selection bar, without holding any
mouse buttons down, the cursor would be repeatably set between the
normal cursor, set by DefWindowProc for the WM_SETCURSOR message, and
the reversed cursor, set by ME_MouseMove.
I created a function to set the default paragraph format to ensure
consistency when this is done. This initial paragraph format is also
now more consistent with native richedit controls. The dwMask value
always appears to have the same value when retrieved from the native
richedit controls, so all the mask values are now initialized when the
PARAFORMAT2 structure is created.
The PARAFORMAT structure has a bit in wEffects to indicate whether the
paragraph is a table or not, so this should be used instead of a private
bTable value, since this structure can be retrieved with EM_GETPARAFORMAT.
The cursor should only be shown when there is no selection, since this
is how it is done in Windows. This patch avoids showing the cursor when
there is a selection, and destroys the cursor when a selection is made.
The caret's x position is stored in ME_TextEditor.nUDArrowX so that when
the caret is moved up or down, it will stay along the same horizontal
position, or at the end of a line. Unfortunately, the value stored in
nUDArrowX was being unconditionally discarded in ME_ArrowKey, preventing
it from serving its purpose.
Checks were added for hexadecimal values that did not have valid
characters, and for EOF received before the final closing brace of the
rich text stream. The error values were tested on richedit versions 1,
2, 3 & 4.1, and they were all the same for these cases.
Consecutively typed characters are grouped together to be undone
together. The grouping of typed characters can be stopped by certain
events that are mentioned in MSDN's remarks on the EM_STOPGROUPTYPING
message, which is also implemented by this patch.
Opening a text file with a NULL terminated character in it was causing
an assertion error after a run was being split due to word wrap.
Windows allows NULL terminated characters to be in the text.
The call to GetClientRect returns 0 values for the returned RECT when
called in WM_NCCREATE in on Windows, which ended up causing an assertion
error when Wine's riched20.dll replaces the native version. Moving the
call to WM_CREATE fixes this problem (probably because NCCALCSIZE is
called in between).
As text is inserted, the cursor is moved to the end, and then back to
offset 0. A reordering of operations prevents a WM_NOTIFY from being
sent on cursor being moved to the end, and another by being moved
back to the beginning. If the cursor was not at offset 0, then
exactly one WM_NOTIFY must be sent, for the movement from previous
position to the beginning. With tests to prove this change and the
previous one (modify flag should be off on WM_SETTEXT-caused
WM_NOTIFY).
EM_SETCHARFORMAT with wParam==0 sets default char format and does NOT set modify step flag.
EM_SETCHARFORMAT with wParam==SCF_SELECTION only sets modify step flag when selection is nonempty.
EM_GETMODIFY returns -1, not 1, when modify flag is set.
Tests for the above behavior.