Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
A nota técnica a seguir não foi atualizada desde que foi incluída pela primeira vez na documentação online. Como resultado, alguns procedimentos e tópicos podem estar desatualizados ou incorretos. Para obter as informações mais recentes, é recomendável que você pesquise o tópico de interesse no índice de documentação online.
Esta nota técnica explica como habilitar o threading de modelo de apartamento em um controle ActiveX. Observe que o threading de modelo de apartamento só tem suporte nas versões 4.2 ou posteriores do Visual C++.
O que é Apartment-Model Threading
O modelo de apartamento é uma abordagem para suportar objetos inseridos, como controles ActiveX, em um aplicativo de contêiner multiencadeado. Embora o aplicativo possa ter vários threads, cada instância de um objeto inserido será atribuída a um "apartamento", que será executado em apenas um thread. Em outras palavras, todas as chamadas em uma instância de um controle ocorrerão no mesmo thread.
No entanto, instâncias diferentes do mesmo tipo de controle podem ser atribuídas a apartamentos diferentes. Portanto, se várias instâncias de um controle compartilharem dados em comum (por exemplo, dados estáticos ou globais), o acesso a esses dados compartilhados precisará ser protegido por um objeto de sincronização, como uma seção crítica.
Para obter detalhes completos sobre o modelo de threading de apartamento, consulte Processos e Threads na Referência do Programador OLE.
Por que dar suporte ao threading de modelo de apartamento?
Controles que dão suporte ao threading de modelo de apartamento podem ser usados em aplicativos de contêiner com multithread que também dão suporte ao modelo de apartamento. Se você não habilitar o threading de modelo de apartamento, você limitará o conjunto de contêineres potencial nos qual seu controle pode ser usado.
Habilitar o threading de modelo de apartamento é fácil na maioria dos controles, especialmente se eles tiverem pouco ou nenhum dado compartilhado.
Protegendo dados compartilhados
Se o controle usar dados compartilhados, como uma variável de membro estático, o acesso a esses dados deverá ser protegido com uma seção crítica para impedir que mais de um thread modifique os dados ao mesmo tempo. Para configurar uma seção crítica para essa finalidade, declare uma variável de membro estático da classe CCriticalSection na classe do controle. Use as funções de membro Lock e Unlock deste objeto de seção crítica onde quer que seu código acesse os dados compartilhados.
Considere, por exemplo, uma classe de controle que precisa manter uma cadeia de caracteres compartilhada por todas as instâncias. Essa cadeia de caracteres pode ser mantida em uma variável de membro estático e protegida por uma seção crítica. A declaração de classe do controle conteria o seguinte:
class CSampleCtrl : public COleControl
{
...
static CString _strShared;
static CCriticalSection _critSect;
};
A implementação da classe incluiria definições para essas variáveis:
int CString CSampleCtrl::_strShared;
CCriticalSection CSampleCtrl::_critSect;
O acesso ao membro estático _strShared pode então ser protegido pela seção crítica:
void CSampleCtrl::SomeMethod()
{
_critSect.Lock();
if (_strShared.Empty())
_strShared = "<text>";
_critSect.Unlock();
...
}
Registrar um controle com reconhecimento de modelo de apartamento
Os controles que dão suporte ao threading de modelo de apartamento devem indicar essa funcionalidade no registro, adicionando o valor nomeado "ThreadingModel" com um valor de "Apartment" na entrada do registro de ID de classe na chave class id\InprocServer32. Para fazer com que essa chave seja registrada automaticamente para o controle, transfira o sinalizador afxRegApartmentThreading no sexto parâmetro para AfxOleRegisterControlClass:
BOOL CSampleCtrl::CSampleCtrlFactory::UpdateRegistry(BOOL bRegister)
{
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_SAMPLE,
IDB_SAMPLE,
afxRegApartmentThreading,
_dwSampleOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid,
m_lpszProgID);
}
Se o projeto de controle tiver sido gerado pelo ControlWizard no Visual C++ versão 4.1 ou posterior, esse sinalizador já estará presente em seu código. Nenhuma alteração é necessária para registrar o modelo de encadeamento.
Se o projeto tiver sido gerado por uma versão anterior do ControlWizard, o código existente terá um valor booliano como o sexto parâmetro. Se o parâmetro existente for TRUE, altere para afxRegInsertable | afxRegApartmentThreading. Se o parâmetro existente for FALSE, altere para afxRegApartmentThreading.
Se o controle não seguir as regras para threading de modelo de apartamento, você não deve transferir afxRegApartmentThreading nesse parâmetro.