Condividi tramite


Controlli ActiveX MFC: uso 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 font vengono implementate come oggetti font e possono essere di due tipi: predefinito o personalizzato. Le proprietà del tipo di carattere predefinite sono proprietà del tipo di carattere integrate che è possibile aggiungere tramite la Creazione guidata per l'aggiunta di 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 illustra gli argomenti seguenti:

Utilizzo della proprietà Stock Font

Le proprietà di caratteri predefiniti 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 funzioni GetFont e SetFont nello stesso modo di ogni altra proprietà Get/Set. Quando è necessario accedere all'oggetto font da un controllo, utilizzare la funzione InternalGetFont.

Come descritto in Controlli ActiveX MFC: Proprietà, l'aggiunta di proprietà standard è semplice con la Creazione guidata per l'aggiunta di proprietà. Si sceglie la proprietà Font e l'Aggiunta guidata proprietà inserisce automaticamente la voce Font predefinita nella mappa di dispatch del controllo.

Per aggiungere la proprietà stock Font utilizzando la Creazione guidata proprietà

  1. Carica il progetto del controllo.

  2. Nella visualizzazione Classi, espandere il nodo della libreria del controllo.

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

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

    Verrà aperta la procedura guidata Aggiungi proprietà.

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

  6. Fare clic su Fine.

L'Assistente di aggiunta proprietà aggiunge la seguente riga alla mappa di invio del controllo, situata nel file di implementazione della classe di controllo.

DISP_STOCKPROP_FONT()

Inoltre, la procedura guidata per l'aggiunta delle proprietà aggiunge la riga seguente al file IDL del controllo:

[id(DISPID_FONT)] IFontDisp* Font;

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

Per aggiungere la proprietà didascalia predefinita utilizzando la procedura guidata per l'aggiunta delle proprietà

  1. Carica il progetto del controllo.

  2. Nella visualizzazione Classi, espandere il nodo della libreria del controllo.

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

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

    Verrà aperta la procedura guidata Aggiungi proprietà.

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

  6. Fare clic su Fine.

L'Assistente di aggiunta proprietà aggiunge la seguente riga alla mappa di invio del controllo, situata nel file di implementazione della classe di controllo.

DISP_STOCKPROP_CAPTION()

Modifica della funzione OnDraw

L'implementazione predefinita di OnDraw usa il tipo di carattere del sistema Windows per tutto il testo visualizzato nel controllo. Ciò significa che è necessario modificare il codice OnDraw 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 funzione OnDraw è stata modificata per utilizzare l'oggetto font, qualsiasi testo all'interno del controllo viene visualizzato con le caratteristiche della proprietà predefinita Font 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 la Procedura guidata Aggiunta proprietà
  1. Carica il progetto del controllo.

  2. Nella visualizzazione Classi, espandere il nodo della libreria del controllo.

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

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

    Verrà aperta la procedura guidata Aggiungi 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 Get/Set Methods (Metodi Get/Set).

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

  8. Fare clic su Fine.

L'Assistente per l'aggiunta crea il codice per aggiungere la proprietà personalizzata HeadingFont alla classe CSampleCtrl e al file SAMPLE.IDL. Poiché HeadingFont è un tipo di proprietà Get/Set, la Creazione guidata delle proprietà modifica la tabella di dispatch della classe in modo da includere una voce della macro CSampleCtrl: CSampleCtrl.

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

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

L'aggiunta guidata delle proprietà aggiunge anche una dichiarazione nel file di intestazione del controllo (.H) per le funzioni GetHeadingFont 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 file .IDL del controllo aggiungendo una voce per la proprietà HeadingFont.

[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 di controllo DoPropExchange aggiungere una chiamata alla funzione PX_Font. 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 di controllo GetHeadingFont.

    IDispatch* CMyAxFontCtrl::GetHeadingFont(void)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       return m_fontHeading.GetFontDispatch();
    }
    
  • Completare l'implementazione della funzione membro di 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, che consente agli utenti 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. La riga seguente illustra quanto segue:

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 .

Implementazione di più interfacce dell'oggetto carattere.
Implementazione di più interfacce di oggetti font

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 dell'interfaccia, chiama AddRef per aumentare 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 .

Vedere anche

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