Введение в WinApi — HackZona.Ru

Введение в WinApi

Введение в WinApi

Тип статьи:
Со старой ХакЗоны.
Источник:
Вот решил сам написать небольшое введение.
Для того чтобы писать программы под Windows достачно обычного компилятора, например DevCpp. Найти его достаточно просто. Пользуйтесь гуглом.
Начнем прям с кода:
Код
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
MessageBox(NULL, «Ура работает», «Test», MB_OK|MB_ICONEXCLAMATION);
return 0;
}

итак windows.h это заголовочный файл котрый содержит практически все функции объявленные в API.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) это так сказать точка входа в программу windows. Если допустим вы пишите консольную программу то точкой входа является int main(int arq,char* pszOfArqs[]).
MessageBox(NULL, «Ура работает»", «Test», MB_OK); Первый параметр это идентификатор родительского окна, его у нас нету по этому он установлен в NULL. Второй параметр текст, третий заголовок, 4 это то какие кнопки содержит окно и его значок. Если у вас нет
MSDN'a смотрите описание этой функции в гугле там и узнаете подробный список параметров.

Немного теории
Windows работает с программами с помощью сообщений. Тоесть если пользователь нажал на кнопку кликнул куда то то система отправляет программе сообщение. Если например в вашей программе есть кнопки(button) то при клике на кнопку (да и вообще при клике на любой элемент) система отправит сообщение программе WM_COMMAND. Если пользователь захочет закрыть окно (нажмет на красный крестик о0) то программе придет сообщение WM_DESTROY. Эти сообщения мы должны обрабатывать.
Сейчас мы создадим окно с кнопкой, а точнее с несколькими кнопками(чтобы показать работу с идентификаторами)

Практика
Итак начнем.
Вот код:
Код
#include «windows.h»

#define ID_BUTTON1 1000
#define ID_BUTTON2 5000
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
int WINAPI WinMain ( HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR IpCmdLine,int nCmdShow )
{
HWND hwnd;//Дескрипторы окон (button — это тоже окна)
HWND button;
HWND button2;
MSG msg;
WNDCLASS w;
memset(&w,0,sizeof(WNDCLASS));
w.style=CS_HREDRAW|CS_VREDRAW;
w.lpfnWndProc=WndProc;
w.hInstance=hInstance;
w.hbrBackground=HBRUSH(COLOR_BTNFACE + 1);
w.lpszClassName =«Super Window»;
RegisterClass(&w);
hwnd = CreateWindow(«Super Window»,«Super Window», WS_OVERLAPPEDWINDOW,
10,10,265,268,NULL,NULL,hInstance,NULL);
//делаем кнопку
button=CreateWindow(«button»,«Кнопка №1»,WS_VISIBLE|WS_CHILD,240,205,28,28,hwnd,(HMENU)ID_BUTTON1,NULL,NULL);
button2=CreateWindow(«button»,«Кнопка №2»,WS_VISIBLE|WS_CHILD,300,300,200,25,hwnd,(HMENU)ID_BUTTON2,hInstance,NULL);
ShowWindow(hwnd,nCmdShow);
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
{
switch (Message){
case WM_COMMAND:
if(wparam==ID_BUTTON1){
MessageBox(NULL, «Вы нажали на кнопку №1», «Test», MB_OK|MB_ICONEXCLAMATION);
}
if(wparam==ID_BUTTON2){
MessageBox(NULL,«Вы нажали на кнопку 2»,«Тест»,MB_OK|MB_ICONEXCLAMATION);
}
}


if (Message == WM_DESTROY )
{
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,Message,wparam,lparam);
}

ЧТо здесь нового? #define ID_BUTTON1 1000
#define ID_BUTTON2 5000
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
#define ID_button это уникальный идентификатор кнопки.
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM)-функция обработки сообщений
дальше HWND это тип дескриптора окна.(Даже не знаю как еще сказать) Всего мы объявили их 3. Это две кнопки(да да кнопки тоже окна) и hwnd — родительское окно(главное)
Что бы создать родительское окно нам нужно заполнить структуру WNDCLASS. Для начала мы ее объявляем WNDCLASS w;
Она содержит следующие поля
Цитата
* UINT style — стиль (поведение) класса окон,
* WNDPROC lpfnWndProc — процедура обработки событий окна,
* int cbClsExtra — размер дополнительной памяти в системной структуре класса для данных пользователя,
* int cbWndExtra — размер дополнительной памяти в системной структуре окна для данных пользователя,
* HINSTANCE hInstance — дескриптор модуля (экземпляра программы), в котором реализована процедура обработки,
* HICON hIcon — дескриптор иконки окна,
* HCURSOR hCursor — дескриптор курсора мыши для окна,
* HBRUSH hbrBackground — дескриптор «кисточки» для закрашивания фона окна,
* LPCSTR lpszMenuName — имя ресурса, содержащего меню окна,
* LPCSTR lpszClassName — имя класса.

Чтобы не заполнять их все мы заполняем память по адресу &w нулями вот этой функцией memset(&w,0,sizeof(WNDCLASS));
Класс окна мы назвали Super Window(Гы похоже на манию величия) Затем мы его регестрируем RegisterClass(&w);
Так теперь создаем окно. Для этого служит функция CreateWindow Она имеет следующие параметры :
1. Имя класса окна(Super Window)
2.Заголовок окна
3.Стиль поведения (мы задали WS_OVERLAPPEDWINDOW — «перекрываемое» окно с системным меню, кнопками сворачивания/разворачивания, рамкой изменения размеров, короче, типичный стиль для главного окна приложения. )
4 и 5 Координаты окна
6 и 7 Ширина и высота
остальные параметры установлен в NULL кроме одного hInstance- дескриптор экземпляра программы
Таким образом мы создали окно.
Теперь давайте сделаем две кнопки. Они тоже создаются функцией CreateWindow. Только нам не нужно регистрировать никаких классов, так как классы кнопок уже предопределены в winapi. Тоесть нужно задать параметр Имя класса лкна как «button» что мы и сделали. Единственное новое здесь это (HMENU)ID_BUTTON1 — это уникальный идентификатор кнопки. Так теперь нам надо отобразить окно на экране делаем это ShowWindow(hwnd,nCmdShow); Затем нужно задать цикл приема сообщений while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Так теперь можно переходить к процедуре обработки сообщений:
Собственно не чего сложного если вы знакомы с синтаксисом switch.
Нам нужно обработать нажатия на наши кнопки:
как я говорил при нажатии передается сообщение WM_COMMAND у него есть два параметра wparam и lparam в lparam передается идентификатор нажатой нами кнопки тоесть ID_BUTTON1 и ID_BUTTON2. Также когда пользователь закроет окно мы должны завершить программу. Делается это функцией PostQuitMessage(0);. Вот в принципе и все.Не надо удивляться объему кода его ведь можно копировать.
Нравится
Не нравится

7 комментариев

00:25
Для новичков статья весьма информативна и понятна. Мне бы в свое время таких статей и побольше.. В общем, респект автору.
10:05
4 за старание. Но в реальных программах так кнопки не размещают. Лучше диалог сделать в RC-файле и загружать его во время выполнения
22:35
не знаю не пробовал через ресурсы.... Может так оно и лучше стоит попробовать
04:27
Даа .. C++ великий системный язык и только. Я как бывалай дельфист хочу сказать, что когда перед тобой КОНКРЕТНАЯ задача, нет времени на изучение API и особ. винды. Но ++ притягивает меня магнитом)))
21:05
какого черта?!?!..вставил код в компилятор а он не компилирует! пишет типа ошибка выделяет вторую строку int WINAPI...красным цветом!! что делать?
22:00
а чем ты компилиш?
22:00
и какая ошибка