Что такое код scrollwindow


ScrollWindow не перерисовывает область

Я последовал примеру в книге Чарльза Петцольда «Программирование Windows». Этот пример показывает сообщение клавиатуры, когда происходит событие клавиатуры. Он автоматически прокручивается, чтобы отобразить дисплей. Вот часть кода (с небольшой модификацией). Проблема в том, что: обычно, когда принимается сообщение клавиатуры, оно должно отображать 0 внизу. Когда получено другое сообщение с клавиатуры, оно прокручивается по строке, отображает 0 в нижней части и над дном, оно должно отображать 1. Но у меня есть то, что оно отображается всегда 0. Только когда я изменяю размер окна, я получаю правильный результат вроде. 4, 3, 2, 1, 0. Я думаю, проблема в том, что что-то не перекрашивается, когда оно называется ScrollWindow, но я не знаю, в чем именно проблема, поскольку я следил за книгой,

Весь смысл ScrollWindow() заключается в перемещении существующего содержимого окна без необходимости перекрашивать все. Основное предположение состоит в том, что перемещаемое содержимое не изменяется в результате действия прокрутки, и нужно раскрасить только «непокрытый» регион.

В вашем примере вы хотите изменить содержимое (путем перенумерации строк), а не просто переместить его. Это означает, что его нужно перерисовать — что ScrollWindow() в обработке ваших ключевых сообщений не вызывает, но InvalidateRect() в вашем обработчике WM_SIZE .

Как остановить UserControl (nee ScrollableControl) от вызова ScrollWindow?

13 Ian Boyd [2011-04-25 21:31:00]

.NET UserControl (который происходит от ScrollableControl ) имеет возможность отображать горизонтальные и вертикальные полосы прокрутки.

Вызывающий может установить видимость и диапазон этих горизонтальных и вертикальных полос прокрутки:

Примечание.. UserControl (т.е. ScrollableControl ) использует стандартный механизм Windows для указания стилей окна WS_HSCROLL и WS_VSCROLL , чтобы отобразить полосы прокрутки. То есть: они не создают отдельные элементы управления прокруткой Windows или .NET, позиционируя их в правом/нижнем углу окна. Windows имеет стандартный механизм для отображения одной или обеих полос прокрутки.

Если пользователь прокручивает элемент управления, UserControl отправляется сообщение WM_HSCROLL или WM_VSCROLL . В ответ на эти сообщения я хочу, чтобы ScrollableControl нарушал клиентскую область, что и произойдет в родной Win32:

Мне нужно, чтобы вся клиентская область была недействительной. Проблема заключается в том, что UserControl (т.е. ScrollableControl ) вызывает ScrollWindow Функция API:

Вместо запуска InvalidateRect на всем клиентском прямоугольнике ScrollableControl пытается «спасти» существующее содержимое в клиентской области. Например, пользователь прокручивает вверх, текущий клиентский контент помещается вниз на ScrollWindowEx , а затем только вновь открытая область становится недействительной, вызывая WM_PAINT :

На приведенной выше диаграмме область шахматной доски — это контент недействительный и должен быть окрашен во время следующего WM_PAINT.

В моем случае это нехорошо; верхняя часть моего элемента управления содержит «заголовок» (например, заголовки столбцов списка). Прокрутка этого содержимого ниже неверна:

и вызывает визуальное повреждение.

Я хочу, чтобы ScrollableControl не использовал ScrollWindowEx , но вместо этого просто сделал недействительным всю клиентскую область.

Я попытался переопределить OnScroll защищенный метод:

Но это вызывает двойную ничью.

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

  • двойная буферизация не должна использоваться в сеансе удаленного рабочего стола/терминала
  • это расточительство ресурсов ЦП.
  • Это не вопрос, который я задаю

я рассмотрел использование Control вместо UserControl (т.е. до ScrollableControl в цепочке наследования) и вручную добавить элемент управления HScroll или VScroll.NET — но это не желательно:

  • Windows уже обеспечивает стандартный поиск позиции полос прокрутки (это не тривиально дублировать)
  • Это много функциональности, которую нужно воспроизводить с нуля, когда я хочу только InvalidateRect, а не ScrollWindowEx

Так как я вижу и отправил код, внутренний для ScrollableControl , я знаю, что нет свойства отключить использование ScrollWindow , но существует ли свойство отключить использование ScrollWindow ?

Обновление:

Я попытался переопределить метод оскорбления и использовать рефлектор, чтобы украсть весь код:

Проблема заключается в том, что SetDisplayRectLocation читает и записывает в переменную частного члена ( displayRect ). Если Microsoft не изменит С#, чтобы позволить потомкам получить доступ к закрытым членам: я не могу этого сделать.

Обновить два

я понял, что копирование вставку ScrollableControl , исправление одной проблемы означает, что мне также придется скопировать-вставить всю цепочку наследования до UserControl

Я бы предпочел работать с объектно-ориентированным дизайном, а не против него.

Что такое код scrollwindow

The ScrollWindow function scrolls the contents of the specified window’s client area.

Syntax

Parameters

Handle to the window where the client area is to be scrolled.

Type: int

Specifies the amount, in device units, of horizontal scrolling. If the window being scrolled has the CS_OWNDC or CS_CLASSDC style, then this parameter uses logical units rather than device units. This parameter must be a negative value to scroll the content of the window to the left.

Type: int

Specifies the amount, in device units, of vertical scrolling. If the window being scrolled has the CS_OWNDC or CS_CLASSDC style, then this parameter uses logical units rather than device units. This parameter must be a negative value to scroll the content of the window up.

Pointer to the RECT structure specifying the portion of the client area to be scrolled. If this parameter is NULL, the entire client area is scrolled.

Pointer to the RECT structure containing the coordinates of the clipping rectangle. Only device bits within the clipping rectangle are affected. Bits scrolled from the outside of the rectangle to the inside are painted; bits scrolled from the inside of the rectangle to the outside are not painted.

Return value

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 caret is in the window being scrolled, ScrollWindow automatically hides the caret to prevent it from being erased and then restores the caret after the scrolling is finished. The caret position is adjusted accordingly.

The area uncovered by ScrollWindow is not repainted, but it is combined into the window’s update region. The application eventually receives a WM_PAINT message notifying it that the region must be repainted. To repaint the uncovered area at the same time the scrolling is in action, call the UpdateWindow function immediately after calling ScrollWindow.

If the lpRect parameter is NULL, the positions of any child windows in the window are offset by the amount specified by the XAmount and YAmount parameters; invalid (unpainted) areas in the window are also offset. ScrollWindow is faster when lpRect is NULL.

If lpRect is not NULL, the positions of child windows are not changed and invalid areas in the window are not offset. To prevent updating problems when lpRect is not NULL, call UpdateWindow to repaint the window before calling ScrollWindow.

Нужно ли использовать ScrollWindowEx / ScrollWindow / ScrollDC для прокрутки?

Я нахожусь в процессе реализации прокрутки пользовательского элемента управления редактированием, что я работаю. Что мне было интересно было, это необходимо использовать ScrollWindowEx / ScrollWindow / ScrollDC реализовать скроллинг? Я вижу, что ScrollWindowEx просто прокручивает область рисования. Все это хорошо, но так как мое управление редактированием реализует двойную буферизацию, я должен обновить BitBlt, а также. Это тривиальная вещь, но мне было интересно, если это необходимо. Если я использую только SetScrollInfo, что также будет иметь тот же эффект. Единственное преимущество, которое я вижу в том, что, когда пользователь прокручивает вверх или вниз, там уже был бы какой-нибудь текст там (потому что ScrollWindowEx сдвигает область клиента цель), и я бы не беспокоить aobut перекрашивать. Есть ли другие преимущества, или причина, почему ScrollWindowEx используется? Я новичок в прокрутке в win32,

Илон Маск рекомендует:  Что такое код puts

PS Просто чтобы быть ясно, я не использую MFC. Только Win32 API. Язык программирования: неуправляемый C ++

Вы можете осуществлять прокрутку любым способом, который вы хотите.

ScrollWindow и т.д. прокручивается соответствующей часть клиентской области и аннулируют ту часть, которая затем нуждается в перекраске.

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

Что такое код scrollwindow

87 просмотра

1 ответ

14 Репутация автора

Мой код показан ниже. Когда программа запущена, я сначала щелкаю правой кнопкой мыши, затем щелкаю левой кнопкой мыши. Результат показан как на первом рисунке. Согласно справочному документу ScrollWindow функции, если четвертый параметр NULL , вся клиентская область должна быть прокручена. Почему при x = 30 единицах устройства наблюдается разрыв в 10 пикселей?

Мне интересно, почему результат не показан как вторая картинка.

Ответы (1)

1 плюс

8212 Репутация автора

если четвертый параметр НЕДЕЙСТВИТЕЛЕН, вся область клиента должна быть прокручена.

Вы также указываете прямоугольник отсечения (5-й параметр), поэтому, конечно, прокручивается не вся клиентская область. Но на самом деле это не имеет отношения к проблеме.

Почему при x = 30 единицах устройства наблюдается разрыв в 10 пикселей?

Потому что вы не рисуете этот пробел, когда Windows говорит вам сделать это.

Область, открытая ScrollWindow, не перекрашивается, но объединяется в область обновления окна. В конечном итоге приложение получает сообщение WM_PAINT, уведомляющее его о том, что регион должен быть перекрашен.

Ваш WM_PAINT обработчик не делает ничего, кроме лжи Windows, проверяя область обновления.

Исправьте ваш код, выполнив все рисование только в WM_PAINT . При прокрутке WM_LBUTTONDOWN вам также придется увеличивать переменную, в которой хранится позиция прокрутки. Добавьте позицию прокрутки к координатам, которые вы передаете Ellipse() в WM_PAINT . Теперь вы должны получить результат, подобный 2-му изображению.

Я предлагаю найти хороший учебник по рисованию Win32 в целом, так как некоторые базовые знания здесь отсутствуют. Получите представление о том, что такое «область обновления» и как она взаимодействует с циклом рисования.

Thread: ScrollWindow()

Thread Tools
Search Thread
Display
  • Linear Mode
  • Switch to Hybrid Mode
  • Switch to Threaded Mode

ScrollWindow()

I have a few questions about this scroll bar example from Charles Petzold’s «Programming Windows.» The code is at the bottom of the post.

1) Why there’s no UpdateWindow(hwnd) in the horizontal scrollbar message handler when there’s one in vertical scrollbar message handler?

2) Can you explain in more detail how ScrollWindow() works? I’ve read MSDN’s explanation but it doesn’t help much.

It scrolls the client area, but invalidates the parts that are uncovered and they then need to be drawn on screen, right? This parts can only be located on the top or or on the bottom of the client area? (Since this is where uncovered parts appear)

You are right that Petzold’s code uses UpdateWindow() in one, and not the other. However, this is not really a bug, although I am not sure why he did not choose to use it in both places, or neither. From the MSDN page for ScrollWindow(), it states:

«The area uncovered by ScrollWindow is not repainted, but it is combined into the window’s update region. The application eventually receives a WM_PAINT message notifying it that the region must be repainted. To repaint the uncovered area at the same time the scrolling is in action, call the UpdateWindow function immediately after calling ScrollWindow.«

If you’ll look at the MSDN page for UpdateWindow(), it states:

«The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window’s update region is not empty. The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent.«

So, MSDN is pretty good at explaining what is going on.

If you wish to process a WM_PAINT message immediately, use UpdateWindow(). WM_PAINT is a low priority message, so it does not get processed until almost all other messages are processed. In this case, if the CPU is doing a lot, the window will appear to be painted in two steps — ScrollWindow() scrolls the window, and at a later time WM_PAINT redraws the invalid portion that is missing. Since UpdateWindow() forces any invalid portions to be drawn immediately, you can use this to fix this problem. I would call it every time I use ScrollWindow().

ScrollWindow имеет абсолютно никакого эффекта

Я создаю пользовательский элемент управления для WinForms и есть необходимость прокручивать раздел окна управления.

Необъяснимо, по-видимому нет методы ScrollWindow() не доступна в WinForms. Так что я пытаюсь использовать InteropServices использовать функцию Win32 API ScrollWindow(), используя вариации следующий:

Результатом является то, что этот код не делает абсолютно ничего. Я пробовал все виды вариаций этого кода, в том числе вызывающего Update() после свитка (который не должен быть необходимым).

ScrollWindow() возвращает 1, что означает успех, но он просто не имеет никакого влияния на содержание окна управления независимо от того, что я стараюсь.

Кто-нибудь знает, если что-то есть пользовательский элемент управления, который предотвращает модифицирования дисплей таким образом? Я проверяю это на C# Express Edition 2008 на Windows XP.

2 ответа

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


Как Will отметил в комментарии, вы легко можете сделать свой пользовательский элемент управления прокручивать, установив его AutoScroll недвижимость — нет необходимости нажмите API Win32 для достижения этой функциональности.

Если вы действительно хотите использовать API, по крайней мере использования ScrollWindowEx вместо ScrollWindow .

Обновление: Так как я случайно догадывался об этом, ответ:

Проходят Null для двух RECT параметры.

Таким образом, получается, ScrollWindow() работает просто отлично. Я скопировал код из Интернета, которые были членами сайта RECT структура из строя. Благодаря MusiGenesis за наконечник, который получил меня, глядя в нужном месте (я только предположил, что код, который я скопировал был правильным. — моя ошибка)

Да, я люблю писать эффективный код иногда и это обычно означает, что стыковые головы I в таких местах, как это, люди, которые думают, что я просто должен использовать все, что на полке. Разные люди, как подходить к разработке программного обеспечения по-разному, и я думаю, что это хорошо.

Как я создавал плагин постраничной прокрутки One Page Scroll с открытым исходным кодом

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

Не так давно Apple представила iPhone 5S, и сайт с презентацией, где страница была поделена на секции, и каждая секция описывала одну из особенностей продукта. Я подумал, что это – замечательный способ представления продукта, исключающий возможность пропустить ключевую информацию.

Я отправился на поиски подходящего плагина, и к удивлению, не обнаружил такового. Так и родился плагин постраничной прокрутки.

Плагин постраничной прокрутки.

Плагин, основанный на jQuery, позволяющий создать раскладку для страницы с несколькими секциями при минимальном использовании разметки.

Илон Маск рекомендует:  Создание анимированной gif-картинки

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

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

К чему всё это?

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

— простым в использовании
— простым в интеграции
— требовать минимальной разметки
— выполнять одну функцию, но хорошо

1. Чертежи

Я начал планировать плагин от общего к частному. Он должен осуществлять прокрутку по секциям. Для этого нужно отключить нормальную прокрутку в браузере, при этом подавая секции одну за другой, и продвигая страницу при необходимости.

Можно представлять всё в уме, а можно делать наброски.

Разобъём концепцию на мелкие задачи, решая каждую последовательно.

1. Подготовим раскладку секций
Отключим обычную прокрутку, применяя overflow: hidden к body. Расположим секции в нужной последовательности, подсчитаем и приспособим нужную информацию и классы.

2. Установим триггер ручной прокрутки
Триггер ловим через jQuery, определяем направление прокрутки, двигаем раскладку при помощи CSS.

3. Добавим возможностей
Добавим адаптивность, цикл, поддержку прокрутки на тачскринах, разбивку на страницы, и т.д.

4. Проверим в разных браузерах.
Проверим браузеры Chrome, Safari, Firefox, Internet Explorer 10 и самые популярные операционки Windows, Mac OS X, iOS and Android 4.0+.

5. Сделаем плагин доступным в репозитории
Создадим репозиторий, напишем инструкцию по использованию плагина

6. Расширим поддержку.
Изучим иные пути для увеличения поддержки плагина.

2. Строим основу

Спроектировав плагин, я занялся построением основы на этом шаблоне:

Шаблон начинаем с модуля !function($) < … >($), который помещает глобальную переменную jQuery в локальную область – это поможет снизить нагрузку и предотвратить конфликты с другими библиотеками.

Переменная defaults содержит настройки по-умолчанию.

$.fn.onepage_scroll – основная функция, которая всё инициализирует. Если вы делаете свой плагин, не забудьте вместо onepage_scroll написать другое название.

Запретить стандартную прокрутку можно, назначив тегу body свойство overflow: hidden
через имя класса, специфичное для данного плагина. Важно использовать уникальные имена стилей, чтобы избежать конфликта с существующими. Я обычно использую аббревиатуру из названия плагина, а потом через тире – имя для стиля, к примеру: .onepage-wrapper.

Фундамент заложен, приступим к первой функции.

3. Подготовим раскладку и расположим секции

Сначала я пошёл неправильным путём. Я думал, что расположу все секции по порядку, проходя их в цикле. Что у меня получилось сначала:

Цикл перебирает все селекторы (sectionContainer определён в разделе переменных по-умолчанию), назначает position: absolute и присваивает каждому следующему разделу правильную top позицию, чтобы они не наезжали друг на друга.

Положение сверху (top) хранится в topPos. Начинаем с нуля и с каждым циклом прибавляем. Чтобы каждая секция занимала всю страницу, я устанавливаю их высоту в 100% и прибавляю к topPos 100.

Разработка и проверка заняла у меня пару часов, но на следующем шаге я понял, что всё это было не нужно.

4. Ручной триггер и преобразование страницы

Можно было бы подумать, что следующий шаг – передвигаем каждую секцию в новое положение, когда срабатывает триггер прокрутки… Но есть способ лучше. Вместо сдвига каждой из секций в цикле, я просто помещаю их все в один контейнер и использую функцию translate3d из CSS3 для его сдвига. Эта функция поддерживает проценты, мы можем передвигать секции так, чтобы они точно позиционировались в окне, не пересчитывая всё заново. Кроме того, это облегчает контроль над скоростью и другими параметрами анимации.

Первое решение – не всегда самое эффективное, поэтому не забывайте оставлять время на эксперименты.

Теперь остаётся только определить направление прокрутки и сдвигать контейнер в нужную сторону.

Сначала цепляем функцию на событие mousewheel (DOMMouseScroll в Firefox), тогда можно будет перехватить данные и определить направление. Встраиваем в обработку init_scroll, которая получает wheelData для этого.

В идеальном мире достаточно было бы посчитать изменение wheelData. Однако при анимации последовательностей необходимо встроить проверку, чтобы событие-триггер не дублировалось (иначе при анимации изображение будет перекрываться). Можно использовать setInterval для вызова каждой анимации по очереди, но это не обеспечит точности и надёжности, т.к. каждый браузер обрабатывает его по-своему. К примеру, у Chrome и Firefox setInterval тормозит в неактивных вкладках, в результате функции не отрабатывают вовремя. В результате я остановился на использовании функции, возвращающей текущее время.

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

Функции moveUp и moveDown меняют атрибуты раскладки, чтобы они отражали текущее состояние сайта. Каждая из них в конце работы вызывает окончательный метод трансформации, чтобы передвинуть следующую секцию в окно просмотра.

Это метод трансформации, который сдвигает секции. Я делал их на яваскрипте вместо задания отдельных стилей, чтобы у разработчиков была возможность изменять настройки в самом плагине (в основном, скорость и ускорение анимации), и не надо было рыться в файле со стилями в поисках настроек. Кроме того, процент трансформации всё равно нужно пересчитывать, поэтому без яваскрипта не обойтись.

5. Дополнительные возможности

Сначала я не хотел ничего добавлять, но получил столько отзывов от сообщества GitHub, что решил постепенно улучшать плагин. Я выпустил версию 1.2.1, в которой добавляется множество обратных вызовов и циклов, и что самое сложное – адаптивность.

Я не делал плагин изначально с расчётом на мобильные платформы (о чём сожалею). Вместо этого пришлось отслеживать и пересчитывать события тачскрина в подходящий для использования в init_scroll вид. Не во всех браузерах это работает хорошо, поэтому пришлось встроить возможность отката – когда браузеру возвращается нормальная прокрутка при достижении определённой ширины окна.

Определим переменную по-умолчанию. Используем responsiveFallback, чтобы определить, когда плагин должен делать откат. Этот код определяет ширину браузера. Если ширина меньше значения из responsiveFallback, функция снимает все события, переносит страницу на начало и позволяет прокручивать её как обычно. Если ширина превосходит значение, плагин проверяет наличие класса disabled-onepage-scroll, чтобы узнать, инициализирован ли он. Если нет – инициализируется заново.

Решение не идеально, но даёт возможность разработчикам и дизайнерам выбирать, как показывать их сайт на мобильной платформе, вместо того чтобы полностью отвергать эти платформы.

6. Тестирование в разных браузерах.

Тестирование – важная часть разработки, перед выпуском плагина надо убедиться, что он работает на большинстве машин. Я всегда разрабатываю в Chrome – во-первых, мне нравятся его инструменты разработчика, во-вторых я знаю, что если плагин работает в Chrome, скорее всего он будет работать в Safari и Opera.

Обычно я использую Macbook Air для разработки, а дома у меня есть PC для проверки. После того, как плагин работает в Chrome, я проверяю его вручную в Safari, Opera, и в конце – в Firefox на Mac OS X, а затем — Chrome, Firefox и Internet Explorer 10 на Windows.

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

Не забудьте тестировать свои плагины на мобильных устройствах.

Чтобы облегчить тестирование, после окончания плагина я создаю демо-страницу для показа всех его возможностей, и загружаю на свой сайт. Бывают ошибки, которые нельзя отловить локально, но которые вылезают при работе на реальном сайте. Когда демо-страница работает, я начинаю тестирование на мобильных устройствах.

Илон Маск рекомендует:  Что такое код ingres_close
7. Выкладываем плагин в опенсорс

Последний шаг – делимся плагином на GitHub. Для этого нужно создать там аккаунт, настроить Git и создать новый репозиторий. Затем клонировать его на локальную машину – это создаст директорию с названием плагина. Копируем туда плагин и настраиваем структуру.

Настраиваете, как вам удобно. Я делаю так:

— директория demo содержит работающие демки, со всеми необходимыми ресурсами
— обычная и сжатая версия плагина лежат в корне
— CSS и тестовые ресурсы, типа картинок (при необходимости) лежат в корне
— файл readme в корне

Важный этап – написание понятных инструкций для опенсорс-сообщества. Обычно я пишу их в readme, но для сложных случаев может понадобиться wiki-страница. Как я пишу readme:

1. Введение
Объясняю назначение плагина, даю изображение и ссылку на демку.
2. Требования и совместимость.
Лучше вынести эту секцию повыше, чтобы сразу было ясно, сможет ли человек воспользоваться плагином.
3. Основные принципы использования
Пошаговые инструкции, начиная от подключения jQuery, заканчивая HTML-разметкой и вызовом функции. Также описываются настройки.
4. Продвинутое использование.
Более сложные инструкции – публичные методы, обратные вызовы и другая полезная информация.
5. Другие ресурсы
Ссылки на обучалку, спасибки и т.п.

8 Расширяем поддержку

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

Но для очистки совести я переработал плагин на чистом яваскрипте (также доступна версия с поддержкой Zepto). На чистом JS нет необходимости включать jQuery, всё работает «из коробки».

To make amends, and exclusively for Smashing Magazine’s readers, I have rebuilt One Page Scroll using pure JavaScript (a Zepto version is also available). With the pure JavaScript version, you no longer need to include jQuery. The plugin works right out of the box.

Чистый JS и версия для Zepto

Перерабатываем плагин на чистом JavaScript

Такая переработка может показаться тяжким делом, но это только спервоначалу. Самое сложное – не ошибиться с математикой. Т.к. я это уже сделал, разработка вспомогательных функций для избавления от jQuery заняла у меня лишь несколько часов.

Плагин основывается на CSS3, поэтому нужно было просто заменить вызовы jQuery на аналогичные собственные. Заодно я реорганизовал структуру скрипта:

— значения переменных по-умолчанию
Всё то же, что и в предыдущей версии
— функция инициализации
Подготавливает и располагает раскладку и инициализацию того, что происходит, когда вызывается функция onePageScroll. Здесь сидят все процедуры, назначающие имена классов, атрибуты и стили позиционирования.
— приватные методы
Все внутренние методы плагина – события прокрутки, трансформация страницы, адаптивный откат и отслеживание прокрутки.
— публичные методы
Все методы для разработчиков: moveDown(), moveUp() и moveTo()
— вспомогательные методы
Всё, что переопределяет вызовы jQuery.

Встретилась пара неприятных моментов – отдельная функция только для того, чтобы добавить или убрать имя стиля, или использование document.querySelector вместо $. Но в конце мы получили лучше структурированный плагин.

Перестраиваем плагин для Zepto

Я решил поддержать Zepto, несмотря на то, что он рассчитан только на самые современные браузеры (IE10+), т.к. он работает быстрее и эффективнее чем jQuery 2.0+, при этом имеет более гибкое API. Zpeto в 4 раза меньше jQuery, что сказывается на скорости загрузки страницы. Из-за того, что люди чаще используют смартфоны, Zepto становится лучшей альтернативой.

Переделывать плагин с jQuery на Zepto проще, потому что у них сходные API. Почти всё одинаково, кроме части с анимацией. Поскольку у функции Zepto $.fn.animate() есть поддержка CSS3-анимации и поддержка обратного вызова animationEnd, следующую часть:

Можно заменить таким кодом:

Zepto позволяет делать анимацию без определения всех стилей или самостоятельного назначения обратных вызовов.

И зачем этим заморачиваться?

Поскольку всё больше людей используют jQuery, он становится всё более сложным и иногда тормозит. Если сделать поддержку других фреймворков, ваш плагин будет более популярным.
Переделка с самого начала также поможет вам в будущем делать плагины лучше. jQuery и другие библиотеки прощают мелкие ошибки, типа пропущенных запятых – в результате вы не очень заботитесь о качестве своей работы. Без этих поблажек на чистом JavaScript я лучше чувствовал работу своего плагина – что как работает, что влияет на производительность, и что можно улучшить.

Хотя библиотеки типа jQuery облегчили нам жизнь, их использование – не самый эффективный метод достижения цели. Некоторые плагины могут обойтись и так.

Заключение.

Ну вот вам и весь процесс создания плагина «One Page Scroll». Были ошибки, но я учился на них по ходу разработки. Если б я разрабатывал его сегодня, я бы сконцентрировался на мобильных устройствах, и добавил бы больше комментариев в код.

Без поддержки таких сообществ, как GitHub, StackOverflow и Smashing Magazine я бы не смог сделать плагин так быстро. Эти сообщества сильно помогали мне в работе, поэтому я и делаю свои плагины доступными бесплатно для всех желающих. Этой мой способ расплатиться за замечательную поддержку.

Можно ли установить цвет ScrollWindow?

У меня есть следующий код:

По какой-то причине цвет окна, но не окна прокрутки, установлен на черный. Как я могу это изменить?

Решение

Все, что вам нужно, это GtkEventBox ,

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

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

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

Что такое код scrollwindow

Но что делать, если позарез нужна функция API Win32, которой в .NET Framework просто нет?

В таком случае можно прибегнуть к службам PInvoke (Platform Invocation Services). PInvoke — это общий механизм вызова функций, экспортируемых из DLL. Функция ScrollWindow находится в динамически подключаемой библиотеке User32.dll , поэтому ее можно точно квалифицировать. Но у этого подхода есть минус: после того как программист воспользовался им, его код перестает быть управляемым и уж подавно независимым от платформы.

В документации по API Win32 приводится такой синтаксис ScrollWindow:

В заголовочных файлах С для Windows BOOL определяется просто как int, a HWND (дескриптор окна) — как указатель на void, но реально это просто 32-разрядное значение.

Но откуда взять дескриптор окна в Windows Forms? У класса Control есть свойство Handle, описанное в документации как дескриптор HWND для экземпляра этого класса. Тип свойства Handle — определяемая в пространстве имен System структура IntPtr — свидетельствует, что это указатель. Типы данных int и IntPtr могут быть легко преобразованы друг в друга. Пока мы не встретили никаких трудностей при переходе от типов данных С# к аргументам функции ScrollWindow и возвращаемым ей значениям.

Трудности связаны с двумя последними аргументами ScrollWindow — указателями на структуру Windows RECT, определяемую в заголовочном файле Windows так:

Тип данных LONG определяется в заголовочном файле Windows как long, но это не 64-разрядный long из С#, а всего лишь 32-разрядный long из С, поэтому он совместим с типом данных int из С#.

Чтобы вызвать ScrollWindow из программы С#, надо определить структуру, набор и порядок полей которой соответствуют таковым структуры Windows RECT, и предварить ее атрибутом:

Structlayout — это атрибут С#, основанный на классе StructLayoutAttribute, определенном в пространстве имен System.Runtime.InteropServices. Кроме того, нужно объявить ScrollWindow как внешнюю функцию extern, предварив ее атрибутом:

Возможно, вы заметили, что класс KeyExamine содержит метод ScrollLines, отвечающий за прокрутку содержимого клиентской области. Метод ScrollLines в KeyExamine просто делает недействительной часть клиентской области ниже заголовков столбцов. В классе KeyExamineWithScroll, порожденном от KeyExamine, определена структура RECT, объявлена функция ScrollWindow и переопределен метод ScrollLines в KeyExamine. Модифицированная версия ScrollLines вызывает функцию Windows ScrollWindow.

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

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