}

}

В этом конструкторе мы начинаем с создания метода обработки события нажатия пользователем кнопки. Обработчиком является метод с именем OnClickChooseColor (см. ниже). Считывание конфигурационной информации делается с помощью другого метода — ReadSettings(). ReadSettings() возвращает true, если находит информацию в реестре, и false, если не находит (что будет, по-видимому, иметь место, так как приложение выполняется первый раз). Мы помещаем эту часть конструктора в блок try на случай возникновения каких-либо исключений при считывании значений реестра (это может произойти, если вмешался некоторый пользователь и сделал какие-то изменения с помощью regedit).

Инструкция StartPosition = FormStartPosition.Manual; говорит форме взять свою начальную позицию из свойства DeskTopLocation вместо используемого по умолчанию положения в Window (поведение по умолчанию). Возможные значения берутся из перечисления FormStartPosition.

SelfPlacingWindow также является одним из немногих приложений в этой книге, для которого существенно используется добавление кода в метод Dispose(). Напомним, что Dispose() вызывается, когда приложение завершается нормально, так что это идеальное место для сохранения конфигурационной информации в реестре. Это делается с помощью другого метода, который будет написан,— SaveSettings():

/// <summary>

/// Очистить все использованные ресурсы

/// </summary>

public override void Dispose() {

 SaveSettings();

 base.Dispose();

 if(components != null) components.Dispose();

}

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

void OnClickChooseColor(object Sender, EventArgs e) {

 if (ChooseColorDialog.ShowDialog() == DialogResult.OK)

  BackColor = ChooseColorDialog.Color;

}

Теперь посмотрим, как сохраняются настройки:

void SaveSettings() {

 RegistryKey SoftwareKey = Registry.LocalMachine.OpenSubKey('Software', true);

 RegistryKey WroxKey = SoftwareKey.CreateSubKey('WroxPress');

 RegistryKey SelfPlacingWindowKey = WroxKey.CreateSubKey ('SelfPlacingWindowKey');

 SelfPlacingWindowKey.SetValue('BackColor', (object)BackColor.ToKnownColor());

 SelfPlacingWindowKey.SetValue('Red', (object)(int) BackColor.R);

 SelfPlacingWindowKey.SetValue('Green', (object)(int)BackColor.G);

 SelfPlacingWindowKey.SetValue('Blue', (object)(int)Backcolor.В);

 SelfPlacingWindowKey.SetValue('Width', (object)Width);

 SelfPlacingWindowKey.SetValue('Height', (object)Height);

 SelfPlacingWindowKey.SetValue('X', (object)DesktopLocation.X);

 SelfPlacingWindowKey.SetValue('Y', (object)DesktopLocation.Y);

 SelfPlacingWindowKey.SetValue('WindowState', (object)WindowState.ToString());

}

Мы начали с перемещения в реестре, чтобы получить ключ реестра HKLM/Software/WroxPress/SelfPlacingWindow с помощью продемонстрированной выше техники, начиная со статического свойства Registry.LocalMachine, которое представляет улей HKLM:

RegistryKey SoftwareKey = Registry.LocalMachine.OpenSubKey('Software' , true);

RegistryKey WroxKey = SoftwareKey.CreateSubKey('WroxPress');

RegistryKey SelfPlacingWindowKey = WroxKey.CreateSubKey ('SelfPlacingWindowKey');

Мы используем метод RegistryKey.OpenSubKey(), а не RegistryKey.CreateSubKey(), позволявший добраться до ключа HKLM/Software. Так происходит вследствие уверенности, что этот ключ уже существует, в противном случае имеется серьезная проблема с компьютером, так как этот ключ содержит настройки для большого объема системного программного обеспечения. Мы также указываем, что нам требуется доступ для записи в этот ключ. Это вызвано тем, что если ключ WroxPress еще не существует, нам нужно будет его создать, что включает запись в родительский ключ.

Следующий ключ для перехода — HKLM/Software/WroxPress, но так как мы не уверены, что ключ уже существует, то используем CreateSubKey() для его автоматического создания, если он не существует. Отметим, что CreateSubKey() автоматически предоставляет доступ для записи к рассматриваемому ключу. Когда мы достигнем HKLM/Software/Wrox. Press/SelfPlacingWindow, то останется просто вызвать метод RegistryKey.SetValue() несколько раз, чтобы создать или задать соответствующие значения. Существуют, однако, некоторые осложнения.

Первое. Можно заметить что мы задействуем пару классов, которые раньше не встречались: свойство DeskTopPosition класса Form указывает позицию верхнего левого угла экрана и имеет тип Point. Рассмотрим структуру Point в главе GDI+. Здесь необходимо знать только, что она содержит два целых числа — X и Y, которые представляют горизонтальную и вертикальную позиции на экране. Мы также используем три свойства члена класса Color: R, G и B. Color представляет цвет, а его свойства задают красный, зеленый и синий компоненты, которые составляют цвет и имеют тип byte. Также применяется свойство Form. WindowState, содержащее перечисление, которое задает текущее состояние окна — minimized, maximized или restored.

Отметим, что при преобразовании типов SetValue() получает два параметра: строку, которая задает имя ключа, и экземпляр System.Object, содержащий значение. SetValue имеет возможность выбора формата для хранения значения, он может сохранить его как REG_SZ, REG_BINARY или REG_DWORD, и он в действительности делает правильный выбор в зависимости от заданного типа данных. Поэтому для WindowsState передается строка и SetValue() определяет, что она должна быть преобразована в REG_SZ. Аналогично для различных позиций и размеров, которые мы передаем, целые значения будут преобразованы в REG_DWORD. Однако компоненты цвета являются более сложными, но мы хотим, чтобы они также хранились как REG_DWORD, потому что они имеют числовые типы. Однако если метод SetValue() видит, что данные имеют тип byte, он будет сохранять их гак строку REG_SZ в реестре. Чтобы избежать этого, преобразуем компоненты цвета в int.

Мы также явно преобразуем все значения в тип object. На самом деле мы не обязаны этого делать, так как преобразование из любого типа данных в тип object выполняется неявно, но мы делаем это, чтобы в действительности показать происходящее и напомнить, что SetValue определен для получения объектной ссылки в качестве второго параметра.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату