Поделиться через


Элементы ActiveX в MFC. Использование шрифтов

Если элемент activeX отображает текст, можно разрешить пользователю элемента управления изменить внешний вид текста, изменив свойство шрифта. Свойства шрифта реализуются как объекты шрифта и могут быть одним из двух типов: акции или пользовательские. Свойства шрифта акций — это предварительно созданные свойства шрифта, которые можно добавить с помощью мастера добавления свойств. Пользовательские свойства шрифта не предимнимы, и разработчик элемента управления определяет поведение и использование свойства.

В этой статье рассматриваются следующие темы:

Использование свойства шрифта акций

Свойства шрифта акций предварительно выполняются классом COleControl. Кроме того, доступна стандартная страница свойств Шрифта, которая позволяет пользователю изменять различные атрибуты объекта шрифта, например его имя, размер и стиль.

Доступ к объекту шрифта через функции GetFont, SetFont и InternalGetFont.COleControl Пользователь элемента управления получит доступ к объекту шрифта с помощью GetFont и SetFont функций таким же образом, как и любое другое свойство Get/Set. Если доступ к объекту шрифта требуется из элемента управления, используйте функцию InternalGetFont .

Как описано в элементах управления ActiveX MFC: свойства, добавление свойств акций легко с помощью мастера добавления свойств. Вы выбираете свойство Font, а мастер добавления свойств автоматически вставляет запись шрифта акций в карту отправки элемента управления.

Добавление свойства шрифта акций с помощью мастера добавления свойств

  1. Загрузите проект элемента управления.

  2. В представлении класса разверните узел библиотеки элемента управления.

  3. Щелкните правой кнопкой мыши узел интерфейса для элемента управления (второй узел узла библиотеки), чтобы открыть контекстное меню.

  4. В контекстном меню выберите команду Добавить, а затем — Добавить свойство.

    Откроется мастер добавления свойств.

  5. В поле "Имя свойства" нажмите кнопку "Шрифт".

  6. Нажмите кнопку Готово.

Мастер добавления свойств добавляет следующую строку в карту отправки элемента управления, расположенную в файле реализации класса элемента управления:

DISP_STOCKPROP_FONT()

Кроме того, мастер добавления свойств добавляет в элемент управления следующую строку. IDL-файл:

[id(DISPID_FONT)] IFontDisp* Font;

Свойство caption акций является примером текстового свойства, которое можно нарисовать с помощью сведений о свойстве шрифта акций. Добавление свойства заголовка акций в элемент управления использует шаги, аналогичные тем, которые используются для свойства Шрифта акций.

Добавление стандартного свойства Caption с помощью мастера добавления свойств

  1. Загрузите проект элемента управления.

  2. В представлении класса разверните узел библиотеки элемента управления.

  3. Щелкните правой кнопкой мыши узел интерфейса для элемента управления (второй узел узла библиотеки), чтобы открыть контекстное меню.

  4. В контекстном меню выберите команду Добавить, а затем — Добавить свойство.

    Откроется мастер добавления свойств.

  5. В поле Имя свойства щелкните Caption.

  6. Нажмите кнопку Готово.

Мастер добавления свойств добавляет следующую строку в карту отправки элемента управления, расположенную в файле реализации класса элемента управления:

DISP_STOCKPROP_CAPTION()

Изменение функции OnDraw

Реализация по умолчанию OnDraw использует системный шрифт Windows для всего текста, отображаемого в элементе управления. Это означает, что код необходимо изменить OnDraw , выбрав объект шрифта в контексте устройства. Для этого вызовите COleControl::SelectStockFont и передайте контекст устройства элемента управления, как показано в следующем примере:

CFont* pOldFont;
TEXTMETRIC tm;
const CString& strCaption = InternalGetText();

pOldFont = SelectStockFont(pdc);
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->Ellipse(rcBounds);
pdc->GetTextMetrics(&tm);
pdc->SetTextAlign(TA_CENTER | TA_TOP);
pdc->ExtTextOut((rcBounds.left + rcBounds.right) / 2,
(rcBounds.top + rcBounds.bottom - tm.tmHeight) / 2,
ETO_CLIPPED, rcBounds, strCaption, strCaption.GetLength(), NULL);

pdc->SelectObject(pOldFont);

OnDraw После изменения функции для использования объекта шрифта любой текст в элементе управления отображается с характеристиками из свойства шрифта элемента управления.

Использование настраиваемых свойств шрифта в элементе управления

Помимо свойства шрифта акций элемент activeX может иметь настраиваемые свойства Шрифта. Чтобы добавить настраиваемое свойство шрифта, необходимо:

Реализация пользовательского свойства шрифта

Чтобы реализовать настраиваемое свойство Font, используйте мастер добавления свойств для добавления свойства, а затем внести некоторые изменения в код. В следующих разделах описывается, как добавить пользовательское HeadingFont свойство в элемент управления Sample.

Добавление настраиваемого свойства Font с помощью мастера добавления свойств
  1. Загрузите проект элемента управления.

  2. В представлении класса разверните узел библиотеки элемента управления.

  3. Щелкните правой кнопкой мыши узел интерфейса для элемента управления (второй узел узла библиотеки), чтобы открыть контекстное меню.

  4. В контекстном меню выберите команду Добавить, а затем — Добавить свойство.

    Откроется мастер добавления свойств.

  5. В поле "Имя свойства" введите имя свойства. В этом примере используйте HeadingFont.

  6. В поле Тип реализациивыберите Методы Get/Set.

  7. В поле "Тип свойства" выберите IDispatch* для типа свойства.

  8. Нажмите кнопку Готово.

Мастер добавления свойств создает код для добавления HeadingFont настраиваемого свойства в CSampleCtrl класс и sample. IDL-файл. Так как HeadingFont это тип свойства Get/Set, мастер добавления свойств изменяет CSampleCtrl карту отправки класса, чтобы включить запись макроса DISP_PROPERTY_EX_ID DISP_PROPERTY_EX:

DISP_PROPERTY_EX_ID(CMyAxFontCtrl, "HeadingFont", dispidHeadingFont,
   GetHeadingFont, SetHeadingFont, VT_DISPATCH)

Макрос DISP_PROPERTY_EX связывает HeadingFont имя свойства с соответствующими CSampleCtrl методами Get и Set класса и GetHeadingFontSetHeadingFont. Также указан тип значения свойства; в этом случае VT_FONT.

Мастер добавления свойств также добавляет объявление в файл заголовка элемента управления (). H) для GetHeadingFont функций и SetHeadingFont добавляет шаблоны функций в файл реализации элемента управления (). CPP):

IDispatch* CWizardGenCtrl::GetHeadingFont(void)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState());

   // TODO: Add your dispatch handler code here

   return NULL;
}

void CWizardGenCtrl::SetHeadingFont(IDispatch* /*pVal*/)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState());

   // TODO: Add your property handler code here

   SetModifiedFlag();
}

Наконец, мастер добавления свойств изменяет элемент управления. IDL-файл путем добавления записи для HeadingFont свойства:

[id(1)] IDispatch* HeadingFont;

Изменения в коде элемента управления

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

В файле заголовка элемента управления (. H), добавьте следующее объявление защищенной переменной члена:

protected:
   CFontHolder m_fontHeading;

В файле реализации элемента управления (. CPP), сделайте следующее:

  • Инициализация m_fontHeading в конструкторе элементов управления.

    CMyAxFontCtrl::CMyAxFontCtrl()
       : m_fontHeading(&m_xFontNotification)
    {
       InitializeIIDs(&IID_DNVC_MFC_AxFont, &IID_DNVC_MFC_AxFontEvents);
    }
    
  • Объявите статическую структуру FONTDESC, содержащую атрибуты шрифта по умолчанию.

    static const FONTDESC _fontdescHeading =
    { sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE(12), FW_BOLD,
      ANSI_CHARSET, FALSE, FALSE, FALSE };
    
  • В функции элемента управления DoPropExchange добавьте вызов PX_Font функции. Это обеспечивает инициализацию и сохраняемость для пользовательского свойства Font.

    void CMyAxFontCtrl::DoPropExchange(CPropExchange* pPX)
    {
       ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
       COleControl::DoPropExchange(pPX);
    
       // [...other PX_ function calls...]
       PX_Font(pPX, _T("HeadingFont"), m_fontHeading, &_fontdescHeading);
    }
    
  • Завершите реализацию функции элемента элемента управления GetHeadingFont .

    IDispatch* CMyAxFontCtrl::GetHeadingFont(void)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       return m_fontHeading.GetFontDispatch();
    }
    
  • Завершите реализацию функции элемента элемента управления SetHeadingFont .

    void CMyAxFontCtrl::SetHeadingFont(IDispatch* pVal)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       m_fontHeading.InitializeFont(&_fontdescHeading, pVal);
       OnFontChanged();    //notify any changes
       SetModifiedFlag();
    }
    
  • Измените функцию элемента управления OnDraw , чтобы определить переменную для хранения ранее выбранного шрифта.

    CFont* pOldHeadingFont;
    
  • Измените функцию элемента управления OnDraw , чтобы выбрать пользовательский шрифт в контексте устройства, добавив следующую строку, где бы ни использовался шрифт.

    pOldHeadingFont = SelectFontObject(pdc, m_fontHeading);
    
  • Измените функцию элемента управления OnDraw , чтобы выбрать предыдущий шрифт обратно в контекст устройства, добавив следующую строку после использования шрифта.

    pdc->SelectObject(pOldHeadingFont);
    

После реализации настраиваемого свойства Font необходимо реализовать стандартную страницу свойств Font, позволяя пользователям управления изменять текущий шрифт элемента управления. Чтобы добавить идентификатор страницы свойств для стандартной страницы свойств Font, вставьте следующую строку после макроса BEGIN_PROPPAGEIDS:

PROPPAGEID(CLSID_CFontPropPage)

Необходимо также увеличить параметр счетчика макроса BEGIN_PROPPAGEIDS по одному. Это показано в следующей строке:

BEGIN_PROPPAGEIDS(CMyAxFontCtrl, 2)

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

Обработка уведомлений шрифта

В большинстве случаев элемент управления должен знать, когда характеристики объекта шрифта были изменены. Каждый объект шрифта может предоставлять уведомления при изменении, вызывая функцию-член IFontNotification интерфейса, реализованную COleControl.

Если элемент управления использует свойство шрифта акций, его уведомления обрабатываются OnFontChanged функцией-членом COleControl. При добавлении настраиваемых свойств шрифта их можно использовать ту же реализацию. В примере в предыдущем разделе это было сделано путем передачи &m_xFontNotification при инициализации переменной члена m_fontHeading .

Implementing multiple font object interfaces.
Реализация нескольких интерфейсов объектов шрифта

Сплошные линии на рисунке выше показывают, что оба объекта шрифта используют одну и ту же реализацию IFontNotification. Это может привести к проблемам, если вы хотите отличить, какой шрифт изменился.

Одним из способов отличия уведомлений о шрифте элемента управления является создание отдельной IFontNotification реализации интерфейса для каждого объекта шрифта в элементе управления. Этот метод позволяет оптимизировать код рисования, обновляя только строку или строки, которые используют недавно измененный шрифт. В следующих разделах показаны шаги, необходимые для реализации отдельных интерфейсов уведомлений для второго свойства Font. Предполагается, что второе свойство шрифта является свойством HeadingFont , добавленным в предыдущем разделе.

Реализация нового интерфейса уведомлений шрифта

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

Дополнения к файлу заголовка

В файле заголовка элемента управления (. H), добавьте следующие строки в объявление класса:

protected:
   BEGIN_INTERFACE_PART(HeadingFontNotify, IPropertyNotifySink)
      INIT_INTERFACE_PART(CMyAxFontCtrl, HeadingFontNotify)
      STDMETHOD(OnRequestEdit)(DISPID);
   STDMETHOD(OnChanged)(DISPID);
   END_INTERFACE_PART(HeadingFontNotify)

При этом создается реализация вызываемого IPropertyNotifySinkHeadingFontNotifyинтерфейса. Этот новый интерфейс содержит метод с именем OnChanged.

Дополнения к файлу реализации

В коде, который инициализирует шрифт заголовка (в конструкторе элемента управления), измените &m_xFontNotification на &m_xHeadingFontNotify. Затем добавьте приведенный ниже код.

STDMETHODIMP_(ULONG) CMyAxFontCtrl::XHeadingFontNotify::AddRef()
{
   METHOD_MANAGE_STATE(CMyAxFontCtrl, HeadingFontNotify)
      return 1;
}
STDMETHODIMP_(ULONG) CMyAxFontCtrl::XHeadingFontNotify::Release()
{
   METHOD_MANAGE_STATE(CMyAxFontCtrl, HeadingFontNotify)
      return 0;
}

STDMETHODIMP CMyAxFontCtrl::XHeadingFontNotify::QueryInterface(REFIID iid, LPVOID FAR* ppvObj)
{
   METHOD_MANAGE_STATE(CMyAxFontCtrl, HeadingFontNotify)
      if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IPropertyNotifySink))
      {
         *ppvObj = this;
         AddRef();
         return NOERROR;
      }
   return ResultFromScode(E_NOINTERFACE);
}

STDMETHODIMP CMyAxFontCtrl::XHeadingFontNotify::OnChanged(DISPID)
{
   METHOD_MANAGE_STATE(CMyAxFontCtrl, HeadingFontNotify)
      pThis->InvalidateControl();
   return NOERROR;
}

STDMETHODIMP CMyAxFontCtrl::XHeadingFontNotify::OnRequestEdit(DISPID)
{
   return NOERROR;
}

Release Методы AddRef в интерфейсе IPropertyNotifySink отслеживают количество ссылок для объекта элемента управления ActiveX. Когда элемент управления получает доступ к указателю интерфейса, элемент управления вызывает AddRef увеличение числа ссылок. Когда элемент управления завершится с указателем, он вызывается Releaseтак же, как GlobalFree и для освобождения глобального блока памяти. Если число ссылок для этого интерфейса переходит к нулю, реализация интерфейса может быть освобождена. В этом примере QueryInterface функция возвращает указатель на IPropertyNotifySink интерфейс для определенного объекта. Эта функция позволяет элементу ActiveX запрашивать объект, чтобы определить, какие интерфейсы она поддерживает.

После внесения этих изменений в проект перестройте проект и используйте тестовый контейнер для тестирования интерфейса. Сведения о том, как получить доступ к Контейнеру для тестирования, см. в разделе Тестирование свойств и событий в Контейнере для тестирования .

См. также

Элементы ActiveX библиотеки MFC
Элементы ActiveX в MFC. Использование изображений в элементе ActiveX
Элементы ActiveX в MFC. Использование стандартных страниц свойств