Controles de ActiveX MFC: Usando fontes
Se seu controle ActiveX exibe o texto, você pode permitir que o usuário de controle alterar a aparência do texto alterando uma propriedade de fonte.Propriedades de fonte são implementadas como objetos de fonte e pode ser de dois tipos: ações ou personalizados.Propriedades de fonte ações são propriedades de fonte preimplemented que você pode adicionar usando o Assistente para adicionar propriedade.Propriedades personalizadas de fontes não são preimplemented e o desenvolvedor do controle determina o comportamento e o uso da propriedade.
Este artigo aborda os seguintes tópicos:
Usando a propriedade de fonte de papel
Usando propriedades de fonte personalizado no seu controle
Usando a propriedade de fonte de papel
Propriedades de fonte de estoque são preimplemented pela classe COleControl.Além disso, uma página de propriedades de fonte padrão também está disponível, permitindo ao usuário alterar diversos atributos do objeto de fonte, como nome, tamanho e estilo.
Acessar o objeto de fonte por meio de GetFont, SetFont, e InternalGetFont funções de COleControl.O usuário do controle irá acessar o objeto font via o GetFont e SetFont funções da mesma maneira como qualquer outra propriedade Get/Set.Quando é necessário de dentro de um controle de acesso para o objeto de fonte, use o InternalGetFont função.
Conforme discutido em controles de ActiveX de MFC: propriedades, adicionando propriedades de ações é fácil com o Assistente para adicionar propriedade.Escolha a propriedade Font e o Assistente para adicionar propriedade insere automaticamente a entrada de fonte ações no mapa de despacho do controle.
Para adicionar a propriedade fonte ações usando o Assistente para adicionar propriedade
Carregar projeto do controle.
No modo de exibição de classe, expanda o nó da biblioteca do seu controle.
Botão direito do mouse no nó de interface para o seu controle (o segundo nó do nó biblioteca) para abrir o menu de atalho.
No menu de atalho, clique em Add e clique em Adicionar propriedade de.
Isso abre o Assistente para adicionar propriedade.
No O nome da propriedade , clique fonte.
Clique em Concluir.
O Assistente para adicionar propriedade adiciona a seguinte linha ao mapa de despacho do controle, localizado no arquivo de implementação da classe de controle:
DISP_STOCKPROP_FONT()
Além disso, o Assistente para adicionar propriedade adiciona a seguinte linha ao controle.Arquivo IDL:
[id(DISPID_FONT)] IFontDisp*Font;
A propriedade Caption ações é um exemplo de uma propriedade de texto que pode ser obtido usando as informações de propriedade fonte ações.Adicionando a propriedade Caption ações para o controle usa etapas semelhantes aos usados para o propriedade Font de estoque.
Para adicionar a propriedade legenda ações usando o Assistente para adicionar propriedade
Carregar projeto do controle.
No modo de exibição de classe, expanda o nó da biblioteca do seu controle.
Botão direito do mouse no nó de interface para o seu controle (o segundo nó do nó biblioteca) para abrir o menu de atalho.
No menu de atalho, clique em Add e clique em Adicionar propriedade de.
Isso abre o Assistente para adicionar propriedade.
No O nome da propriedade , clique legenda.
Clique em Concluir.
O Assistente para adicionar propriedade adiciona a seguinte linha ao mapa de despacho do controle, localizado no arquivo de implementação da classe de controle:
DISP_STOCKPROP_CAPTION()
Modificar a função OnDraw
A implementação padrão de OnDraw usa a fonte de sistema do Windows para todo texto exibido no controle.Isso significa que você deve modificar o OnDraw código, selecionando o objeto de fonte para o contexto de dispositivo.Para fazer isso, chame COleControl::SelectStockFont e passar o contexto de dispositivo de controle, como mostrado no exemplo a seguir:
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);
Após o OnDraw função foi modificada para usar o objeto de fonte, qualquer texto dentro do controle é exibido com as características de propriedade fonte de ações do controle.
Usando propriedades de fonte personalizado no seu controle
Além da propriedade fonte ações, o controle de ActiveX pode ter propriedades de fonte personalizadas.Para adicionar uma propriedade de fonte personalizada, você deve:
Use o Assistente para adicionar propriedade para implementar a propriedade de fonte personalizada.
Processando notificações de fonte.
Implementar uma nova interface de notificação de fonte.
Implementando uma propriedade de fonte personalizado
Para implementar uma propriedade de fonte personalizada, você pode usar o Assistente para adicionar propriedade para adicionar a propriedade e, em seguida, fazer algumas modificações no código.As seções a seguir descrevem como adicionar personalizado HeadingFont propriedade para o exemplo de controle.
Para adicionar a propriedade de fonte personalizada usando o Assistente para adicionar propriedade
Carregar projeto do controle.
No modo de exibição de classe, expanda o nó da biblioteca do seu controle.
Botão direito do mouse no nó de interface para o seu controle (o segundo nó do nó biblioteca) para abrir o menu de atalho.
No menu de atalho, clique em Add e clique em Adicionar propriedade de.
Isso abre o Assistente para adicionar propriedade.
No O nome da propriedade , digite um nome para a propriedade.Para este exemplo, use HeadingFont.
Para O tipo de implementação, clique Métodos Get/Set.
No Tipo de propriedade caixa, selecione IDispatch * para o tipo da propriedade.
Clique em Concluir.
O Assistente para adicionar propriedade cria o código para adicionar o HeadingFont propriedade personalizada para o CSampleCtrl classe e a amostra.Arquivo IDL.Porque HeadingFont é um tipo de propriedade Get/Set, o Assistente para adicionar propriedade modifica o CSampleCtrl mapa de expedição da classe para incluir um DISP_PROPERTY_EX_IDDISP_PROPERTY_EX entrada de macro:
DISP_PROPERTY_EX_ID(CMyAxFontCtrl, "HeadingFont", dispidHeadingFont,
GetHeadingFont, SetHeadingFont, VT_DISPATCH)
O DISP_PROPERTY_EX macro associa o HeadingFont nome da propriedade com o correspondente CSampleCtrl classe métodos Get e Set, GetHeadingFont e SetHeadingFont.O tipo do valor da propriedade também é especificado; Nesse caso, VT_FONT.
O Assistente para adicionar propriedade também adiciona uma declaração no arquivo de cabeçalho de controle (.H) para o GetHeadingFont e SetHeadingFont funções e adiciona seus modelos de função no arquivo de implementação de controle (.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();
}
Finalmente, o Assistente para adicionar propriedade modifica o controle.Arquivo IDL adicionando uma entrada para o HeadingFont propriedade:
[id(1)] IDispatch* HeadingFont;
Modificações no código de controle
Agora que você adicionou o HeadingFont propriedade do controle, você deve fazer algumas alterações para os arquivos de cabeçalho e a implementação de controle para suportar totalmente a nova propriedade.
No arquivo de cabeçalho de controle (.H), adicione a seguinte declaração de uma variável de membro protegido:
protected:
CFontHolder m_fontHeading;
No arquivo de implementação de controle (.CPP), faça o seguinte:
Inicializar m_fontHeading no construtor do controle.
CMyAxFontCtrl::CMyAxFontCtrl() : m_fontHeading(&m_xFontNotification) { InitializeIIDs(&IID_DNVC_MFC_AxFont, &IID_DNVC_MFC_AxFontEvents); }
Declarar um estático FONTDESC estrutura que contém atributos padrão da fonte.
static const FONTDESC _fontdescHeading = { sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE( 12 ), FW_BOLD, ANSI_CHARSET, FALSE, FALSE, FALSE };
No controle de DoPropExchange membro função, adicione uma chamada para o PX_Font função.Fornece inicialização e persistência para a propriedade de fonte personalizada.
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); }
Concluir implementação do controle GetHeadingFont função de membro.
IDispatch* CMyAxFontCtrl::GetHeadingFont(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return m_fontHeading.GetFontDispatch(); }
Concluir implementação do controle SetHeadingFont função de membro.
void CMyAxFontCtrl::SetHeadingFont(IDispatch* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); m_fontHeading.InitializeFont(&_fontdescHeading, pVal); OnFontChanged(); //notify any changes SetModifiedFlag(); }
Modificar o controle OnDraw função de membro para definir uma variável para a fonte selecionada anteriormente.
CFont* pOldHeadingFont;
Modificar o controle OnDraw função de membro para selecionar a fonte personalizada no contexto de dispositivo, adicionando a seguinte linha, onde é a fonte a ser usado.
pOldHeadingFont = SelectFontObject(pdc, m_fontHeading);
Modificar o controle OnDraw função de membro para selecionar a fonte anterior para o contexto de dispositivo adicionando a seguinte linha após a fonte foi usada.
pdc->SelectObject(pOldHeadingFont);
Depois de implementar a propriedade de fonte personalizada, a página de propriedades de fonte padrão deve ser implementada, permitindo que os usuários de controle alterar a fonte atual do controle.Para adicionar a identificação de página de propriedade para a página de propriedades de fonte padrão, insira a seguinte linha após o BEGIN_PROPPAGEIDS macro:
PROPPAGEID(CLSID_CFontPropPage)
Você também deve incrementar o parâmetro de contagem de seu BEGIN_PROPPAGEIDS macro por um.A linha a seguir ilustra isso:
BEGIN_PROPPAGEIDS(CMyAxFontCtrl, 2)
Após essas alterações foram feitas, recrie o projeto inteiro para incorporar a funcionalidade adicional.
Processando notificações de fonte
Na maioria dos casos o controle precisa saber quando as características do objeto font foi modificadas.Cada objeto de fonte é capaz de fornecer notificações quando ele altera chamando uma função de membro de IFontNotification interface, implementada pelo COleControl.
Se o controle usa a propriedade fonte ações, notificações são manipuladas pelo OnFontChanged função de membro COleControl.Quando você adicionar propriedades de fonte personalizada, que eles usam a mesma implementação.No exemplo na seção anterior, isso foi conseguido passando &m_xFontNotification ao inicializar o m_fontHeading variável de membro.
Implementar várias Interfaces de objeto de fonte
As linhas sólidas na figura acima mostram que ambos os objetos de fonte estão usando a mesma implementação de IFontNotification.Isso poderia causar problemas se você quiser distinguir qual fonte alterada.
Uma maneira de distinguir entre notificações de objeto de fonte do controle é criar uma implementação separada da IFontNotification interface para cada objeto de fonte no controle.Essa técnica permite que você otimize seu código desenho atualizando apenas a seqüência de caracteres ou seqüências, que usam fontes modificadas recentemente.As seções a seguir demonstram as etapas necessárias para implementar interfaces notificação separada para uma segunda propriedade de fonte.A segunda propriedade font é considerada o HeadingFont propriedade foi adicionada na seção anterior.
Implementar uma nova Interface de notificação de fonte
Para distinguir entre as notificações de duas ou mais fontes, uma nova interface de notificação deve ser implementada para cada fonte usada no controle.As seções a seguir descrevem como implementar uma nova interface de notificação de fonte modificando os arquivos de cabeçalho e a implementação do controle.
Adições no arquivo de cabeçalho
No arquivo de cabeçalho de controle (.H), adicione as seguintes linhas para a declaração de classe:
protected:
BEGIN_INTERFACE_PART(HeadingFontNotify, IPropertyNotifySink)
INIT_INTERFACE_PART(CMyAxFontCtrl, HeadingFontNotify)
STDMETHOD(OnRequestEdit)(DISPID);
STDMETHOD(OnChanged)(DISPID);
END_INTERFACE_PART(HeadingFontNotify)
Isso cria uma implementação de IPropertyNotifySink interface chamada HeadingFontNotify.Essa nova interface contém um método chamado OnChanged.
Adições no arquivo de implementação
O código que inicializa a fonte do título (no construtor de controle), altere &m_xFontNotification para &m_xHeadingFontNotify.Em seguida, adicione o seguinte código:
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;
}
O AddRef e Release métodos de IPropertyNotifySink interface controlar de contagem de referência para o objeto de controle de ActiveX.Quando o controle obtém acesso ao ponteiro de interface, o controle chama AddRef para incrementar a contagem de referência.Quando o controle for concluído com o ponteiro, ele chama Release, da mesma maneira que GlobalFree pode ser chamado para liberar um bloco de memória global.Quando a contagem de referência para esta interface vai a zero, a implementação de interface pode ser liberada.Neste exemplo, o QueryInterface função retorna um ponteiro para um IPropertyNotifySink interface em um objeto específico.Essa função permite que um controle ActiveX consultar um objeto para determinar quais interfaces suporta.
Após essas alterações foram feitas ao seu projeto, reconstruir o projeto e use o contêiner de teste para testar a interface.Consulte testes de propriedades e eventos com o contêiner de teste do para obter informações sobre como acessar o contêiner de teste.
Consulte também
Referência
Controles de ActiveX MFC: Usando imagens em um controle ActiveX
Controles de ActiveX MFC: Usando páginas de propriedades de ações