Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Теллес М. - Borland C++ Builder. Библиотека программиста - 1998

.pdf
Скачиваний:
764
Добавлен:
13.08.2013
Размер:
4.35 Mб
Скачать

Borland C++ Builder (+CD). Библиотека программиста 211

DWORD dwFileSystemFlags = 0;

char szFileSystemNameBuffer [_MAX_PATH]; strDrive += "\\";

GetVolumeInformation (strDrive.c_str(), szVolName, //буфер для метки диска

_MAX_PATH, //длина буфера

//буфер для серийного номера диска

&dwVolumeSerialNumber,

//указатель на максимальную длину имени //файла в системе

&dwMaxVolumeLength,

//указатель на флаги файловой системы

&dwFileSystemFlags,

//указатель на имя файловой системы szFileSystemNameBuffer,

_MAX_PATH //длина буфера для имени файловой системы

);

//обработка метки "свободное место на диске"

char szBuffer [80] ;

DWORD dwSectorsPerCluster, dwBytesPerSector; DWORD dwFreeClusters, dwClusters;

DWORD dwFreeSpace; GetDiskFreeSpace(strDrive.c_str(), &dwSectorsPerCluster, &dwBytesPerSector, &dwFreeClusters, &dwClusters); dwFreeSpace =

dwSectorsPerCluster * dwBytesPerSector * dwFreeClusters; sprintf(szBuffer, "%ld", dwFreeSpace) ; DriveFreeSpaceLabel->Caption = szBuffer;

// Поместить информацию в метки

DriveLabel->Caption = strDrive + " [" + szVolName + "]"; DirectoryLabel->Caption = strDirectory;

AnsiString strAll = strDirectory + "\\*.*";

//Теперь получаем все файлы в каталоге, используя

//функцию API FindFile

WIN32_FIND_DATA FindFileData;

HANDLE hFirstFileHandle = FindFirstFile (strAll.c_str(), &FindFileData) ;

int nRow = 1;

while (hFirstFileHandle)

{

//Увеличить количество строк в сетке

StringGrid1->RowCount++;

//Получить размер файла

long lFileSize =

(FindFileData.nFileSizeHigh * MAXDWORD) + FindFileData.nFileSizeLow;

// Получить атрибуты файла

AnsiString strArchive = "";

if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) strArchive += "A";

if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)

Borland C++ Builder (+CD). Библиотека программиста 212

strArchive += "C";

if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) strArchive += "D";

if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) strArchive += "H";

if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) strArchive += "R";

if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) strArchive += "S";

if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) strArchive += "T";

// Поместить данные в сетку строк

StringGrid1->Cells[0][nRow] = FindFileData.cFileName; StringGrid1->Cells[1][nRow] = strArchive; sprintf(szBuffer, "%ld", lFileSize) ; StringGrid1->Cells[2][nRow] = szBuffer;

if (FindNextFile (hFirstFileHandle, &FindFileData) == FALSE)

{

if (GetLastError() == ERROR_NO_MORE_FILES) break;

}

nRow ++;

}

}

}

Это слишком большой кусок кода, чтобы разобрать его сразу весь. Давайте рассматривать его по частям, чтобы попытаться понять, что происходит. Сначала пользователь выбирает конкретный файл в каком-нибудь каталоге в окне диалога открытия файла. Когда файл выбран, программа получает букву диска и каталог, в которых лежит файл, используя вспомогательные функции ExtractFileDrive и ExtractFileDir. Эти функции, описанные в заголовочном файле vcl\sysutils.hpp в каталоге с системой CBuilder, возвратят вам части полного пути файла, соответственно определяющие имя диска и каталог. В случае каталога эта информация включает в себя также и диск (например, D:\dir\), так что мы позже можем использовать ее для поиска файлов в каталоге.

Когда у нас есть имя (буква) диска, на котором находится файл, нашим следующим шагом будет получение метки для этого диска. Имя метки диска это имя диска, которое появляется в листингах каталогов этого диска. Например, ваш диск C: в Windows Explorer (и других листингах каталогов) выглядит примерно как C: (Windows 95). Имя метки диска в данном случае в скобках, то есть Windows 95. Хотя они и не очень информативны для жестких дисков, как C:, но очень полезны для однозначного определения компакт-диска или другого съемного устройства.

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

Borland C++ Builder (+CD). Библиотека программиста 213

получить количество свободного места на диске. Информация, которую мы получаем, включает SectorsPerCluster, то есть количество секторов в одном кластере жесткого диска, затем BytesPerSector, что есть количество байтов в одном секторе диска, и количество свободных кластеров. Между прочим, это очень важные параметры диска. Некоторые жесткие диски позволяют вам занимать место побайтно, а другие выравнивают все по границе ближайшего кластера. Вот почему размер файла не отражает на самом деле размер дискового пространства, которое этот файл занимает.

Три значения перемножаются, и результат заносится в двойное слово (DWORD) dwFreeSpace. Затем эта информация форматируется и помещается в метку, отображающую свободное пространство на диске.

Вместе со свободным местом на диске в соответствующие поля статического текста (метки) помещаются имя каталога, имя диска и метка диска. Следующий шаг отображение информации о файлах, находящихся в одном каталоге с выбранным файлом.

Для поиска всех файлов в каталоге используются функции API FindFirstFile и FindNextFile. Эти функции найдут вам файлы, подходящие под заданный критерий, например все файлы (*.*), все исходные файлы (*.cpp) или все библиотечные файлы (*.lib). Кроме того, так как вы можете задавать любую маску, вы можете найти все файлы, начинающиеся с «Fred», использовав маску Fred*.* или даже все файлы с Fred внутри их имени, выбрав *Fred* в качестве маски. Маска файлов нечувствительна к регистру символов, так что файлы с большими и маленькими буквами различаться не будут.

Функция API FindFirstFile имеет два параметра: файловую маску и адрес структуры типа WIN32_FIND_DATA. Среди всего прочего, WIN32_FIND_DATA содержит имя файла в элементе структуры cFileName. В случае удачного поиска функция FindFirstFile

возвратит ссылку (handle), которую можно потом использовать с функцией API FindNextFile.

Определение состояния файла

Как я уже отмечал, функции API FindFirstFile и FindNextFile возвращают указатель на заполненную структуру типа WIN32_FIND_DATA. Эта структура целый кладезь информации о файле. Не только основное, но также и альтернативное имя файла находится здесь. Кроме того, здесь есть и размер файла (по непонятным причинам записанный в двух двойных машинных словах, переставленных относительно друг друга: сначала старшее слово, затем младшее), и атрибуты файла, которые мы, собственно, и искали.

Размер файла хранится в двух раздельных частях типа DWORD (двойное слово, 4 байта). Умножив старшее (двойное) слово размера на константу MAXDWORD, мы получим размер файла, округленный (с недостатком) до двойного слова. Прибавив младшее слово, мы получим полный размер файла в байтах.

После размера файла мы займемся его атрибутами. Атрибуты файла побитовое множество, указывающее на состояние файла. Атрибуты указывают, можно ли производить запись в файл, изменился ли файл после последнего резервного копирования (бит archive), является ли файл временным файлом в системе (и будет удален во время перезагрузки) и много других вещей. В табл. 9.1 приведены возможные значения битов атрибутов файла, а также объясняется, что они означают.

Атрибуты файла проверяются на каждый из битов. Хотя есть комбинации атрибутов, которые реально не применяются (например, временный и системный файл), вы можете присвоить такие

Borland C++ Builder (+CD). Библиотека программиста 214

атрибуты любому файлу в системе, если захотите. Для изменения атрибутов файлов можно использовать программу attr.exe (из командной строки), а для некоторых атрибутов также

Windows Explorer.

Таблица 9.1. Атрибуты файлов в Windows

FILE_ATTRIBUTE_ARCHIVE Указывает, что данный файл изменился. Обычно программа

резервного копирования сбрасывает этот бит

FILE_ATTRIBUTE_COMPRESSED Указывает, что файл хранится в сжатом виде и требует

распаковки для использования

FILE_ATTRIBUTE_DIRECTORY Указывает, что файл на самом деле является каталогом

и может содержать в себе файлы

FILE_ATTRIBUTE_HIDDEN Указывает, что файл скрытый. По умолчанию такие файлы не показываются в Windows Explorer

FILE_ATTRIBUTE_READONLY Указывает, что файл предназначен только для чтения.

В такие файлы нельзя ничего записать. Кроме того, их нельзя напрямую удалить FILE_ATTRIBUTE_SYSTEM Указывает, что это системный файл. Хотя это всего лишь предупреждение, изменение системных файлов может привести к страшным последствиям FILE_ATTRIBUTE_TEMPORARY Указывает, что файл временный. То есть он будет удален

при следующей загрузке операционной системы

После того как мы получили атрибуты файла и поместили результаты в текстовую строку, информация о файле передается в соответствующий ряд в сетке строк. Следующий файл получается вызовом функции API FindNextFile и процесс повторяется. Цикл прекратится, когда метод FindNextFile вернет false. Заметьте, что в этом случае мы делаем проверку, вызывая функцию API GetLastError, чтобы понять, действительно ли это все. Если мы обработали последний файл, то функция API GetLastError вернет ERROR_NO_MORE_FILES (больше нет файлов). Любая другая ошибка означает, что файл просто не может быть обработан (например, он уже открыт каким-либо приложением и модифицируется).

На рис. 9.5 показано работающее приложение с отображенной группой файлов. Здесь вы можете видеть метку компакт-диска, а также отдельные файлы на компакт-диске, каждый с отображенными атрибутами, именем и размером.

В данном примере мы рассмотрели довольно много функций API системы Windows SDK (Software Development Kit, пакет для разработки программного обеспечения). Хорошей новостью является то, что в CBuilder проще работать с API, чем в Delphi или Visual Basic, так как типы данных, которые вы передаете функциям API, в основном совпадают с типами данных, которые C++ понимает непосредственно. Вы рады, что это так просто? Вам бы, конечно, хотелось, чтобы все вещи были настолько же просты?

Borland C++ Builder (+CD). Библиотека программиста 215

Рис. 9.5. Приложение FileAttributeViewer в работе

Круглое окно

Последний пример, который мы рассмотрим в этой главе, наиболее ярко иллюстрирует необходимость использования Windows API. Возможность поддерживать непрямоугольные окна

одна из самых приятных вещей, добавленных в Windows API в Windows 95 и NT. В предыдущих версиях операционной системы Windows было невозможно сделать по-настоящему непрямоугольное окно, хотя вы могли нарисовать окно, выглядящее овальным или круглым, но реально область окна все равно оставалась прямоугольной.

Однако с выпуском Windows 95 и NT корпорация Microsoft добавила поддержку концепции области окна. Область окна это форма (геометрическая фигура), которая определяет, как окно выглядит. Области (regions) использовались в течение многих лет для определения части окна, в которой можно рисовать. Только в последних реализациях операционной системы область может служить рамкой, ограничивающей окно. Область окна определяет не только часть окна, на которой можно рисовать, но также и область, скрытую окном, и часть окна, отзывающую ся на нажатия кнопки мыши. В прошлых версиях операционной системы окно могло выглядеть круглым, но реагировало оно на нажатие кнопки в любом месте прямоугольника. Кроме того, область позади окна не обновлялась, когда окно, находящееся там, изменялось, так как система Windows считала, что эту область по-прежнему занимает верхнее «круглое» окно.

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

На этом примере мы увидим, как создать форму с круглой кнопкой, а затем добавим возможность сделать круглой саму форму.

Круглооконная форма

В поиске более интересных форм круглая форма с круглыми кнопками одно из интересных нововведений. В данном подходе есть свои проблемы (как мы увидим далее, изучив вопрос), но нет ничего такого, чего нельзя было бы достичь при должном усердии (то есть длительном

Borland C++ Builder (+CD). Библиотека программиста 216

программировании).

На рис. 9.6 показана программа, которую мы будем разрабатывать. Конечно, форма не круглая; на самом деле она эллиптическая. Точно так же и кнопка является эллиптической. Круг это частный случай эллипса, у которого обе оси одинаковые. Если вы хотите сделать кнопку именно круглой, то все, что нужно сделать, — это вписать ее на форме в квадрат. Аналогично, чтобы сделать форму круглой, сделайте ее ширину равной высоте.

С другой стороны, на рис. 9.7 показана форма, с которой мы будем работать. Как видите, образ формы и кнопки устанавливается во время работы программы, а не во время дизайна приложения, так как технология, которую мы будем использовать для создания круглой формы, может быть применена только во время работы программы.

Рис. 9.6. Окно круглой формы

Рис. 9.7. Вид окна формы во время дизайна

Реализация круглой кнопки

Для того чтобы получить круглую кнопку, вам необходимо понимать, как API работает с окнами.

В процессе изменения образа кнопки есть два шага и используются

две функции API. Первый шаг создание образа (shape), который будет потом применен к кнопке. Можете считать, что на этом шаге мы делаем заготовку из теста. Вы делаете заготовку, а затем раскатываете ее и придаете ей форму (ну, например, у моих детей получается в таком случае наполовину съеденная заготовка, но это отдельный рассказ). Второй шаг — «раскатать» заготовку на окне. Первый шаг реализуется с помощью функции API CreateEllipticRgn (создать

Borland C++ Builder (+CD). Библиотека программиста 217

эллиптическую область). Эта функция вариант функции CreatePolygonRgn (создать многоугольную область). На самом деле функций, создающих области, мало: CreateRectRgn,

CreateEllipticRgn, CreateRoundRectRgn и CreatePolygonRgn. Каждая из них, как вы можете узнать из файла Win32SDK.hlp, создает свой тип отображаемой области. Если вы хотите получить хитрую область, то можете вызвать несколько этих функций для создания нескольких областей, а затем скомбинировать их функцией API CombineRgn. Это позволит вам, например, создать область в виде бублика. Когда вы создали область, вы применяете ее к окну раскатываете тесто»), используя функцию SetWindowRgn.

Лучше всего создавать область для окна при создании формы. Создайте обработчик события формы OnCreate и добавьте в метод FormCreate следующий код:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

HRGN hRgn = CreateEllipticRgn(

0, // x-координата левого верхнего угла

//ограничивающего прямоугольника 0, // y-координата левого верхнего угла

//ограничивающего прямоугольника

Button1->Width, // x-координата правого нижнего

//угла ограничивающего прямоугольника Button1->Height // y-координата правого нижнего

//угла ограничивающего прямоугольника

);

SetWindowRgn (Button1->Handle, hRgn, TRUE);

}

Этот код создает эллиптическую область внутри границ кнопки и затем присваивает ее кнопке как новую область окна. Заметьте, что область должна быть определена в координатах относительно кнопки, а не относительно экрана. Точка 0,0 — это левый верхний угол кнопки, а точка Width,Height — правый нижний угол кнопки.

Замечание

Очень важно, чтобы вы больше ничего не делали со ссылкой (handle) на область после присваивания ее окну. Самое невинное, что случится при изменении или удалении этой ссылки, — падение программы, самое худшее обвал системы. В данный момент у вас есть кнопка на форме, которая отображает себя как эллипс, и следующим шагом является написание кода, делающего то же самое с формой. Перед тем как это cделать, установите свойство формы BorderStyle (стиль рамки) в bsNone (то есть без рамки). Иначе вы будете видеть части рамки формы, вылезающие за эллипс, что выглядит некрасиво. Кроме того, заметьте, что на картинку, положенную на форму, также оказывает влияние округлость формы: картинка отрисовывается только внутри области формы.

Добавьте этот код в метод FormCreate (после кода, который вы только что ввели для кнопки), который делает форму эллиптической:

HRGN hRgn1 = CreateEllipticRgn(

0, // x-координата левого верхнего угла

//ограничивающего прямоугольника 0, // y-координата левого верхнего угла

//ограничивающего прямоугольника Width, // x-координата правого нижнего

Borland C++ Builder (+CD). Библиотека программиста 218

//угла ограничивающего прямоугольника Height // y-координата правого нижнего

//угла ограничивающего прямоугольника

);

SetWindowRgn (Handle, hRgn1, TRUE);

Код в точности такой же, как и для кнопки. Единственное, что не упоминается Button при обращении к свойствам. Это не так уж удивительно. Все окна одинаковы с точки зрения областей (regions), которые их ограничивают. Например, вы могли бы создать круглое окно списка, круглый список каталогов или окно диалога. Это может странно выглядеть, но такие вещи возможны.

Вы, вероятно, заметите, что кнопка выглядит странно, когда она отображена в эллиптическом виде. Это из-за рамки у кнопки. Напрямую невозможно изменить рамку кнопки, только наследуя новый компонент от класса button. Это можно сделать, но это далеко не так просто, как сделать кнопку круглой.

