Partilhar via


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 (chamada notação húngara). Vale a pena reservar 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). Muito poucas APIs do Windows são fornecidas como classes C++. (Uma exceção notável é o 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 inteiros

Tipo de dados Tamanho Assinado?
BYTE 8 bits Não assinado
DWORD 32 bits Não assinado
INT32 32 bits Assinatura
INT64 64 bits Assinatura
LONGA 32 bits Assinatura
LONGLONG 64 bits Assinatura
UINT32 32 bits Não assinado
UINT64 64 bits Não assinado
ULONG 32 bits Não assinado
ULONGLONG 64 bits Não assinado
PALAVRA 16 bits Não assinado

Como você pode ver, há uma certa 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 bits e 64. Por exemplo, o tipo DWORD de tem sempre 32 bits.

Tipo Booleano

BOOL é um alias de tipo para int, distinto do booldo C++, e de outros tipos que representam um valor booleano . O arquivo de cabeçalho WinDef.h 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 de BOOL pode retornar qualquer valor diferente de zero para indicar a verdade booleana. Portanto, você deve sempre escrever isto:

// Right way.
if (SomeFunctionThatReturnsBoolean()) 
{ 
    ...
}

// or

if (SomeFunctionThatReturnsBoolean() != FALSE)
{ 
    ...
}

e não isto:

if (result == TRUE) // Wrong!
{
    ... 
}

BOOL é um tipo inteiro e não é intercambiável com o booldo C++.

Tipos de ponteiro

O Windows define muitos tipos de dados do formulário ponteiro para X. Estes geralmente têm o prefixo P- ou LP- no nome. Por exemplo, LPRECT é um ponteiro para um RECT, onde RECT é uma estrutura que descreve um retângulo. As seguintes declarações de variáveis 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) existem 2 tipos de ponteiros, P para "ponteiro" e LP significa "ponteiro longo". Ponteiros longos (também chamados de ponteiros far) eram necessários para acessar intervalos de memória fora do segmento atual. O prefixo LP foi preservado para facilitar a portabilidade de 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ê deve usar um, então use P.

Tipos de precisão de ponteiro

Os seguintes tipos de dados são sempre do 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 aritmética de ponteiro e para definir contadores de loop que iteram em toda a faixa de bytes em buffers de memória. Mais geralmente, 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 dar informações adicionais sobre a variável. (O inventor da notação, Charles Simonyi, era húngaro, daí o seu nome).

Na sua forma original, a notação húngara dá-informação semântica sobre uma variável, indicando-lhe a utilização pretendida. Por exemplo, i significa um índice, cb significa um tamanho em bytes ("número de bytes"), e rw e col significam números de linhas e colunas. Esses prefixos são 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 dar tipo informações — por exemplo, dw para DWORD e w para WORD.

Observação

O C++ Core Guidelines desencorajar a notação de prefixo (por exemplo, notação húngara). Consulte "NL.5": Evite codificar informações de tipo em nomes "". Internamente, a equipe do Windows não o usa mais. Mas seu uso permanece em amostras e documentação.

Seguinte

Trabalhando com cadeias de caracteres