Neste segundo post vou dar algumas explicações sobre o código do utilitário que eu descrevi na primeira parte.
C e WinAPI
Este tipo de utilitário é bem apropriado para ser desenvolvido em C usando a API do Windows, pois basicamente envolve o desenho simples na tela. Como ferramenta usei o velho e confiável Visual C++ 6.
Uma série (incompleta) sobre este tipo de programação pode ser vista aqui e aqui.
Os Estados do Programa
A variável modo indica o estado atual do programa:
- ANDANDO: o relógio está andando.
- PARADO: o relógio está parado e ainda não foi decidido se ele funcionará como timer ou cronômetro.
- PAUSADO: o relógio está parado no meio de uma operação como timer ou cronômetro.
- ALARME: o relógio está apresentando a indicação de final da contagem regressiva do timer.
No Windows, uma classe de janela é algo semelhante a uma classe em uma linguagem orientada a objeto: uma espécie de "forma" utilizada para criar as instâncias ou objetos propriamente ditos (no caso as janelas).
A definição de classe utilizada não tem nada de muito especial. O comportamento das janelas desta classe será governado pela Rotina de Janela que veremos adiante.
Na criação da janela são usados dois flags mais incomuns: WS_EX_TOPMOST deixa a janela por cima das demais e WS_EX_TOOLWINDOW cria uma janela sem moldura, sem barra de título e que não aparece na barra de tarefas.
A Rotina de Janela
A interface com operador no Windows funciona através de mensagens. Ocorrências como a movimentação do mouse e o pressionamento dos seus botões ou das teclas do teclado geram mensagens que são passadas para a Rotina de Janela.
No nosso caso, a Rotina de Janela trata as seguintes mensagens (as demais são passadas para DefWindowProc que faz o tratamento padrão do Windows):
- WM_CREATE: gerada quando a janela está sendo criada, é usada para posicionar a janela e criar um timer de 0,5 segundo.
- WM_TIMER: na medida do possível, o Windows irá gerar esta mensagem na frequência que solicitamos. Ela é usada para solicitar a atualização da tela.
- WM_ERASEBKGND: gerada pelo Windows quando toda a janela tem que ser redesenhada, desenha a parte fixa da janela.
- WM_PAINT: gerada pelo Windows para solicitar a atualização da janela.
- WM_NCHITTEST: uma mensagem que normalmente é tratada por DefWindowProc, é gerada pelo Windows para identificar a região da janela em que o cursor do mouse está posicionado. No nosso caso, usamos esta mensagem para definir a nossa barra de título e permitir arrastar a janela.
- WM_LBUTTONUP: gerada quando o botão esquerdo mouse é solto. Usada para detectar os apertões nos botões do programa.
- WM_DESTROY: gerada quando a janela é destruída, é usada para desligar o timer do Windows e gerar a mensagem WM_QUIT que encerra o programa principal.
O desenho do fundo é feito escrevendo o bitmap do fundo por sobre a janela. No Windows isto é feito pela rotina BitBlt, com o auxilio de um "memory device context".
A rotina DesenhaM
Esta rotina é o coração da atualização da contagem. Uma vez que a geração de WM_TIMER não é garantida, a função timer() é usada para obter a data e hora atual em segundos.
Quando a contagem zero é atingida no timer, passa para o modo ALARME e dispara o sinal sonoro através da função PlaySound().
A atualização da tela em si é feita através de BitBlts entre um bitmap com os dígitos e indicações e a janela.
As demais Rotinas
- Encerra trata o pressionamento do botão Close, destruindo a janela.
- BotaoHora, BotaoMinuto e BotaoSegundo tratam o pressionamento dos respectivos botões, mudando o valor no mostrador.
- BotaoClear limpa o mostrador e volta o programa para o estado PARADO.
- BotaoSS: atualiza o estado conforme o estado atual.
Embora bastantes simples, o DQTimer já é um programa bastante útil. Os mais aventureiros, com experiência em programação Windows, podem incluir funções mais avançadas, como permitir escolher um arquivo WAV para o sinal de alarme.
Nenhum comentário:
Postar um comentário