Этим мы завершаем дискуссию о круглой форме. Все, что потребовалось, — по два вызова двух разных функций Windows API. Теперь вы понимаете, почему так важно знать, что можно сделать с помощью Windows API? Представьте себе, каких трудов стоило бы создать круглую форму без этих двух функций.

Что мы узнали в этой главе?

Эта глава являлась небольшим введением в Windows API. Вы могли бы провести годы, изучая все функции API, а в это время в Windows появилось бы еще несколько тысяч функций, нужных для поддержки всяких новшеств. Используя CBuilder, вы гарантированно не отстанете, по крайней мере, от основных тенденций в программировании для Windows.

Вот информация, которую вы должны были почерпнуть из этой главы:

·Из системы CBuilder можно вызывать функции Windows API напрямую, без преобразования типов параметров (в отличие от Delphi и Visual Basic).

·Перетаскивание (drag-and-drop) файлов из проводника Windows (или другого Windows-

приложения) легко обрабатывается в CBuilder путем оповещения системы о том, что вы умеете принимать файлы, и обработки сообщения WM_DROPFILES.

·Функции API файловой системы помогут вам при поиске файлов по маске, определении атрибутов файлов и получении дисковой информации.

·Используя функцию API FindWindow, вы можете запретить запускать несколько копий своего приложения.

·Образ окна или формы можно изменить простым вызовом функции Windows API

SetWindowRgn.

На этом дискуссия о Windows API завершается. Трудно переоценить важность понимания профессиональными программистами внутренней структуры Windows и функций API, которые и реализуют все, что происходит. Если вы начнете понимать кое-что в том, что делают функции и какие из них доступны, вы станете также более профессиональным программистом на CBuilder.

Глава 10. Работа сресурсами

Преимущества использования ресурсов

Работа со строками

Динамические меню

Работа с компилятором ресурсов

Borland C++ Builder (+CD). Библиотека программиста 219

Динамические библиотеки (DLL)

Знаете вы об этом или нет, но ресурсы лежат в основе всего, что вы делаете в CBuilder. Все данные формы, такие как свойства и обработчики событий, хранятся в виде ресурсов, присоединенных к приложениям, которые вы пишете в CBuilder. Строки, меню, управляющие элементы и другая информация доступны классам VCL через ресурсы, присоединяемые к вашей программе во время сборки приложения (компоновки).

В данной главе мы рассмотрим несколько других вариантов использования ресурсов в вашем приложении. Что такое ресурс? В основном это данные, связанные с вашим приложением. Ресурсы не могут непосредственно содержать код, но могут содержать информацию, используемую кодом вашего приложения. Примером ресурсов могут служить строки текста, меню и растровые рисунки (bitmaps). Эта информация передается вместе с вашим исполняемым файлом или может храниться в динамически загружаемой библиотеке (DLL).

Мы исследуем некоторые менее известные варианты использования ресурсов. Мы построим библиотеку DLL, состоящую только из ресурсов, в CBuilder и другой среде разработки (в данном случае Visual C++) и покажем, как загружать из нее информацию во время работы программы.

В добавление к DLL, состоящей из ресурсов, мы исследуем, как динамически загружать меню в ваше приложение. В CBuilder нет прямого способа загрузить меню из ресурса или внешнего файла, но вы легко можете сконфигурировать меню во время работы, основываясь на меню из ресурса.

Само собой, вы научитесь создавать файлы ресурсов. Хотя в основном вы будете строить файлы ресурсов с помощью программы Borland Resource Workshop (поставляется с Borland C++) или другой (например, Resource Editor в Visual C++), вы также можете построить полностью функциональный ресурс сами, набирая текст вручную. Это все не так страшно, как звучит, и скоро вы научитесь это делать.

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

может быть применена для расширения существующих программ при отсутствии их исходного кода. Используя подходящий дизайн, вы сможете быть уверены, что ваша программа не будет устаревать, загружая критический код из внешних динамических библиотек .

Зачем нужны ресурсы?

Вероятно, первый вопрос, который у вас возник, — зачем нам использовать ресурсы? В конце концов, CBuilder сам загружает свои данные из ресурса, зачем же подменять собой систему и пытаться ее переиграть по ее правилам? Ответ в том, что ресурсы можно использовать более широко, чем это делает CBuilder. CBuilder хранит данные статически в файлах ресурсов. Вы же можете держать данные в ресурсе, а затем получать их во время работы, основываясь на каком-то своем критерии. Вы даже можете изменять вид меток статического текста, основываясь на данных из ресурса.

