netlib.narod.ru< Назад | Оглавление | Далее >

Отслеживание изменений

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

Некоторые свойства SystemInformation как будто высечены в камне. Например, для курсора мыши уже очень давно применяется квадрат со стороной в 32 пиксела, и единственное исключение составляет адаптер CGA фирмы IBM в режиме 640 × 200.

Однако другие свойства могут изменяться даже во время работы программ SysInfoPanel или SysInfoScroll. Часто такие изменения производятся из Панели управления Windows.

Например, откройте Панель управления, дважды щелкните по значку Display (Экран) и в диалоговом окне Display Properties (Свойства: Экран) перейдите на вкладку Effects (Эффекты). Если вы измените состояние флажка Show Window Contents While Dragging (Отображать содержимое окна при перетаскивании), это приведет к изменению свойства SystemInformation.DragFullWindows. Свойство MouseButtonsSwapped зависит от параметров, настраиваемых в диалоговом окне Mouse Properties (Свойства: Мышь) на вкладке Buttons (Кнопки мыши) в области Button Configuration (Конфигурация кнопок). Свойство ShowSounds зависит от параметров в окне Accessibility Options (Специальные возможности) на вкладке Sound (Звук) в области Show Sounds (Визуальное оповещение).

Изменение разрешения экрана затрагивает пять свойств класса SystemInformation: MaxWindowTrackSize, PrimaryMonitorMaximizedWindowSize, PrimaryMonitorSize, VirtualScreen и WorkingArea. Изменение системного шрифта в диалоговом окне Display Properties (Свойства: Экран) на крупный шрифт или как-то иначе затрагивает около двадцати свойств SystemInformation, но при таких значительных изменениях системе нужна перезагрузка. (Я еще расскажу о крупных и мелких шрифтах в главе 7.)

Проблема в том, что программы, о которых мы говорили до сих пор, получают свойства SystemInformation только при вызове метода OnPaint. Если вы измените одно из этих свойств в Панели управления, программа ничего не узнает об этих изменениях. Она даже не получит нового значения свойства до следующего вызова OnPaint. А так как метод OnPaint перерисовывает только недостоверную зону, то даже в этом случае отображение экранных элементов может остаться нескорректированным!

К счастью, приложение Windows Forms может быть проинформировано об изменениях в системе, влияющих на свойства SystemInformation. Проинформировано? Но как? Разумеется, при помощи событий! Класс SystemEvents в пространстве имен Microsoft.Win32 позволяет установить 12 событий, сообщающих вам об изменениях на уровне системы. Большая часть других компонентов Microsoft.Win32 (включая делегаты, аргументы событий и перечисления) обеспечивают поддержку этих событий.

Нас интересуют два события: UserPreferenceChanged (отслеживает большинство изменений, которые пользователь может сделать в Панели управления) и DisplaySettingsChanged (инициируется при изменении параметров экрана). Добавление поддержки для этих событий требует модификаций в структуре программы. Ее измененная версия называется SysInfoUpdate.cs.

SysInfoUpdate.cs

  //----------------------------------------------
  // SysInfoUpdate.cs (C) 2001 by Charles Petzold
  //----------------------------------------------
  using Microsoft.Win32;
  using System;
  using System.Drawing;
  using System.Windows.Forms;

  class SysInfoUpdate: Form
  {
      protected int      iCount;
      protected string[] astrLabels;
      protected string[] astrValues;
      protected float    cxCol;
      protected int      cySpace;

      public static void Main()
      {
           Application.Run(new SysInfoUpdate());
      }
      public SysInfoUpdate()
      {
          Text = "System Information: Update";
          BackColor = SystemColors.Window;
          ForeColor = SystemColors.WindowText;
          AutoScroll = true;

          SystemEvents.UserPreferenceChanged += 
              new UserPreferenceChangedEventHandler(UserPreferenceChanged);

          SystemEvents.DisplaySettingsChanged +=
              new EventHandler(DisplaySettingsChanged);

          UpdateAllInfo();
      }
      void UserPreferenceChanged(object obj, UserPreferenceChangedEventArgs ea)
      {
          UpdateAllInfo();
          Invalidate();
      }
      void DisplaySettingsChanged(object obj, EventArgs ea)
      {
          UpdateAllInfo();
          Invalidate();
      }
      void UpdateAllInfo()
      {
          iCount     = SysInfoStrings.Count;
          astrLabels = SysInfoStrings.Labels;
          astrValues = SysInfoStrings.Values;

          Graphics grfx  = CreateGraphics();
          SizeF    sizef = grfx.MeasureString(" ", Font);
          cxCol = sizef.Width + SysInfoStrings.MaxLabelWidth(grfx, Font);
          cySpace = Font.Height;

          AutoScrollMinSize = new Size(
              (int) Math.Ceiling(cxCol + 
                                 SysInfoStrings.MaxValueWidth(grfx, Font)),
              (int) Math.Ceiling(cySpace * iCount));

          grfx.Dispose();
      }
      protected override void OnPaint(PaintEventArgs pea)
      {
          Graphics grfx  = pea.Graphics;
          Brush    brush = new SolidBrush(ForeColor);
          Point    pt    = AutoScrollPosition;

          for (int i = 0; i < iCount; i++)
          {
              grfx.DrawString(astrLabels[i], Font, brush, 
                              pt.X, pt.Y + i * cySpace);

              grfx.DrawString(astrValues[i], Font, brush, 
                              pt.X + cxCol, pt.Y + i * cySpace); 
          }
      }
  }

Все, что зависит от сведений, полученных из класса SysInfoStrings, теперь объединено в модуле UpdateAllInfo. Первый раз UpdateAllInfo вызывается из конструктора программы, и там же устанавливаются обработчики событий. Они вновь вызывают метод UpdateAllInfo для получения новых данных, а затем вызывается метод Invalidate для сброса клиентской области. Invalidate инициирует вызов метода OnPaint.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz