Arquivo de março, 2014

Checkbox

A classe JCheckBox fornece suporte para os botões da caixa de seleção.

TextArea

A classe JTextArea fornece um componente que exibe várias linhas de texto, permitindo opcionalmente o usuário editar o texto.

ScrollPane

A JScrollPane fornece uma visão de rolagem de um componente. Quando a tela é limitada, use um painel de rolagem para exibir um componente que é grande ou um cujo tamanho pode mudar dinamicamente. Outros recipientes utilizados para economizar espaço na tela incluem painéis divididos por abas e painéis.

KeyEvent (mnemônico)

Geralmente a letra sublinhada no texto de cada componente mostra o mnemônico – a alternativa de teclado – para cada componente. Na maioria das GUIs Fell and Look, o usuário pode clicar em um componente, pressionando a tecla Alt e o mnemônico. Por exemplo, Alt+M. O KeyEvent é responsável pela definição do atalho no teclado, exemplo, KeyEvent.VK_M

GridBagConstraints

Uma classe que simplesmente armazena as informações para cada componente adicionado.  A propriedade Fill determina como redimensionar o componente.

Exemplo:

Neste exemplo criamos três componentes checkbox e uma caixa de texto a cada mudança do estado de cada checkbox adicionamos o texto correspondente a caixa de texto, para outros detalhes leia os comentários no código

Java

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class MontaGUI extends JPanel implements  ItemListener
{
	// Declara Objetos
	JLabel rotulo;
	JCheckBox opc1;
	JCheckBox opc2;
	JCheckBox opc3;
	JTextArea texto;

	public MontaGUI()
	{
		// Cria novos Objetos
		rotulo = new JLabel("Escolha um Checkbox ou Alt + A, B ou C:");
		opc1 = new JCheckBox("Opção 1:");
		opc2 = new JCheckBox("Opção 2:");
		opc3 = new JCheckBox("Opção 3:");
		texto = new JTextArea(5,20);

		// Seta atalho do teclado ex: ALT + A ou B ou C
		opc1.setMnemonic(KeyEvent.VK_A);
		opc2.setMnemonic(KeyEvent.VK_B);
		opc3.setMnemonic(KeyEvent.VK_C);

		// Seta Evento
		opc1.addItemListener(this);
		opc2.addItemListener(this);
		opc3.addItemListener(this);

		// Seta texto não editavel
		texto.setEditable(false);

		// Cria barras de rolagem
		JScrollPane barra =  new JScrollPane(texto);

		// Seta restrições para barra de rolagem
		GridBagConstraints c = new GridBagConstraints();
        c.gridwidth = GridBagConstraints.REMAINDER;

        // Seta tamanho do preenchimento para as barras
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 1.0;
        c.weighty = 1.0;

        // cria paineis
		JPanel painel1 = new JPanel();
		JPanel painel2 = new JPanel();
		JPanel painel3 = new JPanel();

		// adiciona componentes nos paineis
		painel1.add(rotulo);
		painel2.add(opc1);
		painel2.add(opc2);
		painel2.add(opc3);
		painel3.add(barra,c );

		// adiciona painel e centraliza
		add(painel1,BorderLayout.CENTER);
		add(painel2,BorderLayout.CENTER);
		add(painel3,BorderLayout.CENTER);

	}

	public void itemStateChanged(ItemEvent e)
	{
		// Evento de mudança de estado do checkbox

		// captura item celecionado
		Object fonte = e.getItemSelectable();

		// coloca o cursor no final do texto para efeito de rolagem
		texto.setCaretPosition(texto.getDocument().getLength());

		// Define click no checkbox
		if (fonte == opc1)
		{
			texto.append("Você clicou no CheckBox 1" + "\n");
		}

		if (fonte == opc2)
		{
			texto.append("Você clicou no CheckBox 2" + "\n");
		}

		if (fonte == opc3)
		{
			texto.append("Você clicou no CheckBox 3" + "\n");
		}

	}

	public static void main(String[] args) {

		// adicona thread do swing
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {

				// cria formulario
				JFrame formulario = new JFrame("Desenvolvimento Aberto");
				formulario.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

				// monta paineis de componetes no frame
				JComponent componentes = new  MontaGUI();
				componentes.setOpaque(true);

				// Seta propriedades do frame
				formulario.setContentPane(componentes);
				formulario.setSize(400, 250);
                formulario.setVisible(true);
			}
		});
	}

}

No post anterior aprendemos como montar telas gráficas dinamicamente, continuaremos criando uma tela gráfica de seleção mesclando tabelas internas e o banco de dados SAP, usando comandos OPEN SQL, para preencher as tabelas transparentes do Flight Model. Para quem não se lembra, o Flight Model é o principal exemplo do NetWeavear 7  e suas tabelas transparentes por default no mandante 001 não possui dados, por isto vamos inserir os dados manualmente, temos que ter cuidado para não esquecer de preencher as outras tabelas que fazem referencia (Foreign Key) a nossa tabela de voo, veja a imagem abaixo:

Fmodel

Flight Model:

https://desenvolvimentoaberto.wordpress.com/2014/02/20/netweaver-flight-model-introducao-ao-database-mini-sap/

Foreign Key

Uma chave externa ou estrangeira é um atributo ou uma combinação de atributos numa relação, cujos valores são necessários para equivaler à chave primária de uma relação. O conceito de Chave estrangeira em uso de banco de dados se refere ao tipo de relacionamento entre distintas tabelas de dados do banco de dados. Uma chave estrangeira é chamada quando há o relacionamento entre duas tabelas. Sempre em chave estrangeira vai haver relacionamentos entre tabelas, por exemplo, uma tabela que possui relação com a chave primaria de outra tabela.

Validação de Parâmetros

A validação de entrada da tela pode ser feita no evento da instrução:

AT SELECTION-SCREEN

Útil se quiser exigir a entrada de dados do usuário antes de processamento principal.

Usando AT SELECTION-SCREEN ON nome do campo:

  • Disparado se nome do campo foi submetido.
  • Se um erro ou aviso é emitido, o campo é realçado.

EM AT SELECTION-SCREEN ON RADIOBUTTON GROUP nome do grupo:

  • Se um erro ou aviso é emitido, o grupo é realçado.

Range of Values

Permite que o usuário selecione um intervalo de valores, criando o componente na tela já com botões e tabelas relacionadas.

Sintaxe:

SELECT-OPTIONS itabname FOR dataobject.

Exemplo:

Neste exemplo temos dois programas distintos o primeiro preenche os dados do Flight Model, preenchendo a tabela de voo e as tabelas que fazem relação e possuem uma chave estrangeira na tabela voo. O segundo é nossa tela de seleção que busca todos os voos de uma agencia de viagem, também como fazer a validação em um campo de parâmetros.

Abap – Programa #1

*&---------------------------------------------------------------------*
*& Report  ZDADOS
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Insere Dados manualmente no Flight Model
*&---------------------------------------------------------------------*

REPORT  ZDADOS.

* Define tabelas do Banco de dados
TABLES SCARR.
TABLES SGEOCITY.
TABLES SAIRPORT.
TABLES SPFLI.

* Apaga dados existentes
DELETE FROM SCARR.
DELETE FROM SGEOCITY.
DELETE FROM SAIRPORT.
DELETE FROM SPFLI.

* Cria MATRIZs de dados (rows)
DATA MATRIZ1 TYPE SCARR.
DATA MATRIZ2 TYPE SGEOCITY.
DATA MATRIZ3 TYPE SAIRPORT.
DATA MATRIZ4 TYPE SPFLI.

* Insere dados.

MATRIZ1-CARRID = '001'.
MATRIZ1-CARRNAME = 'DA Airlines'.
MATRIZ1-CURRCODE = 'REAL'.
MATRIZ1-MANDT = '001'.
MATRIZ1-URL  = 'https://desenvolvimentoaberto.wordpress.com'.

INSERT INTO SCARR VALUES MATRIZ1.

MATRIZ2-CITY = 'São Paulo'.
MATRIZ2-COUNTRY = 'Bra'.
MATRIZ2-LATITUDE = '23'.
MATRIZ2-LONGITUDE = '46'.
MATRIZ2-MANDT = '001'.

INSERT INTO SGEOCITY VALUES MATRIZ2.

MATRIZ2-CITY = 'Rio de Janeiro'.
MATRIZ2-COUNTRY = 'Bra'.
MATRIZ2-LATITUDE = '22'.
MATRIZ2-LONGITUDE = '43'.
MATRIZ2-MANDT = '001'.

INSERT INTO SGEOCITY VALUES MATRIZ2.

MATRIZ3-ID ='001'.
MATRIZ3-MANDT ='001'.
MATRIZ3-NAME = 'Aeroporto de Congonhas'.
MATRIZ3-TIME_ZONE = 'GMT-3'.

INSERT INTO SAIRPORT VALUES MATRIZ3.

MATRIZ3-ID ='002'.
MATRIZ3-MANDT ='001'.
MATRIZ3-NAME = 'Aeroporto Santos Dumont'.
MATRIZ3-TIME_ZONE = 'GMT-3'.

INSERT INTO SAIRPORT VALUES MATRIZ3.

MATRIZ4-AIRPFROM = '001'.
MATRIZ4-AIRPTO = '002'.
MATRIZ4-ARRTIME = '170000'.
MATRIZ4-CARRID = '001'.
MATRIZ4-CITYFROM = 'São Paulo'.
MATRIZ4-CITYTO = 'Rio de Janeiro'.
MATRIZ4-CONNID = '001'.
MATRIZ4-COUNTRYFR = 'Bra'.
MATRIZ4-COUNTRYTO = 'Bra'.
MATRIZ4-DEPTIME = '181500'.
MATRIZ4-DISTANCE = '500'.
MATRIZ4-DISTID = 'KM'.
MATRIZ4-FLTIME = '75'.
MATRIZ4-FLTYPE = 'D'.
MATRIZ4-MANDT = '001'.
MATRIZ4-PERIOD = '1'.

INSERT INTO SPFLI VALUES MATRIZ4.

* Exibe imagem
WRITE : / 'Dados inseridos'.

Abap – Programa #2

*&---------------------------------------------------------------------*
*& Report  ZVISUAL_D
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Selection Screen - Database
*&---------------------------------------------------------------------*

REPORT  ZVISUAL_D.

* Define internal Table
DATA str TYPE spfli.

* Monta tela
SELECTION-SCREEN BEGIN OF BLOCK bloco1 WITH FRAME
  TITLE titulo.

   SELECTION-SCREEN BEGIN OF LINE.

      SELECTION-SCREEN COMMENT 1(22) com.
      SELECT-OPTIONS userair FOR str-carrid.

   SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK bloco1.

SELECTION-SCREEN BEGIN OF BLOCK bloco2 WITH FRAME
  TITLE titulo1.

    SELECTION-SCREEN COMMENT 1(40) com1.
    PARAMETER valor TYPE string.

SELECTION-SCREEN END OF BLOCK bloco2.

* Carrega rotulos da tela
LOAD-OF-PROGRAM.

Titulo = 'Modelo de Voo (Flight Model - NetWeaver 7'.
titulo1 = 'Evento de validação'.
com = 'Selecione Linha Aerea'.
com1 = 'Experimente digitar a palavra: VALIDA'.

* Evento de validação
AT SELECTION-SCREEN ON valor.
  IF valor = 'VALIDA'.
    MESSAGE 'Você digitou uma palavra Invalida' TYPE 'W'.
  ENDIF.

* Inicia o Programa
START-OF-SELECTION.

* Seleciona os dados do banco de dados e coloca na tabela interna
SELECT carrid connid countryfr cityfrom cityto arrtime deptime distance distid  FROM spfli INTO
CORRESPONDING FIELDS OF str WHERE carrid IN userair.

WRITE: / str-carrid, str-connid, str-countryfr, str-cityfrom, str-cityto,
         str-arrtime, str-deptime, str-distance, str-distid.

ENDSELECT.

Quando você precisa que o usuário forneça dados de entrada para algum tipo de processamento, você pode montar uma tela com parâmetros de seleção usando componentes visuais que são criados em tempo de execução, você pode usar rótulos (COMMENT), campos de edição, botões de cheque, botões de radio, botões comuns e eventos para realizar uma interação com a resposta do usuário.

PARAMETERS

Os parâmetros são os componentes de uma tela de seleção que são atribuídos a um objeto de dados elementar global no programa ABAP e um campo de entrada na tela de seleção. Parameters é o tipo mais básico de aceitação de entrada. Usando os parâmetros você pode gerar uma tela de tela de seleção padrão.

EVENT BLOCK

Um programa ABAP é uma coleção de blocos de processamento, chamados pelo ambiente de tempo de execução quando relacionados a eventos é acionado através do fluxo natural do programa de controle ou quando provocado por uma ação do usuário.

LOAD-OF-PROGRAM

Esta palavra-chave define um bloco de evento cujo evento é acionado pelo ambiente ABAP-runtime quando um programa executável, um pool de módulo, um grupo de funções ou uma pool de sub-rotina é carregado na sessão interna.

START-OF-SELECTION

Esta palavra-chave define o bloco de processamento padrão de um programa executável. O evento associado é acionado pelo ambiente de tempo de execução ABAP durante a execução de um programa executável após quaisquer telas de seleção padrão serem processadas.

SELECTION-SCREEN

Telas de seleção são telas especiais que não são criadas no Screen Painter, mas são geradas a partir de declarações ABAP. Você pode usá-las sempre que quiser que o usuário digite um único valor para um campo ou campos, ou para introduzir critérios de seleção.

AT SELECTION-SCREEN

Define uma forma básica de toda uma série de eventos que ocorrem enquanto a tela de seleção está sendo processada.

A tela de seleção standard, em um programa executável ou no banco de dados lógico ligado a ela, é chamada automaticamente entre os eventos da inicialização e o inicio da selecão. Quando você chama a tela de seleção e, quando os usuários interagem com ela, o ambiente de tempo de execução ABAP gera eventos de tela de seleção, que ocorrem entre os comandos INITIALIZATION e START-OF-SELECTION.

Exemplo:
Neste exemplo desenvolvemos uma tela de seleção usando frames e vários componentes de seleção, usamos também o eventos de seleção.

Abap

*&---------------------------------------------------------------------*
*& Report  ZVISUAL
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Selection Screen - List process events
*&---------------------------------------------------------------------*

REPORT  ZVISUAL.

* Define tabela ucommcomponent para o fcode do botão
TABLES sscrfields.

* Define variaveis
DATA evento TYPE i VALUE 0.

* Define bloco do frame 1
SELECTION-SCREEN BEGIN OF BLOCK bloco1 WITH FRAME

  TITLE titulo1.

  SELECTION-SCREEN BEGIN OF LINE.

    SELECTION-SCREEN COMMENT 1(10) com1.
    PARAMETERS: var1 TYPE i,
                var2 TYPE i,
                var3 TYPE i.
    SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK bloco1.

* Define bloco do frame 2
SELECTION-SCREEN BEGIN OF BLOCK bloco2 WITH FRAME

  TITLE titulo2.

  SELECTION-SCREEN BEGIN OF LINE.
    SELECTION-SCREEN COMMENT 1(12) com2.
    PARAMETERS data LIKE sy-datum.
  SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK bloco2.

* Define bloco do frame 3
SELECTION-SCREEN BEGIN OF BLOCK bloco3 WITH FRAME

  TITLE titulo3.

  SELECTION-SCREEN BEGIN OF LINE.
    SELECTION-SCREEN COMMENT 1(9) com3.
    PARAMETERS masc AS CHECKBOX.
    SELECTION-SCREEN COMMENT 18(8) com4.
    PARAMETERS fem AS CHECKBOX.
  SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK bloco3.

* Define bloco do frame 4
SELECTION-SCREEN BEGIN OF BLOCK bloco4 WITH FRAME

  TITLE titulo4.

  SELECTION-SCREEN BEGIN OF LINE.
    SELECTION-SCREEN COMMENT 1(10) com5.
    PARAMETERS: variavel AS CHECKBOX.
  SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK bloco4.

* Define bloco do frame 5
SELECTION-SCREEN BEGIN OF BLOCK bloco5 WITH FRAME

  TITLE titulo5.

  SELECTION-SCREEN BEGIN OF LINE.
    SELECTION-SCREEN PUSHBUTTON 2(10) but1 USER-COMMAND CLIQUE1.
  SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK bloco5.

* Usa componente sem frame

SELECTION-SCREEN COMMENT 1(15) com6.
PARAMETERS : escolha1 RADIOBUTTON GROUP grpa,
escolha2 RADIOBUTTON GROUP grpa,
escolha3 RADIOBUTTON GROUP grpa.

* Carrega variaveis da selecão de tela
LOAD-OF-PROGRAM.

  titulo1 = 'Entre campos numericos (Parameters)'.
  titulo2 = 'Data (Data - Calendario)'.
  titulo3 = 'Sexo (Checkbox)'.
  titulo4 = 'Variave (Checkbox)'.
  titulo5 = 'Botão (PushButton)'.

  but1 = 'OK'.

  com1 = 'Numeros '.
  com2 = 'Data de hoje'.
  com3 = 'Masculino'.
  com4 = 'Feminino'.
  com5 = 'Variavel'.
  com6 = 'RadioButton'.

* Evento do botão
AT SELECTION-SCREEN.

  CASE sscrfields.
    WHEN 'CLIQUE1'.
      evento = 1.
  ENDCASE.

* Inicio do processamento da seleção de tela
START-OF-SELECTION.

* Imprime campo data
  WRITE : / 'Data:', data.
  .
* Imprime campo sexo
  IF masc = 'X'.
    WRITE / 'Você é do sexo masculino!'.
  ENDIF.
  IF fem = 'X'.
    WRITE / 'Você é do sexo feminino!'.
  ENDIF.

* Imprime resultado do Checkbox
  IF variavel = 'X'.
    WRITE / 'Você clicou no checkbox'.
  ELSE.
    WRITE / 'Você não clicou no checkbox'.
  ENDIF.

* Imprime resultado do Radiobutton
  CASE 'X'.
    WHEN escolha1.
      WRITE / 'Você fez a primeira escolha'.
    WHEN escolha2.
      WRITE / 'Você fez a segunda escolha'.
    WHEN escolha3.
      WRITE / 'Você fez a terceira escolha'.
    WHEN OTHERS.
      WRITE / 'Você não fez nenhuma escolha'.
  ENDCASE.

* Captura resultado do evento
  CASE evento.
    WHEN 1.
      WRITE : / 'Você clicou no botão'.
    WHEN 0.
      WRITE : / 'Você não clicou no botão'.
  ENDCASE.

Nós já desenvolvemos muitos aplicativos C++ Standard com saída para o console e no post anterior desenvolvemos um aplicativo C++ Visual usando diretamente a API do Windows para criar a GUI, agora vamos utilizar o método predefinido pela Microsoft para programação C++ em Windows, visto que também é possível utilizar o Framework e desenvolver aplicativos C++ usando o CLR. A seguir vamos saber mais sobre estes assuntos e sobre programação C++ para Windows.

.NET Framework

Microsoft .NET  é uma iniciativa da empresa Microsoft, que visa uma plataforma única para desenvolvimento e execução de sistemas e aplicações. Todo e qualquer código gerado para .NET pode ser executado em qualquer dispositivo que possua um framework de tal plataforma. Com ideia semelhante à plataforma Java, o programador deixa de escrever código para um sistema ou dispositivo específico, e passa a escrever para a plataforma .NET.

O .NET Framework é um conceito central no Visual Studio, bem como em todos os outros  produtos de desenvolvimento da Microsoft .NET.  O .NET Framework é composto de dois elementos: o Common Language Runtime (CLR ), em que o aplicativo é executado em um conjunto de bibliotecas chamado bibliotecas de classes do .NET Framework . As bibliotecas de classe Framework .NET fornecem o apoio funcional para o seu código e será necessário durante a execução do CLR , independente da linguagem de programação assim utilizada nos programas escritos em C++ , C#, ou qualquer das outras línguas que suportam o . NET Framework todos usam a mesma biblioteca .NET.

Existem dois tipos fundamentalmente diferentes de aplicativos C ++  que você pode desenvolver com o Microsoft Visual C++. Você pode escrever aplicações que executam nativamente em seu computador. Estas aplicações serão referidas a programas como C++ nativo , você escrever programas C++ nativo na versão do C++ definida pela ISO/IEC (International Standards Organization  e International Electrotechnical Commision ), este é o padrão da linguagem.

Você também pode escrever aplicativos para serem executados sob o controle do CLR em um versão estendida do C++ chamado C++/CLI. Estes programas irão ser encaminhados para programas como CLR , ou programas C++/CLI.

O NET Framework  não é estritamente parte do Visual C++, mas sim um componente do Sistema operacional Windows que torna mais fácil construir aplicações de software e serviços web.

O .NET Framework oferece vantagens substanciais em termos de viabilidade e segurança do código , bem como a capacidade de integrar o seu código C++ com código escrito em mais de 20 outras linguagens de programação que são alvo do .NET Framework. Uma ligeira desvantagem de segmentação do .NET Framework . É que não há uma penalidade de desempenho pequeno em comparação com código nativo, mas você não consegue perceber isso na maioria das circunstâncias ou seja quando você precisa de um desempenho maior é preciso usar código C++ nativo.

CLR

O Common Language Runtime (CLR) é um ambiente padronizado para a execução de programas escritos em uma ampla gama de linguagens de alto nível.

