Compartilhar via


Folhas de propriedades e páginas de propriedades

As propriedades de um objeto são expostas a clientes da mesma forma que os métodos por meio de interfaces COM ou implementação de IDispatch do objeto, permitindo que as propriedades sejam alteradas por programas que chamam esses métodos. A tecnologia OLE de páginas de propriedades fornece os meios para criar uma interface do usuário para as propriedades de um objeto de acordo com os padrões de interface do usuário do Windows. Assim, as propriedades são expostas aos usuários finais. A folha de propriedades de um objeto é uma caixa de diálogo com guias em que cada guia corresponde a uma página de propriedade específica. O modelo OLE para trabalhar com páginas de propriedades consiste nesses recursos:

  • Cada página de propriedade é gerenciada por um objeto em processo que implementa IPropertyPage ou IPropertyPage2. Cada página é identificada com seu próprio CLSID exclusivo.
  • Um objeto especifica seu suporte para páginas de propriedades implementando ISpecifyPropertyPages. Por meio dessa interface, o chamador pode obter uma lista de CLSIDs que identificam as páginas de propriedades específicas às quais o objeto dá suporte. Se o objeto especificar uma página de propriedade CLSID, o objeto deverá ser capaz de receber alterações de propriedade da página de propriedade.
  • Qualquer parte do código (cliente ou objeto) que deseja exibir a folha de propriedades de um objeto passa o ponteiro IUnknown do objeto (ou uma matriz se vários objetos devem ser afetados) juntamente com uma matriz de CLSIDs de página para OleCreatePropertyFrame ou OleCreatePropertyFrameIndirect, que cria a caixa de diálogo com guias.
  • A caixa de diálogo do quadro de propriedades cria uma instância única de cada página de propriedade, usando CoCreateInstance em cada CLSID. O quadro de propriedades obtém pelo menos um ponteiro de IPropertyPage para cada página. Além disso, o quadro cria um objeto de site de página de propriedade em si mesmo para cada página. Cada site implementa IPropertyPageSite e esse ponteiro é passado para cada página. Em seguida, a página se comunica com o site por meio desse ponteiro de interface.
  • Cada página também é conscientizada sobre o objeto ou os objetos para os quais ela foi invocada; ou seja, o quadro de propriedades passa os ponteirosIUnknowndos objetos para cada página. Quando instruído a aplicar alterações aos objetos, cada página consulta o ponteiro de interface apropriado e passa novos valores de propriedade para os objetos de qualquer maneira desejada. Não há estipulações sobre como essa comunicação tem que acontecer.
  • Um objeto também pode dar suporte à navegação por propriedade por meio da interface IPerPropertyBrowsing permitindo que o objeto especifique qual propriedade deve receber o foco inicial quando a página de propriedade é exibida e especificar cadeias de caracteres e valores que podem ser exibidos pelo cliente em sua própria interface do usuário.

Esses recursos são ilustrados no diagrama a seguir:

Diagrama que mostra os recursos de folhas de propriedades e páginas de propriedades.

Essas interfaces são definidas da seguinte maneira:

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

O método ISpecifyPropertyPages::GetPages retorna uma matriz contada de valores UUID (GUID) cada um dos quais descreve o CLSID de uma página de propriedade que o objeto gostaria de exibir. Quem invocar a folha de propriedades com OleCreatePropertyFrame ou OleCreatePropertyFrameIndirect passa essa matriz para a função. Observe que, se o chamador quiser exibir páginas de propriedades para vários objetos, ele só deverá passar a interseção das listas CLSID de todos os objetos para essas funções. Em outras palavras, o chamador só deve invocar páginas de propriedades comuns a todos os objetos.

Além disso, o chamador passa o IUnknown ponteiros para os objetos afetados para as funções de API também. Ambas as funções de API criam uma caixa de diálogo de quadro de propriedades e instanciam um site de página com IPropertyPageSite para cada página que ele carregará. Por meio dessa interface, uma página de propriedades pode:

  • Recupere o idioma atual usado na folha de propriedades por meio de getLocaleID.
  • Peça ao quadro para processar pressionamentos de teclas por meio de TranslateAccelerator .
  • Notifique o quadro de alterações na página por meio de OnStatusChange.
  • Obtenha um ponteiro de interface para o próprio quadro por meio GetPageContainer, embora não haja interfaces definidas para o quadro no momento para essa função sempre retorna E_NOTIMPL.

O quadro de propriedades cria uma instância de cada objeto de página de propriedade e obtém a interface IPropertyPage de cada página. Por meio dessa interface, o quadro informa a página de seu site de página (SetPageSite), recupera dimensões de página e cadeias de caracteres (GetPageInfo), passa os ponteiros da interface para os objetos afetados (SetObjects), informa à página quando criar e destruir seus controles (Ativar e Desativar), instrui a página a mostrar ou reposicionar a si mesma (Mostrar e Mover), instrui a página a aplicar seus valores atuais aos objetos afetados (Aplicar), verifica o status sujo da página (IsPageDirty), invoca ajuda (Ajuda) e passa pressionamentos de teclas para a página (TranslateAccelerator).

Um objeto também pode dar suporte à navegação por propriedade, que fornece:

  1. Uma maneira (por iPerPropertyBrowsing e IPropertyPage2) para especificar qual propriedade na qual página de propriedades deve receber o foco inicial quando uma folha de propriedades é exibida pela primeira vez
  2. Uma maneira (por meio de IPerPropertyBrowsing) para o objeto especificar valores predefinidos e cadeias de caracteres descritivas correspondentes que poderiam ser exibidas na interface do usuário de um cliente para propriedades.

Um objeto pode optar por dar suporte (2) sem suporte (1), como quando o objeto não tem nenhuma folha de propriedades.

As interfacesIPropertyPage2eIPerPropertyBrowsing são definidas da seguinte maneira:

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 seu suporte para esses recursos, o objeto implementa IPerPropertyBrowsing. Por meio dessa interface, o chamador pode solicitar as informações necessárias para obter a navegação, como cadeias de caracteres predefinidas (GetPredefinedStrings) e valores (GetPredefinedValue), bem como uma cadeia de caracteres de exibição para uma determinada propriedade (GetDisplayString).

Além disso, o cliente pode obter o CLSID da página de propriedades que permite ao usuário editar uma determinada propriedade identificada com um DISPID (MapPropertyToPage). Em seguida, o cliente instrui o quadro de propriedades a ativar essa página inicialmente passando o CLSID e o DISPID para OleCreatePropertyFrameIndirect. O quadro ativa essa página primeiro e passa o DISPID para a página por IPropertyPage2::EditProperty. Em seguida, a página define o foco para o campo de edição dessa propriedade. Dessa forma, um cliente pode saltar de um nome de propriedade em sua própria interface do usuário para a página de propriedades que pode manipular essa propriedade.

páginas de propriedades e folhas de propriedades