Windows Management Instrumentation. Опрос свойств, методов и описателей. Разработка компонента WMIControl, страница 14

Удобные дополнения

Если у вас имеются амбиции (необходимые всем программистам), то разработайте класс FormMsg, производный от Form, который выводит сообщение в рамках отдельной формы.

Размеры окна FormMsg подстраиваются под объем текста сообщения. Форма не имеет заголовка, имеет специфическую окраску и рамку, отображается поверх всех окон (свойство TopMost = true;) в течение указанного промежутка времени (в нашем случае 4000 миллисекунд) и автоматически уничтожается после этого. Если амбиций нет, или вы позорно ленивы, то замените код создания окна FormMsg вызовом обычного MessageBox.

Восстановление дерева

Рассмотрим алгоритм восстановления дерева TreeView на основе данных, хранимых в XML-файле.

void ReadNamespaces()

{

try

{

treeNS.Nodes.Add("root", "root", 1, 2);

xDoc = XDocument.Load(xmlFile);

AddTNodeRecursive (xDoc.Root, treeNS.Nodes[0]);

treeNS.Nodes[0].Expand();

}

catch (Exception ex) { new FormMsg(null, "Read Xml Tree:\r\n" + ex.Message, 4000); }

}

Здесь мы опять прибегаем к услугам рекурсивного метода, который предстоит создать. Новый метод выполняет действия, обратные тем, что выполнял метод AddXNodeRecursive.

¨  Метод AddXNodeRecursive на основе данных TreeView строит дерево XDocument.

¨  Метод AddTNodeRecursive на основе данных XDocument строит дерево TreeView.

void AddTNodeRecursive(XElement x, TreeNode node)

{

foreach (XElement e in x.Elements())

{

string name = e.Name.LocalName;

nsCount++;

AddTNodeRecursive(e, node.Nodes.Add(name, name, 1, 2));

}

}

Метод Elements возвращает перечислимую (IEnumerable) коллекцию XML-узлов, вложенных в узел x. Пробегая по ней и осуществляя рекурсивный вызов для каждого из вложенных узлов, мы строим изоморфное дерево, структура которого может быть произвольной.

Ожидание завершения длительной операции

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

¨  Добавьте в проект Library новую форму с именем FormSplash (см. рис. 5).

¨  Добавьте на форму: Label (lblMsg), ListBox (listItem), ListBox (listMsg) и ProgressBar (progress).

¨  Установите свойства самой формы: ControlBox=False, FormBorderStyle=None, StartPosition=CenterScreen, Cursor=AppStarting, ShowIcon=False, ShowInTaskbar=False, Topmost=True.

¨  Цвет фона и шрифты для элементов управления выберите по вкусу.

¨  Нажмите F7 (перевод в режим редактирования кода).

Ниже следует полный код реализации класса FormSplash.

using System;

using System.Runtime.InteropServices;

using System.Threading;

using System.Windows.Forms;

namespace Library

{

[ComVisible(false)]

public partial class FormSplash : Form

{

static FormSplash form = null;

static Thread thread = null;

static string message;

System.Windows.Forms.Timer timer;

double deltaOpacity;

FormSplash()

{

InitializeComponent();

Opacity = 0.0;

deltaOpacity = 0.02;

timer = new System.Windows.Forms.Timer();

timer.Interval = 3;

timer.Tick += new EventHandler(timer_Tick);

timer.Start();

}

public static void ShowForm(string msg)

{

if (form != null)

return;

message = msg;

thread = new Thread(FormSplash.StartApp);

thread.IsBackground = true;

thread.SetApartmentState(ApartmentState.STA);

thread.Start();

}

static void StartApp()

{

form = new FormSplash();

form.lblMsg.Text = message;

Application.Run(form);

}

public static void CloseForm()

{

if (form != null)

form.deltaOpacity = -form.deltaOpacity; // Форма начинает угасать

form = null;       // Форма может быть уничтожена сборщиком мусора

thread = null;       // Поток закончил свое существование

}

void timer_Tick(object sender, EventArgs e)

{

if (deltaOpacity > 0 && Opacity < 1 || deltaOpacity < 0 && Opacity > 0)

Opacity += deltaOpacity; // Форма изменяет степень своей непрозрачности (opacity)

if (deltaOpacity == 0.0)

timer.Stop();

}

public static void AddItem(string msg)

{

ListBox box = form.listItem;