Artigo: 164166 - Última revisão: terça-feira, 21 de Novembro de 2006 - Revisão: 4.3

Recebe uma asserção de Wincore.cpp quando utiliza uma aplicação do Visual C++ 4.x MFC gerada a partir do serviço do Windows NT ou como um serviço do Windows NT

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Reduzir tudo

Sintomas

Quando utiliza uma aplicação do Visual C++ 4.x MFC gerada a partir do serviço do Windows NT ou como um serviço do Windows NT, poderá ocorrer uma asserção no Wincore.cpp. Especificamente, ocorre na linha seguinte _AfxActivationWndProc():
  LRESULT CALLBACK
 _AfxActivationWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
 {

    WNDPROC oldWndProc = (WNDPROC)::GetProp(hWnd, szAfxOldWndProc);
    ASSERT(oldWndProc != NULL);  // <----- assert occurs here
    .
    .
    .
 }
				
a asserção ocorre em linha 385 com Visual C++ versões 4.2 e 4.2b linha 384 com o Visual C++ versão 4.1, linha 392 com o Visual C++ versão 5.0 e na linha 389 com Visual C++ 6.0.

Causa

MFC subclasses todas as janelas não MFC do-criado para processar problemas de activação específico. Ao subclassing uma janela não MFC do-criada, o procedimento de janela antigo é armazenado nas propriedades da janela. Terminar uma sessão do Windows NT faz com que o átomos utilizados para identificar as propriedades para ser destruído e não é possível obter a propriedade. Isto faz com que a asserção ocorra.

MFC não foi concebido para serviços do Windows NT. Como resultado, se é gerada uma aplicação MFC de um serviço Windows NT, minimizado, e, em seguida, um utilizador inicia - desactivar, em seguida, a declaração irá ocorrer.

Tenha também em mente que existem outros problemas a considerar ao gerar uma aplicação MFC a partir de um serviço ou como um serviço. Fecha o processador de mensagens OnEndSession() para a janela frame principal fora do objecto CDocument. Até a mensagem WM_ENDSESSION tem de ser tratada para evitar esta situação.

Resolução

Pode efectuar um dos seguintes procedimentos:

  • Unsubclass todas as janelas não MFC ao algum tempo antes de terminar sessão ou durante a fim de sessão tal como no processador de WM_ENDSESSION.
  • Modificar o código MFC e recriar as bibliotecas MFC. Neste caso, pode modificar o código MFC para impedir que subclassing quaisquer janelas não MFC ou modificar o código de modo a que pode armazenar o procedimento de janela antigo de uma lista em vez de propriedades para a janela. Como é destruída cada janela (WM_NCDESTROY for recebido), procurar o identificador de janela na lista e unsubclass-lo como o MFC na função _AfxActivationWndProc().
  • Separe a GUI, Graphical User Interface parte da aplicação da parte do serviço. Por outras palavras, tem um arranque do cliente de interface gráfica do utilizador sempre que o utilizador inicia sessão. Então o cliente de GUI, Graphical User Interface falar com o serviço através de alguma forma de comunicação entre processos, como pipes nomeados ou sockets. O serviço deve manter os dados e a GUI é iniciado sempre quando iniciar sessão.
MFC subclasses não MFC janelas geralmente processar problemas de activação de janela oculta. Por exemplo, garante activação adequada de toplevel janelas quando efectuar a activação de OLE no local. Também assegura que o último contexto activo está activado quando um utilizador clica numa janela desactivada que faz parte da aplicação. Normalmente, se tiver uma janela principal que possui uma caixa de diálogo modal e alguns outra janela de pop-up como uma barra de ferramentas flutuante e mude activação para outra aplicação e clique na barra de ferramentas que foi desactivada pela caixa de diálogo modal, o Windows emite um sinal sonoro e não activa a aplicação. MFC assegura que a caixa de diálogo modal é colocada na parte superior quando clica na barra de ferramentas. Tenha em atenção que MFC processa todos estes problemas de activação janelas criadas pelo MFC e o Windows não MFC do-criado. O procedimento de janela antigo é armazenado como uma propriedade associada a janela só para MFC não windows. Se que as janelas não MFC unsubclass (como a primeira técnica sugere acima), ainda obter estas funcionalidades de activação para todas as janelas que foram criadas como objectos MFC CWnd derivado.

O Windows não MFC Unsubclassing

A primeira técnica listada acima pode ser uma solução fácil para os programadores que já tenha escrito uma aplicação e não quiser alterar a respectiva estrutura, recriar as bibliotecas MFC ou não ter de processar a activação problemas MFC alças.

Pode unsubclass não MFC Windows no processador de WM_ENDSESSION da janela da frame principal. O código de exemplo seguinte demonstra como enumerar todas as janelas para o processo e unsubclass-los: 4.x para o Visual C++ e Visual C++ 5.0:
    static const TCHAR szAfxOldWndProc[] = _T("AfxOldWndProc");  
				
para o Visual C++ 6.0:
    static const TCHAR szAfxOldWndProc[] = _T("AfxOldWndProc423");  // Visual C++ 6.0
				
e adicione as funções:
    BOOL CALLBACK EnumProc( HWND hWnd, LPARAM lParam)
 {
    //check for property and unsubclass if necessary
    WNDPROC oldWndProc = (WNDPROC)::GetProp(hWnd, szAfxOldWndProc);
    if (oldWndProc!=NULL)
    {
       SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc);
       RemoveProp(hWnd, szAfxOldWndProc);
    }

    return TRUE;

 }

 void CMainFrame::OnEndSession(BOOL bEnding)
 {
    // unsubclass the non-MFC windows which MFC has subclassed
    DWORD dwProcessId;

    DWORD dwThreadId= GetWindowThreadProcessId(m_hWnd,&dwProcessId);
    EnumThreadWindows(dwThreadId, EnumProc,(LPARAM) dwThreadId);

 }
				

A informação contida neste artigo aplica-se a:
  • Microsoft Foundation Class Library 4.2 nas seguintes plataformas
    • Microsoft Visual C++ 4.0 Standard Edition
    • Microsoft Visual C++ 4.1 Subscription
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Visual Studio 2005 Professional
  • Microsoft Visual Studio 2005 Standard Edition
  • Microsoft Visual Studio 2005 Team System Architect Edition
  • Microsoft Visual Studio 2005 Team System Developer Edition
  • Microsoft Visual Studio .NET 2003 Professional Edition
  • Microsoft Visual Studio .NET 2003 Enterprise Architect
  • Microsoft Visual Studio .NET 2003 Enterprise Developer
Palavras-chave: 
kbmt kberrmsg kbtshoot kbcode kbdocview kbprb kbservice kbuidesign KB164166 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 164166  (http://support.microsoft.com/kb/164166/en-us/ )