netlib.narod.ru | < Назад | Оглавление | Далее > |
Прервемся на секунду и попытаемся получше понять, что происходит, взглянув на реальные числа. Помните только, что некоторые из этих чисел обусловлены параметрами моей системы и могут не совпадать с теми, что видите вы. (Например, в свойствах экрана у меня задан крупный шрифт, и это отражается на некоторых рассматриваемых параметрах.)
Допустим, вашей программе нужна клиентская область шириной в 400 и высотой в 1 600 пикселов. Вот как вы установите свойства AutoScroll и AutoScrottMinSize в конструкторе формы:
AutoScroll = true; AutoScrollMinSize = new Size(400, 1600);
Мой опыт свидетельствует о том, что по умолчанию размер создаваемой формы составляет 300 × 300 пикселов. Каков тогда будет размер клиентской области? Что ж, у нас теперь есть две программы, позволяющих получить информацию о системе, так что вы можете выяснить размер клиентской области. У меня значение свойства SystemInformation.CaptionHeight равно 24. Это высота строки заголовка формы. Нормальная ширина границы окна содержится в свойстве SystemInformation.FrameBorderSize. У меня она равна 4 пикселам, и не забывайте, что граница проходит по всем четырем сторонам формы. Таким образом, ширина клиентской области равна 300 минус два раза по 4, т.е. 292 пикселам. Высота клиентской области равна 300 минус два раза по 4 и минус 24, что составляет 268 пикселов. (Если вы не доверяете моим математическим навыкам, можете проверить эти значения при помощи свойства ClientSize формы.)
Поскольку высота клиентской области, равная 268 пикселам, меньше требуемых нам 1 600, программе потребуется вертикальная полоса прокрутки. Мое значение свойства SystemInformation.VerticalScrollBarWidth составляет 20 пикселов. Таким образом, ширина клиентской части уменьшается до 292 минус 20, что составляет 272 пиксела.
Ширина в 272 пиксела меньше 400, поэтому программе также потребуется и горизонтальная полоса прокрутки. Значение SystemInformation.HorizontalScrollBarНeight также равно 20 пикселам, и высота клиентской части составит 268 минус 20, или 248 пикселов.
Вероятно, диапазон значений для вертикальной полосы прокрутки включает в себя числа от 0 до 1 352. Второе значение получено вычитанием из 1 600 реальной высоты клиентской части, равной 248. Диапазон значений для горизонтальной полосы прокрутки включает в себя числа от 0 до 128 (400 минус 272).
Код, содержащийся в классе ScrollableControl, в ответ на щелчки пользователя по полосе прокрутки или перетаскивание ее ползунка выполняет два действия: изменяет значение свойства AutoScrollPosition и прокручивает содержимое клиентской части. Значение AutoScrollPosition сначала установлено в (0, 0). Когда пользователь передвигает горизонтальную полосу прокрутки, свойство X изменяется от 0 до –128, а свойство Y — от 0 до –1 352.
Для прокрутки клиентской области системе нужно скопировать содержимое из одного положения клиентской области в другое. В Win32 API есть функции ScrollWindow, ScrollWindowEx и ScrollDC, позволяющие программам прокручивать клиентские области. Хотя эти функции не открыты для библиотеки классов Windows Forms, очевидно, что класс ScrollableControl использует одну из них.
Когда код, содержащийся в классе ScrollableControl, прокручивает клиентскую область, он может прокрутить лишь ту часть, что в данный момент отображается на экране. Прокрутка «раскрывает» прямоугольник в клиентской области, делая эту часть клиентской области недействительной, что приводит к вызову метода OnPaint.
Так что, когда вы прокручиваете содержимое в окне SysInfoPanel или SysInfoScroll, методу OnPaint на самом деле надо перерисовать лишь небольшой прямоугольник клиентской области. Было бы нерационально использовать вызов OnPaint для прорисовки каждой строки выводимого текста.
Давайте решим эту проблему в два этапа.
netlib.narod.ru | < Назад | Оглавление | Далее > |