Что такое код getscrollrange

Что такое код getscrollrange

Всем хорошего настроения!

Код: Выделить всё
procedure TForm1.StringGrid1MouseWheelDown(Sender: TObject;
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
StringGrid1.Perform(WM_VSCROLL, SB_PAGEDOWN, 0);
Handled := True;
end;

procedure TForm1.StringGrid1MouseWheelUp(Sender: TObject;
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
StringGrid1.Perform(WM_VSCROLL, SB_PAGEUP, 0);
Handled := True;
end;

Вышеприведённый код, постранично скролит StringGrid1.
Если скролить колёсиком мышки := всё чудесно работает.

ПРОБЛЕМА:
если потянуть за скролеер (а не крутить колёсиком мышки), то постраничное перелистывание сбивается.
Может сбиться на строчку, а может на пол строчки.
Как постранично скролить, перемещая grid за скроллер?

Добавлено спустя 88 минут 88 секунд:
Код: Выделить всё TScrollCode = (
// . Beware. The position of these enums must correspond to the SB_xxx
// values in LCLType (Delphi compatibility, not our decision)
// MWE: Don’t know it this still is a requirement
// afaik have I remeved all casts from the LCL
scLineUp, // = SB_LINEUP
scLineDown, // = SB_LINEDOWN
scPageUp, // = SB_PAGEUP
scPageDown, // = SB_PAGEDOWN
scPosition, // = SB_THUMBPOSITION
scTrack, // = SB_THUMBTRACK
scTop, // = SB_TOP
scBottom, // = SB_BOTTOM
scEndScroll // = SB_ENDSCROLL
);

Выше код из исходников лазаруса ( StdCtrls ). Возможность постраничного перелистывания туда заложена.
Но не могу понять: где мне задать ему TScrollCode := scPageUp and scPageDown, для пролистывания за скроллер ?

Заранее всем спасибо!

Re: StringGr > olegy123 » 22.12.2020 02:21:20

TScrollCode часть оконных сообщений WM_VSCROLL и WM_HSCROLL

var Mes: TWMScroll;
mes.Msg := WM_VSCROLL;
mes.ScrollCode := SB_Right;
mes.Pos := 0;
StringGrid1.Dispatch(mes);

ну и функции
GetScrollRange(StringGrid1.Handle,SB_VERT,vMin,vMax); возращает vMin,vMax значение;
vPos := GetScrollPos(StringGrid1.Handle,SB_VERT); — возращает vPos
SetScrollPos(StringGrid1.Handle,WM_VSCROLL, vPos, True); перейти на vPos

я точно не понял в чем проблема, но для гибкости проще преопределить сообщения:
procedure WMHScroll(var message : TLMHScroll); message LM_HSCROLL;
procedure WMVScroll(var message : TLMVScroll); message LM_VSCROLL;

Re: StringGr > vitaly_l » 22.12.2020 08:40:16

Если установить:
StringGrid1.Perform(WM_VSCROLL, SB_PAGEUP, 0);
StringGrid1.Perform(WM_VSCROLL, SB_PAGEDOWN, 0);
то при прокрутке КОЛЁСИКОМ, программа прокручивает грид ПОСТРАНИЧНО.

Однако, при скроллинге за скроллер, ПОСТРАНИЧНОЕ перемещение ломается и получается некрасиво
( обрезается пол строки, а страницы начинают «скакать» даже при скроллинге за колёсико, т.к. сбилось ПОСТРАНИЧНОЕ перемещение
из-за отсутствия в моём коде, команды, ПОСТРАНИЧНОГО перемещения за скроллер. При этом при перемещении КОЛЁСИКОМ — всё работает. ).

Как ПОСТРАНИЧНО скролить, перемещая grid за СКРОЛЛЕР?
PS: Точнее я уже написал костыль, который после перемещения ставит скроллер в нужное положение на onMouseEnter и всё работает. Как активировать системную функцию ПОСТРАНИЧНОГО перелистывания StringGrid за скроллер ?

Добавлено спустя 88 минут 88 секунд:
По сути нужно установить, у StringGrid: ШАГ ПЕРЕМЕЩЕНИЯ СКРОЛЛЕРА — равный одной странице.
Как это делается? ( Должна быть: какая-то системная команда, т.к. для колёсика она уже существует. )

Re: StringGr > olegy123 » 23.12.2020 22:17:34

Я не большой специалист по скролбарам, но примерах в системных окнах (TWinControl) скролбар не имеет шага. его поведения нужно предопределять
посмотрите на код в grids.pas где в классе TCustomGrid (TStringGrid -> TCustomStringGrid -> TCustomDrawGrid -> TCustomGrid) описана процедура обработки сигналов со скроллбаров
procedure WMVScroll(var message : TLMVScroll); message LM_VSCROLL;

там кстати есть обработка этих сообщений:
StringGrid1.Perform(WM_VSCROLL, SB_PAGEUP, 0);
StringGrid1.Perform(WM_VSCROLL, SB_PAGEDOWN, 0);

если не хотите создовать свой класс от TStringGrid с предопределенным ..message LM_VSCROLL;
можно решить задачу через TScrollBar, он имеет шаг ползунка (LargeChange/SmallChange).
Им можно сэмулировать системный ScrollBar -> StringGr >в событиях OnScroll у ScrollBar можно уже давать
либо позиционировать StringGrid на заданную строку (наверное TopRow?)
или использовать те же:
StringGrid.Perform(WM_VSCROLL, SB_PAGEUP, 0);
StringGrid1.Perform(WM_VSCROLL, SB_PAGEDOWN, 0);

Re: StringGr > vitaly_l » 23.12.2020 22:33:30

Вот именно что там есть. Да, верно оно там заложено. Но как его активировать?

Вы сами привели пример: GetScrollRange(StringGrid1.Handle,SB_VERT,vMin,vMax);
Из этого примера следует, что существует СИСТЕМНАЯ функция, которую нужно вызвать и заложить туда SB_PAGEUP и SB_PAGEDOWN.

Возможно кто-то уже сталкивался и\или знает ответ, вот я и спросил. Как перелистывать постранично за скроллер?

olegy123 писал(а): можно решить задачу через TScrollBar, он имеет шаг ползунка (LargeChange/SmallChange).
Им можно сэмулировать системный ScrollBar -> StringGr >

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

Илон Маск рекомендует:  Эффект разбитого текста

Re: StringGr > olegy123 » 23.12.2020 22:53:05

созданием своего компонента:

TMyStringGr >protected
procedure WMVScroll(var message : TLMVScroll); message LM_VSCROLL;
end;

procedure TMyStringGrid.WMVScroll(var message: TLMVScroll);
.
end;

— уже этого достаточно чтобы он умел правильно скролить.
можно разместить на панели контроллов и использовать везде где надо.
но надо зарегистрировать его.

Добавлено спустя 5 минут 4 секунды:

Re: StringGr > Лекс Айрин » 24.12.2020 10:43:36

А чем не устраивает щелчок не на модификаторе(кнопке), а на самом ползунке? Лично я так делаю даже чаще чем колесиком. Причем, это системное поведение.

CScrollbar SetScrollInfo не имеет никакого эффекта

У меня похожая проблема с этим: Как вы используете элементы управления MFC CScrollbar? но я понял, что мой ON_WM_VSCROLL сообщение отправляет параметр nPos всегда равен 0. Я думал, что я должен установить полосу прокрутки с SetScrollInfo метод или, по крайней мере, с SetScrollRange и я пытаюсь сделать это в PreCreateWindow() функции класса View (которая является производной от CFormView ).

Тем не менее, кажется, что полоса прокрутки не получает данные из SCROLLINFO состав.

Вот мои примеры кода:

Обработчик сообщений VSCROLL:

Поэтому я подозреваю, что я пытаюсь установить полосу прокрутки либо в неправильном месте, либо сделать что-то не так? Я ценю любую помощь.

Решение

PreCreateWindow вызывается до того, как окно (и его полоса прокрутки) были созданы. В классе представления вы должны выполнить инициализацию в OnInitialUpdate. Это вызывается после создания окна, но до того, как окно станет видимым.

Другие решения

я думаю что PreCreateWindow() слишком рано устанавливать полосу прокрутки, «правильное» место будет, когда ваш производный от CDocument класс загрузит / изменит данные, которые будут влиять на диапазон полосы прокрутки.

Прочитайте онлайн СПРАВОЧНИК ПО WinAPI | GetScrollRange

Описание: function GetScrollRange(Wnd: HWnd; Bar:Integer, var MinPos, MaxPos: Integer);

Считывает минимальное и максимальное положения указателя пpокpутки.

Паpаметpы:

Wnd: Окно, содеpжащее полосу пpокpутки.

Bar: Одна из констант sb_Ctl, sb_Horz, sb_Vert. См. pаздел «Константы полосы пpокpутки, sb_» в главе 1.

MinPos: Целое для пpиема минимального положения.

MaxPos: Целое для пpиема максимального положения. функция находится в файле user32.dll

Внимание!

Текст предназначен только для предварительного ознакомительного чтения.

Публикация данных материалов не преследует за собой никакой коммерческой выгоды.

Эта книга способствует профессиональному росту читателей и является рекламой бумажных изданий.

Все права на исходные материалы принадлежат соответствующим
организациям и частным лицам.

И снова — Скролбар

чисто внешне перемещение ползунка связывается с перемещением данных и первое что приходит в голову переместить ползунок, чтоб переместились данные. Но получается что ползунок вторичен, т.е. переместив данные переместим ползунок. Следовательно — необходимо и достаточно использовать SendMessage? если это так , то у меня это работает и значит вопрос снят.

единственное что не понятно — вычисление положения я не нашёл описания этого ни где. есть где почитать об этом?

а для полноты работы со скролом необходимо и SetScrollRange использовать. счас ширина длина ползунка меняется от его положения, что ни есть хорошо.

1мми GetScrollRange дает максимальное значение в конце 16 , в начале 216 (по вертикальному скролу)проверяю и устанавливаю максимальное значение по вертикальному ползункуGetScrollRange . Y. SetScrollRange . 10. GetScrollRange . Y. y не меняется

Диапазон и положение полос прокрутки

Каждая полоса прокрутки имеет соответствующий диапазон(range) – два целых числа, отражающих минимальное и максимальное значение, и положение(position) – местоположение бегунка внутри диапазона.По умолчанию, устанавливается следующий диапазон прокрутки – минимум 0 и максимум 100, но диапазон легко изменить на любое другое значение с помощью функции SetScrollRange (для полос прокрутки окна hWnd):

Параметр iBar равен либо SB_VERT, либо SB_HORZ, iNewMin и iNewMax являются минимальной и максимальной границами диапазона, а bRedraw устанавливается в TRUE, если необходимо, чтобы Windows перерисовала полосы в соответствии с новыми значениями.

Положение бегунка всегда дискретно. Например, полоса прокрутки с диапазоном от 0 до 4 имеет пять положений бегунка. Для установки нового положения бегунка можно использовать функцию SetScrollPos:

· Для определения текущего диапазона полосы прокрутки и текущего положения бегунка используются функции GetScrollRange и GetScrollPos.

Если приложение использует полосы прокрутки, то оно совместно с Windows берет на себя ответственность за поддержку полос прокрутки и обновлению положения бегунка.

Перечислимсферы ответственности Windows:

· Управление логикой работы мыши с полосой прокрутки.

· Обеспечение временной “инверсии цвета” при нажатии на кнопку мыши в полосе прокрутки.

· Перемещает бегунок в соответствие с тем, как внутри полосы прокрутки его перемещает пользователь.

· Отправляет сообщения полосы прокрутки в оконную процедуру для окна, содержащего полосу прокрутки.

Представим теперь сферы ответственности приложения по поддержке полос прокрутки:

· Инициализация диапазона полосы прокрутки.

· Обработка сообщений полосы прокрутки.

· Обновление положения бегунка полосы прокрутки.

Сообщения полос прокрутки

Windows посылает оконной процедуре сообщения WM_VSCROLL и WM_HSCROLL, когда на полосе прокрутки щелкают мышью или перетаскивают бегунок.

Илон Маск рекомендует:  Инструменты разработчика

Сразу отметим, что

При работе с оконными полосами прокрутки следует игнорировать параметр lParam, он используется только для полос прокрутки – элементов управления.Младшее слово параметра wParam этих сообщений – это число, показывающее, что мышь осуществляет какие-то действия на полосе прокрутки. Его значение соответствует определенным идентификаторам, которые начинаются на SB_:

int nScrollCode=(int)LOWORD(wParam); // произведенное действие

short int nPos=(short int)HIWORD(wParam); // текущая позиция

· Оконная процедура может получить сообщения с кодами типа SB_LINEUP, SB_PAGEUP, SB_LINEDOWN и SB_PAGEDOWN, если пользователь изменяет текущее положение на 1 положение или на 1 “страницу”(эти коды приходят с сообщениями как от вертикальной, так и от горизонтальной полос прокрутки).

· Сообщения с кодом SB_ENDSCROLL приходят, когда кнопка мыши отпущена. Как правило, приложение игнорируют такие сообщения.

· Если пользователь перемещает бегунок при помощи мыши, то сообщение от полосы прокрутки несет с собой в младшем слове параметра wParam код SB_THUMBTRACK (таких сообщений может быть слишком много!). Если затем пользователь отпускает клавишу мыши, то в оконную процедуру поступает сообщение с кодом SB_THUMBPOSITION.

· Если младшее слово параметра wParam равно SB_THUMBTRACK или SB_THUMBPOSITION, то в этих случаях старшее слово wParam определяет текущее положение полосы прокрутки. Во всех остальных случаях работы с полосой прокрутки старшее слово wParam можно игнорировать.

Замечание.Согласно документации, сообщения с кодами SB_TOP и SB_BOTTOM показывают, что полоса прокрутки переведена в свое максимальное или минимальное положение. Однако, если приложение самостоятельно не реализовывает интерфейс для работы с полосой прокрутки при помощи клавиатуры и не посылает само себе такие сообщения по мере необходимости, то тогда оно никогда его не получит от Windows.

Пример обработки сообщений от полосы прокрутки окна

Пусть создано окно hWnd с вертикальной линейкой прокрутки и затем для нее установлены диапазон и текущее положение бегунка:

static int min_sb=1,max_sb=100,pos_sb=20;

Рассмотрим фрагмент оконной функции созданного окна, демонстрирующий возможную обработку действий пользователя с вертикальной линейкой прокрутки:

// запоминаем предыдущую позицию бегунка

// lParam для оконных полос просмотра всегда равен NULL

int nScrollCode=(int)LOWORD(wParam); // произведенное действие

short int nPos=(short int)HIWORD(wParam); // текущая позиция

// изменеяем текущую позицию бегунка

case SB_PAGEDOWN: pos_sb+=10; break;

case SB_PAGEUP: pos_sb-=10; break;

case SB_LINEDOWN: pos_sb+=1; break;

case SB_LINEUP: pos_sb-=1; break;

case SB_THUMBPOSITION: pos_sb=nPos; break;

case SB_THUMBTRACK: pos_sb=nPos; break;

default: return 0l;

else if(pos_sb>max_sb) pos_sb=max_sb;

Различные метрики Windows

В программном интерфейсе Windows имеются функции, позволяющие получить информацию о размерах отдельных компонент Windows, таких, как ширина рамки окна, ширина и высота экрана и т.п. Эта информация нужна для определения габаритов и расположения создаваемых окон и других изображений.

Системные метрики

Метрики системных компонент Windows можно определить при помощи функции GetSystemMetrics.Единственный аргумент этой функции задает параметр, значение которого необходимо определить:

int GetSystemMetrics(int nIndex);

Для определения того или иного компонента в заголовочных файлах Windows имеются константы с префиксом SM_. Рассмотрим некоторые из них:

· SM_CXCURSOR — ширина курсора.

· SM_CXICON — ширина пиктограммы.

· SM_CXSCREEN — ширина экрана.

· SM_CYCAPTION — высота заголовка окна.

· SM_CYCURSOR — высота курсора.

· SM_CYICON — высота пиктограммы.

· SM_CYMENU — высота одной строки в полосе меню.

· SM_CYSCREEN — высота экрана.

· SM_CYHSCROLL – высота горизонтальной полосы прокрутки.

· SM_CXVSCROLL – ширина вертикальной полосы прокрутки.

Приведем пример определения высоты графического экрана:

GetScrollRange info Overview Group

The GetScrollRange function retrieves the current minimum and maximum scroll box (thumb) positions for the specified scroll bar.

The GetScrollRange function is provided for compatibility only. New applications should use the GetScrollInfo function.

BOOL GetScrollRange(

// handle of window with scroll bar

// address of variable that receives minimum position

// address of variable that receives maximum position

Parameters

hWnd Identifies a scroll bar control or a window with a standard scroll bar, depending on the value of the nBar parameter.
nBar Specifies the scroll bar from which the positions are retrieved. This parameter can be one of the following values:

Retrieves the positions of a scroll bar control. The hWnd parameter must be the handle of the scroll bar control.

Retrieves the positions of the window�s standard horizontal scroll bar.

Retrieves the positions of the window�s standard vertical scroll bar.

lpMinPos Points to the integer variable that receives the minimum position.
lpMaxPos Points to the integer variable that receives the maximum position.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError .

Remarks

If the specified window does not have standard scroll bars or is not a scroll bar control, the GetScrollRange function copies zero to the lpMinPos and lpMaxPos parameters.

The default range for a standard scroll bar is 0 through 100. The default range for a scroll bar control is empty (both values are zero).

The messages that indicate scroll bar position, WM_HSCROLL and WM_VSCROLL, are limited to 16 bits of position data. However, because SetScrollInfo , SetScrollPos , SetScrollRange , GetScrollInfo , GetScrollPos , and GetScrollRange support 32-bit scroll bar position data, there is a way to circumvent the 16-bit barrier of the WM_HSCROLL and WM_VSCROLL messages. See the GetScrollInfo function for a description of the technique.

Что такое код getscrollrange

1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

SetScrollRange

SetScrollRange функция устанавливает позицию минимального и максимального значения для указанного прокрутки.

Функция SetScrollRange предназначена для обеспечения обратной совместимости. Новые приложения должны использовать функцию SetScrollInfo.

Параметры

hWnd Дескриптор управления полосы прокрутки или окно со стандартным прокрутки, в зависимости от значения параметра nBar. nBar Указывает полосу прокрутки, чтобы установить. Этот параметр может принимать одно из следующих значений:

Значение Значение
SB_CTL Задает диапазон управления полосы прокрутки. HWnd параметр должен быть дескриптор управления полосы прокрутки.
SB_HORZ Задает диапазон окна стандартных горизонтальной полосы прокрутки.
SB_VERT Задает диапазон окна стандартных вертикальной полосы прокрутки.

nMinPos Определяет минимум прокрутки позиция. nMaxPos Указывает максимальный прокрутки позиция. bRedraw Определяет ли полосы прокрутки должны быть перерисованы для отражения изменений. Если этот параметр имеет значение TRUE, полоса прокрутки перерисовывается. Если FALSE, полоса прокрутки не перерисовывается.

Возвращаемые значения

Если функция выполнена успешно, возвращаемое значение не равно нулю.

Если вызов функции был неуспешен, возвращаемое значение равно нулю. Чтобы получить расширенные сведения об ошибке, вызовите GetLastError.

Примечания

Можно использовать SetScrollRange для скрыть полосу прокрутки параметра nMinPos и nMaxPos то же значение. Приложение не следует вызывать функцию SetScrollRange для скрыть полосу прокрутки при обработке сообщения панель прокрутки. Новые приложения должны использовать функцию ShowScrollBar для скрыть полосу прокрутки.

Если вызов SetScrollRange непосредственно следует вызов функции SetScrollPos , параметр bRedraw в SetScrollPos должно быть 0 для предотвращения полосу прокрутки дважды.

Диапазон по умолчанию для стандартных прокрутки — от 0 до 100. Диапазон по умолчанию на элементе управления полосы прокрутки является пустым (значения параметров nMinPos и nMaxPos равны нулю). Разница между значениями, определенных параметрами nMinPos и nMaxPos не должна быть больше, чем значение MAXLONG.

Так как сообщения, указывающие положение, WM_HSCROLL и WM_VSCROLL, ограничены до 16 бит данных, приложения, которые полагаются исключительно на эти сообщения для позиции данных имеют практический максимальное значение 65535 для параметра функции SetScrollRange nMaxPos.

Однако потому что SetScrollInfo, SetScrollPos, SetScrollRange, GetScrollInfo, GetScrollPosи GetScrollRange функции поддерживают 32-разрядных прокрутки бар позиции данных, есть способ обойти 32-16-разрядные барьер WM_HSCROLL и WM_VSCROLL сообщений. Смотрите описание техники GetScrollInfo.

Как отловить событие скроллирования TScrollBox’а?

Вот вопрос — как отловить событие скроллирования TScrollBox’а? В Delphi 7 это легко делалось на OnCanResize, а в новых Delphi почему-то не отрабатывается. Как быть?

А что, в новых делфях сообщения тоже не ловятся? Ловите в WindowProc мессагу WM_VSCROLL —

DRKB: 01226 —
Следующий пример перхватывает сообщения скроллирования в компоненте TScrollBox, тем самым синхронизируя два скролбара. Если один из скролбаров изменяет своё положение, то значение второго скролбара изменяется на такую же величину. Сообщения скролирования перехватываются путём сабклассинга оконной процедуры (WinProc) у скролбара.

Я сделал пока так:

Но все равно, надо еще код для колесика мышки писать. У меня просто в голове не умещается, зачем было отрубать традиционное поведение ScrollBox’а в новых Дельфях? Ведь все же хорошо работало!

PS. Спасибо за «базу знаний». Непременно изучу!

И снова — Скролбар

чисто внешне перемещение ползунка связывается с перемещением данных и первое что приходит в голову переместить ползунок, чтоб переместились данные. Но получается что ползунок вторичен, т.е. переместив данные переместим ползунок. Следовательно — необходимо и достаточно использовать SendMessage? если это так , то у меня это работает и значит вопрос снят.

единственное что не понятно — вычисление положения я не нашёл описания этого ни где. есть где почитать об этом?

а для полноты работы со скролом необходимо и SetScrollRange использовать. счас ширина длина ползунка меняется от его положения, что ни есть хорошо.

1мми GetScrollRange дает максимальное значение в конце 16 , в начале 216 (по вертикальному скролу)проверяю и устанавливаю максимальное значение по вертикальному ползункуGetScrollRange . Y. SetScrollRange . 10. GetScrollRange . Y. y не меняется

Илон Маск рекомендует:  Программа Crunch
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL