ID do artigo: 164166 - Última revisão: terça-feira, 21 de novembro de 2006 - Revisão: 4.3

Você recebe uma declaração em Wincore.cpp ao usar um aplicativo de MFC do Visual C++ 4.x gerado a partir de um 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 | Recolher tudo

Sintomas

Quando você usa um aplicativo de MFC do Visual C++ 4.x gerado a partir de um serviço do Windows NT ou como um serviço do Windows NT, uma declaração pode ocorrer em Wincore.cpp. Especificamente, ele ocorre na linha seguinte da _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 declaração ocorre na linha 385 com as versões do Visual C++ 4.2 e 4.2b, na 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

Subclasses MFC todas as janelas não-MFC criado para lidar com problemas específicos de ativação. Ao subclassificação uma janela não-MFC criado, o procedimento de janela antigo é armazenado nas propriedades da janela. Fazer logoff de uma sessão do Windows NT faz com que o átomos usados para identificar as propriedades a ser destruído e a propriedade não pode ser recuperada. Isso faz com que a declaração ocorrer.

MFC não foi projetado para serviços do Windows NT. Como resultado, se um aplicativo MFC é gerado de um serviço do Windows NT, minimizado, e em seguida, um usuário faz logon - desativar, em seguida, a declaração irá ocorrer.

Tenha em mente que há outros problemas a considerar ao reproduzir um aplicativo MFC de um serviço ou como um serviço também. O manipulador de mensagem OnEndSession() para a janela do quadro principal fecha fora o objeto CDocument. Portanto, a mensagem WM_ENDSESSION deve ser manipulada para evitar que isso aconteça.

Resolução

Você pode fazer uma das seguintes coisas:

  • Unsubclass todas as janelas não MFC em algum momento antes de fazer logoff ou durante o logoff como no manipulador WM_ENDSESSION.
  • Modificar o código MFC e recriar as bibliotecas MFC. Nesse caso, você pode modificar o código MFC para impedir que ele subclassificação todas as janelas não MFC ou modificar o código para que você possa armazenar o procedimento de janela antigo em uma lista em vez de propriedades para a janela. Como cada janela é destruída (WM_NCDESTROY é recebido), consultar o identificador de janela em sua lista e unsubclass-lo como MFC faz na função _AfxActivationWndProc().
  • Separe a parte GUI do aplicativo da parte do serviço. Em outras palavras, ter uma inicialização do cliente GUI toda vez que o usuário efetuar logon. Em seguida, ter o cliente GUI falar com o serviço através de alguma forma de comunicação entre processos, como pipes nomeados ou soquetes. O serviço deve manter os dados e inicia a GUI do backup de cada vez que quando você faz logon.
MFC subclasses não-MFC windows geralmente lidar com problemas de ativação de janela obscuros. Por exemplo, ele garante ativação apropriada de janelas de nível superior ao fazer a ativação de OLE no local. Ele também garante que o último pop-up ativa é ativado quando um usuário clicar em uma janela desativada que seja parte do aplicativo. Normalmente, se você tiver uma janela principal que possui uma caixa de diálogo modal e alguns outra janela pop-up como uma barra de ferramentas flutuante, e você alterne ativação para o outro aplicativo e clique na barra de ferramentas que foi desabilitada pela caixa de diálogo modal, o Windows emite um alarme sonoro e não ativar o aplicativo. MFC garante que a caixa de diálogo modal é colocada na parte superior quando você clica na barra de ferramentas. Observe que o MFC manipula todos esses problemas de ativação para o windows MFC-criado e o Windows não-MFC criado. O procedimento de janela antigo é armazenado como uma propriedade associada a janela somente para janelas de não-MFC. Se você unsubclass as janelas não MFC (como a primeira técnica sugere acima), você ainda obter esses recursos de ativação para todas as janelas que foram criadas como objetos derivados de MFC CWnd.

O Windows não MFC Unsubclassing

A primeira técnica listada acima pode ser uma solução fácil para os desenvolvedores que já tenha escrito um aplicativo e não quiser refazer o design, recriar as bibliotecas MFC ou não precisa lidar com a ativação emite identificadores MFC.

Você pode unsubclass não-MFC Windows no manipulador de WM_ENDSESSION de sua janela de quadro principal. O código de exemplo a seguir demonstra como enumerar todas as janelas para seu processo e unsubclass-los: 4.x para Visual C++ e Visual C++ 5.0:
    static const TCHAR szAfxOldWndProc[] = _T("AfxOldWndProc");  
				
para 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 Edition
  • 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 traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes 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/ )