1. Главная страница » Компьютеры

C создать окно windows

Автор: | 16.12.2019

Самая актуальная документация по Visual Studio 2017: Документация по Visual Studio 2017.

В этом пошаговом руководстве демонстрируется создание простейшего классического приложения Windows, выводящего в окне надпись "Hello, World!". Код, созданный в этом пошаговом руководстве, можно использовать в качестве шаблона для создания других классических приложений Windows.

API-интерфейс Win32 (также известный как Windows API) — это платформа на основе C для создания приложений Windows. Дополнительные сведения об API-интерфейсе Win32 см. в разделе Windows API.

Важно

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

Для выполнения этого пошагового руководства читатель должен владеть основами языка C++.

Видеодемонстрация доступна в разделе Видео. Практическое руководство. Создание приложений Win32 (C++) документации по Visual Studio 2008.

Создание проекта на основе Win32

В меню Файл последовательно выберите пункты Создать и Проект.

Читайте также:  An error occurred while unpacking archive corrupted

В левой области диалогового окна Новый проект щелкните Установленные шаблоны, выберите Visual C++ и щелкните Win32. В средней области выберите шаблон Проект Win32.

В поле Имя введите имя проекта, например win32app . Нажмите кнопку ОК.

На начальной странице мастера приложений Win32 нажмите кнопку Далее.

На странице "Параметры приложения" в разделе Тип приложения выберите Приложение Windows. В поле Дополнительные параметры выберите Пустой проект. Чтобы создать проект, нажмите кнопку Готово.

В обозревателе решений щелкните правой кнопкой мыши проект Win32app, выберите пункт Добавить, а затем пункт Новый элемент. В диалоговом окне Добавление нового элемента выберите Файл C++ (.cpp). В поле Имя введите имя файла, например GT_HelloWorldWin32.cpp . Нажмите кнопку Добавить.

Запуск классического приложения Windows

Точно так же, как каждое приложение на языке C и C++ должно иметь в качестве начальной точки функцию main , каждое приложение на основе Win32 должно иметь функцию WinMain . WinMain имеет следующий синтаксис:

Сведения о параметрах и значениях, возвращаемых этой функцией, см. в разделе Функция WinMain.

Так как в коде приложения должны использоваться существующие определения, следует добавить в файл операторы включения.

Наряду с функцией WinMain в каждом классическом приложении Windows также должна быть определена функция оконной процедуры. Обычно эта функция имеет имя WndProc . WndProc имеет следующий синтаксис:

Эта функция обрабатывает многочисленные сообщения, которые приложение получает от операционной системы. Например, в приложении с диалоговым окном, в котором есть кнопка ОК, при нажатии упомянутой пользователем операционная система отправляет в приложение сообщение о том, что эта кнопка была нажата. Функция WndProc отвечает за реагирование на это событие. В этом примере соответствующей реакцией на это событие может быть закрытие диалогового окна.

Дополнительные сведения см. в разделе Процедуры окна.

Добавление функциональных возможностей в функцию WinMain

В функции WinMain создайте структуру класса окна типа WNDCLASSEX. Эта структура содержит информацию об окне, такую как используемые в приложении значки, цвет фона окна, отображаемое в заголовке окна название, имя функции процедуры окна и т. д. В приведенном ниже примере показана типичная структура WNDCLASSEX .

Сведения о полях этой структуры см. в разделе WNDCLASSEX.

После того как класс окна создан, необходимо зарегистрировать его. Воспользуйтесь функцией RegisterClassEx и передайте структуру класса окна в качестве аргумента.

Теперь можно создать окно. Воспользуйтесь функцией CreateWindow.

Эта функция возвращает объект HWND, являющийся дескриптором окна. Дополнительные сведения см. в разделе Типы данных Windows.

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

На этом этапе в окне не будет отображаться большое количество содержимого, так как функция WndProc еще не реализована.

Теперь добавьте цикл обработки сообщений для прослушивания отправляемых ОС сообщений. Когда приложение получает сообщение, этот цикл пересылает его функции WndProc для обработки. Цикл обработки сообщений напоминает приведенный ниже код.

Дополнительные сведения о структурах и функциях, используемых в цикле обработки сообщений, см. в разделах, посвященных MSG, GetMessage, TranslateMessage и DispatchMessage.

На этом этапе функция WinMain должна напоминать приведенный ниже код.

Добавление функциональных возможностей в функцию WndProc

Чтобы включить обработку получаемых приложением сообщений функцией WndProc , реализуйте оператор switch.

Первым обрабатывается сообщение WM_PAINT. Приложение получает это сообщение, когда часть его отображаемого окна требует обновления. (При первом отображении окна его требуется обновить полностью.)

Для обработки сообщения WM_PAINT сначала вызовите метод BeginPaint, далее обработайте логику расположения текста, кнопок и других элементов управления в окне, а затем вызовите метод EndPaint. В этом приложении логика между начальным и конечным вызовами предполагает отображение в окне строки "Hello, World!". В приведенном ниже коде обратите внимание, что функция TextOut используется для отображения строки.

Обычно приложение обрабатывает много других сообщений, например WM_CREATE и WM_DESTROY. В приведенном ниже коде содержится базовое представление полной функции WndProc .

Сборка примера

Создайте проект на основе Win32, как показано в разделе "Создание проекта на основе Win32" ранее в этом пошаговом руководстве.

Скопируйте код, позволяющий выполнить эти шаги, и вставьте его в исходный файл GT_HelloWorldWin32.cpp.

В меню Сборка выберите Собрать решение.

Чтобы запустить приложение, нажмите клавишу F5. Окно, содержащее текст "Hello, World!", должно отображаться в левом верхнем углу экрана.

Рассмотрим сегодня такой тип приложений приложения win32 на диалоговых окнах, visual C++, создание диалоговых окон. Приложения для windows делятся на три вида: 1. консольные — это самый простой тип приложений, 2.win32 приложения на диалоговых окнах — это самый простой тип win32 приложений и 3.просто приложения win32 это такие, где создаются дочерние окна, множество окон. Третий тип приложений считается самым сложным типом, консольные самый простой тип. Консольные приложения мы умеем создавать, а от увы win32 приложения нет.

Зачем нужно visual C++, создание диалоговых окон

Как правило все коммерческие программы содержать сильный GUI, который довольно тяжело создавать, можно например посмотреть такие программы как microsoft word или exel да и много других. Там программируются множество дочерних окон, создается множество элементов управления там сотни окон, я хз. как такие приложения создавать, они так сложновато устроены. Мы рассмотрим и будем создавать приложения которые будут состоять всего навсего из одного окошка с набором элементов. Сам я недавно с ними познакомился. Будем создавать диалоговые окна.

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

Нажимаем Ок, затем появится окошко жмем кнопку Далее и мы попадаем в окошко в котором ставим галочку на «пустой проект»

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

Создание файла main.cpp

Дальше создадим файл main.cpp со следующим кодом:

Короче вызывается просто функция DialogBox() которой передается в качестве параметра собственная процедура DlgProc() в которой мы обрабатываем 3 вида событий: WM_INITDIALOG, WM_COMMAND, WM_CLOSE. Ну в первый WM_INITDIALOG мы попадаем сразу при создании программы когда производится инициализация окна, в третий WM_CLOSE попадаем когда закрываем окно (нажимем крестик), ну и во втором параметре WM_COMMAND мы уже обрабатываем собственные события. Как видно наша процедура возвращает либо FALSE либо TRUE, если мы возвращаем FALSE, то у нас вызывается процедура которая вырисовывает окно, если мы вернем TRUE, то это означает что функция стандартная для прорисовки окна не вызовется. Это так небольшой ликбез по теории

visual C++, создание диалоговых окон, создание самого окна в редакторе

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

выбираем и мы попадаем в окно «Добавление ресурса»

Выбираем Dialog и нажимаем создать

Все диалог создан, в «Панель элементов» мы видим какие элементы мы можем добавлять, а в «Свойства» мы можем изменять свойства каждого элемента. Дальше компилируем проект, нажимаем Ctrl+F5 и у нас создается окошко с кнопкой ок и отмена

