Partilhar via


Exemplo: Implementação de uma página propriedade

Este exemplo mostra como construir um página de propriedades se exibe (e permite que você altere) propriedades do Classes de documento interface. Essa interface é exposta por documentos Exemplos de modelo de objeto de ambiente ComComumComum (Embora o página de propriedades que serão criados não importa onde sistema autônomo objetos que ele manipula vêm desde que eles oferecem suporte a interface correta).

O exemplo se baseia o Exemplo de ATLPages.

Para concluir este exemplo, você irá:

  • Adicione a classe de página de propriedades do ATL usando a caixa de diálogo Add Class e o Assistente de página de propriedades ATL.

  • edição o recurso de caixa de diálogo adicionando novos controles para as propriedades interessantes do Documento interface.

  • Adicionar mensagem manipuladores para manter o site da página de propriedades informados sobre as alterações feitas pelo usuário.

  • Adicionar alguns #import instruções e um typedef no Manutenção do sistema seção.

  • Substituir IPropertyPageImpl::SetObjects para validar os objetos sejam passados para o página de propriedades.

  • Substituir IPropertyPageImpl::ativar inicializar a interface da página de propriedades.

  • Substituir IPropertyPageImpl::aplicar para atualização o objeto com os valores de propriedade mais recentes.

  • Exibir o página de propriedades, criando um objeto auxiliar simples.

  • Criar uma macro que testará o página de propriedades.

Adicionando a classe de página de propriedades ATL

Primeiro, crie um novo projeto ATL para um servidor DLL denominado ATLPages7. Agora usar o Assistente de página de propriedade do ATL para gerar uma página de propriedades.Fornecer um a página de propriedadesNome abreviado of DocProperties , em seguida, alterne para o Seqüências de caracteres página para conjunto itens específicos de página de propriedade conforme mostrado na tabela a seguir.

Item

Valor

Title

TextDocument

String doc

VCUE TextDocument propriedades

Arquivo de ajuda

<blank>

Os valores que você conjunto nesta página do assistente serão retornadas para o contêiner de página de propriedades, quando ele chama IPropertyPage::GetPageInfo.O que acontece com as cadeias de caracteres depois que é dependente de contêiner, mas normalmente eles serão usados para identificar sua página para o usuário.O título geralmente será exibida em uma guia acima de sua página e a seqüência de caracteres do documento pode ser exibida em uma BAR de status ou a dica de ferramenta (Embora o quadro de propriedade padrão não usa essa seqüência de caracteres em todos os).

Observação:

sistema autônomo seqüências de caracteres que você conjunto aqui são armazenadas sistema autônomo recursos de seqüência de caracteres em seu projeto pelo assistente.Você pode edição com com facilidade essas cadeias de caracteres usando o editor de recursos caso você precise alterar essas informações após o código para a página foi gerado.

clicar OK para que o assistente gerar seu página de propriedades.

O recurso de caixa de diálogo de edição

Agora que seu propriedade página tiver sido gerada, será preciso adicionar alguns controles para o recurso de caixa de diálogo que representa sua página.Adicione uma caixa de edição, um controle de texto estático e uma caixa de seleção e defina suas identificações sistema autônomo mostrado abaixo:

Esses controles serão usados para exibir o nome de arquivo do documento e seu status de somente leitura.

Observação:

O recurso de caixa de diálogo não inclui um quadro ou botões de comando, nem faz ele tem a aparência com guias que você pode ser esperado.Esses recursos são fornecidos por um quadro de página de propriedades sistema autônomo a criado chamando OleCreatePropertyFrame.

Adicionando manipuladores de mensagem

Com os controles em vigor, você pode adicionar manipuladores de mensagens para atualizar o status incorreto da página quando o valor de qualquer um dos controles é alterado:

BEGIN_MSG_MAP(CDocProperties)
   COMMAND_HANDLER(IDC_NAME, EN_CHANGE, OnUIChange)
   COMMAND_HANDLER(IDC_READONLY, BN_CLICKED, OnUIChange)
   CHAIN_MSG_MAP(IPropertyPageImpl<CDocProperties>)
END_MSG_MAP()

   // Respond to changes in the UI to update the dirty status of the page
   LRESULT OnUIChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
   {
      wNotifyCode; wID; hWndCtl; bHandled;
      SetDirty(true);
      return 0;
   }

Esse código responde às alterações feitas no controle de edição ou a caixa de seleção chamando IPropertyPageImpl::SetDirty, que informa o site de página a página foi alterada.Normalmente o site de página responderá por ativar ou desativar um Aplicar botão no quadro de página de propriedades.

Observação:

Em suas próprias páginas de propriedades, talvez seja necessário manter tra CK de precisamente as propriedades que foram alteradas pelo usuário para que você pode evitar atualizar propriedades que não tenha sido alteradas.Este exemplo implementa esse código, manter o controle dos valores de propriedade originais e compará-los com o valor corrente s da interface do usuário quando for o momento para aplicar as alterações.

Manutenção do sistema

Agora adicionar alguns #import instruções para DocProperties.h para que o compilador sabe sobre o Documento interface:

// MSO.dll
#import <libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52> version("2.2") \
   rename("RGB", "Rgb")   \
   rename("DocumentProperties", "documentproperties")   \
   rename("ReplaceText", "replaceText")   \
   rename("FindText", "findText")   \
   rename("GetObject", "getObject")   \
   raw_interfaces_only

// dte.olb
#import <libid:80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2> \
   inject_statement("using namespace Office;")   \
   rename("ReplaceText", "replaceText")   \
   rename("FindText", "findText")   \
   rename("GetObject", "getObject")   \
   rename("SearchPath", "searchPath")   \
   raw_interfaces_only

Também será necessário para se referir a IPropertyPageImpl classe base; adicione o seguinte typedef para o CDocProperties classe:

typedef IPropertyPageImpl<CDocProperties> PPGBaseClass;

Substituindo IPropertyPageImpl::SetObjects

O primeiro IPropertyPageImpl método que você precisa substituir é SetObjects.Aqui você adicionará código para verificar se apenas um único objeto foi passado e que oferece suporte a Documento interface que você estiver esperando:

STDMETHOD(SetObjects)(ULONG nObjects, IUnknown** ppUnk)
{
   HRESULT hr = E_INVALIDARG;
   if (nObjects == 1)
   {
      CComQIPtr<EnvDTE::Document> pDoc(ppUnk[0]);
      if (pDoc)
         hr = PPGBaseClass::SetObjects(nObjects, ppUnk);
   }
   return hr;
}
Observação:

Faz sentido para oferecer suporte a apenas um único objeto para esta página porque você permitirá que o usuário conjunto o nome de arquivo do objeto — somente um arquivo pode existir em qualquer um só local.

Substituindo IPropertyPageImpl::ativar

A próxima etapa é inicializar a página de propriedades com os valores de propriedade do objeto base quando a página é criada pela primeira vez.

Nesse caso adicione os seguintes membros para a classe como você também usará os valores de propriedade inicial para comparação quando os usuários da página aplicar suas alterações:

CComBSTR m_bstrFullName;  // The original name
VARIANT_BOOL m_bReadOnly; // The original read-only state

A implementação da classe base do Ativar método é responsável por criar a caixa de diálogo e seus controles, para que você possa substituir esse método e adicionar sua própria inicialização após chamar a classe base:

STDMETHOD(Activate)(HWND hWndParent, LPCRECT prc, BOOL bModal)
{
   // If we don't have any objects, this method should not be called
   // Note that OleCreatePropertyFrame will call Activate even if
   // a call to SetObjects fails, so this check is required
   if (!m_ppUnk)
      return E_UNEXPECTED;

   // Use Activate to update the property page's UI with information
   // obtained from the objects in the m_ppUnk array

   // We update the page to display the Name and ReadOnly properties
   // of the document

   // Call the base class
   HRESULT hr = PPGBaseClass::Activate(hWndParent, prc, bModal);
   if (FAILED(hr))
      return hr;

   // Get the EnvDTE::Document pointer
   CComQIPtr<EnvDTE::Document> pDoc(m_ppUnk[0]);
   if (!pDoc)
      return E_UNEXPECTED;

   // Get the FullName property
   hr = pDoc->get_FullName(&m_bstrFullName);
   if (FAILED(hr))
      return hr;

   // Set the text box so that the user can see the document name
   USES_CONVERSION;
   SetDlgItemText(IDC_NAME, CW2CT(m_bstrFullName));

   // Get the ReadOnly property
   m_bReadOnly = VARIANT_FALSE;
   hr = pDoc->get_ReadOnly(&m_bReadOnly);
   if (FAILED(hr))
      return hr;

   // Set the check box so that the user can see the document's read-only status
   CheckDlgButton(IDC_READONLY, m_bReadOnly ? BST_CHECKED : BST_UNCHECKED);

   return hr;
}

Esse código usa os métodos COM o Documento interface para obter as propriedades que você está interessado.Em seguida, ele usa os invólucros de Win32 API fornecidos por CDialogImpl e suas classes base para exibir os valores de propriedade para o usuário.

Substituindo IPropertyPageImpl::aplicar

Quando os usuários desejam aplicar suas alterações para os objetos, o site da página de propriedades será telefonar o Aplicar método.Este é o lugar para fazer o contrário do código de Ativar — whereas Ativar levou a valores do objeto e empurrado os controles da página de propriedade, Aplicar usa valores de controles na página de propriedades e envia-los para o objeto.

STDMETHOD(Apply)(void)
{
   // If we don't have any objects, this method should not be called
   if (!m_ppUnk)
      return E_UNEXPECTED;

   // Use Apply to validate the user's settings and update the objects'
   // properties

   // Check whether we need to update the object
   // Quite important since standard property frame calls Apply
   // when it doesn't need to
   if (!m_bDirty)
      return S_OK;

   HRESULT hr = E_UNEXPECTED;

   // Get a pointer to the document
   CComQIPtr<EnvDTE::Document> pDoc(m_ppUnk[0]);
   if (!pDoc)
      return hr;

   // Get the read-only setting
   VARIANT_BOOL bReadOnly = IsDlgButtonChecked(IDC_READONLY) ? VARIANT_TRUE : VARIANT_FALSE;

   // Get the file name
   CComBSTR bstrName;
   if (!GetDlgItemText(IDC_NAME, bstrName.m_str))
      return E_FAIL;

   // Set the read-only property
   if (bReadOnly != m_bReadOnly)
   {
      hr = pDoc->put_ReadOnly(bReadOnly);
      if (FAILED(hr))
         return hr;
   }

   // Save the document
   if (bstrName != m_bstrFullName)
   {
      EnvDTE::vsSaveStatus status;
      hr = pDoc->Save(bstrName, &status);
      if (FAILED(hr))
         return hr;
   }

   // Clear the dirty status of the property page
   SetDirty(false);

   return S_OK;
}
Observação:

A verificação de m_bDirty no início dessa implementação é uma verificação inicial para evitar atualizações desnecessárias dos objetos se Aplicar é chamado mais de uma vez.Também há verificações em cada um dos valores de propriedade para garantir que somente as alterações resultarem em uma telefonar de método para o Documento.

Observação:

Documento exposes FullName sistema autônomo uma propriedade somente leitura.Para atualizar o nome de arquivo do documento com base nas alterações feitas na página de propriedades, você precisa usar o Salvar método para salvar o arquivo com um nome diferente.Assim, o código em um página de propriedades não precisa limitar-se para obter ou definir propriedades.

Exibindo o página de propriedades

Para exibir esta página, você precisará criar um objeto auxiliar simples.O objeto auxiliar irá fornecer um método que simplifica o OleCreatePropertyFrame API para exibir uma página única conectado a um único objeto.Esse auxiliar vai ser projetado de tal forma que possam ser usado no Visual Basic.

Use o Adicionar caixa de diálogo de classe and the ATL Simple objeto assistente para gerar uma nova classe e use Helper sistema autônomo o nome curto. Uma vez criado, adicione um método sistema autônomo mostrado na tabela a seguir.

Item

Valor

Nome do método

ShowPage

Parâmetros

[in] BSTR bstrCaption, [in] BSTR bstrID, [in] IUnknown* pUnk

The bstrCaption parâmetro é a legenda a ser exibido sistema autônomo o título da caixa de diálogo. The bstrID parâmetro é uma seqüência de caracteres que representa um CLSID ou ProgID do página de propriedades para exibir. The pUnk parâmetro será o IUnknown ponteiro de objeto cujas propriedades serão definidas pelo página de propriedades.

Implemente o método conforme mostrado abaixo:

STDMETHODIMP CHelper::ShowPage(BSTR bstrCaption, BSTR bstrID, IUnknown* pUnk)
{
   if (!pUnk)
      return E_INVALIDARG;

   // First, assume bstrID is a string representing the CLSID 
   CLSID theCLSID = {0};
   HRESULT hr = CLSIDFromString(bstrID, &theCLSID);
   if (FAILED(hr))
   {
      // Now assume bstrID is a ProgID
      hr = CLSIDFromProgID(bstrID, &theCLSID);
      if (FAILED(hr))
         return hr;
   }

   // Use the system-supplied property frame
   return OleCreatePropertyFrame(
      GetActiveWindow(),   // Parent window of the property frame
      0,           // Horizontal position of the property frame
      0,           // Vertical position of the property frame
      bstrCaption, // Property frame caption
      1,           // Number of objects
      &pUnk,       // Array of IUnknown pointers for objects
      1,           // Number of property pages
      &theCLSID,   // Array of CLSIDs for property pages
      NULL,        // Locale identifier
      0,           // Reserved - 0
      NULL         // Reserved - 0
      );
}

Criando uma macro

Depois de criar o projeto, você pode testar o página de propriedades e o objeto auxiliar usando uma macro simples que você pode criar e executar no ambiente de desenvolvimento do Visual Studio.Essa macro será criar um objeto auxiliar e, em seguida, chame seu ShowPage método usando o ProgID do DocProperties propriedade página e o IUnknown o ponteiro do documento ativo no momento no editor do Visual Studio.O código que necessário para essa macro é mostrado abaixo:

Imports EnvDTE
Imports System.Diagnostics

Public Module AtlPages

    Public Sub Test()
        Dim Helper
        Helper = CreateObject("ATLPages7.Helper.1")

        On Error Resume Next
        Helper.ShowPage( _
            ActiveDocument.Name, _
            "ATLPages7Lib.DocumentProperties.1", _
            DTE.ActiveDocument _
            )
    End Sub

End Module

Quando você executa essa macro, será exibida a página de propriedades mostram o nome de arquivo e o status somente leitura do documento de texto ativo no momento.O estado de somente leitura do documento apenas reflete a capacidade de gravar no documento no ambiente de desenvolvimento; ela não afeta o atributo somente leitura do arquivo no disco.

Consulte também

Tarefas

Exemplo de ATLPages: Implementa uma página de propriedade usando IPropertyPageImpl

Conceitos

ATL COM propriedade Pages