C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Введение в API-программирование / Использование API / Visual C++ .NET

Введение в API-программирование

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

Структура API-программ

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

Классическая структура API-программы определяется четырьмя компонентами: инициализация; цикл ожидания, или цикл обработки сообщений; функция главного окна; другие функции. В простейшем случае последний компонент может отсутствовать. Два первых компонента распологаятся в функции WinMain. Итак, все по порядку.

Функция WinMain

int WINAPI WinMain
(
            HISTANCE hInstance,
            HINSTANCE hPrevInctance,
            LPSTR lpCmdLine,
            int nCmdShow
)

Функция WinMain вызывается системой, в которую передаются четыре параметра:

  • hInstance - дискриптор текушего экземпляра приложения.
  • hPrevInctance - всегда равен NULL.
  • lpCmdLine - указатель на командную строку запускаемой программы.
  • nCmdShow - способ визуализации окна.

Инициализация

Если кратко, то здесь производится регистрация класса окон, его создание и вывод на икран. Регистрация классв окон осуществляется функцией:

ATOM RegisterClass(CONST WNDCLASS *lpwcx)

Пусть вас не смущает тип ATOM, для нас это просто int. Единственный параметр функции указатель на структуру WNDCLASS. После того как класс будет зарегестрировани, окно из данного класса может быть создано функцией CreateWindow. Разберём теперь структуру WNDCLASS:

typedef struct _WNDCLASS
	{
		UNIT    style;
	    WNDPROC lpfnWndProc;
		int     cbClsExtra;
		int     cbWndExtra;
		HANDLE  hInstance;
		HICON   hIcon;
		HCURSOR hCursor;
		HBRUSH  hbrBackground;
		LPCTSTR lpszMenuName;
		LPCTSTR lpszClassName;
	} WNDClASS

Как видите, в структуре нет ничего сложного. Если регистрация прошла успешно, о чём мы узнаем по нулевому возвращенному значению, значит можно создавать окно.

Перечислим некоторые типичные значения членов структуры:

  • Стили класса окон. Стиль окна определяется комбинацией нескольких предопределённых констант. Довольно часто он пологается нулю, что означает "стиль по умолчанию".
  • Дискриптор иконки окна. Определяется с помощью функции LoadIcon. Первым параметром данной функции является дискриптор приложения, вторы - строка, определяющая имя иконки в ресурсах. Для того чтобы чтобы задать одну из стандартных иконок, первый параметр должен иметь значение NULL, а второй значение одной из следующих констант: IDI_APLICATION - стандартнаю иконка приложения; IDI_ASTERISK - иконка "информация"; IDI_EXCLAMATION - "восклицательный знак"; IDI_HAND - "знак Стоп"; IDI_QUESTION - "вопросительный знак".
  • Дискриптор курсора. Для определения курсора используется API-функция LoadCursor. Функция похожа на функцию LoadIcon.
  • Имя класса. Название класса - это просто строка, которая потом используется при создании окна.

Со значениями других членов структуры мы познакомимся позднее.
Окно создаётся функцией CreteWindow. Вот прототип этой функции:

HWND CreateWindow
(
 LPCTSTR lpClassName, //указывает на имя зарегестрированого окна
 LPCTSTR lpWindowName, //название окна
 DWORD dwStyle, //стиль окна
 int x, //горизонтальная координата
 int y, //вертикальная координата
 int nWidth, //ширина окна
 int nHeight, //высота окна
 HWND hWndParent, //дискриптор родителя или владельца окна
 HMENU hMenu, //дискриптор меню окна
 HANDLE hINSTANCE, //дискриптор приложения
 LPVOID lpParam //указатель на дополнительную информацию
 )

Использование данной функции мы разберём позднее. Главное здесь то, что функция возвращает дискриптор созданного окна, при ошибке - 0.
Для того чтобы корректно отобразить окно на экране, следует выполнить ещё две функции.

BOOL ShowWindow(HWND hWnd, int nCmdShow) - эта функция отображает окно на экране. Первый параметр - дискриптор окна, второй - режим отображения. В качестве этого параметра обычно используют параметр nWinMode функции WinMain. Можно также использовать предопределённые константы:

  • SW_HIDE - скрыть окно
  • SW_MAXIMIZE - максимизировать окно
  • SW_MINIMIZE - минимизировать окно и активировать самое верхнее окно
  • SW_RESTORE - отобразить окно в нормальном состоянии
  • SW_SHOW - активизировать окнос текущими разменами
  • SW_SHOWMAXIMIZED - максимизировать окно и сделать его активным
  • SW_SHOWMINIMIZED - минимизировать окно
  • SW_SHOWNA - отобразить окно в его текущем состоянии. При этом активированое окно оставить активным.
  • SW_SHOWNOACTIVATE - востанавливает окно в его предыдушем состоянии. При этом активное окно остаётся активным.
  • SW_SHOWNORMAL - активизировать и востановить окно в прежних размерах.

BOOL UpdateWindow(HWND hWnd) - вызов данной функции приводит к немедленной перерисовке окна и посылке функции окна сообщения WM_PAINT.

Цикл обработки сообщений

Цикл обработки сообщений присутствует во всех проложеният Windows. Правда, не всегда этот цикл представлен явно в программе.

while (GetMessage(&msg, NULL, 0, 0)) 
{
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}

В цикле сообщения присутствует три функции. Эти функции есть там всегда, но кроме них в цикле могут быть и другие. Функция GetMessage выбирает из очереди сообщений приложения очередное приложение. вместо этой функции используют так же функции PostMessage и PeekMessage.
Во всех трех функциях присутствует указатель на строку MSG. Разберём её:

typedef struct tagMSG
{
	HWND hwnd;
	UINT message;
	WPARAM wParam;
	LPARAM lParam;
	DWORD time;
	POINT pt;
}MSG;
  • hwnd - дискриптор окна.
  • message - код сообщения.
  • wParam - дополнительный параметр.
  • lParam - дополнительный параметр.
  • time - время посылки сообщения.
  • pt - положение курсора мыши.

Прототип функции MessageBox.

BOOL GetMessageBox
(
     LPMSG lpMsg;
     HWND hWnd;
	 UINT wMsgFilterMin,
	 UINT wMsgFilterMax
)

Первый параметр функции - указатель на строку MSG, куда и будет помещена получаемая информация. Вторым параметром является дискриптор окна, которому предназначено сообщение. Если параметр равен NULL, то "отталкиваются" все сообщения, получаемые приложением. Два последних параметра определяют диапазон сообщений. Для того чтобы получать сообщения из всего диапазона, эти параметры должны быть равны 0.

Функция TransleteMessage преабразует сообщения WM_KEYDOWN и WM_KEYUP в WM_CHAR. Функция DispatchMessage просто переправляет сообщение оконной процедуре.

Оконная функция

Это еще один компонент отвечающий за обработку сообщений окна. Эта функция вызывается системой и имеет четыре параметра, совпадающих с первыми четырбмя членами структуры MSG. Искуство API-программирования заключается в основном в написании оконных функций. Вот пример оконной функции:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
        WPARAM wParam, LPARAM lParam)
{

}

Примеры

Среда Visual C++ оказывает некоторую помощь желающим написать API-программы. Вы можете воспользоваться одной из двух возможностей. В списке проектов выбираем Win32 Project и далее следуем одним из двух путей: отменить флажок Empty project или нет. Если не отмечать флажок, то система создаст простейшее оконное приложение с минимальной функциональностью, позволяющей, однако, развивать ваш проект и создавать приложения любой степени сложности.

И так, начнём. Выбираем путь, простой проект. Откроем окно Solution Explorer. Как и следовало ожидать, проект пуст. Щелкним правой кнопкой мыщи по строке проекта и выбирем пункт Add new Item, тип файла - CPP и введём имя api1.cpp. Теперь мы свами можем воспользоваться тем что с вами иже узнали. Как сидите мы обощлись минимальным количеством файлов. Пожключаемый файл windows.h содержит определения всех API-функций, а также необходимых для их использования констант и типов данных. Вот код этой программы:

// api1.cpp

#include <windows.h>

LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.
	char cname[]="Class";
	char title[]="Наше первое окно";
	MSG msg;

	//структура для регистрации класса окон
	WNDCLASS wc;
	wc.style			= 0;
	wc.lpfnWndProc	    = (WNDPROC)WndProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hInstance		= hInstance;
	wc.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
	wc.hCursor		    = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName	    = 0;
	wc.lpszClassName	= cname;
    //регестрируем класс
	if(!RegisterClass(&wc)) return 0;
	//создать окно
	HWND hWnd = CreateWindow(cname, title, WS_OVERLAPPEDWINDOW, 
	                0, 0, 500, 300, NULL, NULL, hInstance, NULL);
	//проверим создалось ли окно
	if(!hWnd)return 0;
	//показать окно
	ShowWindow(hWnd, nCmdShow);
	//обновить содержимое окна
	UpdateWindow(hWnd);

	//цикл обработки сообщений
	while(GetMessage(&msg, NULL,0 ,0))
	{
		TranslateMessage(&msg);
        DispatchMessage(&msg);
	}
	return 0;
};

//процедура окна
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
                  WPARAM wParam, LPARAM lParam)
{
	switch(message) 
	{
	case WM_CREATE:
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_PAINT:
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}