По нажатию на кнопку Ок у нас вызывается окошко

А по нажатии на кнопку отмена вызывается другое информационное окошко

Что происходит

Это все происходит потому что наша функция DialogBox() при завершении функцией EndDialog(hwnd,1); возвращает второй ее параметр поэтому в WinMain() у нас ret принимает либо 1 либо 0 смотря как была завершена функция DialogBox(), это нужно для того что б в приложениях в которых много окон, что б можно было определять какая кнопка была нажата, Ок или Отмена, это мы будем просто понимать, если Ок, то нужно применить изменения, а если Отмена то ничего не делать. Так как у нас одно оконное приложение, то нам это не нужно разбирать visual C++, создание диалоговых окон.

Это короче основа visual C++, создание диалоговых окон, от как из всего выше видно что наше приложение на диалоговых окнах очень просто создается, мы дальше разберем код как можно ввести текст через editbox и вывести на экран, а так же разберем список. Неахота сильно описывать, я просто покажу скрин проги и ниже код ее, ну а дальше опишу немножко как она работает, и так приступим, начнем со Edit Control и Button

Edit Control и Button

И так это просто поле для ввода текста и кнопка. И так создаем в визуальном редакторе для нашего прооекта visual C++, создание диалоговых окон следующий каркас:

Ну и код для работы с каркасом:

Лень описывать что нить, просто пошарте в коде, попробуйте что нить поменять, мы тут используем функцию для получения содержимого поля функции

Ну а для того что б данные вывести в поле мы используем функцию

Тут ничего не могу сказать, сам не сильно знаю, нужно читать дополнительную литературу или МСДН, но лучше конечно Питзольда.

Дальше рассмотрим программу для работы с List Box

List Box.

Это элемент список, вы должны снова создать каркас программы.

Ну и код к этому диалоговому окну:

Описание проги

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

Рассмотрим используемые функции, тут немного функций использовано. При выделении элемента из списка у нас отправляется в наше приложение команда и мы ее можем выловить в case IDC_LIST1: , там создается оператор switch (HIWORD(wParam)) и мы ловим параметр case LBN_SELCHANGE: он будет передан при выделении списка. Мы в общем создали обработчик этого события, для того что бы определить какой элемент был выделен, получить его порядковый номер мы используем функцию

для того что б получить именно само значение строки используем

для удаления элемента используем функцию

для добавление элемента в список юзаем функцию

Создание диалоговых окон — ИТОГИ

Что еще сказать? Наша процедура для обработки событий состоит из трех частей. В первой части инициализируется наше приложение. Там мы инициализировали наш список тремя значениями. Пожалуй это и все. Я сам с этими функциями и возможностями недавно познакомился. Для меня это все новенькое, но уже с данными знаниями мы можем создавать какие нить приложения.

Это вообще то мелочь что мы изучили, если посмотреть визуальный редактор, то там очень много элементов и каждый элемент имеет различные свойства. То что мы рассмотрели сейчас это мелочь «ПУЗАТАЯ». Будем дальше конечно пополнять свой запас знаний, но с этими знаниями мы уже можем создавать более менее нормальные приложения. Ну от например у меня дальше по учебнику идет приложение простая база данных, от я думаю что ж сделать создать ее свою все полностью или использовать тот код что в приложении. Там библиотека dll используется. Я беспокоюсь что ее на моем компе нету. Наверно попытаюсь все таки запустить то приложение что в книге, а затем уже свое приложение создам, где я все напишу на С++ без использования либы БД.

Мне несложно записать в текстовый файл данные, а затем их оттуда извлечь, это так сказать приложение база данных телефонных номеров. Нам уже эти знания по ВИНАПИ дают возможность создавать такие приложения плюс мы будем конечно пополнять свой запас знаний по созданию ГУИ. После этой простой БД мы создадим так же простой текстовый редактор, который будет сохранять файл, открывать файл, создавать файл и все это легко делается на ВИНАПИ. Ладно приступим, хватит писать пора дело делать 🙂 . ГУИ наконец то, аж не верится, что я дошол до его изучения.

