Как сделать оконное приложение c

Добавил пользователь Skiper
Обновлено: 05.10.2024

С такой задачей довольно часто приходится иметь дело начинающим программистам. И нередко она вызывает серьёзные затруднения, несмотря на то, что принцип её решения предельно прост.

Основная проблема чаще всего кроется в ещё недостаточном понимании структуры как консольных таки оконных программ.

Консольную программу, в большинстве случаев, можно условно разделить на три части выполняемые последовательно.

  1. Ввод данных;
  2. Выполнение тех или иных действий;
  3. Вывод результатов на экран консоли.

В оконной программе первая и третья части объединены в оконном интерфейсе, а вторая часть выполняется при возникновении определённого события (например, нажатие кнопки).

Для наглядности рассмотрим следующий простой пример.

Есть консольная программ, которая перемножает два числа введённые пользователем и выводит результат умножения. Ниже приведён её код на Pascal и C++.

Необходимо переделать эту консольную программу в оконную.

Реализацию оконной версии выполним в Delphi и C++ Builder.

Так как программа принимает на вход два числа и возвращает результат в виде одного числа, в окне должны быть два компонента исходных чисел (допустим, поля для ввода Edit) и один компонент для вывода результата (допустим, метка Label).

Для того чтобы дать программе команду выполнить вычисления можно задействовать обычную кнопку. При нажатии на неё оба исходных числа будут перемножены, а результат выведен в Label.

Внешний вид окна показан на скриншоте ниже.

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

Теперь необходимо обработать событие нажатия на кнопку.

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

Создание пустой заготовки оконного приложения

  • Выполните команду меню File/New/Project и выберите из диалогового окна мастера шаблон Empty Project (пустой проект), а также определите имя проекта MyApp и его размещение в файловой системе компьютера. Проследите, чтобы флаг Create directory for solution был сброшен, иначе будет создан каталог для решения и подкаталог для проекта


Обратите внимание, что панель Solution Explorer не отображает ни одного файла


Обратите, также, внимание, что панель Object Browser уже содержит ссылку на базовую сборку mscorlib.dll ( Microsoft Common Object Runtime Library или Multilanguage Standard Common Object Runtime Library ). Она автоматически подключается к проекту, поскольку содержит базовые типы, необходимые для всех приложений. Наш проект тоже присутствует в этой панели, как будующая сборка, но пока сырая.

  • Командой Project/Add Reference вызовите диалоговое окно оболочки и добавьте к проекту ссылки на библиотечные сборки System.dll, System.Windows.Forms.dll и System.Drawing.dll


Создание экземпляра класса Form

  • Добавьте к проекту пустой файл с именем Program.cs командой Proiect/Add New Item


Мы видим, что помещать код в свое пространство имен необязательно и указывать библиотечные пространства имен тоже необязательно. В первом случае для больших проектов это может привести к повторению имен типов, во втором - приходится писать полные имена при использовании библиотечных классов.

  • Запустите приложение - появится только пустое консольное окно

Консольное окно создается и отображается автоматически, а вот графическое окно мы только создали, но не отобразили.

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


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

Отключение консольного окна

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

  • Отключите консольное окно, вызвав окно свойств проекта командой Project/MyApp Properties и установив опцию Windows Application в списке Output type вкладки Application


Теперь при запуске приложения будет появляться только графическое окно


Скриншот панели выбора компонентов для создания графического приложения

1. В первую очередь перечислим, какие компоненты должны быть установлены для создания графического приложения на языке С++. Их три, все относятся к разделу "Desktop development with C++":
- VC++ 2017 v141 toolset (x86,x64)
- Windows 10 SDK (10.0.15063.0) for Desktop C++ x86 and x64
- C++/CLI support

Первые два нужны для создания любого приложения на С++, третий именно для создания графической оболочки программы. Во время исследования данной темы мною подключалось два десятка других - пользы новичкам от них нету.

Окно выбора типа создаваемого приложения

2. После установки среды разработки переходим
File > New > Project. ( ^+N )
В появившемся окне отыскиваем Installed > Visual C++ > CLR > CLR Empty Project

Поля внизу заполняем традиционным для таких программ способом. В названии проекта лучше не допускать пробелов, иначе вам потом придётся мудрить в коде.

3. Необходимо добавить в приложение главную форму. Есть два равносильных пути достижения этой цели.
Первый: в "Solution Explorer" правой кнопкой мыши на названии проекта, во всплывшем контексном меню Add > New Item.
Второй способ: в главном меню выбираем Project > Add New Item.
Или просто нажимаем ^+A

выбор Windows Form

Во появившемся окне Visual C++ > UI > Windows Form

Устранение ошибки 0x8000000A, иногда происходящей при создании формы

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

Эта ошибка хорошо известна ещё по Visual Studio 2015. Можете почитать её обсуждение, к примеру, на сайте Microsoft по ссылке1, ссылке2, ссылке3. И более лучшего решения, чем закрывать вкладку, ещё нет. По всей видимости, команда разработчиков Visual Studio не считает эту ошибку достаточно серьёзным делом, чтобы ломать о неё копья.

Выбор в контекстном меню элемента Свойства

4. Но мало просто создать форму, нужно вплести её в создаваемую программу. Для этого в "Solution Explorer" правой кнопкой мыши на названии проекта, во всплывшем контексном меню выбрать Properties .

Выбор содсистемы (SubSystem)

В открывшемся окне произвести два действия.
• Linker > System > SubSystem , из раскрывающегося списка выбрать " Windows (/SUBSYSTEM:WINDOWS) "

Прописывание точки привязки (Entry Point)

• Linker > Advanced > Entry Point . В пустое поле вписать " main " (без кавычек).

Отлично, всё готово! Теперь проект компилируем и запускаем. Но если у вас ранее выскакивала 0x8000000A, то быстрее всего вам придётся перезапустить Visual Studio и вновь загрузить в нём проект. Далее ошибка ни в чём не проявится.

Вызов панели Toolbox, также показана сама панель

6. Для того, чтобы добавить на нашу только что созданную форму новые элементы, понадобится панель Toolbox. Полезно запомнить горячую клавишу ^!X

Работа с размещением элементов на форме сложностей вызвать не должна. Работает здесь всё удобнее, чем wxWidgets в CodeBlocks или wxDev-C++. Никаких глюков мною замечено не было.

Для изменения свойств только что созданного элемента интерфейса щёлкните на нём правой кнопкой и в контекстном меню выберите, соответственно, Properties.

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

MessageBox::Show("Hello World",
"My heading", MessageBoxButtons::OKCancel,
MessageBoxIcon::Asterisk);

Работающее простейшее графическое приложение, созданное в VS2017

Запускаем и проверяем!

Список Solution Configuration, выставленный на Release

Если вдруг не запустится, то первым делом проверяем, что выставлено в раскрывающемся списке Solution Configurations . Он находится на панели инструментов (под главным меню). Там должно быть Release (а не Debug) .

Дополнительная информация

Альтернативные способы создания графических приложений в Visual Studio 2017.

1. UWP (Universal Windows Platfrom application) - универсальные приложения, способные запускаться на Windows 10, Windows 10 Mobile и аналогичных самых современных платформах от Microsoft. Платформа разработана как расширение Windows Runtime. Всё бы хорошо, но данные приложения не могут запускаться на более старых версиях Windows, даже на восьмёрке.

Пара слов для общего развития о нескольких технологиях, на которые вы будете постоянно натыкаться при чтении документации по разработке GUI в Visual Studio.

ATL (Active Template Library) - набор шаблонных классов языка C++, предназначенных для упрощения написания COM-компонентов.
MFC (Microsoft Foundation Classes) - библиотека объектов, помогающая профессиональным разработчикам создавать десктопные приложения. Что-то вроде более усложнённого и навороченного варианта ATL. ATL и MFC являются хорошими вещами, и с их задействованием также можно создавать графические приложения. Но это инструменты, требующие наличия углублённых знаний тематики.

IncrediBuild - технология ускорения компиляции и сборки приложений с помощью подключения дополнительных компьютеров. К методам создания графических интерфейсов это напрямую не относится.

Примечания:
В интернете можно наткнуться на заголовок "Full C and C++ IDE with Visual Studio". Оттуда закачиваются те же самые стандартные дистрибутивы Visual Studio, проверено по контрольным суммам.

Код и внешний вид простейшего графического калькулятора

P.S.
Теперь можно немного поэкспериментировать с элементами интерфейса. Ниже показан код простейшего графического калькулятора:

private: System::Void button6_Click(System::Object^ sender, System::EventArgs^ e) Application::Exit();
>

private: System::Void radioButton1_CheckedChanged(System::Object^ sender, System::EventArgs^ e) label1->Text = "+";
>
private: System::Void radioButton2_CheckedChanged(System::Object^ sender, System::EventArgs^ e) label1->Text = "-";
>
private: System::Void radioButton3_CheckedChanged(System::Object^ sender, System::EventArgs^ e) label1->Text = "*";
>
private: System::Void radioButton4_CheckedChanged(System::Object^ sender, System::EventArgs^ e) label1->Text = "/";
>

private: System::Void button5_Click(System::Object^ sender, System::EventArgs^ e) char sw = System::Convert::ToChar(label1->Text);
double a = System::Convert::ToDouble(textBox1->Text);
double b = System::Convert::ToDouble(textBox2->Text);
double r;
switch (sw) case '+':
r = a + b;
break;
case '-':
r = a - b;
break;
case '*':
r = a * b;
break;
case '/':
r = a / b;
break;
>
label2->Text = "Result: " + System::Convert::ToString(r);
>

Простой стандандартный windows-калькулятор

А теперь можно попытаться сотворить что-то более похожее на стандартное window-приложение. Пока простейшее.

double iFirstNum;
double iSecondNum;
double iResult;
String^ iOperator;

private: System::Void btnC_Click(System::Object^ sender, System::EventArgs^ e) /*button C ("Global Clear" - clears the entire calculation*/
tbDisplay->Text = "0";
lblShowOp->Text = "";
>

private: System::Void btnCE_Click(System::Object^ sender, System::EventArgs^ e) <
/*button CE ("Clear Entry" is supposed to be used to clear only the thing you are currently
typing into the calculator, before you have performed any operation on it.*/
tbDisplay->Text = "0";
>

private: System::Void buttonS_Number_Click(System::Object^ sender, System::EventArgs^ e) <
//Number Buttons Event
Button ^ Numbers = safe_cast (sender);
if (tbDisplay->Text == "0")
tbDisplay->Text = Numbers->Text;
else
tbDisplay->Text += Numbers->Text;
>

private: System::Void buttonS_Arithmetic_Click(System::Object^ sender, System::EventArgs^ e) <
//Operator Buttons Event
Button ^ op = safe_cast (sender);
iFirstNum = Double::Parse(tbDisplay->Text);
tbDisplay->Text = "0";
iOperator = op->Text;
lblShowOp->Text = System::Convert::ToString(iFirstNum) + " " + iOperator;
>

private: System::Void btnEquals_Click(System::Object^ sender, System::EventArgs^ e) <
//Equals
iSecondNum = Double::Parse(tbDisplay->Text);

if (iOperator == "+")
iResult = iFirstNum + iSecondNum;
else if (iOperator == "-")
iResult = iFirstNum - iSecondNum;
else if (iOperator == "*")
iResult = iFirstNum * iSecondNum;
else if (iOperator == "/")
iResult = iFirstNum / iSecondNum;
else MessageBox::Show("Unknown operation.\nSomething wrong.",
"error", MessageBoxButtons::OK,
MessageBoxIcon::Error);
return;
>

private: System::Void btnDot_Click(System::Object^ sender, System::EventArgs^ e) <
//Decimal Point
if (!tbDisplay->Text->Contains("."))
tbDisplay->Text += ".";
>

private: System::Void btnPM_Click(System::Object^ sender, System::EventArgs^ e) <
//Plus-Minus
if (tbDisplay->Text->Contains("-"))
tbDisplay->Text = tbDisplay->Text->Remove(0, 1);
else
tbDisplay->Text = "-" + tbDisplay->Text;
>

Код создан на основе видеоролика
"Visual C++ Calculator Tutorial with Decimal Point and Backspace" (37:59, DJ Oamen, 2016 Jan 2, Visual C++ 2010) ,
но имеет ряд отличий.

Как продолжение, существует видеоролик
"Visual C++ Scientific Calculator Tutorial" (53:31, Paul Oamen, 2016 Oct 2, Visual Studio 2015). Судя по голосу, автор тот же. К показанному выше калькулятору прибавляется конвертер температуры и ряд более научных функций. Предупрежу, что итоговое "творение" имеет массу изъянов и глюков, поэтому видео можно просматривать исключительно для изучение приёмов программирования. Но не используйте его в качестве образца того, как нужно создавать калькуляторы.

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском.

Закрыт 6 лет назад .

Хочу писать в Visual Studio хотя можно и в чём-нибудь другом, язык С++.

Посоветуйте книги, статьи. Слышал в VS есть Windows Forms, только методом тыка не получилось разобраться.

Поступили предложения использовать Windows Forms, WPF, MFC и Qt. Так, а что лучше?


@Soul Сравнение MFC, Windows Forms, WPF, Qt - это отдельный вопрос, который правильно задать в новой теме.

4 ответа 4

Первым шагом стоит скачать и установить на свою машину Visual C++ Express (если она еще не установлена). Вторым шагом зайти на страницу MSDN Создание приложений Win32 (C++) и выполнить по пунктам все, что там написано. Третьим шагом заглянуть в раздел Интерактивный учебник по Visual C++: там есть, что почитать. Возможно, и книги не понадобятся. :)

По WinForms: это устаревшая технология, тратить время на ее изучение сейчас нет смысла. Если по работе понадобится, тогда да, можно и поизучать, а так лучше ознакомиться с WPF.

Почитайте "Visual C++ и MFC" Мешков А., Тихомиров Ю.

Это почему Windows Forms не получиться использовать? У меня Visual Studio 2010 стоит и в разделе Visual C++ есть Windows Forms Application.

придется нехило поизвращаться, если прям плюсы и прям вижуал студия - то уж лучше MFC. Но я бы посоветовал глянуть в сторону Qt ;-)

@Soul Чтобы писать для WinForms на С++, надо использовать C++/CLI. Это по сути отдельный, хотя и близко родственный к C++, язык.

Привет :) Не слушай usrex-а :))))

Методом тыка, конечно же, не получится :) Читай книги по Шилдту :) Он очень явно и понятно расписывает все :) P.S. При чтении бывают моменты, что ничего не понятно. Ну да ничего. Как правило, при переходе на следующую статью очень быстро осиняют правильные идеи и мысли по отношению к предыдущей.

P.P.S. Сначала научись писать консольные приложения. После этого уже к Win-формам переходи, ибо если начинать учить с середины - маловероятно, что это чем-то толковым для тебя выдет.


Консольные умею писать. В Шилдте разве есть про оконные приложения? И какую именно советуешь книгу его, а то по той ссылке, кот. ты дал, там их много.

Читайте также: