Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/26: Рейтинг темы: голосов - 26, средняя оценка - 4.62
 Аватар для Jamplane
4 / 4 / 1
Регистрация: 13.09.2013
Сообщений: 154

TScrollBar прокрутка колёсиком

26.02.2015, 14:18. Показов 5031. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Хочу реализовать прокрутку ScrollBar'a с помощью колёсика, нужно что-то вроде:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
  i: integer;
begin
  Handled := PtInRect(Image1.ClientRect, Image1.ScreenToClient(MousePos));
  if Handled then
    for i := 1 to Mouse.WheelScrollLines do
    try
      if WheelDelta > 0 then
        ScrollBar1.Perform(WM_HSCROLL, SB_LINERIGHT, 0)
      else
        ScrollBar1.Perform(WM_HSCROLL, SB_LINELEFT, 0);
    finally
      ScrollBar1.Perform(WM_HSCROLL, SB_ENDSCROLL, 0);
    end;
end;
Но не работает.
Perform вообще для ScrollBar'a не работает
Как сообщить ScrollBar'у, что нужно прокручиваться (чтобы сработал ивент OnScroll)?
Заменить OnScroll на OnChange и тупо изменять Position я не могу, т.к. ScrollCode для меня очень важен.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.02.2015, 14:18
Ответы с готовыми решениями:

Прокрутка колёсиком мышки
Здравствуйте. Не могу сообразить код, подскажите пожалуйста, На форме лежит три панельки в ряд, одна из них чёрная, две другие...

Прокрутка колёсиком в StringGrid
По умолчанию в стринггриде колёсико прокручивает "фокус" по ячейкам вверх-вниз. Можно ли сделать так, чтобы колесо не прокручивало...

Компоненты TScrollBar и TShape
Создайте проект, который при изменении положения бегунка полосы прокрутки отображает его позицию в метке.

10
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
26.02.2015, 15:15
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
type
  TScrollBar = class({Vcl.}StdCtrls.TScrollBar) // перед классом формы
  protected
    function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
      MousePos: TPoint): Boolean; override;
  end;
 
  TForm1 = class(TForm) // дальше без изменений...
 
// 
 
// и реализация:
implementation
 
{$R *.dfm}
 
{ TScrollBar }
function TScrollBar.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
  MousePos: TPoint): Boolean;
var
  NewScrollPos: Integer;
begin
  NewScrollPos := Position - WheelDelta;
  Scroll(scPosition, NewScrollPos);
  Position := NewScrollPos;
  Result := true;
end;
, теперь твои TScrollBar-ы будут прокручиваться и колесом мыши...
1
 Аватар для Jamplane
4 / 4 / 1
Регистрация: 13.09.2013
Сообщений: 154
26.02.2015, 15:42  [ТС]
volvo, большое спасибо! Но я что-то не могу понять, куда теперь DoMouseWheel этот пихать?
И ещё вопрос попутный: чем отличается
Delphi
1
TScrollBar = class(StdCtrls.TScrollBar)
от
Delphi
1
TScrollBar = class(TScrollBar)
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
26.02.2015, 15:47
Цитата Сообщение от Jamplane Посмотреть сообщение
куда теперь DoMouseWheel этот пихать?
Никуда. В момент прокрутки колеса он сам отработает, ты просто перекрыл стандартный функционал нужным тебе...
Цитата Сообщение от Jamplane Посмотреть сообщение
чем отличается
Тем, что первый случай - правильный (ты явно указываешь предка, который описан в одном из стандартных модулей, и программа компилируется), а второй - нет (Дельфи считает, что ты хочешь описать класс, который имеет предком самого себя и не позволяет этого).
1
 Аватар для Jamplane
4 / 4 / 1
Регистрация: 13.09.2013
Сообщений: 154
26.02.2015, 16:22  [ТС]
volvo, спасибо огромное, понял
А как сделать так, чтобы прокрутка срабатывала при нахождении курсора в определённой области (мне нужна клиентская область компонента TImage), а за её пределами не работала? (с вашим вариантом получается, что прокрутка начинает работать: 1) при получении ScrollBar'ом фокуса и 2) где бы ни находился курсор)

Я захотел сразу запихнуть PtInRect в DoMouseWheel, но понял, что на момент объявления этого метода ещё никакого Image'а нету. Да и как быть при отсутствии фокуса у ScrollBar'a? (допустим, нажал на кнопку на какой-то панельке, переместил курсор в рабочую область (Image) и прокрутка не работает, пока не ткнешь по ScrollBar'у)
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
26.02.2015, 17:34
Ну, активируй ScrollBar при нахождении мыши над изображением:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
type
  TScrollBar = class(Vcl.StdCtrls.TScrollBar)
    procedure SetActive(Value : Boolean);
  public
    FActive: Boolean;
    constructor Create(AOwner: TComponent); override;
    property Active : Boolean read FActive write SetActive;
  protected
    function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
      MousePos: TPoint): Boolean; override;
  end;
 
// ... 
 
{ TScrollBar }
constructor TScrollBar.Create(AOwner: TComponent);
begin
  inherited;
  Active := False;
end;
 
function TScrollBar.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
  MousePos: TPoint): Boolean;
var
  NewScrollPos: Integer;
begin
  if Active then
  begin
    NewScrollPos := Position - WheelDelta;
    Scroll(scPosition, NewScrollPos);
    Position := NewScrollPos;
    Result := true;
  end;
end;
 
procedure TScrollBar.SetActive(Value: Boolean);
begin
  FActive := Value;
  if Value then SetFocus;
end;
+
Delphi
1
2
3
4
5
6
7
8
9
procedure TForm1.Image1MouseEnter(Sender: TObject);
begin
  ScrollBar1.Active := True;
end;
 
procedure TForm1.Image1MouseLeave(Sender: TObject);
begin
  ScrollBar1.Active := False
end;
1
 Аватар для Jamplane
4 / 4 / 1
Регистрация: 13.09.2013
Сообщений: 154
26.02.2015, 19:05  [ТС]
volvo, спасибо, но как-то это не совсем правильно... не удобно для пользователя. фокус передавать ScrollBar'y. Это же снимает фокус с других компонентов. Вот например на нашем форуме: я сейчас набираю это сообщение в большом поле для ввода, но захотел вернуться к вашему посту чтобы кое-что уточнить - для этого я просто кручу колёсико, хотя фокус у меня на поле ввода, естественно. Код в вашем сообщении отображается не полностью, нужно прокручивать - я просто навожу курсор в это окошко с кодом и начинаю крутить колёсико (при этом фокус по прежнему на поле ввода, он не передаётся ScrollBar'y). У меня примерно такая же ситуация в программе. Забирать у пользователя фокус - не порядочно:)
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
26.02.2015, 21:08
Лучший ответ Сообщение было отмечено Jamplane как решение

Решение

Попробуй что-то вот в таком стиле:
Вложения
Тип файла: 7z VCL_703.7z (170.1 Кб, 34 просмотров)
1
 Аватар для Jamplane
4 / 4 / 1
Регистрация: 13.09.2013
Сообщений: 154
26.02.2015, 22:57  [ТС]
volvo, спасибо ОГРОМНОЕ! супер! Я 2 дня возился, пытался и так и сяк...
для меня Message - туман вообще (все эти wParam...lParam...)
не подскажите на эту тему что-нибудь почитать?
Вы добавили ScrollBar'у метод-обработчик сообщения WM_MOUSEWHEEL (к слову, можно было любое сообщение с одним параметром подставить?), а MakeLParam зачем? просто положенный фейк-параматр?
И ещё по коду вопрос: Performing - это чтобы сообщения не посылались быстрее, чем успевают выполнится?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
27.02.2015, 01:47
Цитата Сообщение от Jamplane Посмотреть сообщение
а MakeLParam зачем? просто положенный фейк-параматр?
Положенный параметр, почему фейк? Описание WM_MOUSEWHEEL говорит, что должно ему передаваться в WParam, а что - в LParam. Вот через MakeLParam и конструируется то, что нужно передать с этим сообщением.
Цитата Сообщение от Jamplane Посмотреть сообщение
Performing - это чтобы сообщения не посылались быстрее, чем успевают выполнится?
Да. По сути, этот флажок запрещает принимать новое сообщение во время обработки предыдущего. Если этого не сделать - программа моментально вылетит с переполнением стека.
Цитата Сообщение от Jamplane Посмотреть сообщение
на эту тему что-нибудь почитать?
Читать нужно, как устроена очередь сообщений Windows вообще, чтобы понять сам механизм работы с сообщениями.
1
 Аватар для Jamplane
4 / 4 / 1
Регистрация: 13.09.2013
Сообщений: 154
27.02.2015, 18:39  [ТС]
volvo, спасибо, буду разбираться!
про фейк я сказал потому, что X и Y в вашем обработчике в итоге не используется же, можно просто 0 передать. Или он как-то используется ещё системой, помимо этой процедуры-обработчика?
а чтобы WheelDelta нормально принималась, её нужно в старший байт wParam запихнуть, как раз тогда нужен
Delphi
1
MakeWParam(0,WheelDelta)
вы это специально, наверное, так оставили, чтобы я подумал и поразбирался?

P.S. в принципе вся фишка сообщений - именно в очереди? Кроме этого они ничем же не отличаются от обычных процедур?
P.S.S. а я могу создавать свои сообщения?

Добавлено через 24 минуты
Кстити, написал в обработчике сообщения:
Delphi
1
2
3
  for p := 0 to 100000 do begin
    Form1.Caption:=inttostr(p);
  end;
чтобы чётко видеть, выполняется ли новое сообщение, пока выполняется старое или нет.
Попробовал и с Perfoming, и без него. Не заметил никакой разницы: пока не закончится выполнение старого, новое не начинает выполнятся. Очереди никакой тоже нет: я могу 10 раз крутануть во время выполнения одного сообщения, но после завершения выполнится максимум ещё одно, а не 10, как следовало бы ожидать. Никаких ошибок не возникает. Может, delphi сама автоматически вставляет защиту от этой ошибки?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.02.2015, 18:39
Помогаю со студенческими работами здесь

TScrollBar и TListBox не могут одновременно работать!
Я создаю аудио-плеер для курсовой, основанный на звуковой библиотеке Bass.dll . Дело в том, что я написал код сперва для TScrollBar и он у...

TScrollBar - некорректное отслеживание позиции
Добрый день всем! Может кто сталкивался с компонентом ScrollBar в РАД студии? Вывожу значение скроллбара в лэйбл (при событии...

Управление TScrollBox через TScrollBar
Здраствуйте. У меня есть пара вопросов по TScrollBox и TScrollBar 1. Как узнать ваообще появилась ли прокурутка в TScrollBox 2. Так как...

Чему равна величина Sizeof(TscrollBar)
Вот такой вот вопрос.Чему равна величина Sizeof(TscrollBar) Добавлено через 12 секунд Как расчитать

Проблемы с колёсиком
На Вин ХР когда прокручуешь колёсико мыши то появлёеться странный курсор


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Чистый C и C++ в Qt Creator: ставим среду без VPN и настраиваем MinGW/CMake, без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru