Простые типы 4 страница

{

CTime now = CTime::GetCurrentTime();

CStrind changetime = now. Format("Changed at %B %d %H.%M.%S");

GetDocument()->m_message = changetime;

GetDocument()->SetModifiedFIag(),

Inval idate();

}

Эта функция, которая вызывается после выполнения команды Edit Change Message, формирует строку соответственно текущей дате и времени и присваивает ее переменной-члену текущего объекта класса документа. Вызов метода SetModifiedFlag() класса документа сообщит объекту, что его содержимое изменено. Если такое изменение зафиксировано, приложение будет предупреждать пользователя о наличии несохраненных изменений в текущем документе при попытке его закрыть. И последняя операция — запуск механизма обновления представления документа на экране, который производится функцией Invalidate().
Если m_message является закрытой переменной-членом класса документа, понадобится разработать открытый метод SetMessage(), который будет самостоятельно вызы-
вать SetModifiedFiag() Таким образом, вы будете навсегда избавлены от необходимости напоминать программистам об обязательном обращении к этой функции при модификации объекта класса документа. В этом и состоит преимущество скурпулез-
ного следования принципам объектно-ориентированного программирования.
Метод Serialize() класса документа должен позаботиться о сохранении-восстановлении данных документа. В листинге 2.4 представлен текст заготовки функции Serialize(), сформированный AppWizard.
Листинг 2.4. Заготовка функции Serialize() класса документа
void CFi leDemoDoc::Serialize(CArchive& ar)

{

if (ar. IsStoring())

{ // TODO сюда вставьте операторы сохранения данных.

}

else

{ // TODO: сюда вставьте операторы загрузки данных.

}

}

Поскольку в классе CString (объектом которого является переменная m_message) определены терминальные операторы >> и << для передачи данных в архив и из него, это значительно упрощает сохранение и восстановление данных в объекте класса документа. Добавьте следующий оператор в том месте, где в заготовке стоит инструктирующий комментарий:
ar << m_message;
Аналогично в том месте текста программы, где должны стоять операторы загрузки, вставьте
Аr >> m_message;
Терминальный оператор << пересылает CString m_message в архив, а терминальный оператор >> заносит данные в m_message из архива. До тех пор, пока данные документа сохраняются в члене— простой переменной (наподобие int или char) или в объекте такого класса, как CString, для которых определены соответствующие терминальные операторы, сохранение и восстановление документа выполняются очень просто. Указанные терминальные операторы определены для следующих простых типов данных.
• BYTE
• WORD
• int
• LONG
• DWORD
• float
• double
Оттранслируйте приложение File Demo и запустите его. Выберите в меню приложения Edit Change Message и убедитесь, что на экране появилась новая строка сообщения, как показано на рис. 2.1. Теперь выберите File Save и введите имя файла. Опять измените текст сообщения с помощью команды Edit Change Message. Выберите File New— на экране появится предупреждающее сообщение о наличии в документе несохраненных изменений. Вам будет предложено сохранить их на диске прежде, чем открывать новый документ. Теперь выберите File Open и введите имя ранее созданного файла документа (его можно найти и в списке в самом низу меню File). После этого на экране появится ранее сохраненный текст сообщения. Таким образом, вы можете убедиться, что приложение File Demo сохранило документ по вашей команде, а затем восстановило его в прежнем виде.

Рис. 2.1 Приложение File Demo изменило текст сообщения по команде пользователя

Если в документ внесены изменения, он сохранен в файле в него внесены новые изменения и вызвана команда открыть файл с тем же именем, приложение File Demo не будет выводить запрос Revert to saved document? (Вернуться к сохраненному документу?), как это делают другие программы Вместо этого перед вами на экране будет самая последняя версия документа Такой механизм встроен теперь в MFC. Если имя открываемого файла соответствует имени текущего, вы не сможете вернуться к прежней версии документа

9.9.5. Создание класса, обеспечивающего сохранение-восстановление объектов
Что произойдет, если вы создадите свой собственный класс, объект которого войдет в документ? Как сделать этот объект живучим (в оговоренном выше смысле)? Ответы на эти вопросы вы найдете в настоящем разделе.
Предположим, что вы хотите усовершенствовать приложение File Demo таким образом, чтобы для хранения данных документа использовался объект изобретенного вами класса CMessages. Пусть теперь член класса документа, в котором содержатся данные, называется m_messages и он является экземпляром класса CMessages. Этот класс содержит три объекта класса CString, каждый из которых должен сохраняться и восстанавливаться при сохранении и загрузке документа. Первый способ обеспечить такую возможность — индивидуально сохранять и восстанавливать каждую отдельную строку. Текст соответствующей программы представлен в листинге 2.5.
Листинг 2.5. Возможный вариант сохранения и восстановления строк нового класса
void CFi leDemoDoc::Serialize(CArchive& ar)

{

i f (ar. IsStoring())

{

ar << m_messages. m_message1;

ar << m_messages. m_message2;

ar << m_messages. m_message3;

}

else

{

ar << m_messages. m_message1;

ar << m_messages. m_message2;

ar << m_messages. m_message3;

Такую программу можно написать в том случае, если, во-первых, все три члена класса CMessages являются открытыми (объявлены как publiс) и, во-вторых, известна реализация самого класса. Если в дальнейшем класс CMessages будет некоторым образом изменен, придется переписать и эту функцию. Если же вы до конца верны моральному кодексу строителя объектно-ориентированных программ, то непременно согласитесь, что функции сохранения и восстановления данных должны быть инкапсулированы в самом классе CMessages. Конечно, это потребует определенной предварительной подготовки. Основные этапы создания класса, который может самостоятельно организовать сохранение-восстановление (в документации на MFC применяется термин serialize — сериализация) собственных членов-переменных, перечислены ниже.
1. Объявите класс как производный от Cobject.
2. В объявление класса включите макрос DECLARE_SERIAL.
3. В реализацию класса включите макрос IMPLEMENT_SERIAL.
4. Перегрузите метод Serialize(), унаследованный от базового класса
5. Объявите для нового класса среди прочих "пустой" конструктор по умолчанию.
Далее в этом разделе мы проанализируем приложение, в котором именно по этой схеме создаются объекты, обладающие свойством живучести.

9.9.6. Приложение MultiString
В приложении MultiString продемонстрирована та последовательность действий по созданию нового класса, о которой шла речь выше. Это приложение будет иметь команду меню Edit Change Messages, которая изменяет все три строки. Как и приложение File Demo, новая программа сможет сохранять и восстанавливать документы, для чего будут использованы пункты Save и Open меню File.
Для создания приложения MultiString запустите AppWizard и настройте его на тип приложения SDI, точно так, как это делалось при создании File Demo. Добавьте в секцию атрибутов класса документа определение переменной, чтобы этот фрагмент файла MultiStri ngDoc. h выглядел следующим образом:
// Атрибуты.
public:
CMessages m_messages;
Следующий шаг — создание класса CMessages.

9.9.7. Класс CMessages
Прежде чем перейти к классу документа, рассмотрим подробно класс CMessages, объект которого — m_messages — и составляет содержимое документа. Ознакомившись с этим классом, вы поймете, как на практике реализуется перечисленная выше последовательность создания класса, наделенного живучестью.
Для создания этого класса нужно выбрать в меню среды разработки Insert New Class. В поле со списком Class type диалогового окна New Class выберите Generic Class (порождающий класс). В поле Name введите имя нового класса CMessages. Ниже введите имя базового класса CObject, а в столбце As оставьте предлагаемую по умолчанию установку public (рис. 2.2).
В результате будут созданы два файла— файл заголовка Messages. h и файл реализации Messages.срр. В каждый из них будут введены заготовки программного кода. Возможно, будет выведено предупреждающее сообщение о том, что среда разработки не может найти файл заголовка для класса CObject. Если такое случится, можете смело щелкать на ОК, поскольку все системные файлы заголовков MFC всегда доступны компилятору без включения директив.
Переключитесь в окне редактора кода на файл MultiStringDoc. h и добавьте в него перед определение класса директиву:
#include "Messages. h"
В результате при трансляции класса документа компилятору будет доступно определение класса CMessages. Чтобы удостовериться в том, что ничего в определениях не забыто, можно запустить компиляцию проекта. Теперь вернитесь к тексту в файле Messages. h и добавьте следующие строки:
DECLARE_SERIAL(CMessages)
protected:
CString m_message1;
CString m_message2;
CString m_message3;
public:
void SetMessage(UINT msgNum, CString msg); CString GetMessage(UINT msgNum); void Serialize(CArchive& ar);
Макрос DECLARE_SERIAL() обеспечивает выполнение ряда дополнительных функций — MFC использует этот макрос для того, чтобы включить в определение класса объявления дополнительных членов (переменных и функций), которые необходимы для реализации живучести объектов класса.
Далее объявлены члены-переменные класса: три объекта класса CString. Обратите внимание, что они объявлены как защищенные— protected. Следующими идут открытые (public) функции-члены. SetMessage() имеет два аргумента— индекс строки, в которую заносятся данные, и собственно записываемая строка символов. Эта функция позволяет изменить состояние объекта класса. GetMessage()— это сопряженная с предыдущей функция, которая позволяет программе прочесть содержимое любой строки объекта. Ее единственный аргумент — индекс считываемой строки. И наконец, в нашем классе перегружается метод Serialize(), в котором и заключено все таинство сохранения и восстановления данных. Эта функция — сердце живучего объекта. Реализация ее уникальна для каждого класса. В листинге 2.6 представлен текст файла реализации методов класса, в котором вы найдете все его функции-члены.
Листинг 2.6 Файл Messagees. cpp – реализация методов класса CMessages
void CMessages: SetMessage(UINT msgNum, CString msg) {

switch (msgNum)
{ case 1:
m_message1 = msg;
break;
case 2:
m_message2 = msg;
break;
case 3:
m_message3 = msg:
break;
}

}

CString CMessages::GetMessage(UINT msgNum)
{

switch (msgNum)
{ case 1:

return m_message1;
case 2:

return m_message2;
case 3:

return m_message3:
default;
return "";
}

}

void CMessages:: Serialize(CArchive& ar)
{

CObject::Serialize(ar);.

if (ar. IsStoring())
}

ar << m_message1 << m_message2 << m_message3;
}

else {

ar >> m_message1 >> m_message2 >> m_message3;
}

}

В функциях SetMessage() и GetMessage() нет никаких фокусов. Они простым "казачьим" способом реализуют то, что от них требуется. А вот по поводу функции Serialize() могут появиться совершенно законные вопросы. Сначала обратите внимание на то, что первый оператор в теле функции — это вызов одноименного метода базового класса CObject. Это стандартный прием, который используется во многих функциях, перегружающих одноименные функции базового класса. В данном случае — это просто дань дисциплине, поскольку метод CObject:: Serialize() ничего не выполняет (он пуст). Но, тем не менее, воспитайте в себе привычку всегда вызывать одноименный метод класса-родителя, поскольку не всегда класс происходит прямо от CObject (является прямым наследником CObject) и Бог его знает, что делает Serialize()в каком-нибудь другом классе, ребенком которого вы решите объявить свой класс.
После вызова родительской версии Serialize () сохраняет или восстанавливает данные так же, как мы это делали в классе документа. Поскольку члены данных, которые нужно сохранять-восстанавливать, есть объекты класса CString, можно использовать терминальные операторы» и «для передачи данных на диск и с диска.
В самом начале файла Messages. срр после директив include вставьте строку
IMPLEMENT_SERIAL(CMessages, CObject, 0)
Макрос IMPLEMENT_SERIAL() сопряжен с DECLARE_SERIAL(). Он обеспечивает реализацию функций, которые и обеспечивают живучесть объектов класса. Три аргумента макроса (имя класса, имя класса-родителя и номер схемы (schema number)) — это нечто вроде номера версии. В большинстве случаев в качестве номера схемы можно задавать 0 или 1.

9.9.8. Использование класса CMessages в программе
Теперь, когда класс CMessages создан, к нему смогут обращаться методы классов документа и представления приложения MultiString. Разверните в окне ClassView класс СМultiStringDoc и, дважды щелкнув на имени метода OnNewDocument(), вызовите его текст в окне редактора кода. Вместо строк комментария TODO вставьте следующие строки:
m_messages.SetMessage(1, "Default Message 1"); m_messages.SetMessage(2, "Default Message 2"); mjnessages SetMessage(3, "Default Message 3");
}
Поскольку методы класса документа не могут напрямую обращаться к защищенным членам класса CMessages, каждый из них инициализируется функцией SetMessage() этого класса.
Теперь разверните в окне ClassView класс CMultiStringView и, дважды щелкнув на имени метода OnDraw(), вызовите его текст в окне редактора кода. После редактирования текст этого метода должен выглядеть следующим образом:
void CMultiStringView: OnDraw(CDC* pDC)
{
CMuItiStringDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

pDC->TextOut(20, 20, pDoc->m_messages.GetMessage(1)); pDC->TextOut(20, 40, pDoc->m_messages.GetMessage(2)); pDC->TextOut(20, 60, pDoc->mjnessages.GetMessage(S));
}
Так же, как и при работе с File Demo, добавьте пункт Change Messages в меню Edit. Подключите его к методу OnEditChangemessages() класса представления. Этот метод будет изменять содержимое документа, обращаясь к методам доступа и к переменным класса CMessages, как показано в листинге 2.7.
Листинг 2.7. Редактирование содержимого документа
void CMuIt iStringView::OnEditChangemessages()
{
CMultiStringDoc* pDoc = GetDocument();
CTime now = CTime::GetCurrentTime();
CStrmd changetime = now. Format("Changed at %B %d %H:%M:%S");
pDoc->m_messages.SetMessage(1, Cstring("String 1 ") + changetime); pDoc->m_messages.SetMessage(2, Cstring("String 2 ") + changetime), pDoc->m_messages. SetMessage(3, Cstring("String 3 ") + changetime); pDoc->SetModifiedFIag();
Invalidate();
}

Существенную работу предстоит выполнить с функцией Serialize () — членом класса
документа приложения, в котором данные из объекта m_messages должны записываться-
считываться с диска. Это выполняется на удивление просто — вызывается одноименная
функция-член класса, которому принадлежит объект, содержащий данные документа, как и
показано в листинге 2.8. - - '
Листинг 2.8. Сохранения и восстановления объекта
void CmultiStringDoc::SeriaIize(CArchive& ar)
{
m_messages. Serialize(ar);
if (ar. IsStormgO)
{
// TODO: сюда вставьте операторы сохранения данных.
}
else
{
// TODO: сюда вставьте операторы загрузки данных.
}
}
Как видно, после вызова метода Serialize() объекта m_messages функции Serialize() — члену класса документа приложения больше и делать нечего. Обратите внимание, что при вызове m_messages. Serialize() в качестве единственного аргумента передается ссылка на объект класса CArchive.

9.9.9. Непосредственное чтение и запись файлов
Хотя использование встроенной в MFC технологии сохранения-восстановления данных и обеспечивает основные требования приложения при работе с файлами, иногда необходимо реализовать нестандартные процедуры управления файловой системой, не укладывающиеся в рамки этой технологии. Например, может возникнуть необходимость вывести информацию в файл, из которого не нужно снова считывать данные в объекты программы, или тот способ записи-считывания, который реализуется в функции Serialize(), вас не устраивает, поскольку там возможен только последовательный доступ к файлу (ввод-вывод в поток). В этих случаях можно использовать знакомые всем, кто когда-либо программировал в среде DOS, методики программирования файловых операций — непосредственное создание файла, чтение и запись информации в файл. Но даже если вы и решитесь снизойти до такого уровня программирования задач управления файлами, средства MFC все равно облегчат вам жизнь. Для непосредственного управления процессами ввода-вывода в файл в распоряжение программиста MFC предоставляет класс CFile и производные от него.

9.9.10. Класс CFile
Включенный в состав MFC класс CFile инкапсулирует все функции, связанные с обработкой файлов любого типа. Собираетесь ли вы использовать обычный последовательный способ записи-чтения данных или организовать файл с произвольным доступом к данным, в любом случае можно использовать методы класса CFile. При этом последовательность операций очень напоминает прежние С-программы, за исключением того, что класс скрывает некоторые их детали. В результате несколько снижается количество операторов, но принципиально это прежний хорошо знакомый подход. Теперь, в частности, создать файл для чтения можно, используя единственный оператор. В табл. 2. 1 перечислены методы класса CFile и дано их краткое назначение.

Таблица 2.1. Методы класса СFilе

Как видно из приведенной таблицы, набор методов класса CFile предоставляет широкие возможности для работы с файлами. В этом разделе вы найдете примеры использования лишь некоторых методов класса CFile. Однако большинство перечисленных методов просто не нуждается в дополнительных разъяснениях — их применение не вызывает трудностей у любого программиста, который когда-либо имел дело с языком С.
Ниже приведен фрагмент текста программы, в котором создается и открывается файл, и него записывается строковая переменная, а затем извлекается некоторая информация о файле.
// Создать файл.
Cfilefile(''TESTFILE.TXT'',

CFile: modeCreate: CFi le:: modeWrite);

// Записать данные в файл.
CString message("Hello file!");
int length = m_message.GetLength();
file Write((LPCTSTR)m_message, length);

// Считать информацию о файле

CString filePath = file. GetFilePath();

int fileLength = file GetLength();

Обратите внимание на то, что при вызове конструктора с аргументом — именем файла — нет необходимости явно вызывать функцию открытия файла. Аргументы конструктора — имя файла и флаги режима доступа к файлу. Как и обычно, можно передавать сразу несколько флагов (если, конечно, они не противоречат друг другу), объединяя их по ИЛИ. Эти флаги объявлены в рамках класса CFile и определяют как режим открытия файла, так и ограничения на доступ к файлу. Флаги и их описания перечислены в табл. 2.2.

Таблица 2.2. Флаги режима доступа к файлу
После создания файла формируется строковая переменная, определяется ее длина и затем переменная записывается в файл. Для этого вызывается метод Write()класса CFile. В качестве аргументов функции Write()передаются адрес буфера данных и количество байтов данных, которые подлежат записи в файл. Обратите внимание на преобразование типа аргумента функции — приведение к типу LPCTSTR
. Оператор преобразования типа такого вида объявлен в классе CString и извлекает строку из экземпляра класса.
Обратите внимание еще на одну особенность этого фрагмента программы. В нем отсутствует явное обращение к методу Сlose(), поскольку файл автоматически закрывается деструктором локального объекта file, как только последний выходит из области видимости.
Считывание данных из файла не намного сложнее, чем запись в него:
// Открыть файл

CFile file("TESTFILE TXT", CFile:: modeRead);

// Прочесть данные из файла

char s[81],

int bytesRead = file. Read(s, 80),

s[bytesRead] = 0,

CString message = s;
На этот раз при открытии файла задается флаг CFilе:: modeRead и таким образом задается режим обращения к файлу только для чтения. После этого программа создает буфер символов и вызывает метод Read() класса CFile, который и выполняет чтение данных из файла в заданный буфер. Аргументами метода Read() являются адрес буфера-приемника и количество байтов, которые следует прочесть из файла. Метод возвращает количество действительно прочитанных байтов, которое в данном случае практически всегда будет меньше, чем запрашиваемые 80. Число считанных байтов нужно программе, чтобы добавить байт 0 в конец считанной последовательности, ограничивая таким образом ее, как строку символов. В результате формируется стандартная строковая переменная языка С, которую можно переслать в переменную message.
В этом фрагменте программы имя файла задается жестко в виде строковой константы. Для того чтобы получить имя требуемого файла от пользователя, придется немного потрудиться. Загляните в электронную документацию MFC и найдите в ней описание класса CFileDialog. Он очень прост в использовании, но позволяет без особого труда организовать запрос у пользователя имени необходимого файла.

9.9.11. Создание объекта класса CArchive
Работать с файлами можно, используя объекты класса CFile, но мы рекомендуем вам пойти дальше и создать собственный объект класса CArchive (будем называть его архивом}. Его можно использовать точно так. как и объект этого же класса в функции Serialize(). Это позволит использовать функции Serialize(), написанные для объектов других классов, передавая им просто ссылку на ваш собственный объект класса CArchive.
Для создания архива нужно сформировать экземпляр класса CFile и передать его конструктору класса CArchive. Например, если планируется записывать данные из объектов каких-либо классов в файл через архив, нужно создать этот архив с помощью такой последовательности операторов:
CFile file("FileNAME.EXT", CFi le::modeWrite);
CArchive ar(&file, CArchive::store);
Затем можно использовать его так же, как и архивы, создаваемые MFC без явного участия программиста. Поскольку в данном примере при создании экземпляра класса CArchive использован флаг CArchive::store, любой вызов метода IsStoring()будет возвращать TRUE и, таким образом, приведет к выполнению фрагмента программы, организующего передачу данных из объекта в архив. После завершения работы с архивом соответствующий файл можно закрыть, вызвав метод Сlose() либо для объекта класса CFilе, либо для объекта класса CArchive:
ar.Close();
file.Close();
Если же объект выходит из области существования (например, локальная переменная функции при выходе из функции), то его уничтожение выполняется компилятором автоматически и соответствующий деструктор вызывает команду закрытия файла. Таким образом, все это происходит без участия программиста. Работая с локальными архивами, можно не беспокоиться об их закрытии.

9.9.12. Системный реестр Registry
В первых версиях операционной среды Windows приложения хранили параметры настройки и собственные опции в файлах инициализации, которые, как правило, имели расширение.INI. Но времена огромных файлов WIN. INI или мириад пользовательских INI-файлов канули в Лету. В современных версиях Windows приложение сохраняет необходимую для его запуска информацию в централизованном системном реестре Registry. И, хотя системный реестр облегчает распределение информации о настройках между несколькими процессами, жизнь программиста от этого легче не стала. В данном разделе вы сможете познакомиться с некоторыми закулисными сторонами существования системного реестра и научиться самостоятельно программировать работу с ним в приложениях.

9.9.13. Как устанавливается системный реестр
В прежних версиях Windows INI-файлы представляли собой обычные текстовые файлы, которые можно было обрабатывать с помощью любого текстового редактора. В отличие от них системный реестр Registry содержит и двоичную информацию, и символьную, записанную в кодах ASCII. Содержимое Registry можно редактировать только с помощью специальной программы Registry Editor или с помощью специальных функций API, разработанных именно для этой цели. Если вам когда-либо приходилось использовать Registry Editor для просмотра системного реестра, то для вас не должно быть новостью, что последний содержит огромное количество информации, организованной в виде иерархической древовидной структуры. На рис. 2.3 показано, каким образом содержимое реестра представляется пользователю при первом обращении к Registry Editor. (Эту программу, выполняемый файл которой называется RegEdit. EXE, можно найти в главной папке Windows или запустить на выполнение из меню Start (Пуск) с помощью команды Run
(Выполнить), набрав в поле ввода имени файла regedit, а затем щелкнув на ОК. В Windows NT файл называется RegEdit32. EXE.)
В левом окне перечислены предопределенные ключи реестра. Знак плюс рядом с именем ключа означает узел дерева, который можно "развернуть", чтобы увидеть более детальную информацию о ключе. Каждый ключ имеет несколько уровней иерархии, которые при желании можно последовательно разворачивать. Каждый ключ (или его подключи) может иметь (а может и НЕ иметь) ассоциированный с ним параметр Если вы заберетесь достаточно глубоко в иерархию ключей, то в правом окне увидите перечень этих параметров На рис. 2.4 показаны параметры, ассоциированные с текущим дизайном экрана. Если вы хотите добраться до этих параметров самостоятельно, разворачивайте последовательно HKEY_CURRENT_USER, Control Panel, Appearence и Schemes, и увидите параметры схемы дизайна экрана, установленные в системе.


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

