i want to select a whole line in a Memo/RichEdit by doubleclicking
on it..insteand of selecting a word..(what normaly occurs when doubleclicking
somewhere in a line)
i found the below delphi code..but i wonder how can it be possible
that SelStart is using here BEFORE it gets declared..? is it normal in delphi..?
how could i translate the below snip into BCB code...?
/*******************************************/
procedure TfrmMain.Memo1Click(Sender: TObject);
var
Line: Integer;
begin
with (Sender as TMemo) do // is there something like "with" in BCB ?
begin
Line := Perform(EM_LINEFROMCHAR, SelStart, 0); // usage..
SelStart := Perform(EM_LINEINDEX, Line, 0); // decleration...
SelLength := Length(Lines[Line]); // whats this: Lines[Line] ? =
Memo->Lines->Strings[...] ?
end;
end;
/*******************************************/
Oren
> i found the below delphi code..but i wonder how can it
> be possible that SelStart is using here BEFORE it gets
> declared..?
SelStart is a property of TMemo. It is always available. The code is not
re-declaring it, it is using that very property. What you probably have
never come across before is the 'with' operator that the code is using.
That code is using the 'with' operator to simplify the coding. Everything
that is accessed inside the 'with' block is first checked for existance in
the TMemo, and if not found then looked for outside the 'with' block. In
this case, Perform(), SelStart, and SelLength are part of TMemo thus are
used from the TMemo, and Line is not a part of TMemo so it used from outside
the 'with' block.
> how could i translate the below snip into BCB code...?
void __fastcall TfrmMain::Memo1Click(TObject *Sender)
{
TMemo *pMemo = static_cast<TMemo*>(Sender);
int Line = pMemo->Perform(EM_LINEFROMCHAR, pMemo->SelStart, 0);
pMemo->SelStart = pMemo->Perform(EM_LINEINDEX, Line, 0);
pMemo->SelLength = pMemo->Lines->Strings[Line].Length();
}
However, I would suggest changing the last line to the following instead:
pMemo->SelLength = pMemo->Perform(EM_LINELENGTH, pMemo->SelStart, 0);
Gambit
Remy this works perfect for a Memo but how could it work in
a RichEdit ? DblClick is just NOT implemented there? or is it
implemented in later versions or doesn't it exist at all...?
Oren
> Remy this works perfect for a Memo but
> how could it work in a RichEdit ?
It works exactly the same for both without change.
> DblClick is just NOT implemented there?
Every TControl component has an OnDblClick event.
Gambit
/**********************/
OnChange
OnDragDrop
OnDragOver
OnEndDrag
OnEnter
OnExit
OnKeyDown
OnKeyPress
OnKeyUp
OnMouseDown
OnMouseMove
OnMouseUp
OnResizeRequest
OnSaveClipboard
OnSelectionChange
OnStartDrag
/**********************/
Where is here OnDblClick....?
Oren
> __published: void __fastcall RichEdit1DblClick(TObject *Sender);
> void __fastcall TfrmMainUnit::RichEdit1DblClick(TObject *Sender)
> it compiles without errors but when i doubleclicked somewhere in the line of
> RichEdit1 it selects ONLY a word NOT the whole line...
>
> what is wrong..?
You can write a thousend functions for your class but if no one calls them
they will not be executed.
You had to assign your eventhandles to an event. By code or with the
objectinspecter. But there is no OnCLick() or OnDblClick event for a TRichEdit.
It selects ONLY a word NOT the whole line... as that is what a TRichedit
usually does. And also now.
Hans.
And the object inspector shows them too.
> OnMouseDown
> Where is here OnDblClick....?
No OnCLick and not a OnDoubleClick.
So use OnMouseDown:
void __fastcall TForm4::RichEdit1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if ( Button == mbLeft && Shift.Contains ( ssDouble ) )
ShowMessage ( "Button == mbLeft && Shift.Contains ( ssDouble )" );
}
Hans.
> You can write a thousend functions for your class but if no one calls them
> they will not be executed.
No calling them ??? what do you think i'm doing here ???
void __fastcall TfrmMainUnit::RichEdit1DblClick(TObject *Sender)
{...
...
}
i'm calling the event that i've declared in the header..
please explain to me what you mean with calling, Hans...
> You had to assign your eventhandles to an event. By code or with the
> objectinspecter. But there is no OnCLick() or OnDblClick event for a
TRichEdit.
from Remy's post: "Every TControl component has an OnDblClick event."
isn't RichEdit derived from TControl.. ?
please explain me this: "But there is no OnCLick() or OnDblClick event for a
TRichEdit"
Oren
> No calling them ??? what do you think i'm doing here ???
>
> void __fastcall TfrmMainUnit::RichEdit1DblClick(TObject *Sender)
> {...
> ...
> }
You just wrote a function. You wrote the implementation/body for
a function.
> i'm calling the event that i've declared in the header..
Please show where you call it. You would call it if you had something
like:
void __fastcall TfrmMainUnit::Button1Click(TObject *Sender)
{
RichEdit1DblClick(NULL);
}
Here function RichEdit1DblClick() is called by Button1Click().
And Button1Click will be called in the code for TButton where
it was assigned to OnClick;
> please explain to me what you mean with calling, Hans...
I just did. But here another example:
int functionA ( void )
{
return 5;
}
int functionB ( void )
{
return functionA();
}
I wrote two functions. You can see that functionA is called by functionB.
Nowhere in the example functionB is called.
> please explain me this: "But there is no OnCLick() or OnDblClick event for a
> TRichEdit"
Why would I ? You have to take that as a fact. Moreover you had come to
the same conclusion already. So I do not understand your invitation.
Hans.
instead of Button1Click(...) i've putted it first into the form constructor..
BUT that gives me an EAccessViolation error...than i've putted it into
Button1Click(...) but also EAccessViolation ...
here's the whole code..
/************************************************/
__fastcall TfrmMainUnit::TfrmMainUnit(TComponent* Owner) : TForm(Owner)
{
RichEdit1DblClick(NULL);
}
void __fastcall TfrmMainUnit::Memo1DblClick(TObject *Sender)
{
TMemo *pMemo = static_cast<TMemo*>(Sender);
int Line = pMemo->Perform(EM_LINEFROMCHAR, pMemo->SelStart, 0);
pMemo->SelStart = pMemo->Perform(EM_LINEINDEX, Line, 0);
pMemo->SelLength = pMemo->Perform(EM_LINELENGTH, pMemo->SelStart, 0);
}
void __fastcall TfrmMainUnit::RichEdit1DblClick(TObject *Sender)
{
TRichEdit *re = static_cast<TRichEdit*>(Sender);
int Line = re->Perform(EM_LINEFROMCHAR, re->SelStart, 0);
re->SelStart = re->Perform(EM_LINEINDEX, Line, 0);
re->SelLength = re->Perform(EM_LINELENGTH, re->SelStart, 0);
}
/************************************************/
> I just did. But here another example:
>
> int functionA ( void )
> {
> return 5;
> }
>
> int functionB ( void )
> {
> return functionA();
> }
>
> I wrote two functions. You can see that functionA is called by functionB.
> Nowhere in the example functionB is called.
OK..i understand that i've need to call the DblClick(..) event function..but
WHERE ?
Oren
> here's the whole code..
> __fastcall TfrmMainUnit::TfrmMainUnit(TComponent* Owner) : TForm(Owner)
> {
> RichEdit1DblClick(NULL);
In the constructor it would be to early I think.
But you make the Sender parameter NULL. So you cannot cast that
to a TRichEdit. And if you try then you don't check for NULL.
The same here:
> void __fastcall TfrmMainUnit::Memo1DblClick(TObject *Sender)
> {
> TMemo *pMemo = static_cast<TMemo*>(Sender);
if ( ! pMemo )
return;
>
> void __fastcall TfrmMainUnit::RichEdit1DblClick(TObject *Sender)
> {
> TRichEdit *re = static_cast<TRichEdit*>(Sender);
TRichEdit *re = dynamic_cast<TRichEdit*>(Sender);
if ( ! re )
return;
> OK..i understand that i've need to call the DblClick(..) event function..but
> WHERE ?
I do not understand that it has to be called. And I cannot decide on that.
But if you want to call it you need to use a pointer to an instance of
a TRichEdit as Sender parameter. I.e.:
RichEdit1DblClick ( RichEdit1 );
Hans.
If you're able to consider a small change to your design, you might be
interested to know that you can select a whole line in a richedit control
by a fast TRIPLE click. And you get this behaviour without the need
for any coding. Doesn't happen the same way for a TMemo though.
AC
> If you're able to consider a small change to your design, you might be
> interested to know that you can select a whole line in a richedit control
> by a fast TRIPLE click. And you get this behaviour without the need
> for any coding.
You need a steady hand and a fast finger. This makes great fun.
Now did you discover what's behind the QUARTER click ?
Hans.
> instead of Button1Click(...) i've putted it first into the form
> constructor.. BUT that gives me an EAccessViolation error...
> than i've putted it into Button1Click(...) but also EAccessViolation ...
You are passing NULL as the Sender, but the event handler code expects a
valid Sender instead.
Gambit
No, I don't have good enough fine motor skills for that.
But I'll bet it's useful.
Adrian
> Hans Galema wrote:
>>Now did you discover what's behind the QUARTER click ?
>
>
> No, I don't have good enough fine motor skills for that.
> But I'll bet it's useful.
Anything you can think of.
But to not let you stand alone there: I did't even try.
Hans.