Controlli ActiveX MFC: utilizzo dei tipi di carattere

Se il controllo ActiveX visualizza testo, è possibile consentire all'utente del controllo di modificare l'aspetto del testo modificando una proprietà del tipo di carattere. Le proprietà del tipo di carattere vengono implementate come oggetti carattere e possono essere uno dei due tipi seguenti: stock o custom. Le proprietà tipo di carattere predefinite sono proprietà del tipo di carattere preimplementate che è possibile aggiungere tramite l'Aggiunta guidata proprietà. Le proprietà del tipo di carattere personalizzate non vengono preimplementate e lo sviluppatore del controllo determina il comportamento e l'utilizzo della proprietà.

Questo articolo include gli argomenti seguenti:

Utilizzo della proprietà Stock Font

Le proprietà tipo di carattere azionario vengono preimplementate dalla classe COleControl. Inoltre, è disponibile anche una pagina delle proprietà Font standard, che consente all'utente di modificare vari attributi dell'oggetto carattere, ad esempio il nome, le dimensioni e lo stile.

Accedere all'oggetto carattere tramite le funzioni GetFont, SetFont e InternalGetFont di COleControl. L'utente del controllo accederà all'oggetto carattere tramite le GetFont funzioni e SetFont nello stesso modo di qualsiasi altra proprietà Get/Set. Quando l'accesso all'oggetto tipo di carattere è necessario dall'interno di un controllo, usare la InternalGetFont funzione .

Come descritto in Controlli ActiveX MFC: Proprietà, l'aggiunta di proprietà azionarie è semplice con l'Aggiunta guidata proprietà. Si sceglie la proprietà Font e l'Aggiunta guidata proprietà inserisce automaticamente la voce tipo di carattere azionario nella mappa di distribuzione del controllo.

Per aggiungere la proprietà Font stock utilizzando l'Aggiunta guidata proprietà

  1. Caricare il progetto del controllo.

  2. In Visualizzazione classi, espandere il nodo di libreria del controllo.

  3. Fare clic con il pulsante destro del mouse sul nodo interfaccia del controllo (il secondo nodo del nodo di libreria) per aprire il menu di scelta rapida.

  4. Scegliere Aggiungi dal menu di scelta rapida e quindi fare clic su Aggiungi proprietà.

    Verrà visualizzata l'Aggiunta guidata proprietà.

  5. Nella casella Nome proprietà fare clic su Tipo di carattere.

  6. Fare clic su Fine.

L'Aggiunta guidata proprietà aggiunge la riga seguente alla mappa di distribuzione del controllo, che si trova nel file di implementazione della classe di controllo:

DISP_STOCKPROP_FONT()

Inoltre, l'Aggiunta guidata proprietà aggiunge la riga seguente al controllo . File IDL:

[id(DISPID_FONT)] IFontDisp* Font;

La proprietà Stock Caption è un esempio di proprietà di testo che può essere disegnata utilizzando le informazioni sulla proprietà Font di titolo. L'aggiunta della proprietà Stock Caption al controllo utilizza passaggi simili a quelli utilizzati per la proprietà Stock Font.

Per aggiungere la proprietà Titolo azionario utilizzando l'Aggiunta guidata proprietà

  1. Caricare il progetto del controllo.

  2. In Visualizzazione classi, espandere il nodo di libreria del controllo.

  3. Fare clic con il pulsante destro del mouse sul nodo interfaccia del controllo (il secondo nodo del nodo di libreria) per aprire il menu di scelta rapida.

  4. Scegliere Aggiungi dal menu di scelta rapida e quindi fare clic su Aggiungi proprietà.

    Verrà visualizzata l'Aggiunta guidata proprietà.

  5. Nella casella Nome proprietà fare clic su Didascalia.

  6. Fare clic su Fine.

L'Aggiunta guidata proprietà aggiunge la riga seguente alla mappa di distribuzione del controllo, che si trova nel file di implementazione della classe di controllo:

DISP_STOCKPROP_CAPTION()

Modifica della funzione OnDraw

L'implementazione predefinita di usa il tipo di carattere di OnDraw sistema windows per tutto il testo visualizzato nel controllo . Ciò significa che è necessario modificare il OnDraw codice selezionando l'oggetto carattere nel contesto del dispositivo. A tale scopo, chiamare COleControl::SelectStockFont e passare il contesto di dispositivo del controllo, come illustrato nell'esempio seguente:

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

Dopo che la OnDraw funzione è stata modificata per utilizzare l'oggetto font, qualsiasi testo all'interno del controllo viene visualizzato con caratteristiche della proprietà Font stock del controllo.

Uso delle proprietà personalizzate dei tipi di carattere nel controllo

Oltre alla proprietà Stock Font, il controllo ActiveX può avere proprietà font personalizzate. Per aggiungere una proprietà del tipo di carattere personalizzata, è necessario:

Implementazione di una proprietà font personalizzata

Per implementare una proprietà Font personalizzata, utilizzare l'Aggiunta guidata proprietà per aggiungere la proprietà e quindi apportare alcune modifiche al codice. Le sezioni seguenti descrivono come aggiungere la proprietà personalizzata HeadingFont al controllo Sample.

Per aggiungere la proprietà Font personalizzata utilizzando l'Aggiunta guidata proprietà
  1. Caricare il progetto del controllo.

  2. In Visualizzazione classi, espandere il nodo di libreria del controllo.

  3. Fare clic con il pulsante destro del mouse sul nodo interfaccia del controllo (il secondo nodo del nodo di libreria) per aprire il menu di scelta rapida.

  4. Scegliere Aggiungi dal menu di scelta rapida e quindi fare clic su Aggiungi proprietà.

    Verrà visualizzata l'Aggiunta guidata proprietà.

  5. Nella casella Nome proprietà digitare un nome per la proprietà. Per questo esempio, usare HeadingFont.

  6. Per Tipo di implementazione, fare clic su Metodi Get/Set.

  7. Nella casella Tipo di proprietà selezionare IDispatch* per il tipo della proprietà.

  8. Fare clic su Fine.

L'Aggiunta guidata proprietà crea il codice per aggiungere la HeadingFont proprietà personalizzata alla CSampleCtrl classe e all'esempio. File IDL. Poiché HeadingFont è un tipo di proprietà Get/Set, la Creazione guidata proprietà modifica la CSampleCtrl mappa dispatch della classe in modo da includere una voce di macro DISP_PROPERTY_EX_ID DISP_PROPERTY_EX:

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

La macro DISP_PROPERTY_EX associa il nome della HeadingFont proprietà ai metodi GetHeadingFont Get e Set corrispondenti CSampleCtrl della classe e SetHeadingFont. Viene inoltre specificato il tipo del valore della proprietà; in questo caso, VT_FONT.

Aggiunta guidata proprietà aggiunge anche una dichiarazione nel file di intestazione del controllo (. H) per le GetHeadingFont funzioni e SetHeadingFont e aggiunge i relativi modelli di funzione nel file di implementazione del controllo (. 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();
}

Infine, l'Aggiunta guidata proprietà modifica il controllo . File IDL aggiungendo una voce per la HeadingFont proprietà :

[id(1)] IDispatch* HeadingFont;

Modifiche al codice di controllo

Dopo aver aggiunto la HeadingFont proprietà al controllo, è necessario apportare alcune modifiche all'intestazione del controllo e ai file di implementazione per supportare completamente la nuova proprietà.

Nel file di intestazione del controllo (. H), aggiungere la dichiarazione seguente di una variabile membro protetta:

protected:
   CFontHolder m_fontHeading;

Nel file di implementazione del controllo (. CPP), eseguire le operazioni seguenti:

  • Inizializzare m_fontHeading nel costruttore del controllo.

    CMyAxFontCtrl::CMyAxFontCtrl()
       : m_fontHeading(&m_xFontNotification)
    {
       InitializeIIDs(&IID_DNVC_MFC_AxFont, &IID_DNVC_MFC_AxFontEvents);
    }
    
  • Dichiarare una struttura FONTDESC statica contenente gli attributi predefiniti del tipo di carattere.

    static const FONTDESC _fontdescHeading =
    { sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE(12), FW_BOLD,
      ANSI_CHARSET, FALSE, FALSE, FALSE };
    
  • Nella funzione membro del controllo DoPropExchange aggiungere una chiamata alla PX_Font funzione . In questo modo viene fornita l'inizializzazione e la persistenza per la proprietà Font personalizzata.

    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);
    }
    
  • Completare l'implementazione della funzione membro del controllo GetHeadingFont .

    IDispatch* CMyAxFontCtrl::GetHeadingFont(void)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       return m_fontHeading.GetFontDispatch();
    }
    
  • Completare l'implementazione della funzione membro del controllo SetHeadingFont .

    void CMyAxFontCtrl::SetHeadingFont(IDispatch* pVal)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       m_fontHeading.InitializeFont(&_fontdescHeading, pVal);
       OnFontChanged();    //notify any changes
       SetModifiedFlag();
    }
    
  • Modificare la funzione membro del controllo OnDraw per definire una variabile per contenere il tipo di carattere selezionato in precedenza.

    CFont* pOldHeadingFont;
    
  • Modificare la funzione membro del controllo OnDraw per selezionare il tipo di carattere personalizzato nel contesto di dispositivo aggiungendo la riga seguente ovunque venga usato il tipo di carattere.

    pOldHeadingFont = SelectFontObject(pdc, m_fontHeading);
    
  • Modificare la funzione membro del controllo OnDraw per selezionare nuovamente il tipo di carattere precedente nel contesto di dispositivo aggiungendo la riga seguente dopo l'utilizzo del tipo di carattere.

    pdc->SelectObject(pOldHeadingFont);
    

Dopo l'implementazione della proprietà Font personalizzata, deve essere implementata la pagina delle proprietà Font standard, consentendo agli utenti di controllare di modificare il tipo di carattere corrente del controllo. Per aggiungere l'ID pagina delle proprietà per la pagina delle proprietà Font standard, inserire la riga seguente dopo la macro BEGIN_PROPPAGEIDS:

PROPPAGEID(CLSID_CFontPropPage)

È inoltre necessario incrementare di uno il parametro count della macro BEGIN_PROPPAGEIDS. Questa condizione è illustrata dalla riga seguente:

BEGIN_PROPPAGEIDS(CMyAxFontCtrl, 2)

Dopo aver apportato queste modifiche, ricompilare l'intero progetto per incorporare le funzionalità aggiuntive.

Elaborazione delle notifiche dei tipi di carattere

Nella maggior parte dei casi, il controllo deve sapere quando sono state modificate le caratteristiche dell'oggetto carattere. Ogni oggetto carattere è in grado di fornire notifiche quando cambia chiamando una funzione membro dell'interfaccia IFontNotification , implementata da COleControl.

Se il controllo utilizza la proprietà Stock Font, le relative notifiche vengono gestite dalla OnFontChanged funzione membro di COleControl. Quando si aggiungono proprietà personalizzate del tipo di carattere, è possibile usarle con la stessa implementazione. Nell'esempio della sezione precedente, questa operazione è stata eseguita passando &m_xFontNotification durante l'inizializzazione della variabile membro m_fontHeading .

Implementing multiple font object interfaces.
Implementazione di interfacce di oggetti con più tipi di carattere

Le linee solide nella figura precedente mostrano che entrambi gli oggetti carattere usano la stessa implementazione di IFontNotification. Ciò potrebbe causare problemi se si desidera distinguere il tipo di carattere modificato.

Un modo per distinguere tra le notifiche degli oggetti carattere del controllo consiste nel creare un'implementazione separata dell'interfaccia IFontNotification per ogni oggetto carattere nel controllo . Questa tecnica consente di ottimizzare il codice di disegno aggiornando solo la stringa o le stringhe che utilizzano il tipo di carattere modificato di recente. Le sezioni seguenti illustrano i passaggi necessari per implementare interfacce di notifica separate per una seconda proprietà Font. Si presuppone che la seconda proprietà del tipo di carattere sia la HeadingFont proprietà aggiunta nella sezione precedente.

Implementazione di una nuova interfaccia di notifica dei tipi di carattere

Per distinguere tra le notifiche di due o più tipi di carattere, è necessario implementare una nuova interfaccia di notifica per ogni tipo di carattere utilizzato nel controllo. Le sezioni seguenti descrivono come implementare una nuova interfaccia di notifica dei tipi di carattere modificando l'intestazione del controllo e i file di implementazione.

Aggiunte al file di intestazione

Nel file di intestazione del controllo (. H), aggiungere le righe seguenti alla dichiarazione di classe:

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

Verrà creata un'implementazione dell'interfaccia IPropertyNotifySink denominata HeadingFontNotify. Questa nuova interfaccia contiene un metodo denominato OnChanged.

Aggiunte al file di implementazione

Nel codice che inizializza il tipo di carattere dell'intestazione (nel costruttore del controllo), imposta &m_xFontNotification su &m_xHeadingFontNotify. Aggiungere quindi il codice seguente:

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

I AddRef metodi e Release nell'interfaccia IPropertyNotifySink tengono traccia del conteggio dei riferimenti per l'oggetto controllo ActiveX. Quando il controllo ottiene l'accesso al puntatore all'interfaccia, il controllo chiama AddRef per incrementare il conteggio dei riferimenti. Quando il controllo viene completato con il puntatore, chiama Release, nello stesso modo in cui GlobalFree potrebbe essere chiamato per liberare un blocco di memoria globale. Quando il conteggio dei riferimenti per questa interfaccia passa a zero, l'implementazione dell'interfaccia può essere liberata. In questo esempio, la QueryInterface funzione restituisce un puntatore a un'interfaccia IPropertyNotifySink su un oggetto specifico. Questa funzione consente a un controllo ActiveX di eseguire query su un oggetto per determinare le interfacce supportate.

Dopo aver apportato queste modifiche al progetto, ricompilare il progetto e usare Test Container per testare l'interfaccia. Per informazioni su come accedere al Test Container, vedere Test di proprietà ed eventi con Test Container .

Vedi anche

Controlli ActiveX MFC
Controlli ActiveX MFC: uso di immagini in un controllo ActiveX
Controlli ActiveX MFC: uso delle pagine delle proprietà predefinite