Зачем вам может понадобиться что-либо подобное? Одним словом для интернационализации .

Возможность хранить информацию для каждого языка отдельно в таблицах строк в ресурсном файле является лучшей альтернативой хранению отдельных таблиц для каждого языка. Это будет все более и более важно, так как программное обеспечение становится все более глобальным. Вам придется думать о том, как версии вашей программы будут работать не только в Америке и Англии, но также и во Франции, Испании, Германии, Израиле, России и многих других странах.

Borland C++ Builder (+CD). Библиотека программиста 220

Чтобы не сойти с ума в такой ситуации, лучше всего иметь одну общую версию программы.

Если у вас есть возможность загружать разные части системы, которые зависят от языка, то вы минимизируете работу, которую нужно проделать для использова ния ваших программ в других странах. Хотя есть некоторые языки, в которых не все так просто, например в китайском есть свои требования, и такой подход не сгодится, но для большинства европейских языков он себя оправдывает. Используя мощь файлов ресурсов, вам нужно думать только о загрузке корректного набора строк из ресурса, вместо того чтобы разрабатывать отдельный продукт для данной страны.

Еще одним громадным преимуществом ресурсов является возможность настройки программы с их помощью. Представьте, что у вашей программы есть три режима работы. Первый предназначен для тех, кто редко использует компьютер и почти ничего не знает о работе с Windows (вице- президент вашей компании, скорее всего, один из таких). Для них вам нужны более подробные сообщения об ошибках, простые экранные запросы и короткая система меню, содержащая самые часто используемые команды. Более опытные пользователи хотят иметь больше возможностей контроля над системой и меньше слов в сообщениях. Они хотят делать то, что им нужно, и при этом иметь возможность увеличить свой контроль над системой в будущем.

Последний вид пользователей, с которыми вы чаще всего встречаетесь, — это так называемый суперпользователь (power user), который хочет иметь полный контроль надо всем. Таким нужны горячие клавиши для быстрого вызова основных команд, сжатые сообщения об ошибках, содержащие только нужную им информацию, и меню, которые можно конфигурировать так, чтобы они содержали нужные команды и не содержали ничего ненужного (например, справки).

Единственный способ удовлетворить нужды всех трех групп использовать ресурсы. Единственная альтернатива поставлять три разных программных продукта или же держать в программе так много логического кода, определяющего группу, что она станет «поперек себя шире». Давайте рассмотрим, как же вы можете использовать ресурсы для решения своих задач более простым способом, чем переписывание одного и того же кода три раза с различными вариациями.

Строковые ресурсы

Основной метод использования ресурсов заключается в хранении и загрузке строк (текстовых символов) из внешнего источника. Как отмечено выше, строковые ресурсы используются в основном для интернационализации программы, но также существуют и другие, не такие очевидные способы использования строковых ресурсов. Например, в ответ на какую-либо ошибку вы используете функцию MessageBox, чтобы проинформировать пользователя о том, что происходит. Текст, который появляется в сообщении, зашит в программу. Что произойдет, если вам понадобится изменить текст сообщения в зависимости от запросов пользователя? Вам придется поменять текст, перекомпилировать программу и заново ее распространить. Кроме того, тестирующий персонал будет настаивать на повторном тестировании новой версии. Так что небольшое изменение программы превратится в кошмар.

Представьте теперь, что строки текста для окон сообщений хранятся во внешнем файле. Длины строк, лежащих в файле, не изменятся, так что тестирующему персоналу не потребуется полная проверка системы, если вам понадобится поменять пару строк. Те, кто пишет документацию, тоже будут счастливы, так как осознают, что текст может меняться, и напишут соответствующие инструкции пользователю. И наконец, вы будете счастливы, так как код не будет меняться, программу не нужно будет перекомпилировать и ваш босс не будет вас ругать. Все, что будет нужно, — поменять строку во внешнем файле и распространить этот файл среди пользователей.

Вот в чем заключается концепция строковых ресурсов. Они хранятся или в программе, в которой

Соседние файлы в предмете Программирование на C++