Win32 API (далее WinAPI) – это набор функций (API – Application Programming Interface), работающих под управлением ОС Windows. Они содержатся в библиотеке windows.h.
С помощью WinAPI можно создавать различные оконные процедуры, диалоговые окна, программы и даже игры. Эта, скажем так, библиотека является базовой в освоении программирования Windows Forms, MFC, потому что эти интерфейсы являются надстройками этой библиотеки. Освоив её, Вы без труда будете создавать формы, и понимать, как это происходит.
Не будем внедряться в теорию. Начнём с того, как создать этот проект в MVS, а в конце статьи будет разобран простой пример.
Итак. Сначала открываем Visual Studio, затем, нажимаем на вкладку «Файл», далее «Создать проект»:

Затем, в раскрывающемся списке Visual C++ выбираем пункт Win32, там и будет «Проект Win32». Щелкаем по нему:
Вводим название проекта, указываем путь и нажимаем «ОК». Далее будет написано: «Добро пожаловать в мастер приложения Win32». Нажимаем далее. По-умолчанию у надписи «Пустой проект» галочка отсутствует. Нам нужно её поставить и убедиться, что у нас «Тип Приложения» — Приложение Windows. Если всё верно, нажимаем – «Готово».

У нас должен быть пустой проект такого вида:

Ну а теперь начнём писать простую программу, которая традиционно будет выводить на экран надпись: «Привет, Мир!!!».
Естественно, к проекту нужно добавить файл типа «имя».cpp. Кликаем по «Файлы исходного кода» правой кнопкой мыши, в раскрывающемся списке выбираем вкладку – «Добавить», далее «Создать элемент…». В результате у нас должно появиться такое окно:

Выбираем «Файл С++», вводим имя, нажимаем «Добавить». Затем открываем этот файл и вставляем в него такой код (подробности далее):
#include <windows.h> // заголовочный файл, содержащий функции API
// Основная функция - аналог int main() в консольном приложении:
int WINAPI WinMain(HINSTANCE hInstance, // дескриптор экземпляра приложения
HINSTANCE hPrevInstance, // в Win32 не используется
LPSTR lpCmdLine, // нужен для запуска окна в режиме командной строки
int nCmdShow) // режим отображения окна
{
// Функция вывода окна с кнопкой "ОК" на экран (о параметрах позже)
MessageBox(NULL, L"Привет, мир!!!", L"Оконная процедура", MB_OK);
return NULL; // возвращаем значение функции
}
Результат должен быть таким:

Теперь остановимся поподробнее на коде программы.
В первой строке мы подключаем заголовочный файл windows.h. В нём содержатся все необходимые «апишные» функции. Здесь всё понятно.
В 4-7 строках у нас описание функции int WINAPI WinMain().
Квалификатор WINAPI, нужен для функции WinMain всегда. Просто запомните это. WinMain – название функции. Она имеет четыре параметра. Первый из них – HINSTANCE hInstance (строка 4). hInstance является дескриптором экземпляра окна (это некий код оконной процедуры, идентификатор, по которой ОС будет отличать её от остальных окон). Через него можно обращаться к окну в процессе работы в других функциях (об этом позже), что-либо менять в параметрах окна. HINSTANCE является одним из многочисленных типов данных определенных в WinAPI, таким же как int, например. А запись HINSTANCE hInstance говорит нам о том, что мы создаём новую переменную типа HINSTANCE с названием hInstance.
О типах данным мы поговорим позже, поэтому переходим к следующему параметру: HINSTANCE hPrevInstance (строка 5). Как написано в комментариях, в Win32 он не используется, так как он создан для 3.x разрядной системы, из предыдущего понятно, что это дескриптор экземпляра окна. Далее у нас переменная типа LPSTR (строка 6) с именем lpCmdLine. Она используется в том случае, если мы запускаем окно через командную строку с прописью параметров. Очень экзотический способ, поэтому мы не будем на нём задерживаться.
И последний параметр: целочисленный, определяет способ показа окна. Нужен для функции ShowWindow, которая будет описана позже. Например, с помощью него мы можем развернуть окно на весь экран, сделать его определённой высоты, прозрачным или поверх остальных.
Переходим к функции MessageBox() (строка 10). Она имеет четыре параметра и нужна для вывода сообщений о ошибках, например. В данном случае мы использовали её для вывода сообщения. В общем виде описание функции выглядит следующим образом:
int MessageBox(HWND hWnd, // дескриптор родительского окна
LPCTSTR lpText, // указатель на строку с сообщением
LPCTSTR lpCaption, // указатель на строку с текстом заголовка
UINT uType);// флаги для отображения кнопок, стиля пиктограммы и прочее
В нашем случае, первому параметру присвоен ноль. Всё потому, что у нас нет родительских окон (оно не запущено какой-нибудь программой).
Далее у нас идут две переменные типа LPCTSTR: lpText и lpCaption. Первая сообщает информацию, которая будет выведена в окне в текстовом виде. Вторая сообщает, что будет написано в тексте заголовка к окну. Это аналог char *str, но всё же нет. Для того, чтобы текст выводился корректно, нужно перед строкой поставить букву L (UNICODE строка).
Ну и последний тип данных – UINT – 32-х битное целое без знака. То есть аналог unsigned int. Этому параметру можно передавать некоторые значения (о них тоже позже), за счёт чего можно менять вид кнопки. В нашем случае – это MB_OK — означает, что окно создаёт кнопку с надписью «ОК» и соответствующим действием при её нажатии (закрытием приложения).
В строке 11 мы возвращаем значение функции, так как она имеет не тип void.
Таким образом, общее представление о WinAPI теперь есть. Продолжение в следующих разделах.
Комментарии
vovkapypkin
как улучшить часики #include <math.h> #define _USE_MATH_DEFINES #include <cmath> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; RECT rect; GetClientRect(hWnd, &rect); static float x=300 , y=400 , r=100; static double i; POINT p; static int x0 = 400, y0 = 400; switch (message) { case WM_CREATE: SetTimer(hWnd, 1, 1000, NULL); break; case WM_TIMER: i+=0.2; y = sin(i)*r; x = cos(i)*r; y += y0; x += x0; InvalidateRect(hWnd, NULL, TRUE); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); MoveToEx(hdc, x0, y0, &p); LineTo(hdc, x, y); EndPaint(hWnd, &ps); break; case WM_DESTROY: KillTimer(hWnd, 1); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }druidvic
Подскажите пжл. как перевести первое предложение в — A handle to the previous instance of the application. This parameter is always NULL. If you need to detect whether another instance already exists, create a uniquely named mutex using the CreateMutex function. CreateMutex will succeed even if the mutex already exists, but the function will return ERROR_ALREADY_EXISTS. This indicates that another instance of your application exists, because it created the mutex first. However, a malicious user can create this mutex before you do and prevent your application from starting. To prevent this situation, create a randomly named mutex and store the name so that it can only be obtained by an authorized user. Alternatively, you can use a file for this purpose. To limit your application to one instance per user, create a locked file in the user’s profile directory.
Общий смысл понятен а вот A handle to ускользает от понимания. Это с https://msdn.microsoft.com/en-us/library/windows/desktop/ms633559(v=vs.85).aspx Относится к параметру hPrevInstance который как Вы пишете не используется.
За статью спасибо. Очень понятно все объяснено.
Vova_vb
При вводе данного кода вываливается ошибка.
1>d:\vova\c++\введение в win32\введение в win32\введение в win32.cpp(7): error C2731: WinMain: функция не может быть перегружена
1> d:\vova\c++\введение в win32\введение в win32\введение в win32.cpp(4): см. объявление «WinMain»
В чем проблема?