2004. április 8., csütörtök
How to detect if a TMemo has been scrolled
Problem/Question/Abstract:
Is there a way of finding out - during or immediately after the fact - that a control has been scrolled? For instance, say someone moves the scroll thumb in a TMemo. Is there a message I can intercept that says this occurred? I don't really need to know which direction or by how much, just that it happened.
Answer:
Here's unit that shows one way to do this without having to create a descendent. It will let you know about "direct" scrolls, but not about scrolls that happen because of cursor movement through the memo's text, etc. It will also report a scroll if the user merely clicked on the thumb track without moving it (without actually scrolling).
To see the code in action, you will need to fill a TMemo with enough text so that it is necessary to scroll.
unit ScrollCatchU;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
ClearButton: TButton;
ScrolledLabel: TLabel;
procedure FormCreate(Sender: TObject);
procedure ClearButtonClick(Sender: TObject);
private
Counter: cardinal;
procedure Memo1ScrollCatcher(var Message: TMessage);
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
type
TMyControl = class(TControl);
procedure TForm1.Memo1ScrollCatcher(var Message: TMessage);
begin
Inc(Counter); {for testing/ diagnostics only ...}
{Add commented out section below, if you only want the "last" scroll
message in a sequence}
if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL))
{ and (TWMVScroll(Message).ScrollCode = SB_ENDSCROLL) }then
ScrolledLabel.caption := 'Scrolled';
{ caption := format('Message: %d ScrollCode: %d Counter: %d', [Message.Msg,
TWMVScroll(Message).ScrollCode, Counter]); }
TMyControl(Memo1).WndProc(Message);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.WindowProc := Memo1ScrollCatcher;
Counter := 0;
ClearButtonClick(nil);
end;
procedure TForm1.ClearButtonClick(Sender: TObject);
begin
ScrolledLabel.Caption := '';
{Using a manual "reset" for the "Scrolled" display}
end;
end.
This technique can be used with any TControl descendent.
You might want to add the Windows Mouse Wheel message to the ones that routine is looking for. Something like:
{ ... }
if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL)
or (Message.Msg = WM_MOUSEWHEEL))
{and (TWMVScroll(Message).ScrollCode = SB_ENDSCROLL)}then
ScrolledLabel.caption := 'Scrolled';
{ ... }
Of course, if you are just fishing for the SB_ENDSCROLL ScrollCode with the other messages, you'll have to separate the test for this message out a little further.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése