Convenções de codificação do Windows
Se você é novo na programação do Windows, pode ser desconcertante quando você vê um programa do Windows pela primeira vez. O código é preenchido com definições de tipo estranhas, como DWORD_PTR e LPRECT, e as variáveis têm nomes como hWnd e pwsz (chamado notação húngara). Vale a pena tirar um momento para aprender algumas das convenções de codificação do Windows.
A grande maioria das APIs do Windows consiste em funções ou interfaces COM (Component Object Model). Pouquíssimas APIs do Windows são fornecidas como classes C++. (Uma exceção notável é GDI+, uma das APIs gráficas 2D.)
Typedefs
Os cabeçalhos do Windows contêm muitos typedefs. Muitos deles são definidos no arquivo de cabeçalho WinDef.h. Aqui estão alguns que você encontrará com frequência.
Tipos de inteiro
Tipo de dados | Tamanho | Assinado? |
---|---|---|
BYTE | 8 bits | Não assinado |
DWORD | 32 bits | Não assinado |
INT32 | 32 bits | Com sinal |
INT64 | 64 bits | Com sinal |
LONG | 32 bits | Com sinal |
LONGLONG | 64 bits | Com sinal |
UINT32 | 32 bits | Não assinado |
UINT64 | 64 bits | Não assinado |
ULONG | 32 bits | Não assinado |
ULONGLONG | 64 bits | Não assinado |
WORD | 16 bits | Não assinado |
Como você pode ver, há uma certa quantidade de redundância nesses typedefs. Parte dessa sobreposição é simplesmente devido ao histórico das APIs do Windows. Os tipos listados aqui têm tamanho fixo e os tamanhos são os mesmos em aplicativos de 32 e 64 bits. Por exemplo, o tipo DWORD sempre tem 32 bits de largura.
Tipos boolianos
BOOL é um alias de tipo para int, diferente do bool do C++e de outros tipos que representam um valor booliano . O arquivo WinDef.h
de cabeçalho também define dois valores para uso com BOOL.
#define FALSE 0
#define TRUE 1
Apesar dessa definição de TRUE, no entanto, a maioria das funções que retornam um tipo BOOL pode retornar qualquer valor diferente de zero para indicar a verdade booliana. Portanto, você sempre deve escrever isso:
// Right way.
if (SomeFunctionThatReturnsBoolean())
{
...
}
// or
if (SomeFunctionThatReturnsBoolean() != FALSE)
{
...
}
e não isso:
if (result == TRUE) // Wrong!
{
...
}
BOOL é um tipo inteiro e não é intercambiável com o bool do C++.
Tipos de ponteiro
O Windows define muitos tipos de dados do ponteiro para X do formulário. Geralmente, eles têm o prefixo P ou LP no nome. Por exemplo, LPRECT é um ponteiro para um RECT, em que RECT é uma estrutura que descreve um retângulo. As declarações de variável a seguir são equivalentes.
RECT* rect; // Pointer to a RECT structure.
LPRECT rect; // The same
PRECT rect; // Also the same.
Em arquiteturas de 16 bits (Windows de 16 bits) há dois tipos de ponteiros, P para "ponteiro" e LP significa "ponteiro longo". Ponteiros longos (também chamados de ponteiros distantes) eram necessários para abordar intervalos de memória fora do segmento atual. O prefixo LP foi preservado para facilitar a portabilidade do código de 16 bits para o Windows de 32 bits. Hoje não há distinção e esses tipos de ponteiro são todos equivalentes. Evite usar esses prefixos; ou se você precisar usar um, use P.
Tipos de precisão de ponteiro
Os tipos de dados a seguir são sempre o tamanho de um ponteiro, ou seja, 32 bits de largura em aplicativos de 32 bits e 64 bits de largura em aplicativos de 64 bits. O tamanho é determinado em tempo de compilação. Quando um aplicativo de 32 bits é executado no Windows de 64 bits, esses tipos de dados ainda têm 4 bytes de largura. (Um aplicativo de 64 bits não pode ser executado no Windows de 32 bits, portanto, a situação inversa não ocorre.)
- DWORD_PTR
- INT_PTR
- LONG_PTR
- ULONG_PTR
- UINT_PTR
Esses tipos são usados em situações em que um inteiro pode ser convertido em um ponteiro. Eles também são usados para definir variáveis para a aritmética de ponteiro e para definir contadores de loop que iteram sobre o intervalo completo de bytes em buffers de memória. Em geral, eles aparecem em locais onde um valor de 32 bits existente foi expandido para 64 bits no Windows de 64 bits.
Notação húngara
Notação húngara é a prática de adicionar prefixos aos nomes das variáveis para fornecer informações adicionais sobre a variável. (O inventor da notação, Charles Simonyi, era húngaro, daí seu nome).
Em sua forma original, a notação húngara fornece informações semânticas sobre uma variável, informando o uso pretendido. Por exemplo, quero dizer um índice, cb significa um tamanho em bytes ("contagem de bytes") e rw e números de linha média e coluna. Esses prefixos foram projetados para evitar o uso acidental de uma variável no contexto errado. Por exemplo, se você visse a expressão rwPosition + cbTable
, saberia que um número de linha está sendo adicionado a um tamanho, o que é quase certamente um bug no código
Uma forma mais comum de notação húngara usa prefixos para fornecer informações de tipo , por exemplo, dw para DWORD e w para WORD.
Observação
As Diretrizes Principais do C++ desencorajam a notação de prefixo (por exemplo, notação húngara). Consulte NL.5: evitar informações de tipo de codificação em nomes. Internamente, a equipe do Windows não o usa mais. Mas seu uso permanece em exemplos e documentação.