Controles MFC ActiveX: Tópicos avançados
Este artigo aborda tópicos avançados relacionados ao desenvolvimento de controles de ActiveX.Eles incluem:
Usando Classes de banco de dados em controles de ActiveX
Implementando uma propriedade parametrizada
Manipulação de erros em seu controle ActiveX
Manipulação de teclas especiais no controle
Acessando controles de caixa de diálogo invisíveis em tempo de execução
Usando Classes de banco de dados em controles de ActiveX
Como as classes de controle de ActiveX são parte da biblioteca de classe, você pode aplicar os mesmos procedimentos e regras para usar classes de banco de dados em um aplicativo MFC padrão para o desenvolvimento de controles de ActiveX usam classes de banco de dados MFC.
Para obter uma visão geral das classes de banco de dados MFC, consulte Classes de banco de dados MFC (DAO e ODBC).O artigo apresenta as classes de ODBC do MFC e o DAO MFC classes e direciona você para obter mais detalhes sobre qualquer um.
Observação |
---|
Como do Visual C++.NET, o ambiente do Visual C++ e assistentes não há mais suportam DAO (embora as classes DAO são incluídas e você ainda pode usá-los).A Microsoft recomenda que você use OLE DB modelos ou ODBC e MFC para novos projetos.Você só deve usar DAO na manutenção de aplicativos existentes. |
Implementando uma propriedade parametrizada
Uma propriedade parametrizada (às vezes chamada de uma matriz de propriedade) é um método para expor uma coleção homogênea de valores como uma única propriedade do controle.Por exemplo, você pode usar uma propriedade parametrizada para expor uma matriz ou um dicionário como uma propriedade.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 propriedade para implementar uma propriedade parametrizada.O Assistente para adicionar propriedade implementa a propriedade adicionando um par de funções Get/Set que permitem ao usuário controle acessar a propriedade usando a notação acima ou no modo padrão.
Semelhante a métodos e propriedades, propriedades parametrizadas também têm um limite para o número de parâmetros permitido.No caso de propriedades parametrizadas, o limite é 15 parâmetros (com um parâmetro reservado para armazenar o valor da propriedade).
O procedimento a seguir adiciona uma propriedade parametrizada, chamada matriz, que pode ser acessado como uma matriz bidimensional de números inteiros.
Para adicionar uma propriedade com parâmetros 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.
No O nome da propriedade , digite Array.
No Tipo de propriedade caixa, selecione curto.
Para implementação tipo, clique em Métodos Get/Set.
No Obter função e Função Set caixas, digite nomes exclusivos para seu Get e Set funções ou aceitar os nomes padrão.
Adicionar um parâmetro chamado row (tipo short), usando o O nome do parâmetro e O tipo de parâmetro controles.
Adicionar um segundo parâmetro chamado column (tipo de short).
Clique em Concluir.
As alterações feitas pelo Assistente de propriedade para adicionar
Quando você adiciona uma propriedade personalizada, o Assistente para adicionar propriedade faz alterações para o cabeçalho de classe de controle (.H) e a implementação (.Arquivos CPP).
As seguintes linhas são adicionadas à classe do controle.Arquivo H:
SHORT GetArray(SHORT row, SHORT column);
void SetArray(SHORT row, SHORT column, SHORT newVal);
Esse código declara duas funções chamadas GetArray e SetArray que permitem ao usuário solicitar uma linha específica e a coluna quando estiver acessando a propriedade.
Além disso, o Assistente para adicionar propriedade adiciona as seguintes linhas ao mapa de despacho de controle, na implementação de classe do controle (.Arquivo CPP):
DISP_PROPERTY_PARAM_ID(CMyAxUICtrl, "Array", dispidArray, GetArray, SetArray, VT_I2, VTS_I2 VTS_I2)
Finalmente, as implementações de GetArray e SetArray funções são adicionadas ao final da.Arquivo CPP.Na maioria dos casos, você modificará a função de Get para retornar o valor da propriedade.A função de conjunto normalmente conterá código deve executar antes ou após as alterações de propriedade.
Para esta propriedade ser útil, você poderia declarar uma variável de membro matriz bidimensional na classe de controle do tipo curto, para armazenar valores de propriedade com parâmetros.Você pode modificar a função de Get para retornar o valor armazenado na linha adequada e coluna, conforme indicado pelos parâmetros e modificar a função de conjunto para atualizar o valor referenciado pelos parâmetros de linha e coluna.
Manipulação de erros em seu controle ActiveX
Se as condições de erro ocorrerem no controle, talvez seja necessário relatar o erro para o recipiente de controle.Há dois métodos para relatar erros, dependendo da situação em que o erro ocorre.Se o erro ocorrer dentro de uma propriedade obter ou definir a função, ou na implementação de um método de automação OLE, o controle deve chamar COleControl::ThrowError, os sinais para o usuário de controle que ocorreu um erro.Se o erro ocorrer a qualquer momento, o controle deve chamar COleControl::FireError, que dispara um evento de erro ações.
Para indicar o tipo de erro que ocorreu, o controle deve passar um código de erro para ThrowError ou 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 do conjunto padrão de códigos definidos no OLECTL.Arquivo de cabeçalho H.A tabela a seguir resume esses códigos.
Códigos de erro de 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 |
Espaço de seqüência de caracteres |
CTL_E_OUTOFSTACKSPACE |
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 inválido |
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 |
Erro de acesso caminho/arquivo |
CTL_E_PATHNOTFOUND |
Caminho não encontrado |
CTL_E_INVALIDPATTERNSTRING |
Seqüência de caracteres padrão inválido |
CTL_E_INVALIDUSEOFNULL |
Uso inválido de nulo |
CTL_E_INVALIDFILEFORMAT |
Formato de arquivo inválido |
CTL_E_INVALIDPROPERTYVALUE |
Valor de propriedade inválido |
CTL_E_INVALIDPROPERTYARRAYINDEX |
Índice de matriz de propriedade inválido |
CTL_E_SETNOTSUPPORTEDATRUNTIME |
Definir não suportada 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 suportada em tempo de execução |
CTL_E_GETNOTSUPPORTED |
Get não suportada (propriedade de somente gravação) |
CTL_E_PROPERTYNOTFOUND |
Propriedade não encontrada |
CTL_E_INVALIDCLIPBOARDFORMAT |
Formato de área de transferência inválido |
CTL_E_INVALIDPICTURE |
Imagem inválida |
CTL_E_PRINTERERROR |
Erro com a Impressora |
CTL_E_CANTSAVEFILETOTEMP |
Não é possível salvar arquivo TEMP |
CTL_E_SEARCHTEXTNOTFOUND |
Texto de pesquisa não encontrado |
CTL_E_REPLACEMENTSTOOLONG |
Substituições muito longas |
Se necessário, use o CUSTOM_CTL_SCODE macro para definir um código de erro personalizada para uma condição que não é coberto por um dos códigos padrão.O parâmetro para essa 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 do VBX, defina os códigos de erro do controle de ActiveX com os mesmos valores numéricos que controle VBX usa para garantir que os códigos de erro são compatíveis.
Manipulação de teclas especiais no controle
Em alguns casos você poderá lidar com determinadas combinações de teclas de maneira especial; Por exemplo, inserir uma nova linha quando a tecla ENTER é pressionada em um texto de várias linhas caixa controle ou mover entre um grupo de editar controles quando um direcional chave ID pressionado.
Se a classe base do seu controle de ActiveX COleControl, você pode substituir CWnd::PreTranslateMessage para controlar mensagens antes do contêiner processa.Ao usar essa técnica, sempre retornará TRUE se você manipular a mensagem em seu substituto do PreTranslateMessage.
O exemplo de código a seguir demonstra uma maneira possível de lidar com 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 manipulação de interfaces de teclado para um controle ActiveX, consulte a documentação do SDK do ActiveX.
Acessando controles de caixa de diálogo invisíveis em tempo de execução
Você pode criar controles de caixa de diálogo sem interface do usuário e são invisíveis em tempo de execução.Se você adicionar um invisível em tempo de execução controle ActiveX para uma caixa de diálogo e use CWnd::GetDlgItem o controle de acesso, 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 membro variável para adicionar, selecione Variável de controle e selecione ID. do controleDigite um nome de variável de membro e selecione a classe de wrapper do controle como o Tipo de controle.
- ou -
Declare uma variável local e subclasse como o item de caixa de diálogo.Inserir código semelhante ao seguinte (CMyCtrl é a classe de wrapper, IDC_MYCTRL1 é a identificação do controle):
CCirc myCirc; myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this); // ... use myCirc ... myCirc.UnsubclassWindow();