Aldeia Numaboa
Um portal diferente em Português do Brasil
Informática da Aldeia

Tutoriais
Home Informática Tutoriais e Programação Linguagem C Linguagem C - Projeto Espião

Na Aldeia

Há 108 visitantes online

3630 registros
0 hoje
14 nesta semana
4 neste mês

Boas vindas: flor

Estatística

Membros: 3639
Artigos: 1045
Links: 90
Leituras: 6681035

Login



Kanji da hora




Faça contato






Sex

28

Nov

2008


12:20

Linguagem C - Projeto Espião PDF Imprimir Indique esta página
(6 votos, média 4.3 de 5)
Escrito por vovó Vicki   


Índice do Artigo
Linguagem C - Projeto Espião
Movendo e redimensionando a janela
Todas as páginas
C

Já que é para fazer alguma coisa, não vamos nos contentar com uma janelinha que mostre um texto qualquer quando o usuário clicar num botão ou num item de menu. Nananinanão! Queremos um projeto mais ambicioso!

Vamos chamar este projeto de espião porque a idéia é mostrar num controle tipo árvore todas as janelas que estejam abertas num dado momento. Além disso, vamos colocar na barra de status algumas informações sobre as janelas encontradas. E dá-lhe, peão!

Criando o projeto Espião

Você já está careca de saber: clicar em |Project|Create| etc e tal. Dê o nome de "espiao" ao projeto, só para ficar compatível com o texto do tutorial. Ah! também criei um novo diretório para o projeto, o /lcc/projects/espiao/. Se você fizer o mesmo, aí fica tudo par e passo.

Crie um "Windows application" tipo "Single user", com "Single window" e "Status bar at the bottom". Na verdade, com exceção do nome, é tudo igual ao tutorial Uma janela de verdade. Deste modo, obtemos o esqueleto do aplicativo.

Criando uma janela-filha

A primeira providência é criar uma janela para um controle de árvore - um controle do tipo do explorer. Para criar janelas deste tipo, uma boa pedida é aproveitar a mensagem WM_CREATE que o sistemão envia para a central de mensagens da janela principal. Para interceptá-la, basta inserir no switch do procedimento MainWndProc um caso de WM_CREATE:

