Введение в Win32 API

Win32 API (далее WinAPI) – это набор функций (API – Application Programming Interface), работающих под управлением ОС Windows. Они содержатся в библиотеке windows.h.

С помощью WinAPI можно создавать различные оконные процедуры, диалоговые окна, программы и даже игры. Эта, скажем так, библиотека является базовой в освоении программирования Windows Forms, MFC, потому что эти интерфейсы являются надстройками этой библиотеки. Освоив её, Вы без труда будете создавать формы, и понимать, как это происходит.

Не будем внедряться в теорию. Начнём с того, как создать этот проект в MVS, а в конце статьи будет разобран простой пример.

Итак. Сначала открываем Visual Studio, затем, нажимаем на вкладку «Файл», далее «Создать проект»:

1

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

2.

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

3

Ну а теперь начнём писать простую программу, которая традиционно будет выводить на экран надпись: «Привет, Мир!!!».

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

4

Выбираем «Файл С++», вводим имя, нажимаем «Добавить». Затем открываем этот файл и вставляем в него такой код (подробности далее):

#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; // возвращаем значение функции
}

Результат должен быть таким:

5

Теперь остановимся поподробнее на коде программы.

В первой строке мы подключаем заголовочный файл 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 теперь есть. Продолжение в следующих разделах.

Автор: Marienko L.
Дата: 07.02.2014
Поделиться:

Комментарии

  1. 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;
    }
  2. druidvic

    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 который как Вы пишете не используется.

    За статью спасибо. Очень понятно все объяснено.

  3. Vova_vb

    При вводе данного кода вываливается ошибка.

    1>d:\vova\c++\введение в win32\введение в win32\введение в win32.cpp(7): error C2731: WinMain: функция не может быть перегружена
    1> d:\vova\c++\введение в win32\введение в win32\введение в win32.cpp(4): см. объявление «WinMain»

    В чем проблема?

Оставить комментарий

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