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
Załaduj projekt kontrolki.
W widoku klasy rozwiń węzeł biblioteki kontrolki.
Kliknij prawym przyciskiem myszy węzeł interfejsu kontrolki (drugi węzeł biblioteki), aby otworzyć menu skrótów.
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.
W polu Nazwa właściwości kliknij pozycję Czcionka.
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
Załaduj projekt kontrolki.
W widoku klasy rozwiń węzeł biblioteki kontrolki.
Kliknij prawym przyciskiem myszy węzeł interfejsu kontrolki (drugi węzeł biblioteki), aby otworzyć menu skrótów.
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.
W polu Nazwa właściwości kliknij pozycję Podpis.
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:
Użyj Kreatora dodawania właściwości, aby zaimplementować niestandardową właściwość Czcionka.
Implementowanie nowego interfejsu powiadamiania o czcionkach.
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
Załaduj projekt kontrolki.
W widoku klasy rozwiń węzeł biblioteki kontrolki.
Kliknij prawym przyciskiem myszy węzeł interfejsu kontrolki (drugi węzeł biblioteki), aby otworzyć menu skrótów.
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.
W polu Nazwa właściwości wpisz nazwę właściwości. W tym przykładzie użyj pozycji HeadingFont.
W polu Typ implementacji kliknij pozycję Pobierz/Ustaw metody.
W polu Typ właściwości wybierz pozycję IDispatch* dla typu właściwości.
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 GetHeadingFont
SetHeadingFont
. 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 funkcjiPX_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 COleControl
program .
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 .
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 Release
metodę 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