LRESULT CALLBACK MainWndProc(
   HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
   static HWND hwndTree;
 
   switch (msg) {
   case WM_CREATE:
      hwndTree = janelaTree(hwnd,IDJANELATREE);
      break;
   ...

Acho que está na hora de dizer que a tradução de "switch", entre outras coisas, é "ligar/desligar", "interruptor" e "mudar para outro trilho". Depois disso, não é difícil imaginar o que faz um switch interruptor ou uma chave de trilhos piscada

Esta arquitetura é chamada de "top down" (de cima para baixo) porque os detalhes da criação da janela da árvore ficam escondidos numa função que retorna o manipulador (handle) da janela criada. Este manipulador é armazenado numa variável estática do tipo HWND, a hwndTree. Esta variável, por ser local, só é pode ser acessada quando se está no procedimento MainWndProc e não conserva seu valor quando saímos dele.

A função janelaTree

A função janelaTree recebe o manipulador (handle) da janela-mãe e o identificador (ID) numérico que o controle da árvore deve ter. O identificador numérico, que chamamos de IDJANELATREE, precisa ser definido no início do código para que possamos utilizá-lo. Optei pelo valor 10545:

#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <string.h>
#include "espiaores.h"
#define IDJANELATREE 10545
...

Chamamos o procedimento de criação de janelas, a função da API CreateWindowsEx com uma série de parâmetros. Esta função é derivada da função CreateWindow, apenas permite estilos mais elaborados. Veja abaixo:

HWND CreateWindowEx(
 
    DWORD dwExStyle,            // estilo de janela ampliado
    LPCTSTR lpClassName,        // ponteiro para o nome da classe registrada
    LPCTSTR lpWindowName,       // ponteiro para o nome da janela
    DWORD dwStyle,              // estilo da janela
    int x,                      // posição horizontal da janela
    int y,                      // posição vertical da janela
    int nWidth,                 // largura da janela
    int nHeight,                // altura da janela
    HWND hWndParent,            // handle para a janela-mãe ou proprietária
    HMENU hMenu,                // handle para o menu
                                // ou identificador da janela-filha
    HINSTANCE hInstance,        // handle para a instância do aplicativo
    LPVOID lpParam              // ponteiro para os dados
                                // para a criação da janela
);

A referência a esta função você encontra no help da API. Se você o instalou, basta posicionar o cursor sobre o nome da função e digitar F1. Conhecendo os parâmetros exigidos por CreateWindowEx, podemos elaborar a função que cria a janela da árvore:

static HWND _stdcall janelaTree(HWND hWnd,int ID)
{
   return CreateWindowEx(WS_EX_CLIENTEDGE,WC_TREEVIEW,"",
      WS_VISIBLE|WS_CHILD|WS_BORDER|TVS_HASLINES|
      TVS_HASBUTTONS|TVS_DISABLEDRAGDROP,
      0,0,0,0,
      hWnd,(HMENU)ID,hInst,NULL);
}

Abaixo são analisados os parâmetros enviados:

  • DWORD dwExStyle: enviamos WS_EX_CLIENTEDGE para obter uma janela com as bordas rebaixadas. O valor de WS_EXCLIENTEDGE é 512.
  • LPCTSTR lpClassName: ponteiro para o nome da classe de controle predefinido no Windows, o WC_TREEVIEW.
  • LPCTSTR lpWindowName: ponteiro vazio para o nome da janela.
  • DWORD dwStyle: enviamos o estilo WS_VISIBLE|WS_CHILD|WS_BORDER|TVS_HASLINES| TVS_HASBUTTONS|TVS_DISABLEDRAGDROP, ou seja, uma sucessão de ORs ligando os bits para a janela visível (WS_VISIBLE = 0x10000000), do tipo janela-filha (WS_CHILD = 0x40000000), com borda de linha fina (WS_BORDER = 0x800000), do estilo da tree-view com linhas (TVS_HASLINES = 2), com botões (TVS_HASBUTTONS = 1) e desabilitando clicar e arrastar (TVS_DISABLEDRAGDROP = 16).
  • int x, y: a posição da janela está nas coordenadas 0,0.
  • int nWidth, nHeight: tanto a largura quanto a altura são zero. O tamanho real da janela será definido na interceptação da mensagem WM_SIZE na função MainWndProc, nossa central de mensagens. A vantagem é que, quando o usuário redimensionar a janela principal, a janela do controle da árvore acompanha o redimensionamento.
  • HWND hWndParent: o ponteiro para a janela-mãe (hWnd), recebido pela função CriaTree como parâmetro, é repassado para a função CreateWindowEx.
  • HMENU hMenu: é enviado como identificador da janela-filha, ou seja, o parâmetro int ID recebido pela função CriaTree é passado para a função CreateWindowEx como tipo HMENU com a notação (HMENU)ID.
  • HINSTANCE hInstance: podemos usar o valor de hInst como instância, uma vez que o código gerado pelo Wedit nos disponibiliza esta variável como global.
  • LPVOID lpParam: não há ponteiro para dados para a criação da janela, portanto, enviamos NULL.

O código para a criação da janela do controle da árvore está pronto. A explicação é muito mais longa do que o código propriamente dito. Mas pode ir se acostumando pois, se quiser produzir um código "enxuto", a romaria vai ser sempre a mesma: muita pesquisa e muita leitura para decidir usar algumas linhas de comando.

NÃO SE ESQUEÇA de colocar o protótipo da função no início do programa, senão o pre-processador vai estrilar. Mais um alerta: se não existir o protótipo, a posição da função dentro do código faz diferença - ela precisa estar ANTES de chamada à função, no nosso caso, antes da função MainWndProc. Mas, como somos programadores profissionais, incluímos o protótipo:

...
HINSTANCE hInst;      // manipulador da instância
HWND hwndMain;        // manipulador da janela principal
 
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
static HWND _stdcall janelaTree(HWND hWnd,int ID);
...


Última atualização ( Sáb, 29.11.2008 17:54 )
 

Topo

Topo

Exceto onde especificamente citado, todo material deste site está sob Licença Creative Commons