Compartir a través de


Hojas de propiedades y páginas de propiedades

Las propiedades de un objeto se exponen a los clientes iguales que los métodos a través de interfaces COM o la implementación de IDispatch del objeto, lo que permite cambiar las propiedades mediante programas que llaman a estos métodos. La tecnología OLE de páginas de propiedades proporciona los medios para crear una interfaz de usuario para las propiedades de un objeto según los estándares de la interfaz de usuario de Windows. Por lo tanto, las propiedades se exponen a los usuarios finales. La hoja de propiedades de un objeto es un cuadro de diálogo con pestañas donde cada pestaña corresponde a una página de propiedades específica. El modelo OLE para trabajar con páginas de propiedades consta de estas características:

  • Cada página de propiedades se administra mediante un objeto en proceso que implementa IPropertyPage o IPropertyPage2. Cada página se identifica con su propio CLSID único.
  • Un objeto especifica su compatibilidad con las páginas de propiedades mediante la implementación de ISpecifyPropertyPages. A través de esta interfaz, el autor de la llamada puede obtener una lista de CLSID que identifican las páginas de propiedades específicas que admite el objeto. Si el objeto especifica un CLSID de página de propiedades, el objeto debe poder recibir los cambios de propiedad de la página de propiedades.
  • Cualquier fragmento de código (cliente o objeto) que quiera mostrar la hoja de propiedades de un objeto pasa el puntero de IUnknown del objeto (o una matriz si se van a ver afectados varios objetos) junto con una matriz de CLSID de página para OleCreatePropertyFrame o OleCreatePropertyFrameIndirect, que crea el cuadro de diálogo con pestañas.
  • El cuadro de diálogo de marco de propiedades crea una instancia única de cada página de propiedades mediante CoCreateInstance en cada CLSID. El marco de propiedad obtiene al menos un puntero IPropertyPage para cada página. Además, el marco crea un objeto de sitio de página de propiedades en sí mismo para cada página. Cada sitio implementa IPropertyPageSite y este puntero se pasa a cada página. A continuación, la página se comunica con el sitio a través de este puntero de interfaz.
  • Cada página también se hace consciente del objeto u objetos para los que se ha invocado; es decir, el marco de propiedad pasa el IUnknownpunteros de los objetos a cada página. Cuando se le indica que aplique cambios a los objetos, cada página consulta el puntero de interfaz adecuado y pasa nuevos valores de propiedad a los objetos de la manera que desee. No hay ninguna información sobre cómo debe ocurrir esa comunicación.
  • Un objeto también puede admitir la exploración por propiedad a través de la interfaz IPerPropertyBrowsing que permite al objeto especificar qué propiedad debe recibir el foco inicial cuando se muestra la página de propiedades y especificar cadenas y valores que el cliente puede mostrar en su propia interfaz de usuario.

Estas características se muestran en el diagrama siguiente:

Diagrama que muestra las características de las hojas de propiedades y las páginas de propiedades.

Estas interfaces se definen de la siguiente manera:

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

El método ISpecifyPropertyPages::GetPages devuelve una matriz contada de valores UUID (GUID) cada uno de los cuales describe el CLSID de una página de propiedades que el objeto desea mostrar. Quien invoque la hoja de propiedades con OleCreatePropertyFrame o OleCreatePropertyFrameIndirect pasa esta matriz a la función. Tenga en cuenta que si el autor de la llamada desea mostrar páginas de propiedades para varios objetos, solo debe pasar la intersección de las listas CLSID de todos los objetos a estas funciones. En otras palabras, el autor de la llamada solo debe invocar páginas de propiedades que son comunes a todos los objetos.

Además, el autor de la llamada pasa también los punteros de IUnknown a los objetos afectados a las funciones de API. Ambas funciones de API crean un cuadro de diálogo de marco de propiedad y crean instancias de un sitio de página con IPropertyPageSite para cada página que se cargará. A través de esta interfaz, una página de propiedades puede:

  • Recupere el idioma actual usado en la hoja de propiedades a través de GetLocaleID.
  • Pida al marco que procese pulsaciones de tecla a través de TranslateAccelerator.
  • Notifique al marco de los cambios en la página a través de OnStatusChange.
  • Obtenga un puntero de interfaz para el propio marco a través de GetPageContainer, aunque no hay interfaces definidas para el marco en este momento para esta función siempre devuelve E_NOTIMPL.

El marco de propiedades crea una instancia de cada objeto de página de propiedades y obtiene la interfaz IPropertyPage de cada página. A través de esta interfaz, el marco informa a la página de su sitio de página (SetPageSite), recupera dimensiones de página y cadenas (GetPageInfo), pasa los punteros de interfaz a los objetos afectados (SetObjects), indica a la página cuándo crear y destruir sus controles (Activar y Desactivar), indica a la página que muestre o cambie su posición (Mostrar y Mover), indica a la página que aplique sus valores actuales a los objetos afectados (Aplicar), comprueba en la página . el estado desfasado de la página (IsPageDirty), invoca ayuda (Ayuda) y pasa pulsaciones de tecla a la página (TranslateAccelerator).

Un objeto también puede admitir la exploración por propiedad, que proporciona:

  1. Una manera (a través de IPerPropertyBrowsing y IPropertyPage2) para especificar qué propiedad en la página de propiedades debe tener el foco inicial cuando se muestra por primera vez una hoja de propiedades
  2. Una manera (a través de IPerPropertyBrowsing) para que el objeto especifique valores predefinidos y cadenas descriptivas correspondientes que se pueden mostrar en la propia interfaz de usuario de un cliente para las propiedades.

Un objeto puede optar por admitir (2) sin admitir (1), como cuando el objeto no tiene ninguna hoja de propiedades.

Las interfacesIPropertyPage2 y IPerPropertyBrowsing se definen de la siguiente manera:

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

Para especificar su compatibilidad con estas funcionalidades, el objeto implementa IPerPropertyBrowsing. A través de esta interfaz, el autor de la llamada puede solicitar la información necesaria para lograr la exploración, como cadenas predefinidas (GetPredefinedStrings) y los valores (GetPredefinedValue), así como una cadena para mostrar para una propiedad determinada (GetDisplayString).

Además, el cliente puede obtener el CLSID de la página de propiedades que permite al usuario editar una propiedad determinada identificada con un DISPID (MapPropertyToPage). A continuación, el cliente indica al marco de propiedad que active esa página inicialmente pasando el CLSID y el DISPID para OleCreatePropertyFrameIndirect. El marco activa primero esa página y pasa el DISPID a la página a través de IPropertyPage2::EditProperty. A continuación, la página establece el foco en el campo de edición de esa propiedad. De este modo, un cliente puede saltar de un nombre de propiedad en su propia interfaz de usuario a la página de propiedades que puede manipular esa propiedad.

páginas de propiedades y hojas de propiedades