Partager via


Contrôles ActiveX MFC : Utilisation des polices

Si votre contrôle ActiveX affiche du texte, vous pouvez permettre à l'utilisateur du contrôle de modifier l'apparence du texte en modifiant une propriété police. Les propriétés sont implémentées en tant qu'objets de police et peuvent être de deux types : standard ou personnalisés. Les propriétés standard sont des propriétés police pré-implementées que vous ajoutez à l'aide de l'assistant d'ajout de propriété. Les propriétés personnalisées sont pas pré-implémentées et le développeur de contrôle détermine le comportement et l'utilisation de la propriété.

Cet article couvre les rubriques suivantes:

  • Utilisation de la propriété de police standard

  • Utilisation de propriétés personnalisées dans votre contrôle

Utilisation de la propriété de police standard

Les propriétés standard sont pré-implémentées par la classe COleControl. En outre, une page de propriétés de police standard est également disponible, ce qui permet l'utilisateur de modifier différents attributs de l'objet de police, telles que son nom, sa taille et son style.

Accédez à l'objet de police par GetFont, SetFont, les fonctions InternalGetFont de COleControl. L'utilisateur du contrôle accède à l'objet de police via les fonctions GetFont et SetFont de la même manière que toute autre propriété Get/Set. Lorsque l'accès à l'objet de police est requis pour un contrôle, utilisez la fonction InternalGetFont.

Comme l'explique Contrôles ActiveX MFC : Propriétés, ajouter des propriétés standard est simple avec l'Assistant Ajout de propriété. Choisissez la propriété, et l'assistant d'ajout de propriété insère automatiquement l'entrée police standard dans la table de dispatch du contrôle.