Visual C++, создание диалоговых окон это легко для новичков с моим мега про гайдом, сможет это сделать любой школьник 🙂

Некоторое время назад я увлекался созданием оконной библиотеки под Windows на C++. И сегодня я расскажу как написать простую обертку над WinAPI для создания оконных приложений.

Как известно, приложение на голом API состоит из функции WinMain(аналог main для оконных приложений) функции WinProc для обработки сообщений.

Главная сложность при «оборачивании» функций API в классы состоит в том чтобы скрыть WinProc и сделать удобоваримую систему обработки сообщений.

Наша обертка будет состоять из двух классов: CApp и CWnd. Первый — это класс приложения, внутри него нахоится основной цикл сообщений. Второй — это класс окна.

Для начала напишем класс приложения. Он совсем простой:

//Класс нашего приложения
class CApp
<
public :
//Функция запуска нашего приложения
//содержит в себе цикл сообщений
void Run()
<
MSG msg;
while (GetMessage(&msg,0,0,0)!=0)
<
TranslateMessage(&msg);
DispatchMessage(&msg);
>
>
>;

* This source code was highlighted with Source Code Highlighter .

Он содержит единственную функцию Run, внутри которой находится цикл сообещний.
В цикле программа получает сообещения и перенаправляет их в оконную функцию(WinProc).

Далее мы создадим класс CWnd:

//Класс простого окна
class CWnd
<
//Тип указателя на функцию
typedef LRESULT (CWnd::*FuncPointer)(LPARAM,WPARAM);

//Структура указателя на функцию-обработчик
struct POINTER
<
CWnd* wnd; //Указатель на класс, которому принадлежит обработчик
FuncPointer func;
>;

protected :
HWND _hwnd; //Хендл нашего окна
map _msgmap;//Карта сообщений

* This source code was highlighted with Source Code Highlighter .

Он содержит хендл(HWND) окна и карту(map) сообщений.
Также объявляем тип указтеля на функцию-обработчик(FuncPointer) и структуру POINTER. Эта структура содержит указатель на функцию и указатель на объект класса, которому она принадлежит.

Затем добавим функцию создания окна:

//Функция создания окна
bool Create(
HWND parent, //Родительское окно, если 0 — то главное окно
LPCWSTR text, //Заголовок окна
DWORD exstyle,DWORD style, //Стили окна
int x, int y, int w, int h, //Размеры и положение
UINT >//Идентификатор окна
)
<
//Регистрируем класс окна
WNDCLASSEX wndc;
wndc.lpsz >"MyWnd" ;
wndc.cbSize= sizeof (WNDCLASSEX);
wndc.lpfnWndProc=WNDPROC(_WndProc); //Оконная процедура
wndc.cbClsExtra=0;
wndc.cbWndExtra=0;
wndc.hbrBackground=HBRUSH(COLOR_WINDOW); //Цвет фона окна
wndc.hInstance=GetModuleHandle(0); //Хендл приложения
wndc.hCursor=LoadCursor(0, >//Загружаем старндартный курсор
wndc.style=CS_HREDRAW|CS_VREDRAW;
wndc.hIcon=0;
wndc.hIconSm=0;
wndc.lpszMenuName=0;
RegisterClassEx(&wndc);

//Создаем само окно
_hwnd=CreateWindowEx(exstyle,L "MyWnd" ,text,
style|WS_CLIPCHILDREN, //Стиль WS_CLIPCHILDREN нужен для того, чтобы дочерние контролы не мигали при перерисовке
x,y,w,h,parent,HMENU(id),
GetModuleHandle(0),
this //Передаем в оконную функцию указатель на класс нашего окна
);

if (!_hwnd) return false ;
return true ;
>

* This source code was highlighted with Source Code Highlighter .

В ней мы регистрируем класс окна и создаем само окно с помощью функции CreateWindowEx.
Так же мы передаем в CreateWindowEx указатель на экземпляр CWnd, чтобы в дальнейшем можно было связать APIшный хендл(HWND) и наш экземпляр CWnd.

Теперь передем к главному.
Добавляем оконную функцию в наш класс. Она должна быть статической.

//Оконная функция
//функция в которую поступают сообщения для обработки
static LRESULT CALLBACK _WndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
<
CWnd *wnd=0;
//Сообщения WM_NCCREATE приходит до WM_CREATE
//т.е при создании окна
if (message==WM_NCCREATE)
<
//Получаем указатель на экземпляр нашего окна, который мы передали в функцию CreateWindowEx
wnd=(CWnd*)LPCREATESTRUCT(lparam)->lpCreateParams;
//И сохраняем в поле GWL_USERDATA
SetWindowLong(hwnd,GWL_USERDATA,LONG(LPCREATESTRUCT(lparam)->lpCreateParams));
wnd->_hwnd=hwnd;
>
//Теперь получаем указатель на наш экземлпяр окна, но уже из поля GWL_USERDATA
wnd=(CWnd*)GetWindowLong(hwnd,GWL_USERDATA);
if (wnd)
<
//Ищем сообщение в карте
map ::iterator it;
it=wnd->_msgmap.find(message);

//Если сообщение не найдено, то обрабатываем его по умолчанию
if (it==wnd->_msgmap.end()) return DefWindowProc(hwnd,message,wparam,lparam);
else
<
POINTER msg=it->second;
//Вызываем функцию обработчик
LRESULT result=(msg.wnd->*msg.func)(lparam,wparam);
if (result) return result;
>
>
return DefWindowProc(hwnd,message,wparam,lparam);
>
>;

* This source code was highlighted with Source Code Highlighter .

В ней происходит следующее. Сначала мы отлавливаем сообщение WM_NCCREATE. В нем мы получаем переданный в CreateWindowEx указатель и сохраняем его в поле GWL_USERDATA окна. Теперь мы в любой момент можем получить указатель на экземпляр CWnd имея на руках только HWND.
Далее ищем в карте текущее сообщение, и если оно есть вызываем по указателю обработчик из этой карты.

Теперь напишем функцию которая будет добавлять сообщение в карту:

//Функкция добавления сообщения в карту
//Приводит указатель на функцию-член класса T к указателю на функцию-член CWnd
template
bool AddMessage(UINT message,CWnd* wnd,LRESULT (T::*funcpointer)(LPARAM,WPARAM))
<
if (!wnd || !funcpointer) return false ;

POINTER msg;
msg.wnd=wnd;
msg.func=reinterpret_cast (funcpointer);

* This source code was highlighted with Source Code Highlighter .

Это шаблонная функция и она делает следующее. Преобразовывает указатель на функцию-член любого класса-наследника CWnd, в указатель на функцию-член CWnd. Это нужно для того чтобы привести все указатели к одному типу.

Вот и все, наша обертка готова.
Пример использования:

//Наследуем класс нового окна от CWnd
class CMyWnd: public CWnd
<
public :
CMyWnd()
<
//Добавляем обработчики сообщений WM_CREATE и WM_DESTROY
AddMessage(WM_CREATE, this ,&CMyWnd::OnCreate);
AddMessage(WM_DESTROY, this ,&CMyWnd::OnDestroy);
>
LRESULT OnCreate(LPARAM lparam,WPARAM wparam)
<
MessageBox(0,_T( "HelloHabr!" ),_T( "" ),0);
return 0;
>
LRESULT OnDestroy(LPARAM lparam,WPARAM wparam)
<
PostQuitMessage(0);
return 0;
>
>;

int APIENTRY WinMain(HINSTANCE hinst,HINSTANCE prev,LPSTR cmd, int showcmd)
<
//Создаем наше окно
CMyWnd *wnd= new CMyWnd;
wnd->Create(0,L "HelloHabr!" ,0,WS_OVERLAPPEDWINDOW|WS_VISIBLE,300,300,500,400,0);

//Запускаем приложение
CApp *app= new CApp;
app->Run();
return 0;
>

* This source code was highlighted with Source Code Highlighter .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *