Культура обозначения переменных в программах Win32 API

Одной из особенностей программ, написанных для Windows, является использование так называемой «венгерской нотации» при записи имен переменных. Суть этой системы можно определить следующими правилами:

· каждое слово в имени переменной пишется с прописной буквы и слитно с другими словами. Например, идентификатор для обозначения какой-то переменной может выглядеть следующим образом - MyVariable, YourVariable, VariableForSavingAnotherVariable и т.п.;

· каждый идентификатор предваряется несколькими строчными символами, определяющими его тип. Например, целочисленная переменная MyVariable будет выглядеть как nMyVariable (n – общепринятый префикс для целочисленных переменных), символьная (char) переменная YourVariable превращается в cYourVariable. Указатель на строку символов, заканчивающуюся нулевым байтом, следут записать lpszVariableForSavingAnotlierVariable (lpsz - сокращение от Long Point то String with Zero). Как видим, префикс указателя может комбинироваться с другими префиксами. Примеры подобных префиксов приведены в таблице 2.

Таблица 2. Префиксы, применяемые в венгерской нотации

Префикс Тип данных Префикс Тип данных  
by BYTE (unsigned char) w WORD (unsigned int)
c char dw DWORD (unsigned long)
i int h HANDLE
n int или short s string
l LONG (long) sz string с завершающим нулем
lp far* (дальний указатель) u UINT (unsigned int)

Применение венгерской нотации не является обязательным, но позволяет упростить процесс чтения и понимания программ, а также делает переменные в некотором смысле самоопределенными - имя переменной определяется ее типом. Отметим также, что параметры функций API представлены в документации «по-венгерски».

Использование функций Win32 API при программировании на языке С/С++

Приложения, разрабатываемые с использованием функций Win32 API, могут быть двух типов: оконные и консольные.

При создании оконного приложения предполагают, что программа будет выполняться в собственном окне с использованием всех возможностей графического пользовательского интерфейса Windows. В этом случае исходный текст программы должен подчиняться определенным требованиям. В частности, главная программа должна иметь имя WinMain() и включать секции подготовки и создания класса окон с заданными характеристиками, создания экземпляра окна только что созданного класса, циклического опроса очереди сообщений приложения и передачи сообщения оконной функции WindowFunction(), обрабатывающей полученное сообщение. Любая, даже самая простая оконная программа, будет состоять как минимум из этих двух функций, и включать несколько десятков строк кода.

Консольное приложение предназначено для поддержки выполнения программ, работающих в текстовом режиме. В этом случае вместо собственного окна приложению выделяется стандартное окно, имитирующее текстовый терминал. Никаких действий по настройке атрибутов консольного окна от программиста не требуется, поэтому консольная программа Windows ничем не отличается по форме от программ, написанных в стиле MS DOS. Например, точкой входа в консольную программу является функция main(). Отметим, что консольному приложению доступны как функции API, так и все стандартные потоки ввода-вывода DOS.

Для применения функций Win32 API и предопределенных типов данных Windows С-программа должна использовать директивы препроцессора, включающие в процесс компиляции файл windows.h (и, возможно, другие файлы):

#include "windows.h"

Рассмотрим пример консольной программы, использующей функцию Win32 API, предназначенную для получения информации о дисковом устройстве: GetVolumeInformation. Прототип функции выглядит следующим образом:

BOOL GetVolumeInformation(

LPCTSTR lpRootPathName,

LPTSTR lpVolumeNameBuffer,

DWORD nVolumeNameSize,

LPDWORD lpVolumeSerialNumber,

LPDWORD lpMaximumComponentLength,

LPDWORD lpFileSystemFlags,

LPTSTR lpFileSystemNameBuffer,

DWORD nFileSystemNameSize);

Как видим, функция возвращает значение типа BOOL и имеет 8 параметров:

lpRootPpathName– входной параметр (in), являющийся указателем на строку символов, содержащую имя корневого каталога диска. Необходимо, чтобы строка завершалась символом \ (backslash). Если указать значение NULL, то будет выбран текущий диск.

lpVolumeNameBuffer – выходной параметр (out), являющийся указателем на буфер, куда будет помещено имя диска.

nVolumeNameSize – входной параметр (in), содержащий длину буфера в символах.

lpVolumeSerialNumber – выходной параметр (out), являющийся указателем на переменную, содержащую серийный номер диска.

lpMaximumComponentLength – выходной параметр (out), являющийся указателем на переменную, содержащую максимальное количество символов в имени файла для данной файловой системы.,

lpFileSystemFlags – выходной параметр (out), являющийся указателем на переменную, содержащую флаги, характеризующие файловую систему.

lpFileSystemNameBuffer – выходной параметр (out), являющийся указателем на буфер, куда будет помещено имя файловой системы (возможные имена: FAT, NTFS и т.п.).

nFileSystemNameSize- входной параметр (in), содержащий длину буфера имени файловой системы в символах.

Возвращаемое значение типа BOOL: 0 - если информация о диске не может быть представлена (например, ошибка в исходных данных); ≠0 - в противном случае.

//Практическое занятие № 18

//Группа xxxxxx Терминал N ФИО

// Пример использования функции GetVolumeInformation

#include "stdafx.h"

#include "windows.h" /* win32 API */

#include <iostream> /* std, cout , cin */

#include <locale.h> /* подключение Русского языка */

using namespace std; /* пространство стандартных имен */

int main() {

setlocale(LC_ALL,"RUS");

char cRootPathName[100]="c:\\";

char cVolumeNameBuffer[100];

char cFileSystemNameBuffer[100];

DWORD dMaxNameFileSize, dFlags;

unsigned long lDriverSerialNumber;

GetVolumeInformationA(

Наши рекомендации