![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Синхронизация двух ScrollBox [D6, WinXP]
Gurd © (2008-09-26 15:26:00)Есть два ScrollBox при изменении 1-го ScrollBar нужно автоматическое изменение 2-го, никак не пойму через что это реализовать, в событиях srollBox нет например onScroll. Подскажите через что это можно сделать.
Gurd (2008-09-29 12:53:00) [1]Спасибо, все работает
{RASkov} (2008-09-26 20:16:00) [2]Вот возможный вариант решения данной "проблемы":
procedure TForm1.NewWnd(var M: TMessage);
var OldPos: Integer;
begin
OldPos:=ScrollBox1.HorzScrollBar.Position;
OldWnd(M);
if (M.Msg<>WM_VSCROLL) and (M.Msg<>WM_HSCROLL)then Exit;
ScrollBox2.ScrollBy(OldPos - ScrollBox1.HorzScrollBar.Position, 0);
end;
OnCreate для формы тот же...
{RASkov} (2008-09-26 19:38:00) [3]Странно конечно.... в справке говорится, что если Visible=False, то можно программно управлять положением(Position).... Но что-то тут не так :)
Но при Visible=False и в ИО невозможно изменить Position....
Справка по TControlScrollBar
Gurd (2008-09-26 18:52:00) [4]Ок, спасибо Вам за помощь
{RASkov} (2008-09-26 18:46:00) [5]> [20] Gurd (26.09.08 18:35)
> назначил visible:= false
Я так и подумал :)
> Но вопрос появился, как сделать с visible:= false :) и возможно ли это
Наверное не получится или придется переписывать
procedure TScrollingWinControl.WMHScroll(var Message: TWMHScroll);
begin
if (Message.ScrollBar = 0) and FHorzScrollBar.Visible then
FHorzScrollBar.ScrollMessage(Message) else
inherited;
end;
Gurd (2008-09-26 18:35:00) [6]Заработало, проблема была в том что я скролу который надо двикать автоматически назначил visible:= false, когда поставил true заработало. Спасибо.
Но вопрос появился, как сделать с visible:= false :) и возможно ли это
{RASkov} (2008-09-26 18:25:00) [7]> [17] Gurd (26.09.08 18:23)
> я создал новый проект два скрола скопировал все точности
> и не работает.
А OnCreate Форме сделал? Т.е. добавил данный обработчик?
{RASkov} (2008-09-26 18:24:00) [8]> [15] Gurd (26.09.08 18:11)
Что не то? :) Справка "не катит"?)
Gurd (2008-09-26 18:23:00) [9]
> > ScrollBox2.perform(M.Msg, M.wParam, M.Lparam); равняется
> 0
>
> Из справки:
> Return Values
> If an application processes this message, it should return
> zero.
Спасибо, теперь ясно почему ноль :), но не работает и все, я создал новый проект два скрола скопировал все точности и не работает.
Как можно проверить какое сообщение посылает ScrollBox1? Я просто не знаю, что и ковырять потому как вроде все очевидно, но не работает....
{RASkov} (2008-09-26 18:13:00) [10]> Из справки:
Справка по WM_H{V}SCROLL
Gurd (2008-09-26 18:11:00) [11]Нет, не то :(
{RASkov} (2008-09-26 18:11:00) [12]> [12] Gurd (26.09.08 17:49)
> ScrollBox2.perform(M.Msg, M.wParam, M.Lparam); равняется 0
Из справки:
Return Values
If an application processes this message, it should return zero.
Перевод:
Возвращаемые значения
Если заявление обрабатывает это сообщение, оно должно возвратить ноль.
> [12] Gurd (26.09.08 17:49)
Что-то не правильно сделал, вот и н6е работает. Я попробывал у меня все ОК.
Vlad Oshin (2008-09-26 17:53:00) [13]
> ScrollBox2.perform(M.Msg, M.wParam, M.Lparam);
попробуй
SendMessage(ScrollBox2.handle,...
хотя они вроде и одинаковы.. но вдруг
Gurd (2008-09-26 17:49:00) [14]
> {RASkov} © (26.09.08 16:17) [6]
>
> Попробуй как-нибудь так:
> ....
> private
> OldWnd: TWndMethod;
> procedure NewWnd(var M: TMessage);
> end;
> .................
>
> На создании формы:
> begin
> OldWnd:=ScrollBox1.WindowProc;
> ScrollBox1.WindowProc:=NewWnd;
> .......
> end;
>
> procedure TForm.NewWnd(var M: TMessage);
> begin
> OldWnd(M);
> if (M.Msg<>WM_VSCROLL) and (M.Msg<>WM_HSCROLL)then Exit;
>
> ScrollBox2.perform(M.Msg, M.wParam, M.Lparam);
> end;
Что то ни как не получается в этом примере у меня значение
ScrollBox2.perform(M.Msg, M.wParam, M.Lparam); равняется 0 и ни как не изменяется, прошу помощи, не могу разобраться
KSergey (2008-09-26 17:15:00) [15]В общем-то действительно бывают интерфейсы, где это вполне логично в использовании. Тот же Araxis Merge, например.
Gurd (2008-09-26 16:30:00) [16]
> Сергей М. © (26.09.08 16:21) [7]
>
> А зачем, собссно, потребовались два контрола ?
на форме два контрола, верхний не прокручивается ни гориз. , не верт., сам, а нижний прокручивается вертикально сам по себе, а горизонт. вместе с верхом, т.е. своеобразная шапка и верхнего контрола
Gurd (2008-09-26 16:24:00) [17]Спасибо сейчас попробую, кстати нашел статью может кому пригодиться
Как перехватить сообщения прокрутки в TScrollBox?
Следующий пример перехватывает сообщения о прокрутке компонента TScrollBox и
синхронизирует обе линейки прокрутки. Сообщения прокрутки перехватываются с помощью
переопределения окнной процедуры (WinProc) ScrollBox'а.
type
{$IFDEF WIN32}
WParameter = LongInt;
{$ELSE}
WParameter = Word;
{$ENDIF}
LParameter = LongInt;
{Declare a variable to hold the window procedure we are replacing}
var
OldWindowProc : Pointer;
function NewWindowProc(WindowHandle : hWnd;
TheMessage : WParameter;
ParamW : WParameter;
ParamL : LParameter) : LongInt
{$IFDEF WIN32} stdcall; {$ELSE} ; export; {$ENDIF}
var
TheRangeMin : integer;
TheRangeMax : integer;
TheRange : integer;
begin
if TheMessage = WM_VSCROLL then
begin
{Get the min and max range of the horizontal scroll box}
GetScrollRange(WindowHandle, SB_HORZ, TheRangeMin, TheRangeMax);
{Get the vertical scroll box position}
TheRange := GetScrollPos(WindowHandle, SB_VERT);
{Make sure we wont exceed the range}
if TheRange < TheRangeMin then
TheRange := TheRangeMin else
if TheRange > TheRangeMax then
TheRange := TheRangeMax;
{Set the horizontal scroll bar}
SetScrollPos(WindowHandle, SB_HORZ, TheRange, true);
end;
if TheMessage = WM_HSCROLL then
begin
{Get the min and max range of the horizontal scroll box}
GetScrollRange(WindowHandle, SB_VERT, heRangeMin, TheRangeMax);
{Get the horizontal scroll box position}
TheRange := GetScrollPos(WindowHandle, SB_HORZ);
{Make sure we wont exceed the range}
if TheRange < TheRangeMin then
TheRange := TheRangeMin
else
if TheRange > TheRangeMax then
TheRange := TheRangeMax;
{Set the vertical scroll bar}
SetScrollPos(WindowHandle, SB_VERT, TheRange, true);
end;
{Call the old Window procedure to allow processing of the message.}
NewWindowProc := CallWindowProc(OldWindowProc, WindowHandle, TheMessage,
ParamW, ParamL);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
{Set the new window procedure for the control and remember
the old window procedure.}
OldWindowProc := Pointer(SetWindowLong(ScrollBox1.Handle, GWL_WNDPROC,
LongInt(@NewWindowProc)));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
{Set the window procedure back to the old window procedure.}
SetWindowLong(ScrollBox1.Handle, GWL_WNDPROC, LongInt(OldWindowProc));
Vlad Oshin (2008-09-26 16:21:00) [18]public
{ Public declarations }
OldWindowProc: TWndMethod;
procedure NewWindowProc(var Message: TMessage);
...
procedure TForm1.FormCreate(Sender: TObject);
begin
OldWindowProc:= ScrollBox1.WindowProc;
ScrollBox1.WindowProc:= NewWindowProc;
end;
procedure TForm1.NewWindowProc(var Message: TMessage);
begin
case Message.Msg of
276: StaticText1.Caption:= 'Horz Scroll';
277: StaticText1.Caption:= 'Vert Scroll';
end;
OldWindowProc(Message);
end;
Сергей М. (2008-09-26 16:21:00) [19]А зачем, собссно, потребовались два контрола ?
{RASkov} (2008-09-26 16:17:00) [20]> [4] Gurd (26.09.08 16:10)
> Или может я не правильно изложил задачу?
Скорее всего накопипастили "решений".... Есть и TScrollB oxи TScrollB ar.... Ужас :)
Попробуй как-нибудь так:
....
private
OldWnd: TWndMethod;
procedure NewWnd(var M: TMessage);
end;
.................
На создании формы:
begin
OldWnd:=ScrollBox1.WindowProc;
ScrollBox1.WindowProc:=NewWnd;
.......
end;
procedure TForm.NewWnd(var M: TMessage);
begin
OldWnd(M);
if (M.Msg<>WM_VSCROLL) and (M.Msg<>WM_HSCROLL)then Exit;
ScrollBox2.perform(M.Msg, M.wParam, M.Lparam);
end;