# Windows API

Uma API (*Application Programming Interface*) é uma interface para uma aplicação "falar" com outra. A Windows API consiste num conjunto de funções expostas para serem usadas por aplicativos rodando em *user mode*.

Para o escopo deste livro, vamos cobrir uma pequena parte da Windows API, pois o assunto é extenso.

Considere o seguinte programa em C:

```c
#include <windows.h>

int main(void) {
    MessageBox(NULL, "Mundo", "Olá", MB_OK);
}
```

A função *MessageBox()* está definida em *windows.h*. Quando compilado, o código acima gera um executável dependente da `USER32.DLL` (além de outras bibliotecas, dependendo de certas opções de compilação), que provê a versão compilada de tal função. A documentação desta e de outras funções da Windows API está disponível no site da Microsoft. Copiamos seu protótipo abaixo para explicar seus parâmetros:

```c
int MessageBox(
  [in, optional] HWND    hWnd,
  [in, optional] LPCTSTR lpText,
  [in, optional] LPCTSTR lpCaption,
  [in]           UINT    uType
);
```

A Microsoft criou definições de anotações e novos tipos na linguagem C que precisam ser explicadas para o entendimento dos protótipos das funções de sua API. Para entender o protótipo da função *MessageBox*, é preciso conhecer o significado dos seguintes termos:

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| \\\[in\\]       | Define que o parâmetro é de entrada                      |
| \\\[optional\\] | O parâmetro é opcional (pode ser NULL, ou 0 normalmente) |
| HWND            | Um *handle* (identificador) da janela                    |
| LPCTSTR         | **L**ong **P**ointer to a **C**onst **T**CHAR **STR**ing |
| UINT            | *unsigned int* ou DWORD (32-bits ou 4 *bytes*)           |

> Um *handle* é um número que identifica um objeto (arquivo, chave de registro, diretório, etc) aberto usado por um processo. É um conceito similar ao *file descriptor* em ambiente Unix/Linux. *Handles* só são acessíveis diretamente em *kernel mode*, por isso os programas interagem com eles através de funções da API do Windows. Por exemplo, a função CreateFile() retorna um *handle* válido em caso de execução com sucesso. A partir daí, toda leitura e escrita neste arquivo deve ser feita a partir do *handle*. Por fim, a função CloseHandle() o fecha o *handle* quando ele não é mais necessário.

Agora vamos explicar os parâmetros da função *MessageBox*:

## MessageBox

### hWnd

É um parâmetro de entrada, ou seja, é uma informação que a função precisa (e não quem chamou). Neste caso, é um *handle* que identifica qual janela é dona da caixa de mensagem. Isso serve para atrelar uma mensagem a uma certa janela (e impedi-la de ser fechada antes da caixa de mensagem, por exemplo). Como é opcional, este parâmetro pode ser NULL, o que faz com que a caixa de mensagem não possua uma janela dona.

### lpText

Um ponteiro para um texto (uma *string*) que será exibido na caixa de mensagem. Se for NULL, a mensagem não terá um conteúdo, mas ainda assim aparecerá.

### lpCaption

Um ponteiro para o texto que será o título da caixa de mensagem. Se for NULL, a caixa de mensagem terá o título padrão "Error" (pode rir).

### uType

Configura o tipo de caixa de mensagem. É um número inteiro que pode ser definido por macros para cada *flag* definida na documentação da função. Se passada a macro `MB_OKCANCEL` (0x00000001L), por exemplo, faz com que a caixa de mensagem tenha dois botões: OK e Cancelar. Se passada a macro `MB_ICONEXCLAMATION` (0x00000030L), a janela terá um ícone de exclamação. Se quiséssemos combinar as duas características, precisaríamos passar as duas *flags* utilizando uma operação OU entre elas, assim:

```c
MessageBox(NULL, "Mundo", "Olá", MB_OKCANCEL | MB_ICONEXCLAMATION);
```

Como macros e cálculos assim são resolvidos numa etapa conhecida por pré-compilação, o resultado da operação OU entre 1 e 0x30 será substituído neste código, antes de ser compilado, ficando assim:

```c
MessageBox(NULL, "Mundo", "Olá"), 0x31);
```

> Dizer que um parâmetro é opcional não quer dizer que você não precise passá-lo ao chamar a função, mas sim que ele pode ser `NULL`, ou `0`, dependendo do que a documentação da função diz. Como o Visual Studio é um compilador de C++, você também pode usar `nullptr`, que também está disponível em C a partir da C23.

Veremos agora algumas funções da Windows API para funções básicas, mas você encontrará informações sobre outras rotinas no apêndice Funções da API do Windows.
