Controles ActiveX MFC: tópicos avançados
Este artigo abrange os tópicos avançados relacionados a desenvolver controles ActiveX. Eles incluem:
Usando classes base de dados do em controles ActiveX
Implementando uma propriedade com parâmetros
Tratar erros no controle ActiveX
Manipulando chaves especiais no controle
Acessando os controles da caixa de diálogo que são invisíveis em tempo de execução
Usando classes base de dados do em controles ActiveX
Como as classes do controle ActiveX são parte da biblioteca de classe, você pode aplicar os mesmos procedimentos e regras para usar classes de base de dados em um aplicativo de MFC de padrão para desenvolver os controles ActiveX que usam as classes da base de dados de MFC.
Para obter uma visão geral das classes da base de dados de MFC, consulte Classes de base de dados de MFC (DAO e ODBC). O artigo apresenta as classes MFC ODBC e classes de MFC DAO e direciona você a obter mais detalhes sobre qualquer pessoa.
Dica
A partir do Visual C++ .NET, o ambiente e os assistentes do Visual C++ não dão suporte a DAO (embora as classes de DAO são incluídas e você ainda pode usar o).A Microsoft recomenda que você use Modelos OLE DB ou ODBC e MFC para novos projetos.Você só deve usar DAO manter os aplicativos existentes.
Implementando uma propriedade com parâmetros
Uma propriedade com parâmetros (às vezes chamada de matriz de propriedade) é um método para expor homogênea uma coleção de valores como uma única propriedade do controle. Por exemplo, você pode usar uma propriedade com parâmetros para expor uma matriz ou um dicionário como uma propriedade. No Visual Basic, essa propriedade é acessada usando a notação de matriz:
x = o.Array(2, 3) ' gets element of 2D array
o.Array(2, 3) = 7 ' sets element of 2D array
Use o assistente para adicionar a propriedade para implementar uma propriedade com parâmetros. O assistente da propriedade adicionar implementa a propriedade adicionando um par de funções Get/conjunto que permitem que o usuário de controle para acessar a propriedade usando notação acima ou na forma padrão.
Semelhante aos métodos e as propriedades, as propriedades com parâmetros também têm um limite para o número de parâmetros permitidos. No caso de propriedades com parâmetros, o limite é 15 (parâmetros com um parâmetro reservado para armazenar o valor da propriedade).
O procedimento a seguir adiciona uma propriedade com parâmetros, chamada a matriz, que pode ser acessada como uma matriz bidimensional de valores inteiros.
Para adicionar uma propriedade com parâmetros usando o assistente para adicionar propriedade
Carregar o projeto do controle.
Na exibição da classe, expanda o nó da biblioteca do controle.
Clique com o botão direito do mouse no nó da interface para o controle (o segundo nó do nó da biblioteca) para abrir o menu de atalho.
No menu de atalho, clique Adicionar e clique em Adicionar Propriedade.
Na caixa de Nome da propriedade , digite Array.
Na caixa de Tipo de propriedade , shortselecione.
Para o tipo de Implementação , clique Get/Set Methods.
Nas caixas de Get Function e de Set Function , os nomes exclusivos do seu e definem ou obtêm funções aceitam nomes padrão.
Adicionar um parâmetro, row chamado (tipo short), usando os controles de Nome do parâmetro e de Tipo de parâmetro .
Adicionar column chamado segundo parâmetro (tipo short).
Clique em Concluir.
Alterações feitas pelo assistente para adicionar propriedade
Quando você adiciona uma propriedade personalizada, o assistente da propriedade adicionar fizer alterações no cabeçalho da classe de controle (. H) e os arquivos de implementação (.CPP).
As seguintes linhas são adicionadas à classe do controle. Arquivo de H:
SHORT GetArray(SHORT row, SHORT column);
void SetArray(SHORT row, SHORT column, SHORT newVal);
Esse código a seguir declara duas funções chamadas GetArray e SetArray que permitem ao usuário solicita uma linha e uma coluna específicas ao acessar a propriedade.
Além disso, o assistente da propriedade adicionar adiciona as seguintes linhas no mapa da expedição de controle, localizado no arquivo de implementação da classe de controle (.CPP):
DISP_PROPERTY_PARAM_ID(CMyAxUICtrl, "Array", dispidArray, GetArray, SetArray, VT_I2, VTS_I2 VTS_I2)
Finalmente, as implementações de GetArray e funções de SetArray são adicionadas ao final do arquivo de .CPP. Na maioria dos casos, você modificará obter a função para retornar o valor da propriedade. A função de conjunto geral conterá o código que deve executar, qualquer um antes ou depois da propriedade é alterado.
Para que essa propriedade é útil, você pode declarar uma variável de membro de matriz bidimensional na classe de controle, de tipo short, os valores das lojas da propriedade com parâmetros. Você pode modificar a função obter para retornar o valor armazenado na linha e coluna apropriada, como indicado pelos parâmetros, e alterar a função de conjunto para atualizar o valor referenciado pelos parâmetros de linha e de coluna.
Tratar erros no controle ActiveX
Se as condições de erro ocorrerá em controle, talvez você precise informar o erro ao contêiner do controle. Há dois métodos para reportar erros, dependendo da situação em que ocorreu o erro. Se o erro ocorrer dentro de uma propriedade obtém ou define a função, ou na implementação de um método de Automação OLE, o controle deve chamar COleControl::ThrowError, que sinaliza ao usuário de controle que ocorreu um erro. Se o erro ocorrer em qualquer outro momento, o controle deve chamar COleControl::FireError, que dispara um evento de erro de estoque.
Para indicar o tipo do erro ocorrido, o controle deve passar um código de erro a ThrowError ou a FireError. Um código de erro é um código de status OLE, que tem um valor de 32 bits. Quando possível, escolha um código de erro de conjunto padrão de código definidos no arquivo de cabeçalho de OLECTL.H. A tabela a seguir resume esses códigos.
Códigos de erro do controle ActiveX
Erro |
Descrição |
---|---|
CTL_E_ILLEGALFUNCTIONCALL |
Chamada de função ilegal |
CTL_E_OVERFLOW |
Estouro |
CTL_E_OUTOFMEMORY |
Memória insuficiente |
CTL_E_DIVISIONBYZERO |
Divisão por zero |
CTL_E_OUTOFSTRINGSPACE |
Sem espaço de cadeia de caracteres |
CTL_E_OUTOFSTACKSPACE |
Sem espaço de pilha |
CTL_E_BADFILENAMEORNUMBER |
Número ou nome de arquivo inválido |
CTL_E_FILENOTFOUND |
Arquivo não encontrado |
CTL_E_BADFILEMODE |
Modo Bad file |
CTL_E_FILEALREADYOPEN |
Arquivo já está aberto |
CTL_E_DEVICEIOERROR |
Erro de dispositivo de E/S |
CTL_E_FILEALREADYEXISTS |
O arquivo já existe |
CTL_E_BADRECORDLENGTH |
Comprimento de registro inválido |
CTL_E_DISKFULL |
Disco cheio |
CTL_E_BADRECORDNUMBER |
Número de registro inválido. |
CTL_E_BADFILENAME |
Nome de arquivo incorreto |
CTL_E_TOOMANYFILES |
Há arquivos demais |
CTL_E_DEVICEUNAVAILABLE |
Dispositivo não disponível |
CTL_E_PERMISSIONDENIED |
Permissão negada |
CTL_E_DISKNOTREADY |
Disco não está pronto |
CTL_E_PATHFILEACCESSERROR |
Caminho/erro de acesso a arquivos |
CTL_E_PATHNOTFOUND |
Caminho não encontrado |
CTL_E_INVALIDPATTERNSTRING |
Cadeia de caracteres inválido de padrão |
CTL_E_INVALIDUSEOFNULL |
Uso inválido de NULL |
CTL_E_INVALIDFILEFORMAT |
Formato de arquivo inválido |
CTL_E_INVALIDPROPERTYVALUE |
Valor de propriedade inválido |
CTL_E_INVALIDPROPERTYARRAYINDEX |
Índice da matriz de propriedade inválido |
CTL_E_SETNOTSUPPORTEDATRUNTIME |
Conjunto não tem suporte em tempo de execução |
CTL_E_SETNOTSUPPORTED |
Definições não suportadas (propriedade somente leitura) |
CTL_E_NEEDPROPERTYARRAYINDEX |
Índice de matriz de propriedade necessário |
CTL_E_SETNOTPERMITTED |
Conjunto não permitido |
CTL_E_GETNOTSUPPORTEDATRUNTIME |
Obter não tem suporte em tempo de execução |
CTL_E_GETNOTSUPPORTED |
Obter não tem suporte (a propriedade somente gravação) |
CTL_E_PROPERTYNOTFOUND |
Propriedade não encontrada |
CTL_E_INVALIDCLIPBOARDFORMAT |
Formato inválido da área de transferência |
CTL_E_INVALIDPICTURE |
Imagem inválido |
CTL_E_PRINTERERROR |
Erro com a Impressora |
CTL_E_CANTSAVEFILETOTEMP |
Não é possível salvar o arquivo na temperatura |
CTL_E_SEARCHTEXTNOTFOUND |
Texto de pesquisa não encontrado |
CTL_E_REPLACEMENTSTOOLONG |
Substituições muito longas |
Se necessário, use a macro de CUSTOM_CTL_SCODE para definir um código de erro personalizada para uma condição que não é coberta por um dos códigos padrão. O parâmetro para esta macro deve ser um inteiro entre 1000 e 32767, inclusive. Por exemplo:
#define MYCTL_E_SPECIALERROR CUSTOM_CTL_SCODE(1000)
Se você estiver criando um controle ActiveX para substituir um controle existente de VBX, defina os códigos de erro do controle ActiveX com os mesmos valores numéricos que o controle de VBX usa para garantir que os códigos de erro sejam compatíveis.
Manipulando chaves especiais no controle
Em alguns casos você queira tratar determinadas combinações de teclas em uma forma especial; por exemplo, insira uma nova linha quando a tecla ENTER é pressionada em um controle ou em um movimentação multilinha da caixa de texto entre um grupo de controles de edição quando um ID chave direcional pressionou.
Se a classe base de seu controle ActiveX é COleControl, você pode substituir CWnd::PreTranslateMessage para tratar mensagens antes que o contêiner as processada. Ao usar essa técnica, Verdadeiro de retorno sempre se você trata a mensagem na substituição de PreTranslateMessage.
O exemplo de código a seguir demonstra uma maneira possível de tratar todas as mensagens relacionadas às chaves direcionais.
BOOL CMyAxUICtrl::PreTranslateMessage(MSG* pMsg)
{
BOOL bHandleNow = FALSE;
switch (pMsg->message)
{
case WM_KEYDOWN:
switch (pMsg->wParam)
{
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
bHandleNow = TRUE;
break;
}
if (bHandleNow)
{
OnKeyDown((UINT)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
}
break;
}
return bHandleNow;
}
Para obter mais informações sobre o teclado de manipulação interfaces para um controle ActiveX, consulte a documentação do SDK do ActiveX.
Acessando os controles da caixa de diálogo que são invisíveis em tempo de execução
Você pode criar os controles da caixa de diálogo que não têm nenhuma interface do usuário e são invisíveis em tempo de execução. Se você adicionar em tempo de execução um controle ActiveX invisível em uma caixa de diálogo e usa CWnd::GetDlgItem para acessar o controle, o controle não funcionará corretamente. Em vez disso, você deve usar uma das seguintes técnicas para obter um objeto que representa o controle:
Usando o assistente variável de membro adicionar Control Variable , selecione e selecione a ID de controle Digite um nome de variável de membro e selecione a classe de invólucro de controle como Tipo de controle.
- ou -
Declare uma variável local e uma subclasse como o item da caixa de diálogo. Inserir o código que se assemelha ao seguinte (CMyCtrl é a classe de invólucro, IDC_MYCTRL1 é a ID do controle):
CCirc myCirc; myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this); // ... use myCirc ... myCirc.UnsubclassWindow();