Olá e bem-vindo à nossa mais nova comunidade de jogos! É esta a sua primeira visita?
.::Conect Cheats::.

Todas notícias de novidades no mundo da tecnologia,jogos,programações,designer entre muitos outros jogos onlines! Acesse já.

 Sistema de cash points atualizado! clique aqui e confira!
 Veja também a Sessão Gráfica do fórum
 Fique por dentro das notícias e Anúncios do Fórum!
 Faça parte da equipe ConectCheats também, acessando o fórum de Recrutamento
 Ajude a equipe dando idéias e Sugestões para que o fórum cresça cada vez mais!
Ainda não se registrou? faça parte dessa mais nova comunidade agora, Registre-se!

Você não está conectado. Conecte-se ou registre-se

Ver o tópico anterior Ver o tópico seguinte Ir para baixo  Mensagem [Página 1 de 1]

#1Tutorial Completo de C Empty Tutorial Completo de C Qua Jul 16, 2014 12:07 pm

Alquimista

Coordenador
Coordenador
Alquimista

Tutorial Completo de C Empty Tutorial Completo de C

[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]

Na ciranda das linguagens de programação a linguagem C permanece firme e forte. Não é necessariamente uma linguagem orientada a objeto, mas você pode pode fazer uma programação orientada a objeto se assim o desejar. Não é uma linguagem funcional, mas você pode programar funcionalmente se quiser. Como dá para perceber, a C não impõe qualquer ponto de vista. Além disto, possui todas as características de uma linguagem de programação de uso geral, como recursividade, procedimentos como tipos de dados de primeira classe e muito mais.

Muitos acham que a C não tem a simplicidade da Java ou a sofisticação da C++. É verdade. C é uma linguagem simples, sem muitas frescuras. Mas é justamente esta simplicidade que faz com que se possa controlar o que os programas realizam sem ter que se preocupar com qualquer característica escondida. O compilador não fará nada a mais do que aquilo que tenha determinado. A linguagem permanece transparente, mesmo quando se implementa características mais sofisticadas, algo do tipo da "garbage collection" típica da Java.

As linguagens surgem e desaparecem, mas a C permanece. Foi o coração do desenvolvimento do sistema operacional UNIX nos anos 70, foi o centro da revolução dos microcomputadores nos anos 80 e, quando surgiram a C++, Delphi, Java e muitas outras, a linguagem C continuou fiel à sua própria natureza.

Minha experiência pessoal talvez sirva de exemplo: sabendo C, aprender qualquer outra linguagem fica fácil, ou seja, quando se domina uma língua, aprender um dialeto é bico. Mesmo se você não tiver a mínima noção de como programar, ainda assim vale a pena seguir este tutorial. Criança também aprende a fala

A organização de programas C

Um programa C é composto por funções, isto é, porções menores de código que realizam determinadas tarefas, e por dados, ou seja, variáveis ou tabelas que são inicializadas antes do início do programa. Existe uma função especial denominada main, onde a execução do programa se inicia. As funções são organizadas em módulos agrupados nos arquivos fonte. Em C, a organização do código em arquivos tem um significado semântico. O arquivo fonte principal, passado como argumento para o compilador, define uma unidade de compilação.

Uma unidade pode importar definições usando a diretiva #include ou apenas declarando algum identificador como externo.

A C permite um modelo de compilação separado, isto é, você pode dividir o programa em várias unidades independentes que são compiladas separadamente e depois são concatenadas com o link editor para construir o programa final. Normalmente, cada módulo é escrito num arquivo texto separado que contém funções ou declarações de dados. As interfaces entre os módulos são escritas em "header files" (arquivos de cabeçalho) que descrevem tipos ou funções visíveis para vários módulos do programa. Estes arquivos possuem a extensão ".h" e são de dois tipos: privados, específicos para aplicação que está sendo elaborada, e para o sistema.

Toda função possui uma lista de parâmetros, um corpo e, eventualmente, um valor de retorno. O corpo pode conter declarações de variáveis locais, ou seja, variáveis que são ativadas quando a execução alcançar o corpo da função.

Exemplo de programa

Ficando na mesmice de sempre, o primeiro exemplo se refere ao código de um programa que colocará na tela "Informática NumaBoa".

Código PHP:
Código:
#include <stdio.h> 
int main(void) 

  printf("Informática NumaBoa\n"); 
  return 0; 
}  

Usando a característica do compilador chamada de "pre-processamento", incluímos textualmente um arquivo completo de fonte C com a diretiva "#include". Neste exemplo incluímos o arquivo cabeçalho "stdio.h", que faz parte das inclusões padrão do compilador.
Definimos uma função chamada "main" que retorna o inteiro 0 (zero) e que não recebe argumentos (void).
O corpo da função é composto por declarações delimitadas pelas chaves { }
Chamamos a função padrão "printf" que formata seus argumentos numa string de caracteres que é mostrada na tela. Uma chamada de função em C é escrita da seguinte maneira: nome-da-função( lista-de-argumentos ). Neste exemplo, o nome da função é "printf" e sua lista de argumentos é a string "Informática NumaBoa\n". Strings são delimitadas por aspas duplas. Em C, são representadas como um array de caracteres terminados por um byte sero.
A declaração "return" indica que o controle deve ser devolvido à função chamadora. Opcionalmente é possível especificar uma valor de retorno que, neste caso, é 0.
A chave terminadora "}" indica o fim da área da função.
Programas em C são definidos em arquivos texto que normalmente possuem a extensão ".c".

Proposta de trabalho

Como em todos os outros tutoriais que escrevi, a proposta é aprender com exemplos práticos - e este tutorial não poderia ser diferente. Escolhi como ferramenta de trabalho um software gratuito, ao alcance de todos e de excelente qualidade.

Há muito tempo atrás esbarrei no lcc-win32 e, para minha surpresa, esta excelente plataforma de desenvolvimento continua sendo atualizada. Os autores do lcc são Chris Fraser e Dave Hanson. Jacob Navia escreveu o sistema de compilação lcc-win32 a partir do compilador lcc. O lcc-win32 não é um software de domínio público ou shareware, tampouco é protegido por copyleft, mas é livre para fins de instrução e para pesquisa pessoal.

