Udostępnij za pośrednictwem


Formanty MFC ActiveX: używanie czcionek

Jeśli kontrolka ActiveX wyświetla tekst, możesz zezwolić użytkownikowi kontrolki na zmianę wyglądu tekstu przez zmianę właściwości czcionki. Właściwości czcionki są implementowane jako obiekty czcionek i mogą być jednym z dwóch typów: stock lub custom. Właściwości czcionki stockowej są wstępnie zaimplementowane właściwości czcionki, które można dodać za pomocą Kreatora dodawania właściwości. Właściwości czcionki niestandardowej nie są wstępnie wdrożone, a deweloper kontrolki określa zachowanie i użycie właściwości.

W tym artykule opisano następujące tematy:

Używanie właściwości czcionki stockowej

Właściwości czcionki stockowej są wstępnie wdrożone przez klasę COleControl. Ponadto dostępna jest również standardowa strona właściwości Czcionka, umożliwiając użytkownikowi zmianę różnych atrybutów obiektu czcionki, takich jak jego nazwa, rozmiar i styl.

Uzyskaj dostęp do obiektu czcionki za pomocą funkcji GetFont, SetFont i InternalGetFont klasy COleControl. Użytkownik kontroli będzie uzyskiwać dostęp do obiektu czcionki za pośrednictwem GetFont funkcji i SetFont w taki sam sposób, jak każda inna właściwość Get/Set. Gdy dostęp do obiektu czcionki jest wymagany z poziomu kontrolki, użyj InternalGetFont funkcji .

Zgodnie z opisem w kontrolkach ActiveX MFC: właściwości dodawanie właściwości akcji jest łatwe za pomocą Kreatora dodawania właściwości. Wybierz właściwość Czcionka, a Kreator dodawania właściwości automatycznie wstawia wpis czcionki akcji do mapy wysyłki kontrolki.

Aby dodać właściwość czcionki stockowej przy użyciu Kreatora dodawania właściwości

  1. Załaduj projekt kontrolki.

  2. W widoku klasy rozwiń węzeł biblioteki kontrolki.

  3. Kliknij prawym przyciskiem myszy węzeł interfejsu kontrolki (drugi węzeł biblioteki), aby otworzyć menu skrótów.

  4. W menu skrótów kliknij pozycję Dodaj , a następnie kliknij pozycję Dodaj właściwość.

    Spowoduje to otwarcie Kreatora dodawania właściwości.

  5. W polu Nazwa właściwości kliknij pozycję Czcionka.

  6. Kliknij przycisk Zakończ.

Kreator dodawania właściwości dodaje następujący wiersz do mapy wysyłania kontrolki znajdującej się w pliku implementacji klasy sterowania:

DISP_STOCKPROP_FONT()

Ponadto Kreator dodawania właściwości dodaje następujący wiersz do kontrolki . Plik IDL:

[id(DISPID_FONT)] IFontDisp* Font;

Właściwość stock Caption jest przykładem właściwości tekstowej, którą można narysować przy użyciu informacji o właściwości czcionki stockowej. Dodanie właściwości stock Caption do kontrolki używa kroków podobnych do tych, które są używane dla właściwości czcionki stockowej.

Aby dodać właściwość stock Caption za pomocą Kreatora dodawania właściwości

  1. Załaduj projekt kontrolki.

  2. W widoku klasy rozwiń węzeł biblioteki kontrolki.

  3. Kliknij prawym przyciskiem myszy węzeł interfejsu kontrolki (drugi węzeł biblioteki), aby otworzyć menu skrótów.

  4. W menu skrótów kliknij pozycję Dodaj , a następnie kliknij pozycję Dodaj właściwość.

    Spowoduje to otwarcie Kreatora dodawania właściwości.

  5. W polu Nazwa właściwości kliknij pozycję Podpis.

  6. Kliknij przycisk Zakończ.

Kreator dodawania właściwości dodaje następujący wiersz do mapy wysyłania kontrolki znajdującej się w pliku implementacji klasy sterowania:

DISP_STOCKPROP_CAPTION()

Modyfikowanie funkcji OnDraw

Domyślna implementacja używa czcionki OnDraw systemu Windows dla całego tekstu wyświetlanego w kontrolce. Oznacza to, że należy zmodyfikować OnDraw kod, wybierając obiekt czcionki w kontekście urządzenia. W tym celu wywołaj metodę COleControl::SelectStockFont i przekaż kontekst urządzenia kontrolki, jak pokazano w poniższym przykładzie:

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 Po zmodyfikowaniu funkcji w celu używania obiektu czcionki każdy tekst w kontrolce jest wyświetlany z cechami z właściwości czcionki akcji kontrolki.

Używanie niestandardowych właściwości czcionki w kontrolce

Oprócz właściwości czcionki stockowej kontrolka ActiveX może mieć niestandardowe właściwości czcionki. Aby dodać niestandardową właściwość czcionki, musisz:

Implementowanie niestandardowej właściwości czcionki

Aby zaimplementować niestandardową właściwość Czcionka, należy użyć Kreatora dodawania właściwości, aby dodać właściwość, a następnie wprowadzić pewne modyfikacje kodu. W poniższych sekcjach opisano sposób dodawania właściwości niestandardowej HeadingFont do kontrolki Przykład.

Aby dodać niestandardową właściwość Czcionka przy użyciu Kreatora dodawania właściwości
  1. Załaduj projekt kontrolki.

  2. W widoku klasy rozwiń węzeł biblioteki kontrolki.

  3. Kliknij prawym przyciskiem myszy węzeł interfejsu kontrolki (drugi węzeł biblioteki), aby otworzyć menu skrótów.

  4. W menu skrótów kliknij pozycję Dodaj , a następnie kliknij pozycję Dodaj właściwość.

    Spowoduje to otwarcie Kreatora dodawania właściwości.

  5. W polu Nazwa właściwości wpisz nazwę właściwości. W tym przykładzie użyj pozycji HeadingFont.

  6. W polu Typ implementacji kliknij pozycję Pobierz/Ustaw metody.

  7. W polu Typ właściwości wybierz pozycję IDispatch* dla typu właściwości.

  8. Kliknij przycisk Zakończ.

Kreator dodawania właściwości tworzy kod, aby dodać właściwość niestandardową HeadingFont do CSampleCtrl klasy i PRZYKŁAD. Plik IDL. Ponieważ HeadingFont jest typem właściwości Get/Set, Kreator dodawania właściwości modyfikuje CSampleCtrl mapę wysyłania klasy w celu uwzględnienia wpisu makra DISP_PROPERTY_EX_IDDISP_PROPERTY_EX :

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

Makro DISP_PROPERTY_EX kojarzy HeadingFont nazwę właściwości z odpowiednią CSampleCtrl klasą Get i Set oraz GetHeadingFontSetHeadingFont. Typ wartości właściwości jest również określony; w tym przypadku VT_FONT.

Kreator dodawania właściwości dodaje również deklarację w pliku nagłówka kontrolki (. H) dla GetHeadingFont funkcji i SetHeadingFont i dodaje swoje szablony funkcji w pliku implementacji kontrolki (. 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();
}

Na koniec Kreator dodawania właściwości modyfikuje kontrolkę . Plik IDL przez dodanie wpisu dla HeadingFont właściwości:

[id(1)] IDispatch* HeadingFont;

Modyfikacje kodu sterującego

Po dodaniu HeadingFont właściwości do kontrolki należy wprowadzić pewne zmiany w plikach nagłówka i implementacji kontrolki, aby w pełni obsługiwać nową właściwość.

W pliku nagłówka kontrolki (. H), dodaj następującą deklarację chronionej zmiennej składowej:

protected:
   CFontHolder m_fontHeading;

W pliku implementacji kontrolki (. CPP), wykonaj następujące czynności:

  • Zainicjuj m_fontHeading w konstruktorze sterującym.

    CMyAxFontCtrl::CMyAxFontCtrl()
       : m_fontHeading(&m_xFontNotification)
    {
       InitializeIIDs(&IID_DNVC_MFC_AxFont, &IID_DNVC_MFC_AxFontEvents);
    }
    
  • Zadeklaruj statyczną strukturę FONTDESC zawierającą atrybuty domyślne czcionki.

    static const FONTDESC _fontdescHeading =
    { sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE(12), FW_BOLD,
      ANSI_CHARSET, FALSE, FALSE, FALSE };
    
  • W funkcji składowej kontrolki DoPropExchange dodaj wywołanie funkcji PX_Font . Zapewnia to inicjowanie i trwałość niestandardowej właściwości Czcionka.

    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);
    }
    
  • Zakończ implementowanie funkcji składowej kontrolki GetHeadingFont .

    IDispatch* CMyAxFontCtrl::GetHeadingFont(void)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       return m_fontHeading.GetFontDispatch();
    }
    
  • Zakończ implementowanie funkcji składowej kontrolki SetHeadingFont .

    void CMyAxFontCtrl::SetHeadingFont(IDispatch* pVal)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       m_fontHeading.InitializeFont(&_fontdescHeading, pVal);
       OnFontChanged();    //notify any changes
       SetModifiedFlag();
    }
    
  • Zmodyfikuj funkcję składową kontrolki OnDraw , aby zdefiniować zmienną do przechowywania wcześniej wybranej czcionki.

    CFont* pOldHeadingFont;
    
  • Zmodyfikuj funkcję składową kontrolki OnDraw , aby wybrać niestandardową czcionkę w kontekście urządzenia, dodając następujący wiersz wszędzie tam, gdzie ma być używana czcionka.

    pOldHeadingFont = SelectFontObject(pdc, m_fontHeading);
    
  • Zmodyfikuj funkcję składową kontrolki OnDraw , aby wybrać poprzednią czcionkę z powrotem do kontekstu urządzenia, dodając następujący wiersz po użyciu czcionki.

    pdc->SelectObject(pOldHeadingFont);
    

