- games maker Все о создании игр и не только
- Введение в WinAPI. Часть первая. Создание окна.
- Структура оконного приложения
- Стартовая функция WinMain
- Регистрация класса окна
- Создание окна
- Отображение и перерисовка окна
- Цикл обработки сообщений
- Оконная функция — обработка сообщений окна
- Комментариев к записи: 13
games maker Все о создании игр и не только
18 января 2010 в 22:06
Введение в WinAPI. Часть первая. Создание окна.
Наконец-то! Наконец-то! Сегодня мы начнём создавать полноценное окно Windows. Прощай убогая консоль.
К этому моменту вы уже должны неплохо знать синтаксис C++, уметь работать с ветвлениями и циклами, хорошо понимать работу функций. Если вы справились с морским боем, можете считать, что всё это вы усвоили.
Венгерская форма записи
Весь код, который мы встретим в WinAPI написан в венгерской форме. Это такое соглашение по написанию кода.
При этом перед именем переменной ставится начальная буква типа. Все слова в именах переменных и функций начинаются с заглавной буквы.
Вот несколько префиксов:
b — переменная типа bool.
l — переменная типа long integer.
w — от word (слово) — 16 бит. Переменная типа unsigned short.
dw — от double word (двойное слово) — 32 бита. Переменная типа unsigned long.
sz — строка заканчивающаяся нулём (string terminated zero). Просто обычная строка, которую мы постоянно использовали.
p или lp — указатель (от pointer). lp (от long pointer) — данные указатели перешли из прошлого. Сейчас lp и p означают одно и то же.
h — описатель (от handle).
Например, указатель будет называться вот так:
Данная форма записи используется Microsoft. Многие критикуют этот способ именования переменных. Но подобные вещи (соглашения о кодировании) в больших компаниях жизненно необходимы.
Напомню, что идентификаторы констант обычно состоят только из заглавных букв: WM_DESTROY. WM_DESTOY — это 2, константа определена через define.
Кроме того, в winAPI используется очень много переопределённых типов. Вот на этой страничке — http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx , можете найти описания всех типов Windows (на английском).
И ещё одна вещь, которую мы не разбирали. Указателям часто присваивается значение NULL. Считайте, что это просто 0 и указатели которым присвоено значение NULL (ноль), не указывают ни на какой участок памяти.
Windows API (WinAPI)
Все программы под Windows используют специальный интерфейс программирования WinAPI. Это набор функций и структур на языке C, благодаря которым ваша программа становится совместимой с Windows.
Windows API обладает огромными возможностями по работе с операционной системой. Можно даже сказать — безграничными.
Мы не рассмотрим даже один процент всех возможностей WinAPI. Первоначально я хотел взять больше материала, но это заняло бы слишком много времени, и увязнув в болоте WinAPI, до DirectX’а мы добрались бы через пару лет. Описание WinAPI займёт два урока (включая этот). В них мы рассмотрим только каркас приложения под Windows.
Программа под Windows точно так же как и программа под DOS, имеет главную функцию. Здесь эта функция называется WinMain.
Программа под Windows состоит из следующих частей (всё это происходит внутри WinMain):
Создание и регистрация класса окна. Не путайте с классами C++. WinAPI написана на C, здесь нет классов в привычном для нас понимании этого слова.
Создание окна программы.
Основной цикл, в котором обрабатываются сообщения.
Обработка сообщений программы в оконной процедуре. Оконная процедура представляет собой обычную функцию.
Вот эти четыре пункта — основа программы Windows. В течение этого и следующего урока мы разберём всё это подробно. Если вы запутаетесь в описании программы, то вернитесь к этим пунктам.
Теперь разберём всё это подробно:
WinAPI: Структура WNDCLASS
Прежде всего нужно создать и заполнить структурную переменную WNDCLASS, а затем на её основе зарегистрировать оконный класс.
Вот как выглядит эта структура:
Структура WNDCLASS в составе WinAPI определяет базовые свойства создаваемого окна: иконки, вид курсора мыши, есть ли меню у окна, какому приложению будет принадлежать окно.
После того как вы заполните эту структуру, на её основе можно зарегистрировать оконный класс. Речь идёт не о таких классах как в C++. Скорее можно считать, что оконный класс это такой шаблон, вы его зарегистрировали в системе, и теперь на основе этого шаблона можно создать несколько окон. И все эти окна будут обладать свойствами, которые вы определили в структурной переменной WNDCLASS.
WinAPI: Функция CreateWindow
После регистрации оконного класса, на его основе создаётся главное окно приложения (мы сейчас приступили ко второму пункту). Делается это с помощью функции CreateWindow. Она имеет следующий прототип:
Если в оконном классе (структуре WNDCLASS) задаются базовые свойства окна, то здесь — более специфические для каждого окна: размер окна, координаты.
Данная функция возвращает описатель окна. С помощью описателя можно обращаться к окну, это примерно как идентификатор.
Обратите внимание, что здесь очень много новых типов. На самом деле они все старые, просто переопределены. Например: HWND — это переопределение типа HANDLE, который в свою очередь является переопределением PVOID, который в свою очередь является переопределением void*. Как глубоко закопана правда! Но всё же тип HWND — это указатель на void.
Окно состоит из нескольких частей. Практически в каждой программе вы увидите: заголовок окна, системное меню (если нажать на иконку приложения в левой верхней части окна), три системные кнопки для работы с окном: свернуть, развернуть на весь экран и закрыть. Также, практически всегда в приложении присутствует меню. Вот как раз последнего у нас точно не будет. И, конечно же, большую часть окна занимает т.н. клиентская область, в которой обычно и работает пользователь.
Это что касается оконного режима. Довольно долго мы будем практиковаться с DiectX именно в окне — не будем пользоваться полноэкранным режимом.
Обработка сообщений (Message handling)
Основным отличием всех наших предыдущих программ от программ под Windows является обработка сообщений.
Например, когда пользователь нажимает какую-нибудь клавишу на клавиатуре, генерируется сообщение, что была нажата клавиша. Затем это сообщение поступает в приложение, которое было активным, когда пользователь нажал клавишу.
Здесь у нас произошло событие (event) — была нажата клавиша.
Событием может быть: перемещение курсора мыши, смена фокуса приложения, нажатие клавиши клавиатуры, закрытие окна. Событий очень много. Очень! За секунду в операционной системе может происходить десятки событий.
Так вот, когда происходит какое-либо событие, операционная система создаёт сообщение: была нажата такая-то клавиша, координаты курсора мыши изменились, открылось новое окно.
Сообщения может создавать как операционная система, так и различные приложения.
Сообщение представляет собой структуру, и выглядят следующим образом:
Обратите внимание, как с помощью typedef переопределяются структуры.
Чтобы создать данную структуру можно воспользоваться следующим кодом:
Всё. Дальше можете использовать эту структуру как обычно.
Здесь, поле, в котором содержится код сообщения (имя сообщения, сравнивается с константой WM_DESTROY. WM — от Windows Message (сообщение Windows). WM_DESTROY — это сообщение, которое генерируется при закрытии окна (destroy — уничтожить).
Коды сообщений определены с помощью констант и имеют префикс WM_: WM_CLOSE, WM_CREATE и др.
В структуре MSG встречается тип HWND — от Window Handle (дескриптор окна или описатель окна). Это такая штука, которая «описывает» окно. Это что-то вроде идентификатора (имени окна).
Запомните это слово — handle (описатель, дескриптор). В Windows это понятие используется очень часто. Почти все типы Windows, которые начинаются с H — описатели: описатель иконки, описатель шрифта, описатель экземпляра приложения. Их штук тридцать насколько я помню.
Все взаимодействия между приложениями в Windows осуществляются с помощью этих самых описателей окон (HWND).
Существует ещё один важный описатель — описатель приложения (HINSTANCE — первый параметр WinMain) — это уникальный идентификатор приложения, благодаря которому операционная система не сможет перепутать две разных программы. Это примерно как штрих-код. Мы рассмотрим его позже.
Каждый раз, когда пользователь совершает какое-то действие, создаётся и заполняется сообщение: задаётся описатель окна, которое должно получить данное сообщение, задаётся идентификатор сообщения, заполняются параметры, заполняется время (текущее) и указываются координаты курсора мыши (смотрите структуру).
После этого данное сообщение помещается в очередь сообщений операционной системы. Когда доходит очередь до нашего сообщения, оно отправляется нужному окну (windows знает какому окну отправлять каждое сообщение благодаря описателям). Когда сообщение приходит в приложение, оно помещается в очередь сообщений приложения. Как только до него доходит очередь, оно обрабатывается.
Смотрите, между тем моментом, когда пользователь совершил какое-либо действие (произошло событие и сгенерировалось сообщение) и тем моментом, когда программа среагировала на это действие (сообщение было обработано программой) происходит много событий. Ведь как в очереди сообщений Windows так и в очереди сообщений приложения может быть много сообщений. В первом случае речь может идти о сотнях, во втором случае как минимум о нескольких.
Оконная процедура (Window procedure — WndProc)
Продолжаем с того момента, как сообщение попало в очередь сообщений приложения. Как только до него дошла очередь, оно обрабатывается. Для обработки сообщений в каждой программе должна существовать специальная функция — оконная процедура. Обычно она называется WndProc (от Window Procedure). Вызов оконной процедуры расположен в основном цикле программы и выполняется при каждой итерации цикла.
Сообщения (в виде структурных переменных MSG) попадают в данную функцию в виде параметров: описатель окна, идентификатор сообщения и два параметра. Обратите внимание, что в оконную процедуру не передаются поля time и pt. То есть сообщение уже «разобрано».
Внутри оконной процедуры расположено ветвление switch, в котором идёт проверка идентификатора сообщения. Вот пример простой оконной процедуры (она полностью рабочая):
И последнее — основной цикл. Он очень прост. Каждую итерацию цикла проверяется очередь сообщений приложения. Если в очереди сообщений есть сообщение, оно вытаскивается из очереди. Затем в теле цикла происходит вызов оконной процедуры, чтобы обработать взятое из очереди сообщение.
Вот, в общем-то, и всё на сегодня. Уже видно, что программа под WinAPI намного сложнее программы под DOS. Как я уже писал выше, в следующем уроке мы разберём код работающей программы.
В качестве упражнения создайте новый проект. В окне New Project (Новый проект) выберите шаблон (template) — Win32Project (до сих пор мы выбирали Win32 Console Application). В одном из следующих окон не ставьте флажок Empty Project (пустой проект) и IDE сгенерирует заготовку программы.
Если вы внимательно посмотрите на код файла имя_проекта.cpp, то вы обнаружите все вещи, которые мы обсуждали: структурную переменную MSG, заполнение структуры WNDCLASS, создание окна функцией CreateWindow, основной цикл программы. Кроме того, в файле определена функция WndProc. В ней происходит обработка нескольких сообщений в ветвях switch: WM_COMMAND, WM_PAINT, WM_DESTROY. Найдите всё это в файле.
Кроме того что мы рассмотрели, в программе содержится много дополнительного кода. В следующем выпуске мы рассмотрим код программы, в котором будет вырезано всё лишнее. Он будет намного проще и понятнее того, что генерирует IDE.
Источник
Структура оконного приложения
Оконные приложения строятся по принципам событийно-управляемого программирования (event-driven programming) — стиля программирования, при котором поведение компонента системы определяется набором возможных внешних событий и ответных реакций компонента на них. Такими компонентами в Windows являются окна.
С каждым окном в Windows связана определенная функция обработки событий – оконная функция . События для окон называются сообщениями . Сообщение относится к тому или иному типу, идентифицируемому определенным кодом (32-битным целым числом), и сопровождается парой 32-битных параметров ( WPARAM и LPARAM ), интерпретация которых зависит от типа сообщения.
Задача любого оконного приложения — создать главное окно и сообщить Windows функцию обработки событий для этого окна. Все самое интересное для приложения будет происходить именно в функции обработки событий главного окна.
В Windows программа пассивна. После запуска она ждет, когда ей уделит внимание операционная система. Операционная система делает это посылкой сообщений. Сообщения могут быть разного типа, они функционируют в системе достаточно хаотично, и приложение не знает, какого типа сообщение придет следующим. Логика построения Windows-приложения должна обеспечивать корректную и предсказуемую работу при поступлении сообщений любого типа.
Классическое оконное приложение, как правило, состоит по крайней мере из двух функций:
Стартовая функция WinMain
В консольной программе на С точкой входа является функция main() . С этого места программа начинает выполняться.
Точкой входа программы для Windows является функция WinMain() .
Эта функция использует последовательность вызовов API и при завершении возвращает операционной системе целое число.
Аргументы функции:
- hInstance – дескриптор процесса (instance handle) – число, идентифицирующее программу, когда она работает под Windows. Если одновременно работают несколько копий одной программы, каждая копия имеет свое значение hInstance .
- hPrevInstance — предыдущий дескриптор процесса (previous instance) — в настоящее время устарел, всегда равен NULL.
- szCmdLine — указатель на оканчивающуюся нулем строку, в которой содержатся параметры, переданные в программу из командной строки. Можно запустить программу с параметром командной строки, вставив этот параметр после имени программы в командной строке.
- iCmdShow — целое константное значение, показывающее, каким должно быть выведено на экран окно в начальный момент. Задается при запуске программы другой программой. В большинстве случаев число равно 1 ( SW_SHOWNRMAL ).
Имя | Значение | Описание |
SW_HIDE | 0 | Скрывает окно и делает активным другое окно |
SW_SHOWNORMAL | 1 | Отображает и делает активным окно в его первоначальном размере и положении. |
SW_SHOWMINIMIZED | 2 | Активизирует окно и отображает его в свернутом виде |
SW_SHOWMAXIMIZED | 3 | Активизирует окно и отображает его в полноэкранном виде |
SW_SHOWNOACTIVATE | 4 | Отображает окно аналогично SW_SHOWNORMAL , но не активизирует его |
SW_SHOW | 5 | Отображает и делает активным окно с текущим размером и положением. |
SW_MINIMIZE | 6 | Сворачивает текущее окно и делает активным следующее окно в порядке очереди. |
SW_SHOWMINNOACTIVE | 7 | Сворачивает окно аналогично SW_SHOWMINIMIZED , но не активизирует его. |
SW_SHOWNA | 8 | Отображает окно в текущей позиции аналогично SW_SHOW , но не активизирует его. |
SW_RESTORE | 9 | Отображает и активизирует окно. Если окно было свернуто или развернуто во весь экран, оно отображается в своем первоначальном положении и размере. |
SW_SHOWDEFAULT | 10 | Отображает окно способом, заданным по умолчанию. |
SW_FORCEMINIMIZE | 11 | Применяется для минимизации окон, связанных с различными потоками. |
В структуре стартовой функции Windows можно выделить следующие операции, образующие «скелет» программы:
Регистрация класса окна
Регистрация класса окна осуществляется функцией
Члены структуры
style — устанавливает стиль(и) класса. Этот член структуры может быть любой комбинацией стилей класса.
Имя | Значение | Описание |
CS_VREDRAW | 0x01 | Вертикальная перерисовка: осуществлять перерисовку окна при перемещении или изменении высоты окна. |
CS_HREDRAW | 0x02 | Горизонтальная перерисовка: осуществлять перерисовку окна при перемещении или изменении ширины окна. |
CS_KEYCVTWINDOW | 0x04 | В окне будет выполняться преобразование виртуальных клавиш. |
CS_DBLCLKS | 0x08 | Окну будут посылаться сообщения о двойном щелчке кнопки мыши. |
CS_OWNDC | 0x20 | Каждому экземпляру окна присваивается собственный контекст изображения. |
CS_CLASSDC | 0x40 | Классу окна присваивается собственный контекст изображения,который можно разделить между копиями. |
CS_PARENTDC | 0x80 | Классу окна передается контекст изображения родительского окна. |
CS_NOKEYCVT | 0x100 | Отключается преобразование виртуальных клавиш. |
CS_NOCLOSE | 0x200 | Незакрываемое окно: в системном меню блокируется выбор пункта закрытия окна. |
CS_SAVEBITS | 0x800 | Часть изображения на экране, закрытая окном, сохраняется. |
CS_BYTEALIGNCLIENT | 0x1000 | Выравнивание клиентской области окна: использование границы по байту по оси x. |
CS_BYTEALIGNWINDOW | 0x2000 | Выравнивание окна: bспользование границы по байту по оси x. |
CS_PUBLICCLASS CS_GLOBALCLASS | 0x4000 | Определяется глобальный класс окон. |
lpfnWndProc — указатель на оконную процедуру.
cbClsExtra — устанавливает число дополнительных байт, которые размещаются вслед за структурой класса окна. Система инициализирует эти байты нулями, в большинстве случаев равен 0.
cbWndExtra — устанавливает число дополнительных байтов, которые размещаются вслед за экземпляром окна. Система инициализирует байты нулями.
hInstance — дескриптор экземпляра, который содержит оконную процедуру для класса.
hIcon — дескриптор значка класса, дескриптор ресурса значка. Если этот член структуры — NULL, система предоставляет заданный по умолчанию значок.
hCursor — дескриптор курсора класса, дескриптор ресурса курсора. Если этот член структуры — NULL, приложение устанавливает форму курсора всякий раз, когда мышь перемещается в окно прикладной программы.
hbrBackground — дескриптор кисти фона класса, дескриптор физической кисти, которая используется, чтобы красить цветом фона, или код цвета, преобразованный к типу HBRUSH .
lpszMenuName — указатель на символьную строку с символом конца строки ( ‘\0’ ), которая устанавливает имя ресурса меню класса. Можно использовать целое число, чтобы идентифицировать меню с помощью макроса MAKEINTRESOURCE( int ) . Если этот член структуры — NULL , окна, принадлежащие этому классу, не имеют заданного по умолчанию меню.
lpszClassName — указатель на символьную строку с именем класса, оканчивающуюся ‘\0’ .
Создание окна
Создание окна осуществляется функцией
Прототип функции находится в файле библиотеки user32.dll.
Возвращаемое значение – дескриптор создаваемого окна. В случае невозможности создать окно возвращается NULL.
Аргументы функции :
lpClassName – указывает на строку с ‘\0’ в конце, которая определяет имя класса окна. Имя класса может быть зарегистрированным функцией RegisterClass или любым из предопределенных имен класса элементов управления.
lpWindowName — указывает на строку с ‘\0’ в конце, которая определяет имя окна.
dwStyle — определяет стиль создаваемого окна.
Имя | Значение | Описание |
WS_BORDER | 0x00800000 | Окно имеет тонкую границу в виде линии. |
WS_CAPTION | 0x00C00000 | Окно имеет строку заголовка. |
WS_CHILD | 0x40000000 | Окно является дочерним. |
WS_DISABLED | 0x08000000 | Окно является изначально неактивным. |
WS_GROUP | 0x00020000 | Окно группирует другие управляющие элементы. |
WS_HSCROLL | 0x00100000 | Окно содержит горизонтальную полосу прокрутки. |
WS_MAXIMIZE | 0x01000000 | Исходный размер окна – во весь экран. |
WS_MINIMIZE | 0x20000000 | Исходно окно свернуто. |
WS_OVERLAPPED | 0x00000000 | Окно может быть перекрыто другими окнами. |
WS_POPUP | 0x80000000 | Всплывающее окно. |
WS_SYSMENU | 0x00080000 | Окно имеет системное меню в строке заголовка. |
WS_VISIBLE | 0x10000000 | Окно изначально видимое. |
WS_VSCROLL | 0x00200000 | Окно имеет вертикальную полосу прокрутки. |
x — определяет координату левой стороны окна относительно левой стороны экрана. Измеряется в единицах измерения устройства, чаще всего в точках (pt). Для дочернего окна определяет координату левой стороны относительно начальной координаты родительского окна. Если установлен как CW_USEDEFAULT , Windows выбирает заданную по умолчанию позицию окна.
у – определяет координату верхней стороны окна относительно верхней стороны экрана. Измеряется в единицах измерения устройства, чаще всего в точках (pt). Для дочернего окна определяет координату верхней стороны относительно начальной координаты родительского окна.
nWidth – определяет ширину окна в единицах измерения устройства. Если параметр соответствует CW_USEDEFAULT , Windows выбирает заданную по умолчанию ширину и высоту для окна.
nHeight – определяет высоту окна в единицах измерения устройства.
hWndParent – дескриптор родительского окна.
hMenu – идентифицирует меню, которое будет использоваться окном. Этот параметр может быть NULL , если меню класса будет использовано.
hInstance — идентифицирует экземпляр модуля, который будет связан с окном.
lpParam — указывает на значение, переданное окну при создании.
Отображение и перерисовка окна
Отображение окна осуществляется функцией
Прототип функции находится в файле библиотеки user32.dll.
Возвращаемое значение: 1 – успешное отображение окна, 0 – ошибка.
Аргументы функции :
hWnd – дескриптор отображаемого окна.
nCmdShow – константа, определяющая, как будет отображаться окно согласно таблице.
Перерисовка окна осуществляется функцией
Прототип функции находится в файле библиотеки user32.dll.
Возвращаемое значение: 1 – успешная перерисовка окна, 0 – ошибка.
Аргумент функции hWnd – дескриптор окна.
Цикл обработки сообщений
После вызова функции UpdateWindow , окно окончательно выведено на экран. Теперь программа должна подготовить себя для получения информации от пользователя через клавиатуру и мышь. Windows поддерживает «очередь сообщений» (message queue) для каждой программы, работающей в данный момент в системе Windows. Когда происходит ввод информации, Windows преобразует ее в «сообщение», которое помещается в очередь сообщений программы. Программа извлекает сообщения из очереди сообщений, выполняя блок команд, известный как «цикл обработки сообщений» (message loop):
Для получения сообщения из очереди используется функция:
Прототип функции находится в файле библиотеки user32.dll.
В случае получения из очереди сообщения, отличного от WM_QUIT , возвращает ненулевое значение.
Аргументы функции :
lpMsg — указатель на структуру сообщения.
Структура POINT имеет вид
hWnd — дескриптор окна, очередь для которого просматривается.
wMsgFilterMin — нижняя граница фильтра идентификаторов сообщений.
wMsgFilterMax — верхняя граница фильтра идентификаторов сообщений.
передает аргумент — структуру msg обратно в Windows для преобразования какого-либо сообщения с клавиатуры. Возвращает ненулевое значение в случае успешной расшифровки сообщения, 0 – ошибка.
передает аргумент — структуру msg обратно в Windows. Windows отправляет сообщение для его обработки соответствующей оконной процедуре — таким образом, Windows вызывает соответствующую оконную функцию, указанную при регистрации класса окна.
После того, как оконная функция обработает сообщение, оно возвращается в Windows, которая все еще обслуживает вызов функции DispatchMessage . Когда Windows возвращает управление в стартовую функцию WinMain() к следующему за вызовом DispatchMessage коду, цикл обработки сообщений в очередной раз возобновляет работу, вызывая GetMessage .
Возвращает значение, определяемое оконной функцией, которое чаще всего игнорируется.
Прототипы функций находятся в файле библиотеки user32.dll.
Пример стартовой функции, создающей и выводящей окно размером 500х300 точек:
Примечание : Для корректной сборки приложения используется многобайтовая кодировка.
Оконная функция — обработка сообщений окна
Оконная функция предназначена для обработки сообщений окна. Функция обработки сообщений окна организована по принципу ветвления, состоящего из последовательной проверки типа сообщения. При совпадении типа сообщения, переданного в структуре Message с соответствующей веткой, осуществляется его обработка. Минимальный вид оконной функции представлен ниже.
4 аргумента оконной функции идентичны первым четырем полям структуры сообщения MSG .
В примере обрабатывается только один тип сообщения WM_DESTROY , которое передается оконной функции при закрытии окна.
Вызов функции DefWindowProc() обрабатывает по умолчанию все сообщения, которые не обрабатывает оконная процедура.
Функция PostQuitMessage() сообщает Windows, что данный поток запрашивает завершение. Аргументом является целочисленное значение, которое функция вернет операционной системе.
Результат выполнения программы, выводящей окно:
Комментариев к записи: 13
/*WinAPI приложение. Минимальный
набор функций для отображения окна.
Эта программа станет базовой заготовкой для всех последующих программ*/
#include
//Создаём прототип функции окна
LRESULT CALLBACK WndProc( HWND , UINT , WPARAM , LPARAM );
//объявляем имя программы
char szProgName[]=&qout;Имя программы&qout;;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
<
HWND hWnd; //идентификатор окна
MSG lpMsg;
WNDCLASS w; //создаём экземпляр структуры WNDCLASS и начинаем её заполнять
w.lpszClassName=szProgName; //имя программы
w.hInstance=hInstance; //идентификатор текущего приложения
w.lpfnWndProc=WndProc; //указатель на функцию окна
w.hCursor=LoadCursor( NULL , IDC_ARROW); //загружаем курсор в виде стрелки
w.hIcon=0; //иконки у нас не будет пока
w.lpszMenuName=0; //и меню пока не будет
w.hbrBackground=( HBRUSH )GetStockObject(WHITE_BRUSH); //цвет фона окна — белый
w.style= CS_HREDRAW | CS_VREDRAW ; //стиль окна — перерисовываемое по х и по у
w.cbClsExtra=0;
w.cbWndExtra=0;
//Если не удалось зарегистрировать класс окна — выходим
if (! RegisterClass (&w))
return 0;
//Создадим окно в памяти, заполнив аргументы CreateWindow
hWnd= CreateWindow (szProgName, //Имя программы
«Моя первая программа!» , //Заголовок окна
WS_OVERLAPPEDWINDOW , //Стиль окна — перекрывающееся
100, //положение окна на экране по х
100, //по у
500, //размеры по х
400, //по у
( HWND ) NULL , //идентификатор родительского окна
( HMENU ) NULL , //идентификатор меню
( HINSTANCE )hInstance, //идентификатор экземпляра программы
( HINSTANCE ) NULL ); //отсутствие дополнительных параметров
//Выводим окно из памяти на экран
ShowWindow(hWnd, nCmdShow);
//Обновим содержимое окна
UpdateWindow(hWnd);
//Цикл обработки сообщений
while ( GetMessage (&lpMsg, NULL , 0, 0)) < //Получаем сообщение из очереди
TranslateMessage(&lpMsg); //Преобразуем сообщения клавиш в символы
DispatchMessage (&lpMsg); //Передаём сообщение соответствующей функции окна
>
return (lpMsg.wParam);
>
//Функция окна
LRESULT CALLBACK WndProc( HWND hWnd, UINT messg,
WPARAM wParam, LPARAM lParam)
<
HDC hdc; //создаём контекст устройства
PAINTSTRUCT ps; //создаём экземпляр структуры графического вывода
//Цикл обработки сообщений
switch (messg)
<
//сообщение рисования
case WM_PAINT :
//начинаем рисовать
hdc=BeginPaint(hWnd, &ps);
//здесь вы обычно вставляете свой текст:
TextOut(hdc, 150,150, «Здравствуй, WIN 32 API. » , 26);
//закругляемся
//обновляем окно
ValidateRect(hWnd, NULL );
//заканчиваем рисовать
EndPaint(hWnd, &ps);
break ;
//сообщение выхода — разрушение окна
case WM_DESTROY :
PostQuitMessage(0); //Посылаем сообщение выхода с кодом 0 — нормальное завершение
break ;
default:
return ( DefWindowProc (hWnd, messg, wParam, lParam));
//освобождаем очередь приложения от нераспознаных
>
return 0;
>
Источник