Tutorial - Aplicações gráficas (GUI) - C/C++

Started by Dark_Side, 08 de July , 2006, 06:11:26 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Dark_Side

GUI Tutorial - Parte 1 - C++
by Dark_Side


Hi,
Em resposta a um tópico sobre como desenvolver aplicações com interface gráfica, escrevei este texto para dar uma ajudinha.

Conteúdo:

1) Introdução
2) Pré-requisitos
3) Primeiro projeto
4) Primeira Janela
5) Informações úteis

Introdução
*******************************************************

Ao aprender C/C++, geralmente, se aprende a deselvolver programas no console certo? Se por acaso, tivéssimos que desenvolver um programa onde existam caixas de textos, botões, listas de itens, etc? É nesta parte que entra a GUI - Graphical User Interface ou Interface Gráfica do Usário, ou simplesmente "interface gráfica" - uma tecnologia utilizada em sistemas operacionais para aplicar ao software, ícones, gráficos, controle por mouse, dentre outros, com o objetivo de fazer com que o usuário interaja com o tal software.

Neste tutorial, demonstrarei os principais fundamentos, exemplos da programação GUI em ambiente WIN32.


Pré-requisitos
*******************************************************
Antes de continuar, tenha em mente que:

»» Você precisa de um conhecimento básico/razoável na linguagem C/C++.
»» Obiviamente, é necessário um compilador em ambiente WINDOWS. É recomendável o uso do Microsoft Visual C++, pois abrange um maior números de rescursos para programar no sistema nativo. Pode-se utilizar também o DEV C++, ou outro de sua preferência.
»» Você precisa de paciência :)..

Primeiro projeto
********************************************************
1) Crie um novo projeto -> Window Application.
2) Adicione ao projeto o arquivo : "main.cpp"
3) Adicione o seguinte código ao arquivo criado:
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    MessageBox(NULL, "CHEGA DE HELL WORLD!", "MENSAGEM", MB_OK);
    return 0;
}

Compile e execute o projeto.

Vamos analisar:
#include
Todo programa WINDOWS deve incluir este header.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

Esta função é a equivalente do Windows, para a função main() do console.

WINAPI -> Indica que que a chamada é definida como "_stdcall".

Seus argumentos:

HINSTANCE hInstance -> Handle (identificação) do programa no sistema. É por este valor que se controla quando um aplicativo está executando ou é encerrado. É usado para carregar recursos como ícones, ou DLLS.

HINSTANCE hPrevInstance -> É um valor sempre nulo nos programa WIN32.Em win32, é ignorado.

LPSTR lpCmdLine -> Retorna a linha de comando, como uma string (LPSTR = char*), não incluindo o nome do executável
.

int nCmdShow -> Retorna o estado inicial da janela, para mudá-lo, utilizamos a função SHOW_WINDOW.

    MessageBox(NULL, "CHEGA DE HELL WORLD!", "MENSAGEM", MB_OK);
É uma função da API, responsável por exibir uma mensagem, para mais informações, consulte o tópico sobre API do Windows:

    return 0;  -> Fim do programa

Primeira Janela
**********************************************************
Veja o código:
#include <windows.h>

LRESULT CALLBACK WinProc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)

{

HWND hwnd;
WNDCLASSEX win;
MSG message;

win.cbClsExtra=0;
win.cbSize=sizeof(win);
win.cbWndExtra=0;
win.hbrBackground=GetSysColorBrush(COLOR_WINDOW);
win.hCursor=LoadCursor(NULL,IDC_ARROW);
win.hIcon=LoadIcon(NULL,IDI_APPLICATION);
win.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
win.hInstance=hInstance;
win.lpfnWndProc=WinProc;
win.lpszClassName="Janela";
win.lpszMenuName=NULL;
win.style=0;
if(!RegisterClassEx(&win))
return 0;
hwnd = CreateWindowEx(0,"Janela","Minha janelinha",WS_OVERLAPPED|WS_SYSMENU,300,100,400,400,NULL,NULL,hInstance,NULL);

if(hwnd == NULL)
return 0;

ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);

while(GetMessage(&message,0,0,0)){
 TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;

}

LRESULT CALLBACK WinProc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam){

switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(window);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(window, msg, wParam, lParam);
}
return 0;

}
Vamos por partes:

1 Passo -  Registrando classe da janela
*************************************************
WNDCLASSEX win; -> Declara variável para a classe da janela

win.cbClsExtra=0; -> Quantidade extra de dados alocados na meória pela classe

win.cbSize=sizeof(win); -> Tamanho da estrutura

win.cbWndExtra=0; -> Quantidade extra de dados alocados na meória pela classe por cada janela do tipo especifidado.

win.hbrBackground=GetSysColorBrush(COLOR_WINDOW); -> Cor de fundo da janela

win.hCursor=LoadCursor(NULL,IDC_ARROW); -> Ponteiro do mouse

win.hIcon=LoadIcon(NULL,IDI_APPLICATION); -> O ícone da janela

win.hIconSm=LoadIcon(NULL,IDI_APPLICATION); -> Ícone da janela quando é pressionado ALT+TAB.

win.hInstance=hInstance; -> Instância da janela, o mesmo valor declarado em WinMain.

win.lpfnWndProc=WinProc; -> Função que irá receber as mensagens enviadas à nossa janela. Esta é a função que controla os eventos, como cliques, movimento de mouse, etc.
 
win.lpszClassName="Janela"; -> Nome da classe da janela

win.lpszMenuName=NULL; ->Especifica o nome de do menu a ser utilizado na janela.

win.style=0; -> Especifica o tipo inicial da janela.

if(!RegisterClassEx(&win)) -> Registra nossa classe, caso ocorra um erro, o programa encerra.
return 0;

2 Passo -  Criando a janela;
*************************************************
hwnd = CreateWindowEx(0,"Janela","Minha janelinha",
WS_OVERLAPPED|WS_SYSMENU,300,100,400,400,
NULL,NULL,hInstance,NULL);

Analisando:
Janela = nome da classe
Minha Janelinha = título da janela
WS_OVERLAPPED = estilo da janela - Fixa
WS_SYSMENU = janela com os botões superiores
300 = posição horizontal (left)
100 = posição vertical (top)
400 = largura da janela
400 = altura da janela
NULL = HWND pai
NULL = O menu criado para janela
Hinstace = instância -> WinMain
NULL = Representa um valor lParam -> caiu em desuso.

if(hwnd == NULL) -> Verifica se a janela foi criada, senão, encerra.
return 0;

ShowWindow(hwnd,SW_SHOW);  -> Mostra a janela.
UpdateWindow(hwnd); -> Atualiza-a.

3 Passo -  LOOP de Mensagens;
*************************************************
Os programas WIN32, executam enquanto estiverem recebendo "mensagens", que por sua vez, são interpretadas e "filtradas", executando uma certa ação.
 
O processo é feito pela seguinte trecho:

while(GetMessage(&message,0,0,0)){ -> Enquanto estiver recebendo mensagens..

TranslateMessage(&message); -> "Traduz" a mensagem, para que possar ser lida.

DispatchMessage(&message); -> Envia a menssagem para a função que irá interpretá-la.
}
return message.wParam; -> Retorna um valo, quando o loop é interrompido.


4 Passo -  WinProc
*************************************************
Esta função, como já foi dito, recebe as mensagens enviadas pelo programa e executa uma determinada ação para cada tipo.

LRESULT CALLBACK WinProc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam){

switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(window);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(window, msg, wParam, lParam); -> Retorna mensagens não geradas para o WinProc.
}
   return 0;

}

window - hwnd da nossa janela.
msg - mensagem recebida
WPARAM - parâmetro 1 da mensagem
LPARAM - parâmetro 2 da mensagem


Algumas Constantes, Estilos de Janelas, Cursores e Mensagem

********************************************************
Até agora demonstrei valores utilizados no exemplo inicial, listarei agora, outros valores que você poderá utilizar.


Estilos de Janela:
WS_BORDER -> Borda fina
WS_CAPTION -> Barra de título e borda fina
WS_CHILD/WS_CHILDWINDOW -> Janela filha
WS_DISABLED -> Desabilitada
WS_DLGFRAME -> Borda usada em dialogs.
WS_HSCROLL/WS_VSCROLL -> Adiciona barra de rolagem horizontal(HSCROLL) e vertical(VSCROLL)
WS_MAXIMIZE -> Janela maximizada
WS_MAXIMIZEBOX /WS_MINIMIZEBOX -> Botões maximizar e minimizar
WS_MINIMIZE -> Janela minimizada
WS_OVERLAPPED -> Borda fixa e barra de título
WS_OVERLAPPEDWINDOW -> Padrão
WS_POPUP -> Janela POPUP
WS_SIZEBOX -> Janela que pode ser redimensionada
WS_SYSMENU -> Define a janela com o menu comum.
WS_TABSTOP -> Define o possível recebimento de focus, pela tecla TAB
WS_VISIBLE -> Janela iniciamente visível
Cursores:
IDC_ARROW -> Padrão
IDC_CROSS -> Cruz
IDC_IBEAM -> Cursor editando
IDC_ICON -> Ícone
IDC_NO -> Sem cursor
IDC_SIZE -> Redimesionar
IDC_SIZEALL -> Mover/Redimesionar
IDC_SIZENESW -> Redimensionar
IDC_SIZENS -> Redimensionar
IDC_SIZENWSE -> Redimensionar
IDC_SIZEWE -> Redimensionar
IDC_UPARROW -> Seta para cima
IDC_WAIT -> Ocupado
ÍCONES:
IDI_APPLICATION -> Padrão
IDI_ASTERISK -> Informação
IDI_EXCLAMATION -> Exclamação
IDI_HAND ->HiperLink
IDI_QUESTION -> Ajuda
IDI_WINLOGO -> Logon

CORES:
COLOR_ACTIVEBORDER
COLOR_ACTIVECAPTION
COLOR_APPWORKSPACE
COLOR_BACKGROUND
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_BTNTEXT
COLOR_CAPTIONTEXT
COLOR_GRAYTEXT
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_INACTIVEBORDER
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_MENUTEXT
COLOR_SCROLLBAR
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_WINDOWTEXT

Mensagens:
WM_ACTIVATE -> Recebe focus
WM_CLOSE -> Fechar janela
WM_COPY -> Copiar
WM_CREATE -> Criação da janel
WM_CUT -> Recortar
WM_DESTROY -> Sair
WM_ENABLE -> Torna habilitade
WM_KEYDOWN -> Tecla pressionada
WM_LBUTTONDNLCLK -> Botão Esquerdo - 2 cliques
WM_LBUTTONDOWN -> Botão Esquerdo - 1 clique
WM_MBUTTONDBLCLK -> Botão Central - 2 clqiues
WM_MBUTTONDOWN -> Botão Central - 1 clique
WM_MOUSEMOVE -> Movimento do mouse
WM_MOUSEWHEEL -> Rodinha do mouse
WM_MOVE -> Movimento da janela
WM_PAINT -> Implementação dos objetos na janela
WM_PASTE -> Colar
WM_QUIT -> Sair
WM_RBUTTONDNLCLK -> Botão Direito - 2 Cliques
WM_RBUTTONDOWN -> Botão Direito - 1 Clique
WM_SETFOCUS -> Recebe focus
WM_SIZE -> Janela Redimensionada
Muito bem, chegamos ao fim da primeira parte do tutorial. No próximo post, demonstrarei como utilizar controles comuns do windows como : labels, botões, caixas de texto, etc. Vou mostrar também como criar DialogBox, e personalizá-lo.

Até...
Bye.

HadeS


Mental_Way

[RitualistaS GrouP]

"Aquele que sabe pouco rapidamente revela isto."

insanity


Dark_Side

C++ GUI Tutorial - Parte 2
By Dark_Side


Hi, vamos dar continuação ao nosso tutorial.

Hoje aprenderemos como criar e manipular alguns controles comuns do Windows.

Muito bem, na primeira parte, aprendemos como um programa Windows é iniciado, alguns argumentos de inicialização, registro de classes, criação da janela e sobre o LOOP de mensagens.Vimos também um exemplo de uma janela vazia.Aprenderemos a seguir, como "enfeitar" nossa janela com os famosos controles do windows: labels, caixas de texto, etc.


Criando e utilizando controles comuns do Windows
***************************************************
Lembra-se de como criamos a nossa primeira janela?
Utilizamos a função CreateWindowEx. Usaremos essa mesma função para criar nossos controles.


Observe:

HWND hwnd;
hwnd = CreateWindow(0,CLASSE,TÍTULO/CAPTION,ESTILO,Horizontal,Vertical,Largura,Altura,HWND-PAI,ID,INSTÂNCIA,lParam);

Entendendo:

CLASSE -> Literalmente, é a classe a qual o objeto pertence.
TÍTULO/CAPTION -> Texto/título do referido objeto.
ESTILO -> Modo de exibição do objeto.
Horizontal -> posição horizontal.
Vertical -> posição vertical.
Altura -> altura do objeto.
HWND-Pai -> Identificação do objeto principal, onde o controle no nosso caso, será criado.
ID -> Identifação do nosso objeto.
INSTÂNCIA -> Propriedade HINSTANCE do objeto principal. (Opicional)
lParam -> Não utilizado.

Exemplo simples - Criando um Label:

#define lb1 1
HWND label1;
label1  = CreateWindowEx(0,"STATIC","OLÁ!",WS_CHILD|WS_VISIBLE,0,0,100,20,HWND-MAIN,(HMENU)lb1,NULL,0);

STATIC -> Classe do LABEL
OLÁ -> Título
WS_CHILD -> Indica que o objeto fica "dentro" de outro.
WS_VISIBLE -> Mostra nosso objeto.
0 -> Posição horizontal
0 -> Posição vertial
100 -> Larguda
20 -> Altura
HWND-MAIN -> HWND do WinProc
(HMENU)lb1 -> Converte o valor de lb1 (nome do nosso objeto) para o dado correto (HMENU).
NULL -> Instância
0 -> lParam

Você deve estar se perguntando:  Onde eu coloco isso?
Bem, existem diversas maneiras de você implementá-lo, vou mostrar duas:

1) Logo após a criação da janela principal. Exemplo:

#define lb1 1
[...]
hwnd = CreateWindowEx(0,"Janela","Minha janelinha",WS_OVERLAPPED|WS_SYSMENU,300,100,400,400,NULL,NULL,hInstance,NULL);
HWND label1;
label1  = CreateWindowEx(0,"STATIC","OLÁ!",WS_CHILD|WS_VISIBLE,0,0,100,20,HWND-MAIN,(HMENU)lb1,NULL,0);
[...]

2) Após o programa receber a mensagem que foi iniciado com sucesso: WM_CREATE. Exemplo:
#define lb1 1
[...]
switch(msg)
    {
case WM_CREATE:
HWND label1;
label1  = CreateWindow(0,"STATIC","OLÁ!",WS_CHILD|WS_VISIBLE,10,10,100,20,window,(HMENU)lb1,NULL,0);
break;
}
[...]

Muito bem, mostrarei agora, algumas classes e estilos dos controles mais comuns:

Label:
************************
Classe: STATIC
Estilos comuns:
SS_SIMPLE -> Simples
WS_EX_TRANSPARENT -> Transparente

Caixa de Texto:
************************
Classe: EDIT
Estilos comuns:
ES_AUTOVSCROLL -> Rolagem vertical automática.
ES_AUTOHSCROLL -> Rolagem horizontál automatica.
ES_MULTILINE -> Múltiplas linhas
ES_NUMBER -> Apenas números
ES_OEMCONVERT -> Converte caracters DOS para fonte normal.
ES_PASSWORD -> Password (não se combina com ES_MULTILINE).
ES_READONLY -> Apenas leitura
ES_UPPERCASE -> Apenas caixa alta
WS_HSCROLL -> Barra de rolagem horizontal (Necessita ES_MULTILINE)
WS_VSCROLL -> Barra de rolagem vertical (Necessita ES_MULTILINE)

Botão:
********************
Classe: BUTTON
Estilos comuns:
BS_DEFPUSHBUTTON -> Botão DEFAULT

CheckBox
********************
Classe: BUTTON
Estilos OBRIGATÓRIOS: BS_AUTOCHECKBOX
Estilos comuns:
BS_AUTO3STATE -> 3 Possibilidades: Marcado, Semi-Marcado e Não-Marcado.

RadioButton
********************
Classe: BUTTON
Estilos OBRIGATÓRIOS: BS_RADIOBUTTON

ListBox
********************
Classe: LISTBOX
Estilos comuns:
LBS_MULTICOLUMN -> Múltiplas colunas
LBS_MULTIPLESEL -> Seleção múltipla
LBS_SORT -> Classifica itens por ordem alfabéticaWS_HSCROLL -> Rolagem horizontal
WS_VSCROLL -> Rolagem vertical

ComboBox
********************
CLASSE: COMBOBOX
Estilos Comuns:
CBS_DROPDOWN -> Seleção/Escrita
CBS_DROPDOWNLIST ->Apenas seleção de itens
CBS_SORT -> Classifica itens em ordem alfabética
WS_HSCOLL -> Rolagem horizontal
WS_VSCROLL -> Rolagem vertical

Estilos OBRIGATÓRIOS à todos os controles:
WS_VISIBLE -> Torna os controles visíveis, dispensando o uso de ShowWindow().
WS_CHILD -> Aclopam o controle dentro da janela.

Estilos comuns à todos os controles:
WS_BORDER -> Adiciona borda ao controle
WS_DISABLED -> Cria o controle iniciamente disabilitado.
WS_TABSTOP -> Permite que o controle receba FOCO pela tecla TAB.

Bem, temos outros controles, por enquanto aprensentarei apenas estes.


Funções comuns à maioria dos controles:

*******************************************
Habilitando/Desabilitando o controle:

EnableWindow(hwnd,valor);
hwnd -> HWND do controle.
valor -> 1 (true - habilitado) ou 0 (false - disabilitado)


Adicionando/Modificando um texto:


SetWindowText(hwnd,texto);
hwnd -> HWND do controle.
texto -> Texto a ser adicionado.

Obtendo um texto:

char buffer[256];
GetWindowText(hwnd,buffer,256);
hwnd -> HWND do controle.
buffer -> variável que receberá o texto
256 -> tamanho do buffer.


Trabalhando com CheckBox e RadioButtons:

*******************************************
Verificando estados:

int estado;
estado =  SendMessage(hwnd,BM_GETCHECK,0,0);
if(x==BST_CHECKED){
//Marcado
}
else
{
//Desmarcado
}

hwnd -> HWND do controle.
BM_GETCHECK -> Mensagem:: Checar estado.
0 -> WPARAM
0 -> Lparam

BST_CHECKED -> Marcado
BST_UNCHECKED -> Desmarcado


Trabalhando com ListBox:

*******************************************

Adicionando um item:

SendMessage(hwnd,LB_ADDSTRING,0,(LPARAM)item);
hwnd -> HWND do controle.
LB_ADDSTRING -> mensagem enviada ao listbox para adicionar um item.
0 -> WPARAM não utilizado.
(LPARAM)item -> converte e adiciona o item desejado.

Obtendo posição de um item selecionado:

int pos;
pos = SendMessage(hwnd,LB_GETCURSEL,0,0);
pos -> Inteiro que receberá a posição do item.
hwnd -> HWND do controle.
LB_GETCURSEL -> Mensagem:: obtém o item selecionado.
0 -> WPARAM
0 -> LPARAM

Obtendo texto de um item:

char buffer[256];
SendMessage(hwnd,LB_GETTEXT,(WPARAM)index,(LPARAM)buffer);
hwnd -> HWND do controle.
LB_GETCURSEL -> Mensagem:: obtém o  texto do item.
(WPARAM)index -> Posição do item a receber o texto.
(LPARAM)buffer -> Converte e armazena o texto do item INDEX no buffer.

Deletando um item:

SendMessage(hwnd,LB_DELETESTRING,(WPARAM)index,0);
hwnd -> HWND do controle.
LB_DELETESTRING -> Mensagem:: deleta um item.
(WPARAM)index -> Posição do item a deletar.

Modificando um item:

SendMessage(hwnd,LB_INSERTSTRING,(WPARAM)index,(LPARAM)valor);
hwnd -> HWND do controle.
LB_DELETESTRING -> Mensagem:: modifica um item.
(WPARAM)index -> Posição do item a modificar.
(LPARAM)valor -> Novo texto do item.

Trabalhando com ComboBox:
*******************************************

Adicionando um item:

SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)item);
hwnd -> HWND do controle.
CB_ADDSTRING -> mensagem enviada ao listbox para adicionar um item.
0 -> WPARAM não utilizado.
(LPARAM)item -> converte e adiciona o item desejado.

Obtendo posição de um item selecionado:

int pos;
pos = SendMessage(hwnd,CB_GETCURSEL,0,0);
pos -> Inteiro que receberá a posição do item.
hwnd -> HWND do controle.
CB_GETCURSEL -> Mensagem:: obtém o item selecionado.
0 -> WPARAM
0 -> LPARAM

Obtendo texto de um item:

char buffer[256];
SendMessage(hwnd,CB_GETTEXT,(WPARAM)index,(LPARAM)buffer);
hwnd -> HWND do controle.
CB_GETCURSEL -> Mensagem:: obtém o  texto do item.
(WPARAM)index -> Posição do item a receber o texto.
(LPARAM)buffer -> Converte e armazena o texto do item INDEX no buffer.

Deletando um item:

SendMessage(hwnd,CB_DELETESTRING,(WPARAM)index,0);
hwnd -> HWND do controle.
CB_DELETESTRING -> Mensagem:: deleta um item.
(WPARAM)index -> Posição do item a deletar.

Modificando um item:

SendMessage(hwnd,CB_INSERTSTRING,(WPARAM)index,(LPARAM)valor);
hwnd -> HWND do controle.
CB_DELETESTRING -> Mensagem:: modifica um item.
(WPARAM)index -> Posição do item a modificar.
(LPARAM)valor -> Novo texto do item.

Exemplos de uso
***************************************************

Exemplo 1:
Utilizando: CAIXA DE TEXTO e RADIOBUTTON.
#include <windows.h>
//Definimos um nome para os controles
#define t_1 1
#define r_1 2
#define r_2 3

//HWND dos controles
HWND txt;
HWND radio1,radio2;