Pour ajouter la propriété de police standard à l'aide de l'assistant d'ajout de propriété

  1. Chargez votre projet.

  2. Sous Class View, développez l'arborescence de votre librairie.

  3. Cliquez avec le bouton droit sur le nœud de votre interface (le deuxième nœud de l'arborescence de la librairie) pour ouvrir le menu contextuel.

  4. Dans le menu contextuel, cliquez sur Ajouter puis sur Ajouter une propriété.

    Cela ouvre l'Assistant Ajout de Propriétés.

  5. Dans la zone de Nom de propriété, cliquez sur Police.

  6. Cliquez sur Terminer.

L'assistant d'ajout de propriétés ajoute la ligne suivante à la table de dispatch de contrôle, située dans le fichier d'implémentation de la classe de contrôle :

DISP_STOCKPROP_FONT()

En outre, l'asssistant d'ajout de propriété ajoute la ligne suivante au fichier .IDL de contrôle :

[id(DISPID_FONT)] IFontDisp*Font;

La propriété de légende standard est un exemple d'une propriété de texte qui peut être tracée à l'aide des informations de propriété de police standard. L'ajout de la propriété de légende standard au contrôle utilise des étapes similaires à celles utilisées pour la propriété de polce standard.

Pour ajouter la propriété de légende standard à l'aide de l'assistant d'ajout de propriété

  1. Chargez votre projet.

  2. Sous Class View, développez l'arborescence de votre librairie.

  3. Cliquez avec le bouton droit sur le nœud de votre interface (le deuxième nœud de l'arborescence de la librairie) pour ouvrir le menu contextuel.

  4. Dans le menu contextuel, cliquez sur Ajouter puis sur Ajouter une propriété.

    Cela ouvre l'Assistant Ajout de Propriétés.

  5. Dans la zone de Nom de propriété, cliquez sur Légende.

  6. Cliquez sur Terminer.

L'assistant d'ajout de propriétés ajoute la ligne suivante à la table de dispatch de contrôle, située dans le fichier d'implémentation de la classe de contrôle :

DISP_STOCKPROP_CAPTION()

Modifier la fonction OnDraw

L'implémentation par défaut de OnDraw utilise la police système Windows pour tout le texte affiché dans le contrôle. Cela signifie que vous devez modifier le code OnDraw en sélectionnant l'objet police dans le contexte du périphérique. Pour cela, appelez COleControl::SelectStockFont et passez le contexte du périphérique du contrôle, comme le montre l'exemple suivant :

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

Après que la fonction OnDraw modifiée pour utiliser l'objet de police, tout texte dans le contrôle s'affiche avec les caractéristiques de la propriété de police standard du contrôle.

Utilisation de propriétés personnalisées dans votre contrôle

Outre la propriété de police standard, le contrôle ActiveX peut avoir des propriétés de police personnalisées. Pour ajouter une propriété de police personnalisée vous devez :

  • Utiliser l'assistand d'ajout de propriété pour implémenter la propriété de police personnalisée.

  • Traiter les notifications de police.

  • Implémenter une interface de notification de nouvelle police.

Implémenter une propriété de police personnalisée

Pour implémenter une propriété de police personnalisée, vous utilisez l'assistant d'ajout de propriété pour ajouter la propriété puis effectuez des modifications au code. Les sections suivantes décrivent comment ajouter la propriété personnalisée HeadingFont au contrôle exemple.

Pour ajouter la propriété de police personnalisée à l'aide de l'assistant d'ajout de propriété

  1. Chargez votre projet de contrôle.

  2. Sous Class View, développez l'arborescence de votre librairie.

  3. Cliquez avec le bouton droit sur le nœud de votre interface (le deuxième nœud de l'arborescence de la librairie) pour ouvrir le menu contextuel.

  4. Dans le menu contextuel, cliquez sur Ajouter puis sur Ajouter une propriété.

    Cela ouvre l'Assistant Ajout de Propriétés.

  5. Dans la zone Nom de la propriété, tapez un nom pour votre propriété. Pour cet exemple, utilisez HeadingFont.

  6. Dans Type d'implémentation, cliquez sur Méthodes Get/Set.

  7. Dans la zone de Type de propriété, sélectionnez IDispatch* pour le type de propriété.

  8. Cliquez sur Terminer.

L'assistant d'ajout de propriété crée le code pour ajouter la propriété personnalisée HeadingFont à la classe CSampleCtrl et au fichier SAMPLE.IDL. Comme HeadingFont une propriété de type Get/Set, l'assistant d'ajout de propriété modifie la table de dispatch de la classe CSampleCtrl pour inclure une macro entrée DISP_PROPERTY_EX_IDDISP_PROPERTY_EX :

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

La macro DISP_PROPERTY_EX associe le nom de la propriété HeadingFont avec les méthodes Get/Set correspondantes de la classe CSampleCtrl, GetHeadingFont et SetHeadingFont. Le type de la valeur de propriété est également spécifié ; dans ce cas, VT_FONT.

L'assistant d'ajout de propriété ajoute également une déclaration dans le fichier d'en-tête de contrôle (.H) pour que les fonctions GetHeadingFont et SetHeadingFont s'exécutent et ajoutent leurs modèles de fonctions au fichier d'implémentation du contrôle (.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();
}

Enfin, l'assistant d'ajout de propriété modifie le fichier .IDL de contrôleen ajoutant une entrée pour la propriété HeadingFont :

[id(1)] IDispatch* HeadingFont;

Modificatons au code du contrôle

Maintenant que vous avez ajouté la propriété HeadingFont au contrôle, vous devez apporter certaines modifications à l'en-tête et aux fichiers d'implémentation du contrôle pour supporter pleinement la nouvelle propriété.

Dans le fichier d'en-tête de contrôle (.H), déclarez une variable membre protégée comme suit :

protected:
   CFontHolder m_fontHeading;

Dans le fichier d'implémentation du contrôle (.CPP), procédez comme suit :

  • Initialisez m_fontHeading dans le constructeur de contrôle.

    CMyAxFontCtrl::CMyAxFontCtrl()
       : m_fontHeading(&m_xFontNotification)
    {
        InitializeIIDs(&IID_DNVC_MFC_AxFont, &IID_DNVC_MFC_AxFontEvents);
    }
    
  • Déclarez une structure statique FONTDESC contenant les attributs par défaut de la police.

    static const FONTDESC _fontdescHeading =
      { sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE( 12 ), FW_BOLD, 
        ANSI_CHARSET, FALSE, FALSE, FALSE };
    
  • Dans la fonction membre de contrôle DoPropExchange, ajoutez un appel à la fonction PX_Font. Cela fournit l'initialisation et la persistance de votre propriété personnalisée de police.

    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);
    }
    
  • Terminez l'implémentation de la fonction membre GetHeadingFont du contrôle.

    IDispatch* CMyAxFontCtrl::GetHeadingFont(void)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       return m_fontHeading.GetFontDispatch();
    }
    
  • Terminez l'implémentation de la fonction membre SetHeadingFont du contrôle.

    void CMyAxFontCtrl::SetHeadingFont(IDispatch* pVal)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       m_fontHeading.InitializeFont(&_fontdescHeading, pVal);
       OnFontChanged();    //notify any changes
       SetModifiedFlag();
    }
    
  • Modifiez la fonction membre OnDraw contrôle pour définir une variable pour contenir la police sélectionnée précédemment.

    CFont* pOldHeadingFont;
    
  • Modifiez la fonction membre OnDraw du contrôle pour sélectionner les polices dans le contexte de périphérique en ajoutant la ligne suivante où la police doit être utilisée.

    pOldHeadingFont = SelectFontObject(pdc, m_fontHeading);
    
  • Modifiez la fonction membre OnDraw du contrôle pour sélectionner la police précédente à nouveau dans le contexte de périphérique en ajoutant la ligne suivante après que la police a été utilisée.

    pdc->SelectObject(pOldHeadingFont);
    

Lorsque la propriété personnalisée a été implémentée, la page de propriétés de la police standard devrait être implémentée, ce qui permet aux utilisateurs de contrôle de modifier la police actuelle du contrôle. Pour ajouter l'ID de propriétés à la page de propriétés de la police standard, insérez la ligne suivante après la macro BEGIN_PROPPAGEIDS :

PROPPAGEID(CLSID_CFontPropPage)

Vous devez également incrémenter de 1 le compte de paramètre de la macro BEGIN_PROPPAGEIDS. La ligne suivante illustre ce comportement :

BEGIN_PROPPAGEIDS(CMyAxFontCtrl, 2)

Une fois que ces modifications ont été apportées, recréez le projet complet pour intégrer des fonctionnalités supplémentaires.

Traiter les notifications de police.

Dans la plupart des cas le contrpole a besoin de savoir quand les caractéristiques de la police ont été modifiées. Chaque objet de police peut fournir des notifications lorsqu'il est modifié en appelant une fonction membre de l'interface IFontNotification, implémenté par COleControl.

Si le contrôle utilise la propriété de police standard, les notifications sont gérées par la fonction membre OnFontChanged de COleControl. Lorsque vous ajoutez des propriétés de police personnalisées, vous pouvez les faire utiliser la même implémentation. Dans l'exemple de la section précédente, cela était possible en passant &m_xFontNotification lors de l'initialisation de la variable membre m_fontHeading.

Implémentation d'interfaces d'objet de police mutlitples

Implémentation de plusieurs interfaces d'objet Font

Les lignes pleines dans l'illustration ci-dessus indiquent que les deux objets de police utilisent la même implémentation de IFontNotification. Cela peut poser des problèmes si vous souhaitez distinguées les polices modifiées.

Une méthode pour distinguer les notifications de police du contrôle consiste à créer une implémentation distincte de l'interface IFontNotification pour chaque objet de police dans le contrôle. Cette technique vous permet d'optimiser votre code de dessin en mettant à jour uniquement la chaîne, ou les chaînes, qui utilisent la police récemment modifiée. Les sections suivantes présentent les étapes nécessaires pour implémenter les interfaces distinctes de notification d'une seconde propriété de police. Il est supposé que la seconde propriété de police est la propriété HeadingFont ajoutée dans la section précédente.

Implémenter une interface de notification de nouvelle police.

Pour distinguer les notifications de deux ou plusieurs polices, une nouvelle interface de notification doit être implémentée pour chaque police utilisée dans le contrôle. Les sections suivantes décrivent comment implémenter une interface de notification de nouvelle police en modifiant l'en-tête et les fichiers d'implémentation du contrôle.

Ajouts au fichier d'en-tête

Dans le fichier d'en-tête du contrôle (.H), ajoutez les lignes suivantes à la déclaration de classe :

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

Cela crée une implémentation de l'interface IPropertyNotifySink appelée HeadingFontNotify. Cette nouvelle interface contient une méthode appelée OnChanged.

Ajouts au fichier d'implémentation

Dans le code qui initialise la police du titre (dans le constructeur de contrôle), changez &m_xFontNotification en &m_xHeadingFontNotify. Puis ajoutez le code suivant :

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

Les méthodes AddRef et Release dans l'interface IPropertyNotifySink contiennent le nombre de référence pour l'objet de contrôle ActiveX. Lorsque le contrôle obtient l'accès au pointeur d'interface, le contrôle appelle AddRef pour incrémenter le nombre de références. Lorsque le contrôle a terminé avec le pointeur, il appelle Release, d'une façon similaire à l'appel à GlobalFree pour libérer un bloc de mémoire globale. Lorsque le nombre de références de l'interface parvient à zéro, l'implémentation de l'interface peut être libérée. Dans cet exemple, la fonction QueryInterface retourne un pointeur vers une interface IPropertyNotifySink sur un objet particulier. Cette fonction permet à un contrôle ActiveX d'interroger un objet pour déterminer les interfaces qu'elle prend en charge.

Une fois ces modifications apportées à votre projet, reconstruisez le projet et utilisez Container Test pour tester l'interface. Pour plus d'informations sur la manière d'accéder à Test Container, consultez Test des propriétés et des événements à l'aide de Test Container.

Voir aussi

Référence

Contrôles ActiveX MFC : Utilisation des images dans un contrôle ActiveX

Contrôles ActiveX MFC : À l'aide de les pages de propriétés stock

Concepts

Contrôles ActiveX MFC