• HKEY_CLASS_ROOT
• HKEY_CURRENT_USER
• HKEY_LOCAL_MACHINE
• HKEY_USERS
• HKEY_CURRENT_CONFIG
• HKEY_DYN_DATA

Ключ HKEY_CLASS_ROOT хранит информацию о типах документов и свойствах, а также информацию о классах и различных приложениях, установленных на компьютере. Например, если вы развернете этот ключ на своем компьютере, то, скорее всего, найдете в развернутом списке элемент с расширением файла doc, под которым будут перечислены приложения, которые могут обрабатывать документы этого типа (рис. 2.5)
Ключ HKEY_CURRENT_USER содержит все системные установки, сделанные пользователем, включая схему цветов, принтеры, программные группы и т.п. С другой стороны, ключ HKEY_LOCAL_MACHINE содержит статусную информацию, касающуюся компьютера, а ключ HKEY_USERS организует информацию о каждом пользователе системы и о конфигурации системы по умолчанию. И наконец, ключ HKEY_CURRENT_CONFIG содержит информацию о конфигурации аппаратных средств системы, а ключ HKEY_DYN_DATA— о динамических данных реестра, т.е. о данных, которые часто изменяются.

9.9.15. Использование реестра в MFC-приложениях
Теперь, когда вы кое-что узнали о реестре, позвольте мне вас несколько разочаровать — для того, чтобы описать все возможности доступа к реестру и методы его использования в приложениях, понадобится написать отдельную книгу. Как вы наверняка уже догадались, Win32 API располагает огромным множеством функций для манипуляций реестром. И если вы собрались их использовать, то, наверное, вы лучше меня знаете, как это сделать! Однако можно довольно легко добраться до реестра в MFC-приложении с тем, чтобы хранить информацию, в которой приложение нуждается во время запуска. Для того чтобы максимально упростить решение этой задачи, MFC предлагает к вашим услугам класс CWinАрр и его метод SetRegistryKey(). Этот метод создает новый или открывает в дереве реестра существующий узел, соответствующий ключу вашего приложения. Все, что требуется от программиста, — передать имя ключа (как правило, имя фирмы) в качестве аргумента вызова метода, например
SetRegistгуКеу("MyCooI Company");
Функцию SetRegistryKey() нужно вызвать внутри функции InitInstance() (члене класса приложения), которая вызывается только однажды — при запуске программы.
После того как будет вызвана функция SetRegistryKey(), приложение сможет создать подключи и задать их параметры, вызвав еще одну или две функции-члены класса CWmApp. Функция WriteProfileString() включает параметр— строку— в реестр, а WriteProfileInt() включает параметр —
целое — в реестр. Для того чтобы считать параметры из реестра, можно использовать методы GetProfileString() и GetProfilelnt(). (Кроме того, для обращения к параметрам реестра можно использовать методы RegSetValueEx(), RegQueryValueEx().)
В первых версиях функции WriteProfileStrlng(), WriteProfilelnt(), GetProfileString()
заметку и Getprofilelnt() программировался обмен информацией с INI-файлом. При их ио
пользовании по отдельности они по-прежнему функционируют именно так. Однако
если вызову этих методов предшествует обращение к SetRegistryKey(), то MFC пере
назначает приемник-источник информации — устанавливает в качестве такового сис
темный реестр. В результате программирование обращения к системному реестру в
приложении происходит совершенно безболезненно для программиста.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: