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, в результате получается то, что показано ниже (конечно, в увеличенном виде):


Рис. 5.7.

В верхнем левом углу фигуры находится пиксел с координатами (xy). Если высота и ширина прямоугольника будут равны 2, программа нарисует прямоугольник размером 3 на 3 пиксела, внутренняя область которого состоит лишь из одного пиксела:


Рис. 5.8.

Если высота и ширина равны 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< Назад | Оглавление | Далее >

Сайт управляется системой uCoz