Po zaimplementowaniu niestandardowej właściwości Czcionka należy zaimplementować standardową stronę właściwości Czcionka, umożliwiając użytkownikom sterowania zmianę bieżącej czcionki kontrolki. Aby dodać identyfikator strony właściwości dla standardowej strony właściwości Czcionka, wstaw następujący wiersz po makrze BEGIN_PROPPAGEIDS:

PROPPAGEID(CLSID_CFontPropPage)

Należy również zwiększać parametr count makra BEGIN_PROPPAGEIDS o jeden. Poniższy wiersz ilustruje to:

BEGIN_PROPPAGEIDS(CMyAxFontCtrl, 2)

Po wprowadzeniu tych zmian ponownie skompiluj cały projekt, aby uwzględnić dodatkowe funkcje.

Przetwarzanie powiadomień o czcionkach

W większości przypadków kontrolka musi wiedzieć, kiedy charakterystyki obiektu czcionki zostały zmodyfikowane. Każdy obiekt czcionki może dostarczać powiadomienia, gdy zmienia się, wywołując funkcję składową interfejsu IFontNotification zaimplementowaną przez COleControlprogram .

Jeśli kontrolka używa właściwości czcionki stockowej, powiadomienia są obsługiwane przez funkcję składową OnFontChanged .COleControl Podczas dodawania niestandardowych właściwości czcionki można je używać tej samej implementacji. W przykładzie w poprzedniej sekcji wykonano to przez przekazanie i m_xFontNotification podczas inicjowania zmiennej składowej m_fontHeading .

Implementing multiple font object interfaces.
Implementowanie wielu interfejsów obiektów czcionek

Linie stałe na powyższej ilustracji pokazują, że oba obiekty czcionek używają tej samej implementacji elementu IFontNotification. Może to spowodować problemy, jeśli chcesz odróżnić czcionkę zmienioną.

Jednym ze sposobów rozróżnienia między powiadomieniami obiektu czcionki kontrolki jest utworzenie oddzielnej implementacji interfejsu IFontNotification dla każdego obiektu czcionki w kontrolce. Ta technika pozwala zoptymalizować kod rysunku, aktualizując tylko ciąg lub ciągi, które używają ostatnio zmodyfikowanej czcionki. W poniższych sekcjach przedstawiono kroki niezbędne do zaimplementowania oddzielnych interfejsów powiadomień dla drugiej właściwości Czcionka. Przyjmuje się, że druga właściwość czcionki jest właściwością HeadingFont dodaną w poprzedniej sekcji.

Implementowanie nowego interfejsu powiadomień czcionek

Aby odróżnić powiadomienia co najmniej dwóch czcionek, należy zaimplementować nowy interfejs powiadomień dla każdej czcionki używanej w kontrolce. W poniższych sekcjach opisano sposób implementowania nowego interfejsu powiadomień czcionki przez zmodyfikowanie plików nagłówka i implementacji kontrolki.

Dodatki do pliku nagłówka

W pliku nagłówka kontrolki (. H), dodaj następujące wiersze do deklaracji klasy:

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

Spowoduje to utworzenie implementacji interfejsu IPropertyNotifySink o nazwie HeadingFontNotify. Ten nowy interfejs zawiera metodę o nazwie OnChanged.

Dodatki do pliku implementacji

W kodzie, który inicjuje czcionkę nagłówka (w konstruktorze sterującym), zmień &m_xFontNotification na &m_xHeadingFontNotify. Następnie dodaj następujący kod:

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;
}

Metody AddRef i Release w interfejsie IPropertyNotifySink śledzą liczbę odwołań dla obiektu kontrolki ActiveX. Gdy kontrolka uzyskuje dostęp do wskaźnika interfejsu, kontrolka wywołuje AddRef metodę inkrementacji liczby odwołań. Gdy kontrolka zostanie zakończona za pomocą wskaźnika, wywołuje Releasemetodę w taki sam sposób, jak GlobalFree w celu zwolnienia globalnego bloku pamięci. Gdy liczba odwołań dla tego interfejsu przekroczy zero, implementacja interfejsu może zostać zwolniona. W tym przykładzie QueryInterface funkcja zwraca wskaźnik do interfejsu IPropertyNotifySink w określonym obiekcie. Ta funkcja umożliwia kontrolce ActiveX wykonywanie zapytań względem obiektu w celu określenia, jakie interfejsy obsługuje.

Po wprowadzeniu tych zmian w projekcie ponownie skompiluj projekt i przetestuj interfejs przy użyciu kontenera testowego. Aby uzyskać informacje na temat uzyskiwania dostępu do kontenera testowego, zobacz Testowanie właściwości i zdarzeń za pomocą kontenera testowego.

Zobacz też

Kontrolki ActiveX MFC
Kontrolki ActiveX MFC: używanie obrazów w kontrolce ActiveX
Kontrolki ActiveX MFC: używanie stron właściwości standardowych