----------------------------------------------------------------------------------------------------------------------------------

Você encontra o software para download em LCC-Win32: A free compiler system for Windows Operating Systems by Jacob Navia e na Q software solutions. Faça o download nos endereços indicados para garantir que seja a versão mais atualizada ou baixe o lcc-win32 na seção de downloads da Aldeia (está em Informática/Programação).

O pacote contém instalador e desinstalador, além de alguns aplicativos interessantes. O mais importante deles é o Wedit, que será a ferramenta principal deste tutorial. Tenho certeza de que você ficará admirado com os resultados que pode obter sem muito esforço e em tempo recorde!

Este é um projetinho inicial, só para sentir o gosto da coisa. Nada como um passo depois do outro para ir se familiarizando com a linguagem C. Este é o objetivo deste tutorial.

Após fazer o download do lcc-win32 (veja na Introdução), a instalação deste sistema de compilação é muito tranquila - basta indicar o diretório desejado, o resto fica por conta do instalador. Como todo software de qualidade, possibilita inserir uma entrada no menu de programas e possui um desinstalador.

Com o lcc-win32 à disposição, clique no item lcc-win32 do menu de programas ou chame diretamente o Wedit que se encontra no subdiretório bin. Em todos os módulos do tutorial, os itens de menu serão indicadas entre barras - por exemplo |File|. Quando a opção for um item de submenu, a indicação será |File/New|. Botões são indicados por colchetes, por exemplo [Browse].

Criando um projeto

Para criar um novo projeto clique em |File/New/Project|. A caixa de diálogo "Definition of a new project" é apresentada e algumas indicações precisam ser feitas:

Clique no campo "Name of the project" e digite o nome do projeto, por exemplo TESTE.
Clique em [Browse] para abrir a janela de navegação de diretórios.
Escolha ou crie com [Make new folder] o diretório onde queira guardar o projeto TESTE (sugiro que você crie um subdiretório TESTE no diretório /lcc/projects) e clique em [OK].
O campo "Sources working directory" indica sua escolha (digamos, C:\lcc\projects\TESTE) e o campo seguinte, "Objects and executables", é preenchido automaticamente (C:\lcc\projects\TESTE\lcc).
Em "Options" assinale apenas "Single user".
Em "Type of project" assinale "Console Application".
Clique em [Create] para obter o diálogo "Do you want to use the wizard to generate the application skeleton?" (Quer usar o wizard para gerar o esqueleto do aplicativo?). Clique em [No].
Na janela "Add source files to project" digite teste1.c no campo "File name" e clique em [Open].
Na janela "Source files for project" selecione teste1.c e clique em [OK].
É apresentada a janela "Compiler settings" - clique em [Next]. A seguir vem a janela "Linker settings" - clique também em [Next]. Segue-se a janela "Debugger settings" - clique em [Finish].
Finalmente é apresentada a janela de edição onde é possível escrever o código de teste1.c

Um programa de console

Este primeiro exemplo se refere ao código de um programa que colocará na tela "Informática NumaBoa", conforme já explicado na Introdução. Como optamos por um programa de console, o mesmo rodará num shell do DOS (aquela telinha preta). Digite na janela de edição o exemplo abaixo:
Código PHP:
Código:
#include <stdio.h> 
int main(void) 

  printf("Informática NumaBoa\n"); 
  return 0; 
}  

Note o texto destacado em cores, a indentação automática quando se digita as chaves e a indicação de sintaxe quando se digita a função printf. NÃO SE ESQUEÇA de terminar as linhas de comando com ponto e vírgula - este é o caractere terminador!

O asterisco no título da janela de edição (TESTE.c*) indica que o projeto TESTE.c foi alterado. Clique em |File/Save| ou digite Ctrl+S para salvar as alterações.
Clique em |Compiler/Compile TESTE.c|. Se o código fonte não tiver erros, o rodapé do aplicativo apresentará "teste1.exe built successfully.(0.3 sec)."
Clique em |Compiler/Execute teste1.exe| ou digite Ctrl+F5 para executar o programa. Se tudo correu bem, observe abaixo o resultado obtido.


[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]

Observações 

Viu só, não foi tão difícil assim. Se você é da turma que não entende chongas de linguagem de programação, foi a glória ver esta telinha preta - diz que não foi Se você faz parte dos iniciados e está tentando virar poliglota, tenho certeza de que também foi um bom começo. Aproveitando o entusiasmo inicial, só mais umas coisinhas:

O arquivo stdio.h incluído no início do programa contém um caminhão de informações para o pre-processador. Ao invés de escrever todas estas informações no código fonte do nosso arquivo teste1.c, pedimos simplesmente para que ele fosse incluído (daí #include - êta mordomia!). O nome do arquivo vem de standard input/output, ou seja, entrada/saída padrão. Como precisamos de uma saída para a tela, precisamos do stdio.h. Aliás, você vai cansar de usar este #include.

Se você tiver curiosidade, o arquivo stdio.h se encontra no diretório /lcc/include/. É só abrí-lo, por exemplo com o próprio Wedit, para poder dar uma olhada. Procure pela referência à função printf que, claro, está neste arquivo. Afinal, esta função não apareceu do nada, né não? Tome cuidado para não alterá-lo, senão é caca na certa quando for usá-lo na próxima vez.

Um programa para o Windows

Hoje em dia a maioria dos aplicativos são controlados por uma GUI (Graphical User Interface). Com o uso de janelas, que têm controles como campos de edição, botões, menus, etc, a interatividade do usuário torna-se mais fácil e intuitiva.

Você viu na Introdução que a organização de um programa C exige SEMPRE uma função principal, geralmente denominada de main, por onde o programa é iniciado. No caso de um programa para o Windows, esta função é a WinMain (poderia ser diferente?). As funções utilizadas num programa Windows podem ser de dois tipos: aquelas que você programar (suas funções) e aquelas que fazem parte do sistema operacional Windows e estão prontinhas para serem usadas.

Todas as funções "usáveis" do Windows estão agrupadas por tipo em arquivos com a extensão . DLL (dynamic-linked libraries). O conjunto destas DLLs é chamado de API (Application Programming Interface). As principais DLLs são kernel32.dll, user32.dll e gdi32.dll. A kernel32.dll contém funções API que lidam com a memória e com a administração de processos, a user32.dll possui funções que controlam a aparência da interface do usuário e a gdi32.dll tem funções responsáveis por operações gráficas. São milhares de funções que, quando chamadas com os parâmetros corretos, criam as janelas e os controles da GUI (Ainda bem, já pensou ter que programar cada risquinho???).

O primeiro programa GUI para Windows

Crie um novo projeto clicando em |Project/Create|. Dê-lhe um nome (eu o chamei de testedlg) e indique o diretório onde o projeto deve ser colocado. Em "Options" assinale "Single user". Até aqui, tudo igual ao módulo anterior. Mas, para um programa Windows, siga os passos a seguir:

Em "Type of project" assinale "Windows Application".
Clique em [Create] e no diálogo "Do you want to use the wizard to generate the application skeleton?" (Quer usar o wizard para gerar o esqueleto do aplicativo?) clique em [Yes].
Na caixa de diálogo "Application characteristics", em "Type of apllication", assinale a opção "Dialog based" e depois clique em [Ok].
Clique em [OK] na caixa de mensagem avisando que o projeto foi criado.
Na janela "Compiler settings", clique em [Next]. Na janela "Linker settings", clique em [Next]. Na janela "Debugger settings", clique em [Finish].
Surpresa! A janela de edição mostra nosso programa gentilmente preparado pelo lcc-win32. Mordomia pura, pois o programa está pronto. Basta compilá-lo com |Compiler/Compile testedlg.c| e rodá-lo com |Compiler/Execute testedlg.exe| para ver o resultado.
[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]

O programa montado pelo lcc

Não se assuste com todo este código, mesmo porque vamos cansar de vê-lo e, pode ter certeza, a gente acaba se acostumando. Observe que o programa possui três funções: WinMain (linha 10), InitializaApp (linha 33) e a DialogFunc (linha 38). A InitializaApp não faz nada além de retornar 1 - serve apenas de gancho se quisermos configurar alguma coisa antes da caixa de diálogo ser mostrada. Vou tentar explicar em detalhes as outras duas, a WinMain e a DialogFunc.
Código PHP:
Código:
#include <windows.h> 
#include <windowsx.h> 
#include <commctrl.h> 
#include <string.h> 
#include "testedlgres.h" 
  
static BOOL CALLBACK DialogFunc( 
   HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); 
  
int APIENTRY WinMain( 
   HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpCmdLine, int nCmdShow) 

   WNDCLASS wc; 
   INITCOMMONCONTROLSEX cc; 
  
   memset(&wc,0,sizeof(wc)); 
   wc.lpfnWndProc = DefDlgProc; 
   wc.cbWndExtra = DLGWINDOWEXTRA; 
   wc.hInstance = hinst; 
   wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
   wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); 
   wc.lpszClassName = "testedlg"; 
   RegisterClass(&wc); 
   memset(&cc,0,sizeof(cc)); 
   cc.dwSize = sizeof(cc); 
   cc.dwICC = 0xffffffff; 
   InitCommonControlsEx(&cc); 
  
   return DialogBox( 
      hinst, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, (DLGPROC) DialogFunc); 

  
static int InitializeApp(HWND hDlg,WPARAM wParam, LPARAM lParam) 

  return 1; 

  
static BOOL CALLBACK DialogFunc( 
   HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) 

   switch (msg) { 
   case WM_INITDIALOG: 
      InitializeApp(hwndDlg,wParam,lParam); 
      return TRUE; 
   case WM_COMMAND: 
      switch (LOWORD(wParam)) { 
         case IDOK: 
            EndDialog(hwndDlg,1); 
            return 1; 
         case IDCANCEL: 
            EndDialog(hwndDlg,0); 
            return 1; 
      } 
      break; 
   case WM_CLOSE: 
      EndDialog(hwndDlg,0); 
      return TRUE; 
   } 
   return FALSE; 
}  

Uma janela com firulas

Proceda exatamente como indicado no tutorial anterior, A primeira janela para criar um novo projeto com o nome dlg2. NÃO compile o programa. Quando chegar à janela de edição do programa, está na hora de dar uma olhada nos recursos. Mas, o que são recursos? Acompanhe a seguir e tente entender o máximo possível, porque é exatamente nos recursos que vamos mexer para personalizar nossa caixa de diálogo.

Os recursos da caixa de diálogo

Recursos são a descrição gráfica de elementos da interface com o usuário. Esta descrição fica num arquivo à parte, o arquivo de recursos. Numa linguagem com sintaxe própria - a Resource Script Language - são descritos elementos como menus, cursores, ícones, caixas de diálogo com botões, strings de texto, etc. É como se fosse um "programa" à parte. Para ser incorporado ao executável, este "programa" também precisa ser compilado, o que é feito com compiladores especiais, os compiladores de recursos (o lcc-win32 também possui um compilador de recursos, o lrc.exe).

Como até agora não fizemos nada relacionado aos recursos, é sinal que o lcc-win32 cuidou disso para nós. Efetivamente, o sistema criou dois arquivos "irmãos": o dlg2res.h e o dlg2.**. O primeiro, o dlg2res.h, é um arquivo cabeçalho com uma definição:
Código PHP:
Código:
#define  IDD_MAINDIALOG  100  

Se você quiser conferir o conteúdo deste arquivo, clique em |File/Open|, selecione o arquivo dlg2res.h e clique em [Open]. Na janela de edição aparece o texto acima. Este texto nada mais é do que a definição do apelido IDD_MAINDIALOG para o número identificador 100. Cada elemento da interface gráfica descrito nos recursos precisa de um número de identificação (ou ID) próprio. Digamos que se pretenda incluir uma caixa de texto nos recursos - é claro que ela não poderá ser identificada pelo ID 100 (pode ser 110, 120, 15, qualquer número diferente de 100). O apelido também pode ser outro. Podemos trocá-lo por ID_DIALOGOPRINCIPAL ou qualquer outra coisa.

O arquivo "irmão" do dlg2res.h é o arquivo de código fonte dos recursos, o dlg2.**, escrito em Resource Scripting Language (RSL). Neste arquivo encontram-se as características dos elementos gráficos:
Código PHP:
Código:
IDD_MAINDIALOG DIALOG 38, 27, 195, 86 
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU 
CAPTION "testedlg" 
FONT 8, "Helv" 
BEGIN 
    DEFPUSHBUTTON   "OK", IDOK, 35, 66, 40, 14 
    PUSHBUTTON        "Cancel", IDCANCEL, 95, 66, 40, 14 
END  

Confira abrindo o arquivo com |File/Open| e, na caixa de diálogo "Open as resource file?" clique em [No]. Todas estas declarações se referem à caixa de diálogo, sua aparência, a posição das janelas-filhas (lembre-se, cada elemento é, na verdade, uma janela-filha), etc. Analisando as declarações temos:

Encontramos o mesmo "apelido" IDD_MAINDIALOG seguido pela declaração DIALOG e por algumas coordenadas. Isto significa em RSL que o elemento IDD_MAINDIALOG é uma caixa de diálogo e que as coordenadas estão expressas em Unidades de Diálogo (não em pixels!). Estas unidades são uma mandrakaria para fazer com que a caixa de diálogo tenha uma aparência semelhante em todas as resoluções e em diferentes tamanhos de tela. Estão baseadas indiretamente no tamanho da fonte do sistema e existem APIs que transformam estas unidades em pixels e vice-versa.
A declaração STYLE (estilo) indica ao interpretador o que deve ser feito quando a janela for criada. Mais adiante, em outro módulo, quando criarmos uma janela real e não uma caixa de diálogo, existe uma porção de coisas que podem ser feitas. Mas, no presente caso, o estilo indica que se trata de uma janela pop-up, visível, com título e um menu padrão do sistema.
E, já que indicamos que queremos um título, precisamos indicar qual é este título através de uma string que segue a declaração CAPTION.
A declaração FONT indica que queremos tamanho 8 e Helv.
As declarações seguintes enumeram os controles da caixa de diálogo e suas descrições estão entre os delimitadores de bloco BEGIN e END. Aí se encontram dois botões, um destacado (DEFPUSHBUTTON) e um normal (PUSHBUTTON). Ambos possuem um texto ("Ok" e "Cancel"), IDs (IDOK, de valor numérico 1 e IDCANCEL, de valor numérico 2) e as coordenadas.
Este é o conjunto de instruções que será transformado pelo compilador de recursos num arquivo binário de recursos que o Windows possa interpretar. O mesmo será incorporado ao executável através de uma diretiva include. Reveja o início do programa:
Código PHP:
Código:
#include <windows.h> 
#include <windowsx.h> 
#include <commctrl.h> 
#include <string.h> 
#include "testedlgres.h"  

Observe a forma de chamar os quatro primeiros (#include <...>) e o último (#include "..."). Para o pre-processador, include com <...> significa que o arquivo a ser incluído se encontra no diretório indicado na configuração do lcc (no caso, \lcc\include\), enquanto que o include "dlg2res.h" se encontra no diretório do projeto (no caso, \lcc\projects\teste\)

A esta altura do campeonato já deu para perceber que o grande lance na programação Windows está diretamente relacionado à troca de mensagens entre o sistemão (o sistema operacional Windows) e a central de mensagens do nosso programa. Conforme prometido no final do módulo anterior, o Diálogo Personalizado, vamos rastrear as informações fornecidas pelo usuário. Se você não leu o tutorial anterior, sugiro que o faça, pois este é apenas a continuação do assunto. Além do mais vamos expandir o programa dlg2.c, também criado no módulo anterior.

Definindo os objetivos

Se o usuário clicar no botão [OK], queremos saber o teor do texto digitado. Esta operação tem dois aspectos:

Saber se o botão [OK] foi clicado (se o usuário clicar em [Cancela] ou fechar a janela, é sinal de que não quer revelar o conteúdo digitado).
Obter o texto do campo de edição.


Interceptando um clique no botão [OK]
Lá vamos nós para a central de mensagens do programa. Vou mostrá-la novamente para não dar margem a dúvidas:
Código PHP:
Código:
static BOOL CALLBACK DialogFunc( 
   HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) 

   switch (msg) { 
   case WM_INITDIALOG: 
      InitializeApp(hwndDlg,wParam,lParam); 
      return FALSE; 
   case WM_COMMAND: 
      switch (LOWORD(wParam)) { 
         case IDOK: 
            EndDialog(hwndDlg,1); 
            return 1; 
         case IDCANCEL: 
            EndDialog(hwndDlg,0); 
            return 1; 
      } 
      break; 
   case WM_CLOSE: 
      EndDialog(hwndDlg,0); 
      return TRUE; 
   } 
   return FALSE; 
}  

O ponto para interceptar um clique no botão [OK] já está definido: é quando nossa central de mensagens receber uma mensagem do tipo WM_COMMAND trazendo no parâmetro wParam o valor IDOK. O que precisamos, além de fechar a caixa de diálogo com EndDialog, é obter o texto que foi digitado (ou não) no campo de edição. Chegou finalmente a hora de botar a mão na massa - vamos escrever uma função que realize o trabalho desejado.

Caçando o texto

Sabemos que o texto que queremos se encontra no campo de edição de apelido ID_EDICAO. Para capturá-lo, mais uma vez existe uma função da API, a GetDlgItemText. Acontece que esta função extrai o texto da janela-filha ID_EDICAO e transfere os caracteres para uma área de memória. Áreas de memória reservadas para armazenarem dados são chamadas de buffer, cuja tradução literal é pára-choque. Só Deus sabe porque escolheram este termo; pra mim, não tem nada a ver, preferia algo como cesta ou balaio 

É claro que o balaio... perdão, o buffer precisa ter um tamanho suficientemente grande para conter todos os caracteres que pretendemos transferir. Além disso, é uma exclusividade da casa e não precisa cair no domínio público, ou seja, outros programas ou módulos não precisam saber da sua existência. Chamamos isto de buffer estático.

Por uma questão de ordem, colocamos a definição desta variável estática no início do programa, logo depois dos includes e da declaração do protótipo da função DialogFunc (aliás, ainda não expliquei a razão de protótipos de funções. Aguarde mais um pouco que a gente chega lá). Então, a coisa fica assim se chamarmos a variável estática de balaio e determinarmos que possa conter até 1024 caracteres:
Código PHP:
Código:
... 
#include "testedlgres.h" 
  