Em C++ o caderno de especificações da CLR está agora incorporada nos Fabricantes European Computer Manufacturers (ECMA) para o Common Language Infrastructure (CLI), o ECMA – 335, e também na norma ISO equivalente, ISO/IEC 23271, de modo que o CLR é uma aplicação do presente padrão.

O CLI é, essencialmente, um caderno de especificações para um ambiente de uma máquina virtual que permite que os aplicativos escrito em diversas linguagens de programação de alto nível sejam executados em sistema de diferente ambientes sem que o código fonte original seja alterado ou replicado. As especificações CLI referem se a uma linguagem intermediária padrão para a máquina virtual com uma linguagem de alto nível onde o código-fonte é compilado. Com o .NET Framework, esta linguagem intermediária é conhecida como Microsoft Intermediate Language (MSIL). Código na linguagem intermediária é finalmente mapeado para código de máquina pelo Just-in-time (JIT) quando você executa um programa. Claro que, o código na linguagem intermediária CLI pode ser executado em qualquer outro ambiente que tenha uma implementação CLI.

C++ no Windows

Você tem duas opções básicas para aplicações do Windows: Você pode escrever código que executa com o CLR, e você também pode escrever código que compila diretamente para código de máquina e, portanto, executa nativamente. Para as janelas com base aplicações que visam a CLR, você usa o Windows Forms como a base para a interface gráfica fornecida pelas bibliotecas do .NET Framework. Usando o Windows Forms permite o desenvolvimento GUI rápido, porque você monta a GUI graficamente a partir de componentes padronizados e têm o código gerado automaticamente.

Para executar nativamente o código, você tem várias maneiras de fazer este trabalho. Uma possibilidade é usar o Microsoft  Fundation Classes (MFC) para a programação da interface gráfica de usuário para a sua aplicação Windows. O MFC encapsula o Application Programming Interface (API) do sistema operacional Windows para a criação e controle da GUI e facilita muito o processo de desenvolvimento do programa.

C++

A API do Windows se originou muito antes da linguagem C++ chegar ao sistema, por isso não tem nenhuma das características orientada a objetos que seria de esperar se fosse escrito hoje, no entanto, você está não é obrigado a usar o MFC. Se você quer um melhor em desempenho, você pode escrever seu código C++ para acessar a API do Windows diretamente.

Conceitos Windows

Um programa do Windows, se é um programa nativo  C++ ou um programa escrito para o CLR, tem uma estrutura diferente daquela do programa típico de console que executa a partir da linha de comando, e é mais complicado. Em um programa de console você pode obter a entrada do teclado e escrever saída de volta para a linha de comando diretamente, ao passo que um programa do Windows pode acessar a entrada e instalações de saída do computador, apenas a título de funções fornecidas pelo ambiente do hospedeiro, não é permitido ter acesso direto aos recursos de hardware. Porque vários programas podem estar ativos de uma só vez no Windows, o Windows determina a aplicação de uma determinada entrada cru, como um clique do mouse ou o acionamento de uma tecla no teclado, é destinado a, e sinalizar o programa em causa. Assim, o sistema operacional Windows tem controle primário de toda comunicação com o usuário.

Windows Messages

Eventos em um aplicativo do Windows são ocorrências como ao usuário clicar com o mouse ou pressionando uma tecla ou se um temporizador atingir zero. O sistema operacional Windows registra cada evento em uma mensagem e coloca a mensagem em uma fila de mensagens para o programa para o qual a mensagem se destina. Assim uma mensagem do Windows é simplesmente um registro dos dados relativos a um evento, e a fila de mensagens para uma aplicação é apenas uma sequência de tais mensagens aguardando para serem processados pela aplicação, por envio de uma mensagem, o Windows pode dizer ao seu programa de que algo precisa ser feito, ou que algum informação tornou-se disponível, ou que um evento como um clique do mouse ocorreu. Se o seu programa está devidamente organizado, ele vai responder de forma adequada à mensagem. Tem muitos tipos diferentes de mensagens e eles podem ocorrer com muita frequência, muitas vezes até por segundo quando o mouse está sendo arrastado, por exemplo.

Um programa do Windows deve conter uma função especificamente para lidar com essas mensagens. a função é muitas vezes chamada WndProc () ou WindowProc (), embora ele não  tenha um nome específico porque o Windows acessa a função através de um ponteiro para uma função que você forneceu.

Você passa uma mensagem de volta para o Windows chamando uma função padrão fornecido pelo Windows chamada DefWindowProc (), o que proporciona o processamento de mensagem padrão.

Windows API

Todas as comunicações entre qualquer aplicativo do Windows e o próprio Windows usam o Windows Application Programming Interface, também conhecido como a API do Windows. Isto consiste em, literalmente, centenas de funções que são fornecidos como padrão com o sistema operacional Windows que fornece os meios pelos quais um aplicativo se comunica com o Windows, e vice-versa. A API do Windows foi desenvolvida nos dias em que C foi a principal língua em uso, muito antes do advento do C++, e, por esta razão, as estruturas, em vez de classes são frequentemente utilizadas para a passagem de alguns tipos de dados entre o Windows e o seu programa aplicativo.

A API do Windows abrange todos os aspectos das comunicações entre o Windows e a sua aplicação. Porque há um número tão grande de funções na API, utilizando-as na mão pode ser uma tarefa muito difícil.

Tipos de Dados Windows

O Windows define um número significativo de tipos de dados que são usados para especificar parâmetro de função, tipos e tipos de retorno na API do Windows. Estes tipos específicos do Windows também se propagam através de funções que são definida em MFC.

MICROSOFT FOUNDATION CLASSES

O Microsoft Foundation Classes (MFC) é um conjunto de classes predefinidas sobre a qual a programação Windows com Visual C++ é construída. Estas classes representam uma abordagem orientada a objeto para programação Windows que encapsula a API do Windows. O MFC não cumpri rigorosamente os princípios de orientação a objeto e de encapsulamento e ocultamento de dados, principalmente porque grande parte do código MFC foi escrito antes de tais princípios serem bem estabelecidos.

O processo de escrever um programa do Windows envolve a criação e uso de objetos MFC ou objetos de classes derivadas do MFC. No principal, você vai derivar suas próprias classes de MFC, com assistência considerável a partir das ferramentas especializadas em Visual C++ que tornam este trabalho muito mais fácil.

Como Criar uma Aplicação MFC

O MFC Application utiliza o método da Microsoft de Design Time, o “Design First, Code Later”, o que significa que você desenvolve o design da tela usando a IDE do Visual Studio, colocando os componentes diretamente da ToolBox no Form e pode manipular as propriedades e eventos dos componentes utilizando a janela Properties. Para nossa aplicação MFC utilize a imagem abaixo como referencia de design.

C++1

Visual Studio

  1. No menu Files escolha New Project.
  2. Na Lista de projetos C++ escolha MFC Application.
  3. Nomeie o projeto para: Concatenador e clique em OK.
  4. No Wizard clique em Next.
  5. Na pagina Application Type escolha: Dialog Based e clique em Finish.
  6. A IDE abre no modo Design Time, que possibilita você arrastar componentes da ToolBox para o Form aberto.
  7. Apague os componentes default do form, que são um Static Text e dois Buttons.
  8. Selecione na ToolBox e coloque no Form os seguintes componentes:
  9. Um componente Static Text.
  10. Três componentes Edit Control.
  11. Um componente Button e mude o seu texto para: Somar.
  12. Monte a disposição na tela de acordo com a figura acima.
  13. Clique com o botao direito do mouse em cima do primeiro componente Edit Control e escolha ADD Variable, no Wizard em variable name coloque o nome: texto1 e clique em Finish.
  14. Clique com o botao direito do mouse em cima do segundo componente Edit Control e escolha ADD Variable, no Wizard em variable name coloque o nome: texto2 e clique em Finish.
  15. Clique com o botao direito do mouse em cima do componente Button e escolha ADD Variable, no Wizard em variable name coloque o nome: botao e clique em Finish.
  16. Clique com o botao direito do mouse em cima do terceiro componente Edit Control e escolha ADD Variable, no Wizard em variable name coloque o nome: resultado e clique em Finish.
  17. Ainda no terceito Edit Control na janela de propriedades, mude Read Only para True.
  18. Clique com o botão direito em cima do componente Button e escolha: Add Event Handler, no Wizard em Message Type selecione BN_CLICKED clique em Add and EDIT.
  19. Neste momento uma nova unidade de codigo fonte é aberta com o evento escolhido, preencha a void do evento igual ao codigo abaixo.

Exemplo:

Neste exemplo criamos um programa visual em C++ utilizando MFC que concatena duas String, como usamos o conceito de “Design First e Code Later” da Microsoft você precisa apenas copiar o conteúdo da ultima void do código, todo o resto é gerado automaticamente.

C++

// Código Gerado automaticamente - MFC - Visual Studio 2013 - Ultimate
// Vá para o final do código
// Nossa implementação se trata apenas da ultima void

// ConcatenadorDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Concatenador.h"
#include "ConcatenadorDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()

// CConcatenadorDlg dialog

CConcatenadorDlg::CConcatenadorDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CConcatenadorDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CConcatenadorDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT1, texto1);
	DDX_Control(pDX, IDC_EDIT2, texto2);
	DDX_Control(pDX, IDC_BUTTON1, botao);
	DDX_Control(pDX, IDC_EDIT3, resultado);
}

BEGIN_MESSAGE_MAP(CConcatenadorDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CConcatenadorDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

// CConcatenadorDlg message handlers

BOOL CConcatenadorDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CConcatenadorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CConcatenadorDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CConcatenadorDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

/*
*********************
** Evento do Botão **
*********************
*/

// Evento do Botão
void CConcatenadorDlg::OnBnClickedButton1()
{
	// TODO: Add your control notification handler code here

	// Copie este codigo

	CString _texto1;
	CString _texto2;
	CString concatena;

	texto1.GetWindowTextW(_texto1);
	texto2.GetWindowTextW(_texto2);

	concatena = _texto1 + _texto2;

	resultado.SetWindowText(concatena);
}

A linguagem de programação Python possui o modulo de construção da GUI, o Tkinter que necessita de uma codificação dinâmica para montar a interface gráfica de usuário.

Em nossa configuração da IDE Spyder estavamos executando os scripts Python com saída direta para o terminal Linux, para configurar a IDE Spyder para executar a GUI diretamente quando clicar no botão RUN, entre no menu: Tools, Preferences, Run e escolha a opção, “Execute in a new dedicated Python interpreter”, clique em aplicar e em OK.

Controles Basicos do Tkinter

Tk

Para inicializar Tkinter, temos que criar um widget raiz Tk. Esta é uma janela comum, com uma barra de título e outra decoração fornecido pelo seu gerenciador de janelas. Você só deve criar um widget de raiz para cada programa, e ele deve ser criado antes de quaisquer outros widgets.

Label

O Widget de Label é um widget Tkinter padrão usado para exibir um texto ou a imagem na tela. A etiqueta só pode exibir texto em uma única fonte, mas o texto pode abranger mais de uma linha. Além disso, um dos caracteres podem ser destacados (Underline), por exemplo, para marcar um atalho.

Entry

O Widget de entrada é utilizada para introduzir cadeias de texto. Este widget permite que o usuário insira uma linha de texto, em uma única fonte.

Button

O Widget de botão é um widget Tkinter padrão usado para implementar vários tipos de botões. Os botões podem conter texto ou imagens, e você pode associar uma função Python ou método com cada botão. Quando o botão é pressionado, Tkinter que chama automaticamente a função ou método.

O botão só pode exibir texto em uma única fonte, mas o texto pode abranger mais de uma linha. Além disso, um dos caracteres podem ser destacados, por exemplo, para marcar um atalho de teclado. Por padrão, a tecla Tab pode ser usado para mover-se para um widget de botão

Grid Geometry Manager

Grid Manager é o mais flexível dos gerenciadores de geometria em Tkinter. Se você não quiser saber como e quando usar os três gerentes, pelo menos, certifique-se de aprender este.

O Grid Manager é especialmente conveniente para usar ao projetar caixas de diálogo. Você ficará surpreso com o quanto é fácil usar o gerenciador de grid. Você pode, na maioria dos casos, simplesmente despejar todos os widgets em um único widget de recipiente, e usar o gerenciador de grid para obter todos eles onde quiser.

CallBack

Um botão sem uma chamada de retorno(callback) é bastante inútil, ele simplesmente não faz nada quando você pressiona o botão. O callback delega o evento a um botão fazendo com que ele execute a ação programada pelo desenvolvedor.

Exemplo:

Neste exemplo criamos um pequeno programa visual que concatena duas strings.

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# visual.py

# importa modulo
from Tkinter import *

# Cria formulario
formulario = Tk()
formulario.title = "Desenvolvimento Aberto"

# Alimenta variaveis do label
r = StringVar()
r= "Resultado"

# Evento do botão
def callback():
    r = texto1.get() + texto2.get()
    resultado = Label(formulario, text = r)
    resultado.grid(row=4, column=1)

# Cria um novo label
rotulo = Label(formulario, text = "Concatena Strings")
texto1 = Entry(formulario)
texto2 = Entry(formulario)
botao =  Button(formulario, text = "Somar", command = callback)
resultado = Label(formulario, text = r)

# Adiciona Componentes no Grid
rotulo.grid(row=0, column=1)
texto1.grid(row=1, column=1)
texto2.grid(row=2, column=1)
botao.grid(row=3, column=1)
resultado.grid(row=4, column=1)

# Roda o loop principal do tcl
mainloop()

Por default no Visual Studio um projeto visual já cria o primeiro formulário para o desenvolvedor como já vimos no post anterior, e é muito mais fácil desenvolver usando os componentes em Design Time, mas como em Java o C# também pode ser manipulado usando somente código fonte e este tipo de codificação chama-se: código dinâmico. Dependo do tipo de software que você esta desenvolvendo códigos dinâmicos são um recurso extremamente útil.

Desenvolvedores puristas preferem escrever códigos dinamicamente, estes deixam o código mais limpo e mais leve e as vezes até mais rápido  do que IDEs de Design Time, que criam um arquivo extra para gerenciar os componentes e suas posições na tela.

Controles Básicos

Para criar programas em C# você precisa conhecer os controles básicos, programadores iniciantes sabem usar as propriedades de objetos como por exemplo, a classe Size (tamanho) usando o inspetor de objetos, mas na hora de criar controles de tamanho e posições de tela dinamicamente se embaralham um pouco, pois não se pode atribuir os valores diretamente como se faz no inspetor de objetos, é necessário o uso de classes para fazer este trabalho.

Point

Representa um par ordenado de inteiros X e Y de coordenadas que define um ponto em um plano bidimensional.

Size

Armazena um par ordenado de números inteiros, que especificam a altura e largura.

Form

Representa uma janela ou caixa de diálogo que compõe a interface de usuário do aplicativo

Label

Representa o rótulo de texto para um controle e fornece suporte para teclas de acesso.

TextBox

Representa um controle de caixa de texto do Windows.

Button

Representa um controle de botão do Windows.

EventHandler

Representa o método que manipulará um evento que não tem dados do evento. O modelo de evento no .NET Framework. Baseia-se em ter um representante do evento que conecta um evento com seu manipulador.

Exemplo:

Neste exemplo criamos dinamicamente os controles básicos e um evento para um programa que concatena duas strings.

C#


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DesenvolvimentoAberto
{
    public partial class Form1 : Form
    {
        // Cria Componentes
        Label rotulo = new Label();
        TextBox texto1 = new TextBox();
        TextBox texto2 = new TextBox();
        Button botao = new Button();
        Label resultado = new Label();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            // Altera titulo do formulario
            Form1.ActiveForm.Text = "Desenvolvimento Aberto";

            // Seta valores para as propriedades dos objetos
            rotulo.Text = "Concatena Strings:";
            rotulo.Location = new Point(5, 5);

            texto1.Text = "Digite uma String";
            texto1.Location = new Point(5, 30);
            texto1.Size = new Size(200, 20);

            texto2.Text = "Digite uma String";
            texto2.Location = new Point(5, 60);
            texto2.Size = new Size(200, 20);

            botao.Text = "Somar";
            botao.Location = new Point(5, 85);

            // Delega evento OnClick para o botão
            botao.Click += new System.EventHandler(botao_Click);

            resultado.Text = "Resultado:";
            resultado.Location = new Point(5, 110);
            resultado.Size = new Size(300, 20);

            // Adiciona objetos no formulário
            Form1.ActiveForm.Controls.Add(rotulo);
            Form1.ActiveForm.Controls.Add(texto1);
            Form1.ActiveForm.Controls.Add(texto2);
            Form1.ActiveForm.Controls.Add(botao);
            Form1.ActiveForm.Controls.Add(resultado);
        }

        // Método OnClick do botão
        private void botao_Click(object sender, EventArgs e)
        {
            resultado.Text = texto1.Text + texto2.Text;
        }

    }
}

Por default o Eclipse não possui uma perspectiva para Design-Time para componentes AWT e SWING do Java, então escrever códigos de layout à mão pode ser um desafio. Se você não estiver interessado em aprender todos os detalhes de gerenciamento de layout, você pode preferir usar uma ferramenta de Design Time para definir o seu GUI. Uma dessas ferramentas é a da IDE do NetBeans.

Desenvolvedores puristas preferem escrever os layouts na mão, estes deixam o código mais limpo e mais leve e as vezes até mais rápido  do que IDEs de Design Time, que criam um arquivo extra para gerenciar os componentes e suas posições na tela.

Java AWT e Swing possuem muitas classes especificas para o design da GUI chamadas de Layout Manager:

  • BorderLayout
  • BoxLayout
  • CardLayout
  • FlowLayout
  • GridBagLayout
  • GridLayout
  • GroupLayout
  • SpringLayout

Cada uma das classes acima possui suas caracteristas especificas, neste post usaremos uma das mais flexiveis e que ainda possui uma classe de utilidades para adicionar mais poder a suas caracteristicas originais.

Mais informações sobre as classes de layout: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

SpringLayout

SpringLayout é um gerenciador de layout muito flexível que pode emular muitas das características de outros gerenciadores de layout. SpringLayout é, no entanto, de muito baixo nível e, como tal, você realmente só deve usá-lo com um construtor de GUI, ao invés de tentar codificar um gerenciador de layout na mão.

SpringLayout faz o seu trabalho através da definição de relações direcionais, ou restrições, entre as bordas de componentes. Por exemplo, você pode definir a borda esquerda de um componente é uma distância fixa (5 pixels, por exemplo) a partir da margem direita do outro componente.

Spring Utilities

Faz com que os componentes sejam dispostos com o mesmo tamanho lado a lado usando coluna e linha ou também que sejam dispostos em tamanhos diferentes utilizando colunas e linhas.

Action Listner

Toda vez que o usuário digita um caractere ou aperta um botão do mouse, ocorre um evento. Qualquer objeto pode ser notificado do evento. Tudo que o objeto tem que fazer é implementar a interface apropriada e ser registrado como um ouvinte de evento sobre a origem do evento apropriado.

JFrame

É um recipiente de nível superior JFC / Swing, um JFrame contém uma JRootPane como seu único filho. O painel de conteúdo fornecido pelo painel de raiz deve, como regra, conter todos os componentes não-menu apresentados pelo JFrame.

JLabel

Um objeto JLabel pode exibir texto, uma imagem, ou ambos, definir o alinhamento vertical e horizontal e etc.

JTextFielfd

É um componente leve que permite a edição de uma única linha de texto.

JButton

É uma implementação de um botão. Os botões podem ser configurados, e até certo ponto controlados por Ações. Usando uma ação com um botão tem muitos benefícios além de configurar diretamente um botão

Exemplo:

Neste exemplo desenvolvemos um programa visual para concatenar duas Strings, usamos os controles básicos para criar uma janela visual com os componentes de entrada e botões, também utilizamos layouts e a classe Spring Utilities para o design da tela.

Classe #1 – Java

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SpringLayout;

 class GUI implements ActionListener
{
	 // Declara Componentes
	 static JLabel label = new JLabel("Concatena Strings");
	 static JTextField jtexto1 = new JTextField("Digite um palavra");
	 static JTextField jtexto2 = new JTextField("Digite um palavra");
	 static JButton botao = new JButton("Somar");
	 static JLabel resultado = new JLabel("Resultado");

	public void inicalizaComponentes()
	{
        // Seta Valores para componentes e Cria Evento
		// uma void não estatica é necessario para o action listner
		botao.setToolTipText("Clique aqui para somar os valores acima.");
        botao.addActionListener(this);
	}

	 static void addPainel (Container painel)

	 {
		// Cria um layout
		SpringLayout layout  = new SpringLayout();

        // Adiciona layout no container
		painel.setLayout(layout);

        // Adiciona componentes no container
		painel.add(label);
        painel.add(jtexto1);
        painel.add(jtexto2);
        painel.add(botao, painel);
        painel.add(resultado);

        // Utiliza Oracle Spring Utilities
        SpringUtilities.makeCompactGrid(painel, 5, 1, 5, 5, 5, 5);

	 }

	public static void main(String[] args) {

		// Especifica Thread do Swing
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {

            	// Cria um frame
            	JFrame formulario = new JFrame("Desenvolvimento Aberto");

            	// Adiciona o frame no container com os objetos
            	addPainel(formulario.getContentPane());

            	//inicializa os componentes
            	GUI comp = new GUI();
            	comp.inicalizaComponentes();

            	// Seta propriedades do formulario
            	formulario.setSize(300, 200);
                formulario.setVisible(true);

            }
        });

	}

	// Evento do botão
	public void actionPerformed(ActionEvent e)
	{
		String r =  jtexto1.getText() +  jtexto2.getText();
		resultado.setText(r);
	}

}

Classe #2 – SpringUtilities

/*
 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle or the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import javax.swing.*;
import javax.swing.SpringLayout;
import java.awt.*;

/*
 * A 1.4 file that provides utility methods for
 * creating form- or grid-style layouts with SpringLayout.
 * These utilities are used by several programs, such as
 * SpringBox and SpringCompactGrid.
 */
public class SpringUtilities {
    /*
     * A debugging utility that prints to stdout the component's
     * minimum, preferred, and maximum sizes.
     */
    public static void printSizes(Component c) {
        System.out.println("minimumSize = " + c.getMinimumSize());
        System.out.println("preferredSize = " + c.getPreferredSize());
        System.out.println("maximumSize = " + c.getMaximumSize());
    }

    /*
     * Aligns the first <code>rows</code> * <code>cols</code>
     * components of <code>parent</code> in
     * a grid. Each component is as big as the maximum
     * preferred width and height of the components.
     * The parent is made just big enough to fit them all.
     *
     * @param rows number of rows
     * @param cols number of columns
     * @param initialX x location to start the grid at
     * @param initialY y location to start the grid at
     * @param xPad x padding between cells
     * @param yPad y padding between cells
     */
    public static void makeGrid(Container parent,
                                int rows, int cols,
                                int initialX, int initialY,
                                int xPad, int yPad) {
        SpringLayout layout;
        try {
            layout = (SpringLayout)parent.getLayout();
        } catch (ClassCastException exc) {
            System.err.println("The first argument to makeGrid must use SpringLayout.");
            return;
        }

        Spring xPadSpring = Spring.constant(xPad);
        Spring yPadSpring = Spring.constant(yPad);
        Spring initialXSpring = Spring.constant(initialX);
        Spring initialYSpring = Spring.constant(initialY);
        int max = rows * cols;

        //Calculate Springs that are the max of the width/height so that all
        //cells have the same size.
        Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)).
                                    getWidth();
        Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)).
                                    getHeight();
        for (int i = 1; i < max; i++) {
            SpringLayout.Constraints cons = layout.getConstraints(
                                            parent.getComponent(i));

            maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth());
            maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight());
        }

        //Apply the new width/height Spring. This forces all the
        //components to have the same size.
        for (int i = 0; i < max; i++) {
            SpringLayout.Constraints cons = layout.getConstraints(
                                            parent.getComponent(i));

            cons.setWidth(maxWidthSpring);
            cons.setHeight(maxHeightSpring);
        }

        //Then adjust the x/y constraints of all the cells so that they
        //are aligned in a grid.
        SpringLayout.Constraints lastCons = null;
        SpringLayout.Constraints lastRowCons = null;
        for (int i = 0; i < max; i++) {
            SpringLayout.Constraints cons = layout.getConstraints(
                                                 parent.getComponent(i));
            if (i % cols == 0) { //start of new row
                lastRowCons = lastCons;
                cons.setX(initialXSpring);
            } else { //x position depends on previous component
                cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST),
                                     xPadSpring));
            }

            if (i / cols == 0) { //first row
                cons.setY(initialYSpring);
            } else { //y position depends on previous row
                cons.setY(Spring.sum(lastRowCons.getConstraint(SpringLayout.SOUTH),
                                     yPadSpring));
            }
            lastCons = cons;
        }

        //Set the parent's size.
        SpringLayout.Constraints pCons = layout.getConstraints(parent);
        pCons.setConstraint(SpringLayout.SOUTH,
                            Spring.sum(
                                Spring.constant(yPad),
                                lastCons.getConstraint(SpringLayout.SOUTH)));
        pCons.setConstraint(SpringLayout.EAST,
                            Spring.sum(
                                Spring.constant(xPad),
                                lastCons.getConstraint(SpringLayout.EAST)));
    }

    /* Used by makeCompactGrid. */
    private static SpringLayout.Constraints getConstraintsForCell(
                                                int row, int col,
                                                Container parent,
                                                int cols) {
        SpringLayout layout = (SpringLayout) parent.getLayout();
        Component c = parent.getComponent(row * cols + col);
        return layout.getConstraints(c);
    }

    /*
     * Aligns the first <code>rows</code> * <code>cols</code>
     * components of <code>parent</code> in
     * a grid. Each component in a column is as wide as the maximum
     * preferred width of the components in that column;
     * height is similarly determined for each row.
     * The parent is made just big enough to fit them all.
     *
     * @param rows number of rows
     * @param cols number of columns
     * @param initialX x location to start the grid at
     * @param initialY y location to start the grid at
     * @param xPad x padding between cells
     * @param yPad y padding between cells
     */
    public static void makeCompactGrid(Container parent,
                                       int rows, int cols,
                                       int initialX, int initialY,
                                       int xPad, int yPad) {
        SpringLayout layout;
        try {
            layout = (SpringLayout)parent.getLayout();
        } catch (ClassCastException exc) {
            System.err.println("The first argument to makeCompactGrid must use SpringLayout.");
            return;
        }

        //Align all cells in each column and make them the same width.
        Spring x = Spring.constant(initialX);
        for (int c = 0; c < cols; c++) {
            Spring width = Spring.constant(0);
            for (int r = 0; r < rows; r++) {
                width = Spring.max(width,
                                   getConstraintsForCell(r, c, parent, cols).
                                       getWidth());
            }
            for (int r = 0; r < rows; r++) {
                SpringLayout.Constraints constraints =
                        getConstraintsForCell(r, c, parent, cols);
                constraints.setX(x);
                constraints.setWidth(width);
            }
            x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad)));
        }

        //Align all cells in each row and make them the same height.
        Spring y = Spring.constant(initialY);
        for (int r = 0; r < rows; r++) {
            Spring height = Spring.constant(0);
            for (int c = 0; c < cols; c++) {
                height = Spring.max(height,
                                    getConstraintsForCell(r, c, parent, cols).
                                        getHeight());
            }
            for (int c = 0; c < cols; c++) {
                SpringLayout.Constraints constraints =
                        getConstraintsForCell(r, c, parent, cols);
                constraints.setY(y);
                constraints.setHeight(height);
            }
            y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad)));
        }

        //Set the parent's size.
        SpringLayout.Constraints pCons = layout.getConstraints(parent);
        pCons.setConstraint(SpringLayout.SOUTH, y);
        pCons.setConstraint(SpringLayout.EAST, x);
    }
}

Até agora todos os nossos programas Python tinha a saída no terminal do Linux, primeiro usamos o editor de texto Vim para escrever nossos scripts .py, depois mudamos para a IDE do MIT, a Spyder, agora vamos mudar a interface de nossos aplicativos usando a GUI do Linux através do Tkinter.

O que é Tkinter?

O módulo Tkinter (“Interface Tk”) é a interface padrão do Python para o toolkit Tk GUI de Scripts (anteriormente desenvolvida pela Sun Labs).

Ambos Tk e Tkinter estão disponíveis na maioria das plataformas Unix, bem como em sistemas Windows e Macintosh. A partir da versão 8.0, Tk oferece um look and feel nativo em todas as plataformas.

Tkinter consiste de um número de módulos. A interface de Tk é fornecido por um módulo de extensão binário chamado _tkinter. Este módulo contém a interface de baixo nível para Tk, e nunca deve ser usado diretamente por programadores de aplicativos. Geralmente é uma biblioteca compartilhada (ou DLL), mas pode em alguns casos ser ligado estaticamente com o interpretador Python.

Tkinter acompanha a distribuição oficial do interpretador Python. É a biblioteca padrão da linguagem Python. Programas escritos usando a Tkinter são portáveis livremente entre Linux, Unix, Windows e Mac, além da garantia de que qualquer um poderá executar o programa sem precisar instalar bibliotecas extras. Ainda possui uma API simples de se aprender e fácil de lembrar.

Exemplo:

Neste exemplo importamos o módulo tkinter e criamos uma janela  e um label.

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# visual.py

# importa modulo
from Tkinter import *

# Cria formulario
formulario = Tk()

# Cria um variave de Texto.

texto = "Desenvolvimento Aberto\nHello World\nTkinter!!!!"
# Cria um novo label
rotulo = Label(formulario, text = texto)

# Retira espaço desocupado na janela
rotulo.pack()

# Roda o loop principal do tcl
mainloop()

Visual – Introdução – Design Time .NET – C#

Publicado: 7 de março de 2014 em C#

C# é uma linguagem totalmente amigável do ponto de vista visual, segue a linha do antigo Delphi, usando método de design time, onde você pode arrastar os componentes da caixa de ferramentas(toolbox) diretamente para o formulário e inspecionar as propriedades e eventos dos objetos usando sua janela de propriedades. Também é possível criar objetos dinamicamente, para criar um programa visual em C# siga os passos abaixo:

Visual Studio

  1. No menu File, clique em New, Project.
  2. Na caixa de dialogo para projetos C#, escolha  Windows Forms Application.
  3. Nomeie o projeto para Hello e clique em OK.
  4. No modo Design de um duplo clique no Form1 para acessar o arquivo Form1.cs.
  5. Renomeie o namespace para: DesenvolvimentoAberto.
  6. Digite a void Form1_Shown do exemplo abaixo.

Exemplo:

Neste exemplo o C# cria um formulário automaticamente na abertura do projeto e vamos adicionar um objeto label dinamicamente e manipular algumas de suas propriedades.

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DesenvolvimentoAberto
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            // Cria um label dinamicamente
            Label label = new Label();
            label.Text = "Hello World";
            label.Visible = true;

            // troca o nome do formulario na barra de titulos
            Form1.ActiveForm.Text = "Hello World";

            // Adiciona o label no formulario
            Form1.ActiveForm.Controls.Add(label);

        }
    }
}

Você pode criar um aplicativo Win32 quando você quer fazer um aplicativo de desktop nativo que tem uma interface de usuário baseada em janelas e pode ser executado em versões do Windows a partir do Windows 95 para o Windows 8.1. Você pode usar qualquer uma das edições do Visual Studio, exceto a versão Express.

Um aplicativo Win32 é o termo convencional para um aplicativo que usa a mensagem de loops para lidar com  as mensagens do Windows diretamente em vez de usar um quadro como o Microsoft Foundation Classes (MFC), o Active Template Library (ATL), ou o .NET Framework..

Conceito Win32

Embora o termo é “Win32“, pode se referir a qualquer aplicativo de 32 bits ou um aplicativo de 64 bits. Um aplicativo Win32 em C ++ pode usar C Runtime (CRT) e Standard Template Library (STL), classes, funções, objetos COM, e qualquer uma das funções públicas do Windows, que coletivamente são conhecidas como a API do Windows.

Usando a API do Windows

Em nosso artigo de introdução ao visual C++ explicamos os conceitos básico da programação para Windows, neste post mostramos como isto é feito na pratica.

Basicamente uma aplicação para Windows onde não se utiliza nenhum método da Microsoft (Framework ou biblioteca de classes), além de suas APIs, podemos afirmar que um programa mínimo para o Windows que pode rodar em qualquer versão do sistema operacional é composto basicamente de duas funções, a primeira WinMain é responsável por criar uma aplicação de janelas e a segunda função chamada WndProc é responsável pelas mensagens do Windows. Existem muitas outras funções mas trabalhar com elas exigem um nível avançado de conhecimento em programação e da arquitetura do sistema operacional, veremos aos poucos os conceitos de arquitetura, tipos de variáveis e  regras básicas para utilizar as APIs do Windows.

 

Visual Studio

Para criar um programa Visual em C++ siga os passos abaixo:

  1. No menu File, clique em New, Project.
  2. Na caixa de dialogo para projetos C++, escolha Win32 Project.
  3. Nomeie o projeto de Hellocpp.
  4. No wizard de boas vindas, clique em Next.
  5. Na janela de parâmetros clique em Empty Project e clique no botão Finish.
  6. No Solution Explorer, clique com o botão direito em cima do nome do seu projeto e escolha: Add, New Item.
  7. Escolha um arquivo .cpp e o nomeie para hello.cpp.

Exemplo:

Neste exemplo criamos uma janela visual em mensagem de loops. Você pode usar o este código como um padrão para criar outros aplicativos baseados em Win32.

C++

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Variaveis globais

// Classe da janela principal.
static TCHAR szWindowClass[] = _T("win32app");

// String que aparece na barra de titulos
static TCHAR szTitle[] = _T("Win32 Guided Tour Application");

HINSTANCE hInst;

// Declarações de funções incluidas neste modulo:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = szWindowClass;
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

	if (!RegisterClassEx(&wcex))
	{
		MessageBox(NULL,
			_T("Call to RegisterClassEx failed!"),
			_T("Win32 Guided Tour"),
			NULL);

		return 1;
	}

	hInst = hInstance; // Guarda a instancia e manipula a variavel local.

	// Parametros para criar a janela
	// szWindowClass: nome da aplicação
	// szTitle: texto da barra de titulos
	// WS_OVERLAPPEDWINDOW: tipo da janela
	// CW_USEDEFAULT, CW_USEDEFAULT: posição inicial (x, y)
	// 500, 300: tamanho inicial (width, length)
	// NULL: parent desta janela
	// NULL: esta aplicação não tem uma barra de menu
	// hInstance: o primeiro parametro da WinMain
	// NULL: não é usado nesta aplicação

	HWND hWnd = CreateWindow(
		szWindowClass,
		szTitle,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT,
		500, 300,
		NULL,
		NULL,
		hInstance,
		NULL
		);

	if (!hWnd)
	{
		MessageBox(NULL,
			_T("Call to CreateWindow failed!"),
			_T("Win32 Guided Tour"),
			NULL);

		return 1;
	}

	// Parametros do ShowWindow :
	// hWnd: valor retornado do CreateWindow
	// nCmdShow: o quarto parametro do WinMain

	ShowWindow(hWnd,
		nCmdShow);
	UpdateWindow(hWnd);

	// Menssagem principal do loop:
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processa menssagem para a janela principal
//
//  WM_PAINT    - pinta a janela principal
//  WM_DESTROY  - posta e cancela menssagem e retorna
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR greeting[] = _T("Hello, World!");

	switch (message)
	{
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);

		//Aqui sua aplicação é criada.
		// Para esta introdução nos só imprimiremos, "Hello, World!"
		// no canto esquerdo superior da janela.
		TextOut(hdc,
			5, 5,
			greeting, _tcslen(greeting));
		// fim da aplicação de layout.

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
		break;
	}

	return 0;
}