Partager via


Pages et feuilles de propriétés

Les propriétés d’un objet sont exposées aux clients de la même façon que les méthodes via des interfaces COM ou l’implémentation IDispatch de l’objet, ce qui permet aux propriétés d’être modifiées par des programmes appelant ces méthodes. La technologie OLE des pages de propriétés permet de créer une interface utilisateur pour les propriétés d’un objet conformément aux normes d’interface utilisateur Windows. Ainsi, les propriétés sont exposées aux utilisateurs finaux. La feuille de propriétés d’un objet est une boîte de dialogue à onglets où chaque onglet correspond à une page de propriétés spécifique. Le modèle OLE pour l’utilisation des pages de propriétés se compose des fonctionnalités suivantes :

  • Chaque page de propriétés est gérée par un objet in-process qui implémente IPropertyPage ou IPropertyPage2. Chaque page est identifiée avec son propre CLSID unique.
  • Un objet spécifie sa prise en charge des pages de propriétés en implémentant ISpecifyPropertyPages. Grâce à cette interface, l’appelant peut obtenir une liste de CLSID identifiant les pages de propriétés spécifiques que l’objet prend en charge. Si l’objet spécifie un CLSID de page de propriétés, l’objet doit être en mesure de recevoir les modifications de propriété de la page de propriétés.
  • Tout élément de code (client ou objet) qui souhaite afficher la feuille de propriétés d’un objet transmet le pointeur IUnknown de l’objet (ou un tableau si plusieurs objets doivent être affectés) ainsi qu’un tableau de CLSIDs de page à OleCreatePropertyFrame ou OleCreatePropertyFrameIndirect, ce qui crée la boîte de dialogue tabbed-dialog.
  • La boîte de dialogue cadre de propriété instancie une seule instance de chaque page de propriétés, à l’aide de CoCreateInstance sur chaque CLSID. Le cadre de propriété obtient au moins un pointeur IPropertyPage pour chaque page. En outre, le cadre crée un objet de site de page de propriétés pour chaque page. Chaque site implémente IPropertyPageSite et ce pointeur est passé à chaque page. La page communique ensuite avec le site via ce pointeur d’interface.
  • Chaque page est également informée du ou des objets pour lesquels elle a été appelée ; autrement dit, le cadre de propriété transmet les pointeurs IUnknowndes objets à chaque page. Lorsqu’il est demandé d’appliquer des modifications aux objets, chaque page interroge le pointeur d’interface approprié et transmet de nouvelles valeurs de propriété aux objets de la manière souhaitée. Il n’y a aucune disposition sur la façon dont une telle communication doit se produire.
  • Un objet peut également prendre en charge la navigation par propriété dans l’interface IPerPropertyBrowsing , ce qui permet à l’objet de spécifier la propriété qui doit recevoir le focus initial lorsque la page de propriétés est affichée et de spécifier des chaînes et des valeurs qui peuvent être affichées par le client dans sa propre interface utilisateur.

Ces fonctionnalités sont illustrées dans le diagramme suivant :

Diagramme montrant les fonctionnalités des feuilles de propriétés et des pages de propriétés.

Ces interfaces sont définies comme suit :

interface ISpecifyPropertyPages : IUnknown 
  { 
    HRESULT GetPages([out] CAUUID *pPages); 
  }; 
 
 
interface IPropertyPage : IUnknown 
  { 
    HRESULT SetPageSite([in] IPropertyPageSite *pPageSite); 
    HRESULT Activate([in] HWND hWndParent, [in] LPCRECT prc 
        , [in] BOOL bModal); 
    HRESULT Deactivate(void); 
    HRESULT GetPageInfo([out] PROPPAGEINFO *pPageInfo); 
    HRESULT SetObjects([in] ULONG cObjects 
        , [in, max_is(cObjects)] IUnknown **ppunk); 
    HRESULT Show([in] UINT nCmdShow); 
    HRESULT Move([in] LPCRECT prc); 
    HRESULT IsPageDirty(void); 
    HRESULT Apply(void); 
    HRESULT Help([in] LPCOLESTR pszHelpDir); 
    HRESULT TranslateAccelerator([in] LPMSG pMsg); 
  } 
 
interface IPropertyPageSite : IUnknown 
  { 
    HRESULT OnStatusChange([in] DWORD dwFlags); 
    HRESULT GetLocaleID([out] LCID *pLocaleID); 
    HRESULT GetPageContainer([out] IUnknown **ppUnk); 
    HRESULT TranslateAccelerator([in] LPMSG pMsg); 
  } 
 

