The parent window for the richedit control on creation is the one that
receives notify messages, even after the parent has been changed using
SetParent.
Using the ITextHost interface allows this notification to be received
for windowless richedit controls. Windowed richedit conrols have an
ITextHost implementation that will fill in hwndFrom and idFrom, but
these should probably be initialized to 0 for windowless richedit
controls.
For some reason the code previously mixed up a selection cursor with the
result cursor. The problem seemed to have corrected itself before as a
result of conversion between offsets and cursors, but my recent changes
made this bug more severe.
The function was used in one place, and was simply a wrapper around a
call to ME_InsertRunAtCursor, so I removed it to avoids it use in other
parts of the code.
Previously the function was only used to move a single character in
either direction, so I made the function more general so that it could
be used in more places.
The test that succeeded from this change was as a result of allowing the
end of the character format change be specified using NULL as the rest
of the text. Before, the end paragraph run at the end of the text was
not being set for this case, when all the text was supposed to have its
character format changed.
Plenty of places in the code find following or preceding runs, then
afterwards find the paragraph from the run. This is inefficient because
the same linked list is used for both runs and paragraphs, so changes in
paragraphs can be detected while returning the next or previous run.
The code was previously getting the same text in the loop from the
editor, and it was converting each of the prefixes to compare against
for each URL candidate.
Before a single length was used for the number of characters to retrieve
from the text, and to keep track of the size of the buffer. These are
not equivalent, since there is a possible end of line conversion.
Previously the only convenient way to get the start and end of the
selection was through offsets, which eventually need to get converted
back into items in the linked list storing the text. The new function
will help with eliminating these inefficiencies.
This function will make it easier to work with ME_Cursor objects, which
should be used in a lot of places instead of character offsets (which
often require seeking through the linked lists to perform operations
with).
Since the table row start is inserted after the rest of the table is
inserted, the cursor is saved, and temporarily moved to the start of the
row to insert the table row start paragraph. Unfortunately the
paragraph in saved cursor becomes invalid during this insertion and
needs to be updated, so this code introduced a regression once
paragraphs started to be stored in cursors.
Style objects are referenced counted in richedit controls, so I tried to
make sure styles were released properly. This can be checked using with
the all_refs global reference count to see if everything is cleaned up.
Previously inserting the object didn't result in the text being wrapped,
which would cause an assertion error when this is checked for during
repainting the text. It is also important to invalidate the affected
areas of text, update the scrollbar, and end the creation of undo
transactions for this insertion.
The application AutoGK was getting the length of the text with
WM_GETTEXTLENGTH to allocate an appropriate buffer size, but then
claimed the buffer was twice the size when sending WM_GETTEXTEX. This
caused the memcpy call to overflow the actual buffer since the count
is based on the size of the buffer alone, regardless of the amount of
text retrieved.
ME_GetTextEx directly handles EM_GETTEXTEX, and previously a NULL buffer
would be dereferenced, and a 0 buffer length would cause nCount an
underflow in the nCount value which would allow a buffer overflow to
occur.