static BOOL CALLBACK DialogFunc( 
   HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); 
static char balaio[1024]; 
...  

Também, por uma questão de ordem, deixamos que a primeira função do programa seja a da entrada, a WinMain, seguida pela função de inicialização, a InitializeApp. Bem, então logo após, podemos escrever a seguinte função:

Código PHP:
Código:
int PegaTexto(HWND hwnd) 

   memset(balaio,0,sizeof(balaio)); 
   if (GetDlgItemText(hwnd, ID_EDICAO, balaio, sizeof(balaio))) { 
      return 1; 
   } 
   return 0; 
}  

A função de nome PegaTexto exige como parâmetro um manipulador (handle) e retorna um inteiro (int). Agora vamos por partes:

A função memset preenche a área de memória reservada para a variável balaio com 1024 zeros. A função sizeof dá o tamanho do balaio (1024 caracteres). O que queremos é enviado através dos parâmetros e o resultado é que o buffer é zerado - o mesmo que dizer "o balaio é esvaziado".
Segue-se uma diretiva if (cuja tradução é se). Então, SE GetDlgItemText conseguir transferir o conteúdo do campo de edição para o balaio, retorne 1 (o mesmo que TRUE); caso contrário, retorne 0 (o mesmo que FALSE).
Falta destrinchar a função GetDlgItemText. Esta função precisa dos seguintes parâmetros:

hwnd: o manipulador da janela-mãe, nossa caixa de diálogo.
ID_EDICAO: o apelido do campo de edição, a janela-filha da qual se quer extrair o texto.
balaio: o buffer onde devem ser colocados os caracteres.
sizeof(balaio): o tamanho do buffer, ou seja, o número máximo de caracteres que podem ser transferidos.
Tudo bem, mas o que é que o if faz com a função GetDlgItemText? SE o que? É que GetDlgItemText retorna o número de caracteres transferidos. Se for 1 ou mais caracteres, é o mesmo que dizer if TRUE, a condição é preenchida e o valor de retorno é 1; caso contrário o valor de retorno é 0. Tudo em riba, só falta chamar nossa função quando o usuário clicar o botão [OK]:

Código PHP:
Código:
static BOOL CALLBACK DialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) 

   switch (msg) { 
   case WM_INITDIALOG: 
      InitializeApp(hwndDlg,wParam,lParam); 
      return FALSE; 
   case WM_COMMAND: 
      switch (LOWORD(wParam)) { 
         case IDOK: 
            PegaTexto(hwndDlg); 
            EndDialog(hwndDlg,1); 
            return 1; 
         ...  

As bibliotecas padrão

Para inserir funções da API nos nossos programas é preciso indicar ao pre-processador onde ele poderá encontrá-las. Sabemos que funções da API do Windows ficam agrupadas em arquivos próprios de acordo com o tipo, numa espécie de biblioteca de funções. Estas bibliotecas são aquivos que possuem a extensão .dll, chamados simplesmente de DLLs.

Quando queremos usar uma função da API, ou uma função própria da linguagem C, não escrevemos a função no nosso programa. É muito mais prático pedir ao pre-processador que inclua o código da função desejada. Para isto, precisamos fornecer ao pre-processador um "mapa da mina", para que ele possa localizar e incluir a função desejada. O lcc-win32 possui vários "mapas" prontinhos para serem utilizados, arquivos com a extensão .h chamados de cabeçalhos e que se encontram no diretório /lcc/include. Os principais são:
Cabeçalho Uso
stdio.h 
Standard Input Output (entradas e saídas padrão): este cabeçalho contém a definição da estrutura FILE, usada para todas as entradas (input) e saídas (output), além das definições de todas as funções que lidam com a abertura, fechamento, etc de arquivos. A famosa função printf também é definida aqui, juntamente com sprintf, fprintf e toda a família de funções relacionadas.

math.h 
Funções Matemáticas: sin, cos, atan, log, exp, etc. Aqui encontramos trigonometria (sin, cos, tan, atan, etc), arredondamentos (ceil, floor), logaritmos (log, exp, log10, etc), raiz quadrada e cúbica (sqrt, cbrt) e constantes como pi, e, etc.

stdlib.h 
Standard library functions (funções da biblioteca padrão): Contém abort (término anormal do programa), exit (término normal), atoi, itoa (conversão de texto para inteiro), malloc, calloc, free (módulo de memória dinâmica), rand, srand (números randômicos), putenv, getenv (administração do ambiente), qsort (ordenação), strtod, strtol (conversão de string para double/long), sleep (suspender a execução por um certo período de tempo).

stddef.h 
Este arquivo define macros e tipos de uso geral em programas: NULL, offsetof, ptrdiff_t, size_t e muitos outros.

string.h 
Manipulação de strings: aqui são definidas todas as funções que lidam com a representação padrão de como as strings são usadas em C. Temos strcmp (comparação de strings), strlen (obtenção do comprimento de uma string), strcpy (cópia de uma string para outra), strcat (concatenação de strings), strstr (substring numa string), memset (atribuição de uma região RAM para um caracter), memcpy (copiar memória), memmove (copiar memória cuidando da região de sobreposição).

windows.h 
Todas as definições de janelas: criar, abrir, etc. É um arquivo cabeçalho grande com cerca de 500 mega de definições. Saiba que o lcc-win32 incorpora neste arquivo muitos dos arquivos que normalmente são individualizados em outras distribuições (como o winbase.h, por exemplo).

Se você tiver curiosidade de saber como são montados estes arquivos de cabeçalho, basta abrí-los em qualquer editor de texto (o do lcc-win32 também serve).


Os tipos padrão

A linguagem C possui os seguintes tipos padrão:

Tipo Tamanho Descrição
_BOOL 1 Tipo lógico, pode ser 0 ou 1.
char 1 Tipo caracter, podendo ser com sinal ou sem sinal.
short 2 Inteiro armazenado em 16 bits, com ou sem sinal.
int 4 Inteiro armazenado em 32 bits, com ou sem sinal.
long 4 Idêntico ao int.
long long 8 Inteiro armazenado em 64 bits, com ou sem sinal.
float 4 Ponto flutuante de precisão simples (cerca de 7 dígitos).
double 8 Ponto flutuante de precisão dupla (cerca de 15 dígitos).

Manifestos e definições

É uma confusão danada! "Declaration" em Inglês é "manifesto" e "Statement" é "declaração". É muito importante entender a diferença entre um manifesto e uma declaração (ou definição) na C.

Um manifesto apresenta um identificador ao compilador. É como se um manifesto dissesse "este identificador é o XXX e ele será declarado (definido) mais adiante". Um manifesto pode ser, por exemplo:
Código PHP:
Código:
extern double sqrt(double);  

Com este manifesto apresentamos o identificador sqrt ao compilador, dizendo que se trata de uma função que usa um argumento de precisão dupla (double) e que retorna um resultado de precisão dupla (double). A apresentação pára por aí e nem ocupa espaço. É que, se esta função não for utilizada pelo programa, ela nem será incorporada - portanto, não ocupará espaço no executável.

Uma declaração (definição) diz ao compilador para alocar espaço para o identificador. Por exemplo, para definir a variável "contador":
Código PHP:
Código:
int contador;  

Neste caso, o compilador cria um espaço na área de variáveis locais da função que contenha esta definição, abrindo espaço suficiente para conter um número inteiro.

O que precisa ficar bem claro é que uma variável pode ser manifestada quantas vezes quisermos, mas só deve ser definida num único ponto. É o mesmo que dizer que, quando definimos uma variável, emitimos sua "carteira de identidade" (que precisa ser única) e fixamos sua residência (para que possamos encontrá-la quando for preciso). Quando manifestamos uma variável (ou uma função), dizemos apenas que deve aparecer uma "moça" de nome tal, ou um "rapaz" de nome tal, ou um int ou um double de nome tal... enfim, uma entidade de nome tal cujo tipo seja o que foi manifestado - mas que ainda está sem lenço e sem documento.

Criando o projeto

Os passos para criar um projeto você já conhece: |Project|Create|, dar nome ao projeto (eu dei o nome de "janela"), selecionar o diretório de trabalho (continuei usando o /lcc/projects/teste/), selecionar "Windows application" e clicar em [Create]. Confirme o diretório com [Yes], aceite o wizard com [Yes]. Selecione "Single window" e clique em [Ok], [Next], [Finish] e novamente em [OK]. Deixe tudo como está e clique em [Next], [Next] e [Finish] para finalmente chegar na janela de edição.

Deu para perceber que aceitamos todas as configurações apresentadas pelo wedit - só tivemos o trabalho de assinalar "Windows application". Dando uma olhada no código fonte gerado automaticamente, dá para perceber que é um pouco mais elaborado do que o código fonte da caixa de diálogo. Algumas coisas já conhecemos, em compensação tem umas outras que... bem, serão vistas mais para frente.

Compile e rode o programa. O que se vê é uma janela de fundo branco, com uma barra de título na parte superior, uma barra de status na parte inferior e um menu - este é o esqueleto de um aplicativo windows (mas não esquecido dentro do armário )

Analisando o código fonte

Como sempre, vamos começar com a função WinMain. Sabemos que ela não pode faltar, pois é a porta de entrada do nosso aplicativo:
Código PHP:
Código:
int WINAPI WinMain( 
HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) 

   MSG msg; 
   HANDLE hAccelTable; 
  
   hInst = hInstance; 
   if (!InitApplication()) 
      return 0; 
   hAccelTable = LoadAccelerators(hInst,MAKEINTRESOURCE(IDACCEL)); 
   if ((hwndMain = CreatejanelaWndClassWnd()) == (HWND)0) 
      return 0; 
   CreateSBar(hwndMain,"Ready",1); 
   ShowWindow(hwndMain,SW_SHOW); 
   while (GetMessage(&msg,NULL,0,0)) { 
      if (!TranslateAccelerator(msg.hwnd,hAccelTable,&msg)) { 
         TranslateMessage(&msg); 
         DispatchMessage(&msg); 
      } 
   } 
   return msg.wParam; 
}  

O esquema básico é o mesmo dos nossos projetos de caixas de diálogo, mas esta função é mais parruda: iniciamos o aplicativo chamando a função InitApplication (onde será registrada a classe da janela, etc), carregamos os aceleradores de teclado (as teclas de atalho), criamos a janela, a barra de status, mostramos a janela na tela e entramos num loop de mensagens - o mesmo que dizer que entramos na central de comunicação do nosso programa. A única mensagem que pode nos "expulsar" da central de comunicação é a WM_QUIT.

Como sempre, um aplicativo windows nada mais é do que receber e enviar mensagens entre o sistema operacional e a central de comunicação do nosso programa. Vamos analisar o código por partes, começando com a primeira função chamada, a InitApplication.

A inicialização

Este procedimento começa manifestando a estrutura wc, do tipo WNDCLASS (esta estrutura já está manifestada no arquivo cabeçalho windows.h que inclui o win.h). Não é a primeira vez que falamos em estruturas, aliás, um conceito tão importante que será o assunto do próximo tutorial. Se quiser se antecipar, dê uma lida em Estruturas e Uniões e depois volte para este texto.

Vamos dar uma olhada na função estática InitApplication, que não precisa de parâmetros (void) e que retorna um valor lógico ou BOOL (1=verdadeiro ou 0=falso):
Código PHP:
Código:
static BOOL InitApplication(void) 

   WNDCLASS wc; 
  
   memset(&wc,0,sizeof(WNDCLASS)); 
   wc.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS ; 
   wc.lpfnWndProc = (WNDPROC)MainWndProc; 
   wc.hInstance = hInst; 
   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
   wc.lpszClassName = "janelaWndClass"; 
   wc.lpszMenuName = MAKEINTRESOURCE(IDMAINMENU); 
   wc.hCursor = LoadCursor(NULL,IDC_ARROW); 
   wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); 
   if (!RegisterClass(&wc)) 
      return 0; 
  
   return 1; 
}  

O estilo da janela (wc.style) é uma combinação de constantes inteiras (CS_HREDRAW, CS_VREDRAW e CS_DBLCLKS) feita através do operador OR, representado por uma barra vertical.

O operador OR, um operador lógico cuja tradução é OU, é o modo padrão da linguagem C manipular bits. Quais bits? Neste caso, dos valores correspondentes às constantes. Experimente o seguinte: clique com o botão direito do mouse sobre CS_HREDRAW e escolha |Show definition of CS_HREDRAW|. Na janelinha pop-up é possível verificar que o valor desta constante é 2. Faça o mesmo com as outras duas. A declaração wc.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; pode ser traduzida para wc.style = 2 OR 1 OR 8; ou wc.style = 2 | 1 | 8;. Aliás, HREDRAW pode ser traduzido para "Redesenhar a Horizontal", VREDRAW para "Redesenhar a Vertical" e DBLCLKS para "Cliques Duplos".

Note que os valores das constantes são potências de 2, ou seja, 2 é igual a 2 elevado a 1, 1 é igual a 2 elevado a 0 e 8 é igual a 2 elevado a 3. Existe uma regrinha fácil de ser guardada: toda potência de 2 possui apenas um único bit com valor 1; todos os outros bits estão zerados. Outra dica: a operação lógica OR é a comparação de dois bits. Apenas se os dois bits forem 0, o resultado será 0; caso contrário, será 1.

Conhecendo os valores e sabendo como funciona o OR, fica fácil perceber que 2 OR 1 OR 8, expresso em binário, será 0010 OR 0001 OR 1000, o que é igual a 1011, que correspode a 11 na notação decimal. Na verdade, cada bit desta "tripinha" de 4 bits, onde os bits são numerados da direita para a esquerda a partir de 0, funciona como uma flag: bit 0 ligado = janela redesenha na vertical; bit 1 ligado = janela redesenha na vertical; bit 3 ligado = janela aceita duplos cliques.

Logo após, ao invés de usar o DefDialogProc (próprio para caixas de diálogo), atribui-se o MainWndProc. O restante não difere da definição da estrutura WNDCLASS vista nas caixas de diálogo.

A tabela de teclas de atalho

Os aceleradores, dispostos em uma tabela, são as de teclas de atalho que permitem o acesso rápido a itens de menu sem o uso do mouse. Encontram-se nos recursos e podem ser editados.

Clique em |Design|New/Open|, a seguir escolha janelares.h, clique em [Open] e escolha "Accelerator" com um duplo clique. Você obterá uma janela de teclas aceleradoras indicando IDM_EXIT, com o valor 300 e com um valor de tecla ("Key value") de 81. 81 corresponde ao valor ASCII da letra "q".

Dê um duplo clique na linha do "Key value" 81 para obter a janela "Changing an accelerator key". Você pode mudar, adicionar ou eliminar teclas aceleradoras. Fique à vontade... só que, como já compilamos nosso programa, as alterações nos recursos terão de ser feitas "na unha", o que é assunto para mais tarde.

Isto foi só um adendo. Vamos voltar à vaca fria...

A central de mensagens

Após carregar os aceleradores, é criada a barra de status no rodapé da janela e, finalmente, a janela é mostrada. Até então, enquanto estava sendo "enfeitada", a janela permaneceu "escondida". Isto impediu que uma janela inacabada ficasse sassaricando na tela, mareando o usuário, e economizou muito tempo de execução.

Na verdade, a parte mais importante é o loop de mensagens que vem logo depois da chamada à função da API ShowWindow (mostre a janela):
Código PHP:
Código:
... 
   ShowWindow(hwndMain,SW_SHOW); 
   while (GetMessage(&msg,NULL,0,0)) { 
      if (!TranslateAccelerator(msg.hwnd,hAccelTable,&msg)) { 
         TranslateMessage(&msg); 
         DispatchMessage(&msg); 
      } 
   } 
   ...  

Este loop, administrado por um comando de controle de fluxo while, chama a função da API GetMessage (pegar mensagem). Se a função retornar verdadeiro (TRUE), chamamos novamente a API para traduzir teclas aceleradoras (TranslateAccelerator). Esta função converterá uma sequência de teclas digitadas numa mensagem WM_COMMAND, como se tivesse sido enviada por um item de menu, se encontrar uma correspondência entre as teclas digitadas e a tabela de aceleradores que foi carregada algumas linhas antes.

Se TranslateAccelerator não encontrar nenhuma correspondência, a linha de execução passa para a função da API TranslateMessage (traduzir mensagem). Esta função controla as teclas digitadas e realiza o trabalho penoso de depurar a digitação do usuário (controlar sequências repetidas, intervalos, etc).

Finalmente é chamada a função da API DispatchMessage (despachar mensagem), que envia a mensagem para o procedimento indicado na classe janela, o MainWndProc.

É isso aí. Ficamos dando voltas e mais voltas neste loop até que, num dado momento seja gerada a mensagem WM_QUIT (terminar). Esta mensagem faz com que GetMessage retorne FALSE, interrompendo o loop e terminando o programa.

Criando uma estrutura

Estruturas são manifestadas através da palavra-chave struct seguida pelo nome da estrutura e por uma área delimitada por chaves que contém os campos. Os campos também são manifestados da forma habitual, . Veja abaixo:

Código PHP:
Código:
struct coordenadas { 
   int x; 
   int y; 
}  

Lembre-se de que o manifesto de uma variável do tipo estrutura é apenas um aviso para o pre-processador (se tiver dúvidas, reveja Bibliotecas e Tipos) - a entidade existe, mas não possui dados. Usando esta nova entidade, que na verdade é um novo tipo criado por nós, podemos manifestar ou definir variáveis ou objetos deste novo tipo:
Código PHP:
Código:
struct coordenadas coordTela {35,98};  

Aqui definimos a variável coordTela, que é uma estrutura do tipo coordenadas, que possui dois campos de inteiros, o "x" e o "y". Aproveitamos o embalo e indicamos os valores 35 e 98 (observe que os valores estão entre chaves). O pre-processador, quando processar esta definição, atribuirá o valor 35 para o campo x e o valor 98 para o campo y.

Acessando dados
Existem duas formas de acessar dados armazenados numa estrutura. Para obter diretamente o valor de um campo, a forma é . . Para obter o valor de um campo apontado por um ponteiro, a forma é -> .Veja o exemplo abaixo:
Código PHP:
Código:
void fn(void) 

   coordenadas c; 
   coordenadas *pc; 
   coordenadas &** = c; 
  
   c.x = 35;    // Atribui o valor 35 para o campo x 
   c.y = 98;    // Atribui o valor 98 para o campo y 
   pc = &c;     // Faz pc apontar para c 
   pc->x = 67;  // Muda o valor do campo x para 67 
   pc->y = 33;  // Muda o valor do campo y para 33 
   **.x = 88;   // Referências usam a notação de ponto 
}  


Recursividade
Estruturas podem ser recursivas, isto é, podem conter ponteiros para si mesmas - o que é o mesmo que dizer que podem "se chamar". Esta peculiaridade ajuda a definir estruturas do tipo lista:
Código PHP:
Código:
struct lista { 
   struct lista *Next; 
   int Dado; 
}  

Aqui definimos uma estrutura que contém um ponteiro para a mesma estrutura no primeiro campo e um inteiro no segundo campo. Mas ATENÇÃO: estamos fazendo o manifesto de um ponteiro para uma outra estrutura idêntica, NÃO a própria. Uma estrutura não pode conter ela mesma!

Listas duplas podem ser manifestadas da forma mostrada abaixo, com dois ponteiros: um para o próximo elemento da lista (*Next) e um para o elemento anterior (*Previous).
Código PHP:
Código:
struct lista_dupla { 
   struct lista_dupla *Next; 
   struct lista_dupla *Previous; 
   int Dado; 
};  


Campo de Bits
Um manifesto especial que só pode ser usado em estruturas é o campo de bits. Com ele pode-se especificar um campo da estrutura com um certo número de bits. Veja o exemplo:
Código PHP:
Código:
struct <a class="mosinfopop" style="cursor:help;border-bottom:1px dotted #000000;" href="javascript:void(0)" onmouseover="return overlib('<p>Bandeiras de sinalização ou bits de indicação de estado. Muito usadas na linguagem assembly.</p>&nbsp;<br />', CAPTION, 'flags',BELOW,RIGHT, WIDTH, 300, FGCOLOR, '#CCCCFF', BGCOLOR, '#333399', TEXTCOLOR, '#000000', CAPCOLOR, '#FFFFFF', OFFSETX, 10, OFFSETY, 10);" onmouseout="return nd();" > flags</a> { 
   unsigned JaFoiProcessado:1; 
   unsigned JaFoiImpresso:1; 
   unsigned Paginas:5; 
};  

Esta estrutura possui três campos. Os dois primeiros são campos de 1 bit, isto é, só podem conter um valor lógico (ou booleano) de 0 ou 1. O terceiro campo pode armazenar um inteiro de 5 bits, ou seja, números de 0 a 31.

Estruturas Aninhadas
Estruturas podem conter outras estruturas ou tipos. Por exemplo, tendo manifestado a estrutura coordenadas (veja acima), é possível manifestar uma nova estrutura que a contenha:
Código PHP:
Código:
struct Ponto { 
   struct coordenadas coordTela; 
   int Dado; 
};  

Esta estrutura contém uma estrutura "coordenadas". Para acessar o campo "x" da estrutura coordTela contida na estrutura Ponto, basta referenciá-lo com:
Código PHP:
Código:
struct Ponto pto; 
... 
pto.coordTela.x = 78;  


Estruturas em Arrays
Arrays (ou matrizes) podem conter estruturas. Abaixo está o manifesto de um array com 25 estruturas do tipo coordenadas:
Código PHP:
Código:
struct coordenadas arrayCoord[24];  

Lembre-se que os elementos dos arrays são numerados a partir de 0 (zero). Neste caso, os elementos são numerados de 0 a 24, perfazendo 25 elementos. Se quisermos acessar o "x" do sexto elemento, escrevemos:
Código PHP:
Código:
arrayCoord[5].x = 48;  


Um bom exemplo de uso
O número de estruturas possíveis é praticamente infinito. As estruturas podem ser modeladas de acordo com a necessidade e o projeto. De qualquer forma, são extremamente versáteis e permitem atribuir, obter e modificar dados com facilidade. Veja um exemplo prático, como se fosse um registro de uma tabela de dados:
Código PHP:
Código:
struct mailsRecebidos { 
   int IDmail; 
   time_t data_hora; 
   char *Remetente; 
   char *Assunto; 
   char *Texto; 
   char *Anexos; 
};  

Esta estrutura, de nome mailsRecebidos, é composta pelos seguintes campos: um número inteiro para armazenar a identificação do email (IDmail), um time_t (tipo time) para armazendar a data e a hora (data_hora) e mais quatro campos com endereços apontando para o início de uma string de caracteres.


Uniões
Código PHP:
Código:
union inteiroFlutuante { 
   int i; 
   double d; 
};  

Sabemos que um número inteiro (int), no lcc-win32, possui o tamanho 4 e que o um número de precisão dupla (double) ocupa 8 bits. Para poder acomodar qualquer um dos dois valores declarados, é claro que esta união vai reservar 8 bits. Num dado momento, apenas um dos números poderá ser armazenado, nunca os dois juntos. E qual é a vantagem que Maria leva?

Bem, uma união funciona mais ou menos como um rascunho ocupando um número fixo de bits na memória. Imagine o seguinte: num determinado programa manifestamos um montão de estruturas ligeiramente diferentes que nunca serão usadas simultaneamente. No momento em que forem definidas e receberem valores, cada uma delas ocupará determinado espaço na memória. Quando tivermos usado cada uma delas, uma grande área da memória estará alocada, mas apenas uma pequena porção, referente à estrutura em uso no momento, estará sendo utilizada.

É aí que está o pulo do gato: empacotamos as estruturas numa união. A união reserva um espaço correspondente à maior estrutura da lista e o resultado é que trocamos a soma dos espaços necessários para cada estrutura pelo espaço necessário para a maior delas. Cada vez que quisermos trabalhar com uma das estruturas, podemos copiar a mesma para a união porque temos a certeza de que haverá espaço suficiente para contê-la.

Resumindo: uniões são uma forma prática e elegante de economizar memória!

Ver o tópico anterior Ver o tópico seguinte Ir para o topo  Mensagem [Página 1 de 1]

Permissões de Postagem

Permissões neste sub-fórum
Não podes responder a tópicos