La méthode ISpecifyPropertyPages::GetPages retourne un tableau compté de valeurs UUID (GUID) qui décrivent chacune le CLSID d’une page de propriétés que l’objet souhaite afficher. Quiconque appelle la feuille de propriétés avec OleCreatePropertyFrame ou OleCreatePropertyFrameIndirect transmet ce tableau à la fonction . Notez que si l’appelant souhaite afficher des pages de propriétés pour plusieurs objets, il doit uniquement passer l’intersection des listes CLSID de tous les objets à ces fonctions. En d’autres termes, l’appelant doit appeler uniquement les pages de propriétés communes à tous les objets.

En outre, l’appelant transmet également les pointeurs IUnknown aux objets affectés aux fonctions d’API. Les deux fonctions d’API créent une boîte de dialogue de cadre de propriété et instancient un site de page avec IPropertyPageSite pour chaque page qu’elle va charger. Grâce à cette interface, une page de propriétés peut :

  • Récupérez la langue actuelle utilisée dans la feuille de propriétés via GetLocaleID.
  • Demandez au cadre de traiter les frappes via TranslateAccelerator.
  • Informez le cadre des modifications apportées à la page via OnStatusChange.
  • Obtenez un pointeur d’interface pour l’image elle-même via GetPageContainer, bien qu’aucune interface ne soit définie pour l’image pour l’instant pour cette fonction retourne toujours E_NOTIMPL.

Le cadre de propriété instancie chaque objet de page de propriétés et obtient l’interface IPropertyPage de chaque page. Par le biais de cette interface, le cadre informe la page de son site de page (SetPageSite), récupère les dimensions et chaînes de la page (GetPageInfo), transmet les pointeurs d’interface aux objets affectés (SetObjects), indique à la page quand créer et détruire ses contrôles (Activer et désactiver), indique à la page de s’afficher ou de se repositionner (Afficher et Déplacer), indique à la page d’appliquer ses valeurs actuelles aux objets affectés (Appliquer ), vérifie le sale status de la page (IsPageDirty), appelle l’aide (Aide) et transmet les frappes à la page (TranslateAccelerator).

Un objet peut également prendre en charge la navigation par propriété, qui fournit :

  1. Moyen (via IPerPropertyBrowsing et IPropertyPage2) de spécifier la propriété sur laquelle la page de propriétés doit être mise au point initialement lorsqu’une feuille de propriétés est affichée pour la première fois
  2. Moyen (via IPerPropertyBrowsing) pour l’objet de spécifier des valeurs prédéfinies et des chaînes descriptives correspondantes qui peuvent être affichées dans la propre interface utilisateur d’un client pour les propriétés.

Un objet peut choisir de prendre en charge (2) sans prendre en charge (1), par exemple lorsque l’objet n’a pas de feuille de propriétés.

Les interfaces IPropertyPage2 et IPerPropertyBrowsing sont définies comme suit :

interface IPerPropertyBrowsing : IUnknown 
  { 
    HRESULT GetDisplayString([in] DISPID dispID, [out] BSTR *pbstr); 
    HRESULT MapPropertyToPage([in] DISPID dispID, [out] CLSID *pclsid); 
    HRESULT GetPredefinedStrings([in] DISPID dispID, [out] CALPOLESTR *pcaStringsOut, [out] CADWORD *pcaCookiesOut); 
    HRESULT GetPredefinedValue([in] DISPID dispID, [in] DWORD dwCookie, [out] VARIANT *pvarOut); 
  } 
 
interface IPropertyPage2 : IPropertyPage 
  { 
    HRESULT EditProperty([in] DISPID dispID); 
  } 
 

Pour spécifier sa prise en charge de ces fonctionnalités, l’objet implémente IPerPropertyBrowsing. Grâce à cette interface, l’appelant peut demander les informations nécessaires pour effectuer la navigation, telles que des chaînes prédéfinies (GetPredefinedStrings) et des valeurs (GetPredefinedValue) ainsi qu’une chaîne d’affichage pour une propriété donnée (GetDisplayString).

En outre, le client peut obtenir le CLSID de la page de propriétés qui permet à l’utilisateur de modifier une propriété donnée identifiée avec un DISPID (MapPropertyToPage). Le client demande ensuite au cadre de propriété d’activer cette page initialement en passant le CLSID et le DISPID à OleCreatePropertyFrameIndirect. Le cadre active d’abord cette page et transmet le DISPID à la page via IPropertyPage2::EditProperty. La page définit ensuite le focus sur le champ de modification de cette propriété. De cette façon, un client peut passer d’un nom de propriété dans sa propre interface utilisateur à la page de propriétés qui peut manipuler cette propriété.

Pages de propriétés et feuilles de propriétés