netlib.narod.ru | < Назад | Оглавление | Далее > |
Прямоугольники не так часто встречаются в природе, но определенно являются самой распространенной формой объектов, созданных человеком. Их можно встретить повсюду: страница, которую вы сейчас читаете — прямоугольник, абзацы ее текста имеют форму прямоугольника, расположенный перед этим разделом снимок экрана — тоже. Стол, за которым вы сидите, кровать, на которой вы отдыхаете, тоже скорее всего прямоугольные. И окно, куда вы посматриваете, когда надоедает читать эту книгу, вероятно, прямоугольное.
Несомненно, прямоугольник можно нарисовать при помощи методов DrawLine или DrawLines (что мы и делали, когда очерчивали клиентскую область), но проще сделать это методом DrawRectangle. В каждой из трех его версий прямоугольник определяется точкой, задающей положение верхнего левого угла, шириной и высотой. Аналогично определяется структура Rectangle, которую использует одна из версий DrawRectangle:
Методы DrawRectangle класса Graphics
void DrawRectangle(Pen pen, int x, int y, int cx, int cy) |
void DrawRectangle(Pen pen, float x, float y, float cx, float cy) |
void DrawRectangle(Pen pen, Rectangle rect) |
Как ни странно, метод DrawRectangle использующий структуру RectangleF, отсутствует. Возможно, программист просто забыл пометить его модификатором public. Надеюсь, мы все же увидим такой метод в следующем выпуске.
Ширина и высота прямоугольника должны быть больше 0. Прямоугольники с отрицательной шириной и высотой не вызовут исключения, но и не будут нарисованы.
При рисовании прямоугольников часто возникают ошибки смещения на 1 пиксел, поскольку толщина контура прямоугольника составляет минимум 1 пиксел. Входит ли вообще толщина контуров в ширину и высоту прямоугольника и, если да, то со всех сторон или с какой-то одной?
При использовании свойств пера по умолчанию (об этом я расскажу в главе 17) методу DrawRectangle передаются значения ширины и высоты, равные 3, в результате получается то, что показано ниже (конечно, в увеличенном виде):
В верхнем левом углу фигуры находится пиксел с координатами (x, y). Если высота и ширина прямоугольника будут равны 2, программа нарисует прямоугольник размером 3 на 3 пиксела, внутренняя область которого состоит лишь из одного пиксела:
Если высота и ширина равны 1, рисуется квадрат размером 2 × 2 пиксела. Может возникнуть искушение поместить свойство формы ClientRectangle прямо в вызов DrawRectangle, чтобы очертить клиентский прямоугольник снаружи видимым контуром:
grfx.DrawRectangle(pen, ClientRectangle); // Избегайте этого!
Это работать не будет! Правая и нижняя стороны прямоугольника станут невидимыми. Ниже показана программа, которая должным образом выводит целый прямоугольник как в клиентской области, так и на принтер. Я сделал прямоугольник красным, чтобы он был лучше виден на экране.
OutlineClientRectangle.cs
//------------------------------------------------------- // OutlineClientRectangle.cs (C) 2001 by Charles Petzold //------------------------------------------------------- using System; using System.Drawing; using System.Windows.Forms; class OutlineClientRectangle: PrintableForm { public new static void Main() { Application.Run(new OutlineClientRectangle()); } public OutlineClientRectangle() { Text = "Outline Client Rectangle"; } protected override void DoPage(Graphics grfx, Color clr, int cx, int cy) { grfx.DrawRectangle(Pens.Red, 0, 0, cx - 1, cy - 1); } }
Попробуйте указать в качестве последних двух аргументов метода DrawRectangle просто значения сх и су, не вычитая из них 1, и вы увидите, что правая и нижняя стороны прямоугольника станут невидимыми в клиентской области. Это следствие той же проблемы, что возникает при использовании свойства ClientRecTangle и вызове DrawRectangle.
Класс Graphics также включает два метода, позволяющих рисовать несколько прямоугольников:
Методы DrawRectangles класса Graphics
void DrawRectangles(Pen pen, Rectangle[] arect) |
void DrawRectangles(Pen pen, RectangleF[] arectf) |
Пользы от них намного меньше, чем от DrawLines. Но предположим, что есть структура RectangleF с именем, скажем, rectf. На основе этой структуры нужно нарисовать один прямоугольник. Помня об отсутствии перегруженных версий метода DrawRectangle, можно решить поставленную задачу методом DrawRectangles:
grfx.DrawRectangles(pen, new RectangleF[] { rectf }};
netlib.narod.ru | < Назад | Оглавление | Далее > |