davegreen
asked on
Scrolling 2 Richedit controls in sync
I have 2 richedit controls. I want to scroll one of them in sync with the other... so that if I cursor up/down or scroll using the scroll bar, the other richedit scrolls with it. Anyone have any ideas for the best way to do this?
ASKER
Thanks for a quick response!
I am actually using two WPTools Richedits... have you got any example code to give me more of an idea what to do?
I am actually using two WPTools Richedits... have you got any example code to give me more of an idea what to do?
You are too quick Dave!
After dashing off that quick answer I decided to give it a go. I am very embarassed to say the initial approach I outlined does not appear to work. I also tried overriding the WM_NCHITTEST message and passing that along but again this didn't work.
You should reject my answer and allow other experts to answer it. My apologies.
Cheers,
Raymond.
After dashing off that quick answer I decided to give it a go. I am very embarassed to say the initial approach I outlined does not appear to work. I also tried overriding the WM_NCHITTEST message and passing that along but again this didn't work.
You should reject my answer and allow other experts to answer it. My apologies.
Cheers,
Raymond.
ASKER
Thanks Raymond,
Well in theory it seems easy to do..but I have yet to come p with a solution. Still its not a thing you need to do everyday.
Dave
Well in theory it seems easy to do..but I have yet to come p with a solution. Still its not a thing you need to do everyday.
Dave
Have you tried sending an EM_SCROLL message?
Dave, I wrote this (code below), which DOES work in terms of keeping them in sync when the user click on a scroll bar (I actually messed up the first attempt which is why it didn't work :-( )
Unfortunately this doesn't deal with the user arrowing down. Though I think this could be done with using EM_GETFIRSTVISIBLELINE and EM_SETFIRSTVISIBLELINE in the OnChange event (I havn't tried it out yet - I'll let you know how I go...)
I also tried EM_SCROLL (as Philipleighs suggested), but for some reason the control does not appear to be sent that message.
Cheers,
Raymond.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TMyRichEdit = class(TRichEdit)
protected
procedure OnWMHScroll(var Message : TMessage); message WM_HSCROLL;
procedure OnWMVScroll(var Message : TMessage); message WM_VSCROLL;
public
SyncWithRichEdit : TRichEdit;
end;
procedure Register;
implementation
{ TMyRichEdit }
procedure TMyRichEdit.OnWMHScroll(va r Message: TMessage);
begin
SendMessage(SyncWithRichEd it.Handle, WM_HSCROLL, Message.WParam, Message.LParam);
end;
procedure Register;
begin
RegisterComponents('Sample s', [TMyRichEdit]);
end;
procedure TMyRichEdit.OnWMVScroll(va r Message: TMessage);
begin
SendMessage(SyncWithRichEd it.Handle, WM_VSCROLL, Message.WParam, Message.LParam);
inherited;
end;
end.
Unfortunately this doesn't deal with the user arrowing down. Though I think this could be done with using EM_GETFIRSTVISIBLELINE and EM_SETFIRSTVISIBLELINE in the OnChange event (I havn't tried it out yet - I'll let you know how I go...)
I also tried EM_SCROLL (as Philipleighs suggested), but for some reason the control does not appear to be sent that message.
Cheers,
Raymond.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TMyRichEdit = class(TRichEdit)
protected
procedure OnWMHScroll(var Message : TMessage); message WM_HSCROLL;
procedure OnWMVScroll(var Message : TMessage); message WM_VSCROLL;
public
SyncWithRichEdit : TRichEdit;
end;
procedure Register;
implementation
{ TMyRichEdit }
procedure TMyRichEdit.OnWMHScroll(va
begin
SendMessage(SyncWithRichEd
end;
procedure Register;
begin
RegisterComponents('Sample
end;
procedure TMyRichEdit.OnWMVScroll(va
begin
SendMessage(SyncWithRichEd
inherited;
end;
end.
Except there isn't a EM_SETFIRSTVISIBLELINE so you can't do
RichEdit1.Perform(EM_SETFI RSTVISIBLE LINE,
Perform(EM_GETFIRSTVISIBLE LINE, 0, 0));
sigh.
Raymond.
RichEdit1.Perform(EM_SETFI
Perform(EM_GETFIRSTVISIBLE
sigh.
Raymond.
I tried this in the on change but jut moving the cursor does not generate an onchange...
Cheers,
Raymond
if Richedit1.Perform(EM_GETFI RSTVISIBLE LINE, 0, 0) >
MyRichEdit1.Perform(EM_GET FIRSTVISIB LELINE, 0, 0) then
MyRichEdit1.perform(em_scr oll, SB_LINEDOWN, 0)
else
MyRichEdit1.perform(em_scr oll, SB_LINEUP, 0);
Cheers,
Raymond
if Richedit1.Perform(EM_GETFI
MyRichEdit1.Perform(EM_GET
MyRichEdit1.perform(em_scr
else
MyRichEdit1.perform(em_scr
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Eureka! Here 'tis: A complete solution...
Cheers,
Raymond.
//************************ * Source for the TMyRichEdit component...
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TMyRichEdit = class(TRichEdit)
protected
procedure OnWMHScroll(var Message : TMessage); message WM_HSCROLL;
procedure OnWMVScroll(var Message : TMessage); message WM_VSCROLL;
procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
public
SyncWithRichEdit : TRichEdit;
end;
procedure Register;
implementation
uses
RichEdit;
{ TMyRichEdit }
procedure TMyRichEdit.OnWMHScroll(va r Message: TMessage);
begin
SendMessage(SyncWithRichEd it.Handle, WM_HSCROLL, Message.WParam, Message.LParam);
end;
procedure TMyRichEdit.OnWMVScroll(va r Message: TMessage);
begin
SendMessage(SyncWithRichEd it.Handle, WM_VSCROLL, Message.WParam, Message.LParam);
inherited;
end;
procedure TMyRichEdit.CNNotify(var Message: TWMNotify);
var
Diff : Integer;
c : integer;
begin
Inherited;
with Message do
case NMHdr^.code of
EN_SELCHANGE:
begin
Diff := SyncWithRichEdit.Perform(E M_GETFIRST VISIBLELIN E, 0, 0) -
Perform(EM_GETFIRSTVISIBLE LINE, 0, 0);
c := abs(diff);
while c > 0 do
begin
if diff < 0 then
SyncWithRichEdit.perform(e m_scroll, SB_LINEDOWN, 0)
else
SyncWithRichEdit.perform(e m_scroll, SB_LINEUP, 0);
dec(c);
end;
end;
end;
end;
procedure Register;
begin
RegisterComponents('Sample s', [TMyRichEdit]);
end;
end.
//************************ * Form to test it with - just put a TRichEdit and a TMyRichEdit on it
unit RicheditForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, Unit1;
type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
MyRichEdit1: TMyRichEdit;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
MyRichEdit1.SyncWithRichEd it := RichEdit1;
end;
Cheers,
Raymond.
//************************
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TMyRichEdit = class(TRichEdit)
protected
procedure OnWMHScroll(var Message : TMessage); message WM_HSCROLL;
procedure OnWMVScroll(var Message : TMessage); message WM_VSCROLL;
procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
public
SyncWithRichEdit : TRichEdit;
end;
procedure Register;
implementation
uses
RichEdit;
{ TMyRichEdit }
procedure TMyRichEdit.OnWMHScroll(va
begin
SendMessage(SyncWithRichEd
end;
procedure TMyRichEdit.OnWMVScroll(va
begin
SendMessage(SyncWithRichEd
inherited;
end;
procedure TMyRichEdit.CNNotify(var Message: TWMNotify);
var
Diff : Integer;
c : integer;
begin
Inherited;
with Message do
case NMHdr^.code of
EN_SELCHANGE:
begin
Diff := SyncWithRichEdit.Perform(E
Perform(EM_GETFIRSTVISIBLE
c := abs(diff);
while c > 0 do
begin
if diff < 0 then
SyncWithRichEdit.perform(e
else
SyncWithRichEdit.perform(e
dec(c);
end;
end;
end;
end;
procedure Register;
begin
RegisterComponents('Sample
end;
end.
//************************
unit RicheditForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, Unit1;
type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
MyRichEdit1: TMyRichEdit;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
MyRichEdit1.SyncWithRichEd
end;
ASKER
BRILLIANT!
Thank you Raymond...this looks a great solution.
Just when I thought there was not solution you found one..
Thanks again.
Dave
Thank you Raymond...this looks a great solution.
Just when I thought there was not solution you found one..
Thanks again.
Dave
Cheers,
Raymond.