I have run up against 2 problems when pasting into a RichEdit control
via the PasteFromClipboard method. Firstly, it almost always causes the
text from the clipboard to be pasted twice and, secondly, it often
causes a Carriage Return (CR) and Line Feed (LF) to be appended to each
of these where no CR or LF existed in original the clipboard text.
Thankyou in advance
Chris Bargh
Hi Chris,
Regarding duplicate pasting - well 'PasteFromClipboard' is so
straightforward in implementation that I can't help thinking you must have
some other code associated with it. Can we see it?
With regard to the CR + LF - I hadn't noticed it before (or possibly I had
but didn't regard it as an issue) but on checking this out I see that it
occurs where there is a trailing space in the clipboard data and 'Plain
Text' is set false.
Whether this is a feature, a quirk or a bug is a moot point but I didn't
find it occurring in a memo.
--
Regards
Chris Luck
ch...@bvhg.freeserve.co.uk
Many thanks for looking at the problem. Your ideas inspired me to look
in some other directions. This has thrown further light on the problems.
Firstly, further analysis has shown the "dual-paste" problem to be
unrelated to the "appended CRLF" problem. I can now reliably cause each
problem independently.
The dual-paste problem only occurs if I invoke the PasteFromClipboard
method by pressing the Ctrl-V key combination, with the handler code
being as follows:
procedure TfrmDetailsDialog.richeditDetailsEditKeyUp(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
if Shift = [ssCtrl] then
case Key of
Word('a'),Word('A'): richeditDetailsEdit.SelectAll;
Word('x'),Word('X'): richeditDetailsEdit.CutToClipboard;
Word('c'),Word('C'): richeditDetailsEdit.CopyToClipboard;
Word('v'),Word('V'): richeditDetailsEdit.PasteFromClipboard;
end;
end;
It does not happen if I invoke the PasteFromClipboard method from a
right-click popup menu item, whose handler code is as follows:
procedure TfrmDetailsDialog.popupmenuPasteClick(Sender: TObject);
begin
richeditDetailsEdit.PasteFromClipboard;
end;
In the first (KeyUp) handler I put a breakpoint on the
PasteFromClipboard function call. This did not alter the dual-paste
behaviour but did show that the handler (and function call) only ever
get invoked once.
So I have a solution to the problem but bo idea why the first handler
does not work correctly.
As to the "appended CRLF" problem, this occurs if I do a SelectAll on
the RichEdit field or hold down the Shift key and press the End key. In
both cases the selection appears to go one character beyond the last
character that I actually typed in. If I Cut or Copy this to the
clipboard and then Paste into Notepad all appears fine (ie. no extra
characters, spaces or CRLFs) but when I paste into WordPad I find that a
CRLF has been mysteriously appended to the text I typed in the RichEdit
control. (In this application no CRs or LFs are permitted in this field
- long lines just wrap.) When I paste back into my RichEdit field by
either of the methods above the appended CRLF gets pasted as well (twice
in the 1st case). So it seems that no trailing space was involved.
I did look in the VCL source - in ComCtrls - but could not find the code
that you mentioned, I must have been looking in the wrong place, perhaps
you could tell me where I should be looking.
I also tried the following change to the 2nd handler but it made no
difference to the appended CRLF problem (plus, text with font and colour
attributes, copied from WordPad, still get pasted into my field with
those attributes):
procedure TfrmDetailsDialog.popupmenuPasteClick(Sender: TObject);
begin
richeditDetailsEdit.PlainText := True;
richeditDetailsEdit.PasteFromClipboard;
richeditDetailsEdit.PlainText := False;
end;
If this helps you understand the problem better and you have time to
take a further look at these problems then thanks again.
Cheers
Chris Bargh
Aahhh... I see ...
>if Shift = [ssCtrl] then
>case Key of
>Word('a'),Word('A'): richeditDetailsEdit.SelectAll;
>Word('x'),Word('X'): richeditDetailsEdit.CutToClipboard;
>Word('c'),Word('C'): richeditDetailsEdit.CopyToClipboard;
>Word('v'),Word('V'): richeditDetailsEdit.PasteFromClipboard;
These keystrokes perfectly duplicate the built-in functionality of both
RichEdit and Memo. Since you don't follow your key processing with a Key :=
0 it gets passed on to the RichEdit which does it all again!
Delete the key code in its entirety and all, or at least the worst of it,
will be well.
VCL source, ComCtrls ??
No, my thoughts hadn't got that far - must be another thread.
>The dual-paste problem only occurs if I invoke the PasteFromClipboard
>method by pressing the Ctrl-V key combination, with the handler code
>being as follows:
>...
>
I think that you have this problem because Ctrl-V is a Windows default
paste shortcut and so paste is executed twise - once by you in
EditKeyUp and once by system.
HTH
ain
The solution involves NOT handling Ctrl-X, Ctrl-C or Ctrl-V keys myself
(I should have worked this out for myself earlier). Incidentally, I
tried setting Key := 0 at the end of the KeyUp handler but found that
this did not work because the RichEdit control's built-in Ctrl-V occurs
before the handler is called.
As to the "appended CRLF" problem, the RichEdit control stores lines as
a TStrings object which delimits these lines using CRLF pairs (which you
can see if you examine the object's Text property). So, the RichEdit
control puts this CRLF pair in for you whether you want it not. This
gets taken across into the clipboard during Copy or Cut, if the
selection includes it, and pasting just returns this. For my application
I now just filter these out again in the OnChange event handler.
Again, many thanks
Chris Bargh
Chris Luck wrote:
>
> Chris Bargh -
> >The dual-paste problem only occurs if I invoke the
> >PasteFromClipboard method by pressing the Ctrl-V key
> >combination, with the handler code being as follows:
>
> Aahhh... I see ...
>
> >if Shift = [ssCtrl] then
> >case Key of
> >Word('a'),Word('A'): richeditDetailsEdit.SelectAll;
> >Word('x'),Word('X'): richeditDetailsEdit.CutToClipboard;
> >Word('c'),Word('C'): richeditDetailsEdit.CopyToClipboard;
> >Word('v'),Word('V'): richeditDetailsEdit.PasteFromClipboard;
>
> These keystrokes perfectly duplicate the built-in functionality
> of both RichEdit and Memo. Since you don't follow your key
> processing with a Key := 0 it gets passed on to the RichEdit
> which does it all again!
>
> Delete the key code in its entirety and all, or at least the
> worst of it, will be well.
>
> VCL source, ComCtrls ??
> No, my thoughts hadn't got that far - must be another thread.
>
Chris, previously you wrote:
"With regard to the CR + LF - I hadn't noticed it before (or possibly I
had but didn't regard it as an issue) but on checking this out I see
that it occurs where there is a trailing space in the clipboard data and
'Plain Text' is set false. Whether this is a feature, a quirk or a bug
is a moot point but I didn't find it occurring in a memo."
Hence I thought the source of these comments was the VCL code (or was it
just observed behaviour) - perhaps you could enlighten me. Cheers CB.
You're too kind.
>AND understand the problems!
You've got further than me then!
>Incidentally, I tried setting Key := 0 at the end of the KeyUp handler >but
found that this did not work because the RichEdit control's >built-in Ctrl-V
occurs before the handler is called.
Life is full of little presumptions.
>For my application I now just filter these out again in the OnChange event
handler.
The one drawback of using OnChange is it fires at each char when typing
directly into the control.
>So, the RichEdit control puts this CRLF pair in for you whether you want it
not.
This, by the way, is not a feature of Borland but MicroSoft. TRichEdit just
taps into Riched32.dll in the Windows\System dir. Rename that and you lose
the RTF features in TRichEdit (though it still functions showing behaviour
like a TMemo).
The same CRLF funtionality is shown by Wordpad, which uses Riched20.dll, and
MSWord.
So, as you concluded, It comes down to a matter of formatting after pasting.
The Streams solution given by Mike Orriss and Jan Sprengers in the 'RichEdit
to RichEdit' thread in ObjectPascal NG are more controlled methods, but
whichever approach you use you'll want to consider what attributes the
pasted/copied text is to adopt. Do you want the original and copied text to
retain their individual TTextAttributes or should pasted text adopt the
default attribs?
>I see that it occurs where there is a trailing space in the clipboard data
..
Best observation when half asleep, looked different next day.
The PlainText property only affects saving and loading.
One last thought.
RichEdit1.Lines.BeginUpdate;
Try
{ process paste/copy and formatting }
Finally
RichEdit1.Lines.EndUpdate;
end;
Stops the control updating till it's all done.