LRESULT CALLBACK WinProc(HWND window,UINT msg, WPARAM
wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
MSG message;
HWND hwnd;
WNDCLASSEX wc;
wc.cbClsExtra=0;
wc.cbSize=sizeof(wc);
wc.cbWndExtra=0;
wc.hbrBackground=GetSysColorBrush(COLOR_BTNFACE);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
wc.lpfnWndProc=WinProc;
wc.lpszClassName="Janela";
wc.lpszMenuName=NULL;
wc.style=0;
RegisterClassEx(&wc);
hwnd = CreateWindowEx(0,"Janela","EXEMPLO 1",WS_OVERLAPPED|WS_SYSMENU,200,200,400,120,NULL,NULL,NULL,NULL);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
while(GetMessage(&message,0,0,0)){
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam ;

}
LRESULT CALLBACK WinProc(HWND window,UINT msg, WPARAM wParam,LPARAM lParam){
switch(msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;

case WM_CREATE: //No processo de criação da janela
txt = CreateWindowEx(0,"EDIT","" ,WS_CHILD|WS_VISIBLE|WS_BORDER,10,10,370,20,window,(HMENU)t_1,0,0); //Cria nosso textbox
radio1 = CreateWindowEx(0,"BUTTON","Obter nome do usuário",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,10,50,240,15,window,(HMENU)r_1,0,0); //Cria o primeiro radiobutton
radio2 = CreateWindowEx(0,"BUTTON","Sair do programa" ,WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,240,50,240,15,window,(HMENU)r_2,0,0); //Cria o segundo
break;
case WM_COMMAND: //Mensagem enviada quando se clica em um controle
switch(wParam) //Verifica o parâmetro
{
case r_1: //Caso seja o primeiro radiobutton

//Obtém o nome do usuário
char buffer[256];
DWORD size;
size=256;
GetUserName(buffer,&size);
SetWindowText(txt,buffer); //Mostra no textbox
break;
case r_2: //Caso seja o segundo
ExitProcess(0); //Encerra

} break;
default:
return DefWindowProc(window,msg,wParam,lParam);
}
return 0;
}


Exemplo 2:
Utilizando: LABEL, CAIXA DE TEXTO, COMBOBOX e BOTÃO .

#include <windows.h>
//Nomes para os controles
#define lb1 1
#define txtbox 2
#define combo 3
#define btn 4

//HWND do controles
HWND label1;
HWND txt1;
HWND combo1;
HWND bot1;

LRESULT CALLBACK WinProc(HWND window,UINT msg, WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
MSG message;
HWND hwnd;
WNDCLASSEX wc;
wc.cbClsExtra=0;
wc.cbSize=sizeof(wc);
wc.cbWndExtra=0;
wc.hbrBackground=GetSysColorBrush(COLOR_BTNFACE);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
wc.lpfnWndProc=WinProc;
wc.lpszClassName="Janela";
wc.lpszMenuName=NULL;
wc.style=0;
RegisterClassEx(&wc);
hwnd = CreateWindowEx(0,"Janela","EXEMPLO 1",WS_OVERLAPPED|WS_SYSMENU,200,200,400,100,NULL,NULL,NULL,NULL);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
while(GetMessage(&message,0,0,0)){
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam ;

}
LRESULT CALLBACK WinProc(HWND window,UINT msg, WPARAM wParam,LPARAM lParam){
switch(msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_CREATE: //Processo de criação da janela
label1 = CreateWindowEx(0,"STATIC","Texto:" ,WS_CHILD|WS_VISIBLE,10,10,40,20,window,(HMENU)lb1,0,0);
txt1 = CreateWindowEx(0,"EDIT","" ,WS_CHILD|WS_VISIBLE|WS_BORDER,60,10,140,20,window,(HMENU)txtbox,0,0); //Cria label
combo1 = CreateWindowEx(0,"COMBOBOX","" ,WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,230,10,140,400,window,(HMENU)combo,0,0); //Cria ComboBox
bot1 = CreateWindowEx(0,"BUTTON","Adicionar texto..." ,WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,140,40,120,20,window,(HMENU)btn,0,0); //Cria botão

break;
case WM_COMMAND: //Mensagem enviada quando um controle é clicado:
switch(wParam) //Verifica parâmetro
{
case btn: //Se for o botão
//Obtém conteúdo do textbox.
char buffer[256];
GetWindowText(txt1,buffer,256);
//Adiciona este no combobox. SendMessage(combo1,CB_ADDSTRING,0,(LPARAM)buffer);
} break;
default:
return DefWindowProc(window,msg,wParam,lParam);
}
return 0;
}


Exemplo 3:
Utilizando: CHECKBOX, LISTBOX e BOTÃO.
#include <windows.h>
//Nomes dos controles
#define check 1
#define list 2
#define btn_add 3
#define btn_del 4

//HWND dos controles
HWND check1;
HWND list1;
HWND bot1,bot2;

LRESULT CALLBACK WinProc(HWND window,UINT msg, WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
MSG message;
HWND hwnd;
WNDCLASSEX wc;
wc.cbClsExtra=0;
wc.cbSize=sizeof(wc);
wc.cbWndExtra=0;
wc.hbrBackground=GetSysColorBrush(COLOR_BTNFACE);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
wc.lpfnWndProc=WinProc;
wc.lpszClassName="Janela";
wc.lpszMenuName=NULL;
wc.style=0;
RegisterClassEx(&wc);
hwnd = CreateWindowEx(0,"Janela","EXEMPLO 1",WS_OVERLAPPED|WS_SYSMENU,200,200,400,200,NULL,NULL,NULL,NULL);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
while(GetMessage(&message,0,0,0)){
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam ;

}
LRESULT CALLBACK WinProc(HWND window,UINT msg, WPARAM wParam,LPARAM lParam){
switch(msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_CREATE: //Processo de criação da janela
check1 = CreateWindowEx(0,"BUTTON","Manipular ListBox" ,WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,10,10,150,20,window,(HMENU)check,0,0); //Criamos o checkbox
list1 = CreateWindowEx(0,"LISTBOX","" ,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL,240,10,145,150,window,(HMENU)list,0,0); //Criamos a Listbox
bot1 = CreateWindowEx(0,"BUTTON","Adicionar Item" ,WS_CHILD|WS_VISIBLE|WS_DISABLED,10,35,100,20,window,(HMENU)btn_add,0,0); //Criamos o botão para adicionar item
bot2 = CreateWindowEx(0,"BUTTON","Remover Item" ,WS_CHILD|WS_VISIBLE|WS_DISABLED,120,35,100,20,window,(HMENU)btn_del,0,0); //Criamos o botão para deletar item.

break;
case WM_COMMAND: //Mensagem enviada quando um controle é clicado:
switch(wParam) //Verifa o parâmetro
{
case check: //Se for o checkbox
int estado; //Variável Retorno
estado = SendMessage(check1,BM_GETCHECK,0,0); //Verfica estado
if(estado==BST_CHECKED){ //Se checado, habilita os botões
EnableWindow(bot1,1);
            EnableWindow(bot2,1);
}
else //Se não, os desabilitada.
{
EnableWindow(bot1,0);
            EnableWindow(bot2,0);
}break;
case btn_add: //Se for o botão para adicionar itens
SendMessage(list1,LB_ADDSTRING,0,(LPARAM)"ITEM"); //Adicione "ITEM" à Listbox
break;
case btn_del: //Se for o botão para deletar
int pos;//Variável Retorno
pos = SendMessage(list1,LB_GETCURSEL,0,0); //Verifica posição
if(pos==-1) //Se for -1 (nenhum item)
MessageBox(window,"Nenhum item selecionado!","ERRO",MB_OK|MB_ICONINFORMATION);
else //Se não
SendMessage(list1,LB_DELETESTRING,(WPARAM)pos,0); //Deleta o item selecionado.
break;

} break;
default:
return DefWindowProc(window,msg,wParam,lParam);
}
return 0;
}


Considerações finais
***************************************************
Hoje apredemos a utilizar alguns controles padrões do Windows. No próximo tutorial, aprenderemos como utilizar arquivos de recurso, e veremos que é algo muito interessante que nos permite a trabalhar com aplicações gráficas de modo mais simples, eficiente, e menos cansativo.Fico devendo também, a criação de DialogBox's, que estará presente no próximo tutorial.
Bye.

Skayler

Away

Dark_Side

C++ GUI Tutorial - Parte 3
By Dark_Side


Hi, após um tempo parado, gogo.

Nesta parte do tutorial, aprenderemos o que são arquivos de recurso, como criar DialogBox's e trabalhar com estes, e veremos como trabalhar com controles neste novo recurso.

Arquivos de recurso
***************************************************
Se você acompanhou as partes 1 e 2 do tutorial, percebeu que todo o trabalho poderia ser feito apenas utilizando a API do Windows. Dependendo do projeto que se deseja desenvolver, este trabalho se torna cansativo e utilizar arquivos de recurso nesta hora, é uma grande vantagem.
Mas afinal, o que são estes arquivos de recurso?
Bem, arquivos de recurso são acima de tudo arquivos (lol), têm extensão .RC, e quando compilados, são transformados em arquivos .RES. O seu papel é configurar os objetos, controles, e gráficos que serão adicionados ao programa.

Para facilitar, existem programas e até mesmos compiladores que acompanham um editor de recursos visual, isto é, você pode adicionar, deletar, e modificar controles e gráficos, de forma semelhante ao Delphi, Visual Basic, etc.

Particularmente, prefiro utilizar o Visual C++ para esse trabalho.
Caso esteja utilizando um compilador que não possua um Editor Visual de recursos, você pode utilizar o ResEd:
http://www.radasm.com/projects/ResEd.zip
Uma ótima opção gratuita.

Obs: O DEV C++, pode compilar arquivos de recursos, porém não pode editá-los visualmente.

Uma informação: A linguagem utilizada nos arquivos de recurso é a Resource Script Language ou RSL.


DialogBox's
***************************************************
Antes de mais nada, DialogBox's, são caixas de diálogo que podem assumir um comportamento de uma janela comum, podendo conter objetos, gráficos, controles, etc.
A principal vantagem de usá-los, é que o trabalho necessário para criar suas aplicações é menor, além de ser mais simples - como já foi dito, há a possibilidade de trabalhar visualmente.

Observe:
recurso.h
#define DIALOGBOX 100
#define txt1 101
recurso.rc
#include "recurso.h"
DIALOGBOX DIALOG DISCARDABLE  0, 0, 186, 90
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Hello world não..."
FONT 8, "MS Sans Serif"
BEGIN
    EDITTEXT        txt1,25,20,120,14,ES_AUTOHSCROLL
END

Vamos analisar por partes:
#define DIALOGBOX 100
#define txt1 101
Como já foi dito, são definidos os nomes dos controles.

#include "recurso.h"
Inclui o header com o nome dos controles do DialogBox. Pode-se adicionar diretamente os nomes.

Exemplo:
#define DIALOGBOX 100
#define txt1 101
DIALOGBOX DIALOG DISCARDABLE  0, 0, 186, 90
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Hello world não..."
FONT 8, "MS Sans Serif"
BEGIN
    EDITTEXT        txt1,25,20,120,14,ES_AUTOHSCROLL
END

Muito bem, continuando:
DIALOGBOX DIALOG DISCARDABLE  0, 0, 186, 90
DIALOGBOX => Nome definido em recurso.h
DIALOG DISCARDABLE => Define o objeto como um dialogbox
0 => Posição vertical
0 => Posição horizontal
186 => Altura
90 => Largura

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
STYLE => Define o início dos estilos do DialogBox.
DS_MODALFRAME => Quadro fixo
WS_POPUP => Janela POP UP
WS_CAPTION => Mostra barra de título
WS_SYSMENU => Mostra botões padrões, no caso, apenas o botão FECHAR [X].

Lembrando que para se adicionar os botões Minimizar e Maximizar, utilizamos, respectivamente: WS_MINIMIZEBOX e WS_MAXIMIZEBOX.

CAPTION "Hello world não..."
Título do DialogBox.

FONT 8, "MS Sans Serif"
Fonte padrão do Dialog, no caso, MS Sans Serif, tamanho 8.

BEGIN
    EDITTEXT        txt1,25,20,120,14,ES_AUTOHSCROLL
END

BEGIN => Inicia a configuração dos objetos do DialogBox.

EDITTEXT        txt1,25,20,120,14,ES_AUTOHSCROLL

EDITTEXT => Adiciona um textbox
txt1 => Nome definido em recurso.h
25 => Posição vertical
20 => Posição horizontal
120 => Altura
14 => Largura
ES_AUTOHSCROLL => Estilo adicional (rolagem horizontal automática). Podemos adicionar outros estilos, utilizando PIPE. Exemplo: ES_AUTOHSCROLL | WS_DISABLED.

END => Fim da configuração

Acima, foi demonstrada a estrutura básica de um DialogBox feito com arquivo de recurso. O arquivo acima foi feito manualmente, portanto, se você abrir o arquivo de recurso gerado pelo seu editor visual, outras configurações podem estar presentes, mas nada que altere a função principal do arquivo.

Criando um DialogBox com o Visual C++ 6.0
**************************************************
1) Vá até Insert » Resource ou pressione CTRL+R.


2) Escolha Dialog e em seguinda, em NEW.


3)Uma nova tela se abrirá contendo um DialogBox básico, contendo os botões: OK e CANCEL. Próximo ao dialog, uma caixa deve aparecer contendo os controles que poderão ser adicionados a este.

