TN001: registro da classe Window
Esta observação descreve as rotinas MFC que registram os WNDCLASSes especiais, necessários ao Microsoft Windows. São discutidos atributos WNDCLASS
específicos usados por MFC e Windows.
O problema
Os atributos de um objeto CWnd, como um identificador HWND
no Windows, são armazenados em dois locais: o objeto window e o WNDCLASS
. O nome de WNDCLASS
é passado para funções gerais de criação de janela, como CWnd::Create e CFrameWnd::Create no parâmetro lpszClassName.
Este WNDCLASS
deve ser registrado por uma das quatro alternativas:
Implicitamente, usando um MFC fornecido para
WNDCLASS
.Implicitamente, subclassificando um controle do Windows (ou algum outro controle).
Explicitamente, chamando o MFC AfxRegisterWndClass ou AfxRegisterClass.
Explicitamente, chamando a rotina do Windows RegisterClass.
Campos WNDCLASS
A estrutura WNDCLASS
consiste em vários campos que descrevem uma classe de janela. A tabela a seguir mostra os campos e especifica como eles são usados em um aplicativo MFC:
Campo | Descrição |
---|---|
lpfnWndProc | window proc, deve ser um AfxWndProc |
cbClsExtra | não usado (deve ser zero) |
cbWndExtra | não usado (deve ser zero) |
hInstância | preenchido automaticamente com AfxGetInstanceHandle |
hIcon | ícone para janelas de quadro, confira abaixo |
hCursor | cursor para quando o mouse estiver sobre a janela, confira abaixo |
hbrBackground | cor da tela de fundo, veja abaixo |
lpszMenuName | não usado (deve ser NULL) |
lpszClassName | nome da classe, veja abaixo |
WNDCLASSes fornecidos
As versões anteriores do MFC (antes do MFC 4.0) forneceram várias classes de janela predefinidas. Essas classes de janela não são mais fornecidas por padrão. Os aplicativos devem usar AfxRegisterWndClass
com os parâmetros apropriados.
Se o aplicativo fornecer um recurso com a identificação de recurso especificada (por exemplo, AFX_IDI_STD_FRAME), o MFC usará esse recurso. Caso contrário, ele usará o recurso padrão. Para o ícone, será usado o ícone de aplicativo padrão e, para o cursor, será usado o cursor de seta padrão.
Dois ícones dão suporte a aplicativos MDI com tipos de documento único: um ícone para o aplicativo principal, e o outro ícone para janelas de documento/MDIChild icônicos. Para vários tipos de documentos com ícones diferentes, você deve registrar WNDCLASS
adicionais ou usar a função CFrameWnd::LoadFrame.
CFrameWnd::LoadFrame
registrará uma WNDCLASS
usando a ID de ícone que você especificar como o primeiro parâmetro e os atributos padrão a seguir:
estilo de classe:
CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
ícone AFX_IDI_STD_FRAME
cursor de seta
COLOR_WINDOW cor da tela de fundo
Os valores de cor da tela de fundo e do cursor para a CMDIFrameWnd não são usados, pois a área do cliente da CMDIFrameWnd
é completamente coberta pela janela MDICLIENT. A Microsoft não incentiva a subclasse da janela MDICLIENT, portanto, use as cores e os tipos de cursor padrão, sempre que possível.
Controles de subclasse e superclasse
Se você usar subclasse ou superclasse de um controle do Windows (por exemplo, CButton), sua classe obterá automaticamente os atributos WNDCLASS
fornecidos na implementação do Windows desse controle.
A função AfxRegisterWndClass
O MFC fornece uma função auxiliar para registrar uma classe de janela. Dado um conjunto de atributos (estilo de classe de janela, cursor, pincel de plano de fundo e ícone), será gerado um nome sintético e será registrada a classe de janela resultante. Por exemplo,
const char* AfxRegisterWndClass(UINT nClassStyle,
HCURSOR hCursor,
HBRUSH hbrBackground,
HICON hIcon);
Essa função retorna uma cadeia de caracteres temporária do nome da classe de janela registrada gerada. Para obter mais informações sobre esta função, consulte AfxRegisterWndClass.
A cadeia de caracteres retornada é um ponteiro temporário para um buffer de cadeia de caracteres estático. Ela é válida até a próxima chamada para AfxRegisterWndClass
. Se você quiser manter essa cadeia de caracteres por perto, armazene-a em uma variável CString, como neste exemplo:
CString strWndClass = AfxRegisterWndClass(CS_DBLCLK, ...);
...
CWnd* pWnd = new CWnd;
pWnd->Create(strWndClass, ...);
...
AfxRegisterWndClass
gerará um CResourceException se a classe de janela não tiver sido registrada (por causa de parâmetros ruins ou memória insuficiente do Windows).
Funções RegisterClass e AfxRegisterClass
Se você quiser fazer algo mais sofisticado que o fornecido por AfxRegisterWndClass
, pode chamar a API RegisterClass
do Windows ou a função AfxRegisterClass
do MFC. As funções CWnd
, CFrameWnd e CMDIChildWndCreate
tomam um nome de cadeia de caracteres lpszClassName para a classe de janela como o primeiro parâmetro. Você pode usar qualquer nome de classe de janela registrado, independentemente do método usado para registrá-lo.
É importante usar AfxRegisterClass
(ou AfxRegisterWndClass
) em uma DLL no Win32. O Win32 não cancela automaticamente as classes registradas por uma DLL, portanto, você deverá cancelar explicitamente as classes quando a DLL for encerrada. Ao usar AfxRegisterClass
em vez de RegisterClass
, isso será tratado automaticamente para você. AfxRegisterClass
mantém uma lista de classes exclusivas registradas pela DLL e as cancelará automaticamente quando a DLL for encerrada. Ao usar RegisterClass
em uma DLL, você deve garantir que todas as classes sejam canceladas quando a DLL for encerrada (na função DllMain). Não fazer isso pode fazer com que RegisterClass
falhe inesperadamente quando outro aplicativo cliente tentar usar sua DLL.
Confira também
Observações técnicas por número
Observações técnicas por categoria