БлогNot. Visual C++: рисуем мышью графическую кривую на PictureBox

Visual C++: рисуем мышью графическую кривую на PictureBox

Мы уже рисовали на канве формы с помощью Visual C++/CLI вот в этом примере. На сей раз используем для рисования канву компоненты PictureBox.

В Studio 2015 создадим проект Windows Forms на C++, добавим на форму компоненту PictureBox и растянем её на всё окно (свойство Dock установим в значение Fill).

Для использования в проекте списка точек (Point) шаблонного класса List, в начале файла MyForm.h подключим нужное пространство имён:

using namespace System::Collections::Generic;

Мы хотим мышкой рисовать кривую по точкам, следя при этом за регенерацией рисунка при изменении размеров окна. Прилагаемый ниже исходник - это вся пользовательская часть проекта, расположенная после директивы #pragma endregion в коде файла MyForm.h. Обратите внимание на "двойной" вызов сначала pictureBox1->Refresh(), а затем pictureBox1->Invalidate() в методе pictureBox1_SizeChanged, следящем за изменением размеров окна. Без этого рисунок нормально перерисовываться не будет, например, перерисуется при увеличении, но не при уменьшении размеров окна мышкой. Стоит также помнить о возможности подключения для формы двойной буферизации, она может изменить поведение кода при перерисовке элементов "на лету".

private: 
  Graphics ^g; //канва
  List <Point> ^points; //точки; подлючен using namespace System::Collections::Generic;
  Pen ^ pen; //перо
  bool draw; //флажок перерисовки
	
 private: System::Void MyForm_Load(System::Object^  sender, System::EventArgs^  e) {
	 //загрузка формы
  Bitmap ^ Img = gcnew Bitmap(pictureBox1->Width, pictureBox1->Height);
  g = Graphics::FromImage(Img);
  pictureBox1->Image = Img;
  pen = gcnew Pen(Color::Red);
  points = gcnew List <Point>();
  draw = false;
 }
 	
  private: System::Void pictureBox1_Paint(System::Object^  sender, 
	  System::Windows::Forms::PaintEventArgs^  e) { //перерисовка PictureBox
  if (points->Count > 1) {
   g->DrawLines(pen, points->ToArray());
  }
 }

 private: System::Void pictureBox1_MouseDown(System::Object^  sender, 
	 System::Windows::Forms::MouseEventArgs^  e) { //нажатие кнопки мыши - начало рисования
  //points->Clear(); /* раскомментарить, если каждый раз рисуем заново */
  points->Add(e->Location);
  draw = true;
  pictureBox1->Invalidate();
 }

 private: System::Void pictureBox1_MouseUp(System::Object^  sender, 
	 System::Windows::Forms::MouseEventArgs^  e) { //отпускание кнопки мыши - завершение рисования
  draw = false;
  pictureBox1->Invalidate();
 }

 private: System::Void pictureBox1_MouseMove(System::Object^  sender, 
	 System::Windows::Forms::MouseEventArgs^  e) { //движение мыши - рисование
  if (draw && points->Contains(Point(e->X, e->Y)) == false) { 
	  //если включён флажок и текущая точка не содержится в списке точек
   if (e->Button == System::Windows::Forms::MouseButtons::Left) {
	   //если нажата левая кнопка
    points->Add(e->Location);
    pictureBox1->Invalidate();
   }
  }
 }

 private: System::Void pictureBox1_SizeChanged(System::Object^  sender, 
	 System::EventArgs^  e) { //после изменения размеров PictureBox
  if (pictureBox1->Image) { //если есть рисунок, скопировать через Bitmap и перерисовать компоненту
   Bitmap ^Img = gcnew Bitmap(pictureBox1->Width, pictureBox1->Height, 
	   Graphics::FromImage(pictureBox1->Image));
   delete g;
   g = Graphics::FromImage(Img);
   pictureBox1->Image = Img;
   pictureBox1->Refresh();
   pictureBox1->Invalidate(); 
  }
 }

 Скачать папку с этим проектом Stuido 2015, развернуть, не создавая новой папки (7 Кб)

05.11.2017, 19:37 [3480 просмотров]


теги: программирование графика c++/cli

К этой статье пока нет комментариев, Ваш будет первым