Obs: Você pode pré-vizualizar o seu DialogBox, pressionando CTRL+T ou acionando do menu Layout » Test.

4) Salve os arquivos: SCRIPT1.RC e resource.h (os nomes podem ser diferentes, contanto que sejam adicionados ao projeto mais tarde).

Criando um DialogBox com o ResEd
**************************************************
1) Vá até File » New, digite um nome para o arquivo e clique em Salvar.

2) Vá até Project » Add Dialog:


3) Uma nova tela se abrirá contendo um DialogBox em branco. Ao lado, você verá os controles disponíveis:


4) Salve o arquivo.

Obs 1: Você pode pré-vizualizar o seu DialogBox: Vá até o menu View » Preview dialog.
Obs 2: O ResEd, não gera um HEADER automaticamente. Você deve definir os nomes gerados no arquivo .RC manualmente em um header ou no arquivo principal. Exemplo:

//Arquivo de recurso criado com o ResEd
#define IDD_DLG1 1000
IDD_DLG1 DIALOGEX 6,6,194,102
CAPTION "IDD_DLG"
FONT 8,"MS Sans Serif",0,0
STYLE 0x10CF0000
BEGIN
END
Você deverá criar um arquivo header (.H) ou incluir no arquivo principal:

#define IDD_DLG1 1000
Observe que os nomes e constantes devem ser iguais.

Trabalhando com DialogBox's
***************************************************
Bem, após termos criado o arquivo de recurso e nele configurado nosso dialog, veremos agora como fazer com ele que seja exibido no programa e também, como manipulá-lo.

1) Criamos um projeto para Windows.
2) Adicionamos ao projeto os arquivos: main.cpp e o arquivo de recurso e seu respectivo header (criados e salvos no processo anterior)
3) No arquivo main.cpp temos:
#include "resource.h"
#include <windows.h>

LRESULT CALLBACK dlgproc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevHinstance,LPSTR lpCmdLine,int nShowCmd)
{
DialogBox(hInstance,MAKEINTRESOURCE(DIALOGBOX),NULL,(DLGPROC)dlgproc);
}

LRESULT CALLBACK dlgproc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam){
switch(msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return 0;
}
Explicando:

#include "resource.h"Este é o header gerado para o arquivo de recurso, este como já havia dito, contém o nome dos objetos do DialogBox. Você pode ao invés de criar um HEADER, adicionar diretamente os nomes no arquivo MAIN.CPP, exemplo:
#include <windows.h>
#define objeto1 xxx
#define objeto2 xxx
#define objeto3 xxx
[...]

LRESULT CALLBACK dlgproc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam);Definimos a função CALLBACK, que desempenha o mesmo papel da função WinProc utilizada nos módulos anteriores.

DialogBox(hInstance,MAKEINTRESOURCE(DIALOGBOX),NULL,(DLGPROC)dlgproc);Esta linha é responsável pela "chamada" ao dialog.
Sua sintaxe é: DialogBox(Instância,NOME_DO_DIALOGBOX,HWND-PAI,FUNÇÃO CALLBACK);

Instância => Parâmetro HINSTANCE da função WinMain.

NOME_DO_DIALOGBOX => Nome do DialogBox definido em resource.h. A função MAKEINTRESOURCE, retorna a constante do objeto.

HWND-PAI => Define a quem o DialogBox pertence.

FUNÇÃO CALLBACK => Define o nome da função CALLBACK que receberá as mensagens enviadas ao dialog. Deve estar no formato DLGPROC, por isso utilizamos (DLGPROC)NOME_DA_FUNÇÃO.

LRESULT CALLBACK dlgproc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam){
switch(msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return 0;
}
Esta função já faz parte do cotidiano, nada novo. Revisando: Esta função recebe a mensagem enviada ao dialog, e daí em frente, você pode manipulá-lo.
Um detalhe importante: Note que não foi necessário incluir o LOOP de mensagens no código, pois isto é feito de forma "automática".Se não se lembra, este é o LOOP:

while(GetMessage(&message,0,0,0)){
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam ;

Como você pôde perceber, você teve que digitar bem menos :).

Manipulando controles
***************************************************
Na segunda parte deste tutorial, você viu como podemos criar e manipular controles quando se trata de uma janela esquematizada. Abordaremos agora a como trabalhar com os mesmos controles, utilizando desta vez, dialogs. Você verá que é mais simples do que se pensa.
Você sabe que nós já criamos nossos controles no arquivo de recurso certo? Então, não precisamos criar os controles na unha hehehe. Uma vez já criados, nos resta agora manipulá-los, o processo é o mesmo, veja o exemplo:

EnableWindow(hwnd,valor);
Você sabe que a função EnableWindow, habilita ou desabilita um objeto e sabe também que:
hwnd -> Handle do nosso objeto;
valor -> 1 (habilitado) ou 0 (disabilitado)
O único problema, é que como o objeto foi criado pelo arquivo de recurso, não fomos nós quem definimos o seu HWND, e precisamos dele para tornar a função válida. Nestas ocasiões, recorremos à função GetDlgItem, que obtém o HWND do objeto, pelo seu nome.

Sintaxe:
hwnd = GetDlgItem(HWND_DO_DIALOG,NOME_DO_OBJETO);Veja a função:
LRESULT CALLBACK dlgproc(HWND [b]window[/b],UINT msg,WPARAM wParam,LPARAM lParam)
Nesse caso, 'window', é o HWND do dialogbox.
Retome os trechos:

No arquivo resource.h:
#define txt1 101

No arquivo script1.rc

BEGIN
    EDITTEXT        txt1,25,20,120,14,ES_AUTOHSCROLL
END

Temos destacado: txt1, que é o nome do textbox.
Uma observação importante, o nome do objeto (txt1), deve ser igual nos dois arquivos.
Então, o HWND do textbox, pode ser obtido por:

HWND txt_hwnd;
txt_hwnd = GetDlgItem(window,txt1);
E por fim, podemos utilizar:
EnableWindow(txt_hwnd,0);

Daqui em diante, você sabe o que fazer... :)
A forma de manipular os controles é exatamente igual.

Algumas funções interessantes.
**************************************************
GetDlgItemText -> Esta função obtém o texto de um objeto.

Sua sintaxe:
GetDlgItemText(HWND,OBJETO,BUFFER,TAMANHO);
HWND -> hwnd do dialog;
OBJETO -> nome do objeto;
BUFFER -> buffer que armazenará o texto;
TAMANHO -> tamanho do buffer.

Veja o exemplo:
char buffer[256];
HWND hwnd2;
hwnd2 = GetDlgItem(window,txt1);
GetWindowText(hwnd2,buffer,256);
Acima o método utilizado anterioremente. Este processo por ser simplificado:
char buffer[256];
GetDlgItemText(window,txt1,buffer,256)
Temos o inverso da função GetDlgItemText: a função SetDlgItemText, que define um texto ao objeto.

Sintaxe:
SetDlgItemText(HWND,OBJETO,TEXTO);
Veja:
SetDlgItemText(window,txt1,"teste");

E por fim: SendDlgItemMessage.
Esta função envia diretamente para o objeto, uma mensagem específica.

Sintaxe: SendDlgItemMessage(HWND,OBJETO,MENSAGEM,WPARAM,LPARAM)
Exemplo, suponhamos que no arquivo de recurso tivéssimos:

BEGIN
    EDITTEXT        txt1,8,1,120,14,ES_AUTOHSCROLL
    LISTBOX        list1,7,18,121,45,LBS_SORT
END

E no header:

#define DIALOGBOX                  100
#define txt1                       101
#define list1                      102

Além do TEXTBOX, temos também uma ListBox, cujo nome é: list1.
Vejamos agora um exemplo:
SendDlgItemMessage(window,list1,LB_ADDSTRING,0,(LPARAM)"LOL!!!");
Acima, inserimos um item à listbox.


Exemplo de código
**************************************************

RECURSO.RC

#include "recurso.h"
dialogbox DIALOGEX 6,5,167,49
CAPTION "Programa teste"
FONT 8,"MS Sans Serif",0,0
STYLE 0x10CC0000
BEGIN
  CONTROL "Digite alguma coisa:",label,"Static",0x50000000,50,3,66,20
  CONTROL "",txt,"Edit",0x500100C0,4,14,160,13,0x00000200
  CONTROL "OK",btn,"Button",0x50010001,56,29,54,13
END



RECURSO.H

#define dialogbox 1000
#define label 1001
#define txt 1002
#define btn 1003


EXEMPLO.CPP

#include "recurso.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
char buffer[256],result[310];
int x,num;

LRESULT CALLBACK dlgproc(HWND window,UINT msg,WPARAM  wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevHinstance,LPSTR lpCmdLine,int nShowCmd)
{
DialogBox(hInstance,MAKEINTRESOURCE(dialogbox),NULL,(DLGPROC)dlgproc);
}

LRESULT CALLBACK dlgproc(HWND window,UINT msg,WPARAM wParam,LPARAM lParam){
switch(msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_COMMAND:
     if(wParam==btn){
               num=0;
                     GetDlgItemText(window,txt,buffer,256);
             for(x=0;x<strlen(buffer);x++){
                if(buffer[x]=='a' || buffer[x]=='A')
                    num++;
                    }
sprintf(result,"Ocorrência(s) da letra 'A' na string \"%s\": %d resultados",buffer,num);
MessageBox(window,result,"Resultado",MB_OK|MB_ICONINFORMATION);
                     }
                     
}
return 0;
}


Algumas considerações
**************************************************
Chegamos ao fim da terceira parte do tutorial, brevemente, espero postar a quarta parte deste, onde abordarei mais sobre dialog's, cores e fontes. Pretendo avançar um pouco nos controles do Windows, demonstrando o uso de por exemplo: ListView, Progress Bar, dentro outros. Isso se eu tiver tempo :)....
FIM!
Bye.

locator.dll



Anonymous

12 ^^

nunk vi nd taum bem explicado, merece 10 pontos de respeito x)

Dark_Side

Hi,

Revisei algumas coisas no tutorial e escrevi a parte 4. Achei melhor ir adicionando ao arquivo "GUI.RAR" as futuras partes do tutorial, possibilitando assim, um maior conforto para ler o material. Lolz, download:

http://three.fsphost.com/darkside/gui.rar

Bye ;)

Anonymous

opa, vow ler agorinha x)

vlw!

ah vow fazer um pedido, num outro modulo tu dar uma explicada no tabstrip x_x


nizep

ae malz revive o topico mas o link http://three.fsphost.com/darkside/gui.rar nao esta mais on e eu keria da uma olhada na parte 4 do turorial

se tiver como upa di novo ae por favor

Anonymous

Seus tutos são ótimos, esse está exlemtemente muito bom.....
Parabéns cara.....  vou exploralo ao maximo..  ;)

Edu