segunda-feira, 1 de julho de 2013

Verificar se um ano é bissexto

Hoje vou mostrar como podemos verificar se um ano é bissexto usando uma função bem simples:

bool IsBissextile( int year )
{
return ( year % 4 == 0) && ( ( year % 400 ) == 0 || ( year % 100 ) > 0 );
}

O que fizemos aqui foi verificar se o ano é divisível por 4, ou seja, verificamos se o módulo da divisão é igual a zero, depois verificamos uma segunda condição, o ano não deve ser divisível por 100 ao menos que ele seja divisível por 400, se as duas condições forem verdadeiras é porque o ano é bissexto.

Vamos testar a função verificando se o ano atual é bissexto, para isso vamos usar a classe wxDateTime.

int year = wxDateTime::Today().GetYear();

if( IsBissextile( year ) )
wxMessageBox( wxT( "É bissexto" ) );
else
wxMessageBox( wxT( "Não é bissexto" ) );

Até a próxima dica

quarta-feira, 13 de março de 2013

ScreenShot com wxWidgets

Hoje vamos ver como podemos tirar um screenshot usando wxWidgets.

Em primeiro lugar vamos ver quais as classes que usaremos para isso:

O wxWidgets trabalha com alguns tipos de DC ou Device Context, cada um deles é responsável por selecionar um determinado objeto para que possamos desenhar ou obter informações de imagem, um dos Dcs que já expliquei por aqui foi o wxPaintDC, com ele, selecionamos um objeto derivado de wxWindow e podemos desenhar nesse objeto, hoje vamos ver outros dois Dcs, o wxScreenDC, que seleciona a tela do Desktop, fazendo com que possamos convertê-la em imagem, depois usaremos o wxMemoryDC que seleciona um wxBitmap e consegue desenhar no mesmo.

Vamos criar uma função chamada GetScreenShot que vai nos retornar um wxBitmap:

wxBitmap GetScreenShot()
{

	wxSize mSize = wxGetDisplaySize();

	wxBitmap mBmp = wxBitmap(mSize.x, mSize.y);

	wxMemoryDC mDC(mBmp);

	wxScreenDC sDC;

	mDC.Blit(0, 0, mSize.x, mSize.y, &sDC, 0, 0);

	mDC.SelectObject(wxNullBitmap);

	return mBmp;

}

Na linha 1 temos a declaração da função.

Na linha 4 pegamos o tamanho do nosso Desktop, incluindo a área do painel, usando a função wxGetDisplaySize() que me retornará um wxSize.

Na linha 6 criamos um wxBitmap com as dimensões da nossa Área de Trabalho.

ha 8 criamos o wxMemoryDC passando como parâmetro o wxBitmap, ele será responsável por plotar a imagem da Área de Trabalho em nosso bitmap.

Na linha 10 criamos o wxScreenDC, ele será responsável por pegar a imagem da Área de Trabalho, ele fará isso automaticamente.

Em 12 temos a parte mais complicada da função, é quando plotamos a imagem da área de trabalho no bitmap usando a função Blit.

Os parâmetros da função Blit que usaremos aqui são:

O primeiro e o segundo parâmetros são usados para passar a posição inicial do bitmap onde queremos desenhar, aqui uso 0 e 0 pois quero que a Área de Trabalho seja plotada iniciando nessas coordenadas.

O terceiro e quarto parâmetros são a altura e largura que irei usar na plotagem, no caso o tamanho total da área de trabalho.

O quinto parâmetro é um ponteiro para o DC que quero “colar” na imagem, no caso o wxScreenDC com a imagem da nossa Área de Trabalho.

O sexto e o sétimo parâmetros definem a partir de qual ponto do DC que estamos plotando será iniciado o processo, aqui eu usei 0 e 0 mais uma vez pois quero a área total do mesmo.

Na linha 14 removo o mBmp do controle do wxMemoryDC.

E em 16 finalizo retornando o mBmp na função.

Vejam que com poucas linhas conseguimos obter um ScreenShot da nossa área de trabalho.

Para testar a função:

class wxAppSS : public wxApp
{
    public:
        virtual bool OnInit(void);
};

bool wxAppSS::OnInit(void)
{
    wxInitAllImageHandlers();
    GetScreenShot().SaveFile(wxT("test.png"), wxBITMAP_TYPE_PNG);
    return false;
}

IMPLEMENT_APP(wxAppSS)
Resultado Final no Mint/Linux

segunda-feira, 19 de novembro de 2012

wxAutomationObject – Parte 5 – Contando o número de Workbooks abertos em uma Instância

Hoje vamos criar uma função simples para contar o número de Workbooks abertos na instância do Excel que estamos trabalhando.

Na classe wxAutomationExcel em public digitamos a declaração da função.

int wxAutomationExcel::GetWorkbookCount()

no arquivo mexcel.cpp sua contrução.

int wxAutomationExcel::GetWorkbookCount()
{
     const wxVariant workbooksCountV = this->GetProperty(wxT("Workbooks.Count"));
   
     if (workbooksCountV.IsNull())
    {
        wxLogError(wxT("Problemas ao executar a operação"));
        return 0;
    }

    const long workbooksCount = workbooksCountV;

    return workbooksCount;
}

Aqui estamos trabalhando mais uma vez com propriedades, no caso, chamamos a propriedade Workbooks.Count, ela retornará um long como resultado, veja que se meu wxVariant for igual a nulo, eu retorno o 0, eu faço assim, pois se existirem Workbooks na instância, ele será maior que zero.

Para testar a função:

wxAutomationExcel m_excel;

//Primeiro pegamos a instância do Excel,
//se ela não existir eu retorno Nulo
if(!m_excel.GetExcelInstance())
     return;

//Pego o número de Workbooks abertos...
int getWBCount = m_excel.GetWorkbookCount();

//Exibo uma mensagem com o valor.
wxMessageBox(wxString::Format("Número de Workbooks abertos\n%d", getWBCount));

Lembrando que essa função conta apenas o número de Workbooks que estão abertos na instância que estamos controlando, se tivéssemos 5 instâncias rodando, cada uma com 1 Workbook aberto, o valor retornado seria 1.

Uma imagem com o resultado do teste, veja que tenho 3 Workbooks abertos, todos na instância que eu estou controlando.



sábado, 27 de outubro de 2012

wxAutomationObject – Parte 4 – Exibir ou esconder o Excel

Agora começaremos a trabalhar com propriedades, na classe wxAutomationObject usamos dois métodos para isto, um chamado GetPropert para pegarmos o valor de uma propriedade e PutPropert para alterarmos uma propriedade, note que a partir daqui iremos utilizar com frequência wxVariants, então recomendo que vocês leiam a documentação da mesma.

Primeiro vamos verificar se o Excel está visível ou se está correndo em segundo plano.

Na classe wxAutomationExcel em public digitamos a declaração da função.

bool GetVisible();

no arquivo mexcel.cpp sua contrução.

bool wxAutomationExcel::GetVisible()
{
     if(this == NULL)
         return false;

     wxVariant m_show = this->GetProperty(wxT("Visible"));

     return m_show.GetBool();
}

No código acima, vemos o uso do método GetProperty, passamos para o mesmo o nome da propriedade que queremos pegar o valor e passamos esse para um wxVariant, veja que antes verifico se wxAutomationExcel é nulo, se o Excel estiver visível nossa função retornará verdadeiro, caso contrário, falso...

Agora, vamos alterar essa propriedade, escondendo ou exibindo a instância do Excel que estiver setada em nosso wxAutomationExcel.

Na classe wxAutomationExcel em public digitamos a declaração da função.

bool SetVisible(bool visible);

no arquivo mexcel.cpp sua contrução.

bool wxAutomationExcel::SetVisible(bool visible)
{
     if(this == NULL)
         return false;

    if(!this->PutProperty(wxT("Visible"), visible))
    {
        wxLogError(wxT("Excel não pode ser exibido"));
         return false;
    }

     return true;
}

Nessa função utilizamos o método PutProperty, esse método é utilizado para pegarmos alguma propriedade do objeto setado em nossa classe, passamos primeiro o nome da propriedade e depois o valor que queremos dar para ela, no caso da propriedade Visible passamos um valor booleano.

Vale lembrar que essa classe está trabalhando apenas com o Excel.Application, então todos os métodos e propriedades passados como parâmetros servem apenas para a aplicação em si.

Para testarmos as duas funções apresentadas nesse tutorial:

wxAutomationExcel m_excel;

if(!m_excel.GetExcelInstance())
     return;

//ou
//if(!m_excel.CreateExcelInstance())
//   return;

//Vejo se o Excel está visível...
if(m_excel.GetVisible())//...se sim...
     m_excel.SetVisible(false);//...escondo...
else//...se não...
     m_excel.SetVisible(true);//...exibo o mesmo...

No próximo tutorial iremos iniciar com Workbooks, até.

quarta-feira, 24 de outubro de 2012

wxAutomationObject – Parte 3 – Criando uma nova instância do Excel.

Criaremos agora uma função que executa uma nova instância do Excel, ela  será publica e do tipo booleana também.

Na classe wxAutomationExcel em public digite a função.

bool CreateExcelInstance();

no arquivo mexcel.cpp sua contrução.

bool wxAutomationExcel::CreateExcelInstance()
{
     if(!this->CreateInstance(wxT("Excel.Application")))
     {
         wxLogError(wxT("Não foi possível criar a instância"));
         return false;
     }

     return true;
}

Nesse código utilizamos outro método da classe wxAutomationObject, CreateInstance passando para o mesmo a string "Excel.Application", ela retornará verdadeiro se conseguir criar uma nova instância do Excel passando o ponteiro para nosso wxAutomationExcel, se ocorrer algum problema ela retornará falso e nosso wxAutomationExcel será nulo.

Para testar a função:

wxAutomationExcel m_excel;
if(!m_excel.CreateExcelInstance())
     return;

//Aqui poderíamos seguir...

wxAutomationObject – Parte 2 – Verificando se o Excel está em execução:

Vamos iniciar criando uma função que verifica se o Excel está em execução, ela será pública do tipo booleana, se uma instância do Excel estiver em execução ela retornará verdadeiro, se não, retornará falso.

Na classe wxAutomationExcel em public digite:

bool GetExcelInstance();

no arquivo mexcel.cpp sua construção.

bool wxAutomationExcel::GetExcelInstance()
{
     if(!this->GetInstance(wxT("Excel.Application")))
     {
         wxLogError(wxT("Excel não está em execução"));
         return false;
     }

     return true;
}


No código acima vemos a função GetInstance da classe wxAutomationObject, ela verificará se o Excel está rodando, se o mesmo estiver executando, ele passará o ponteiro da aplicação para nosso wxAutomationExcel e retornará verdadeiro, nesse ponto já podemos trabalhar com a automação, se o Excel não estiver rodando, ele retornará falso e nosso wxAutomationExcel será nulo, ou seja, não estará preparado para executar a automação.

Uma coisa que você deve ter em mente é que, se mais de uma instancia do Excel existir, ele  pegará como ponteiro a primeira instancia criada.

Para testar essa função :

wxAutomationExcel m_excel;

if(!m_excel.GetExcelInstance())
     return;

//Aqui poderíamos prosseguir...

segunda-feira, 22 de outubro de 2012

wxAutomationObject - Excel - Reiniciando

Voltando com os tutoriais sobre wxAutomationObject, como sempre, vou postando as coisas sem muito critério e as elas acabam ficando um pouco complicadas, vou reiniciar do zero pra explicar melhor como as coisas funcionam, e criar classes para gerenciar o conteúdo das explicações.

wxAutomationObject é uma classe que fornece um ponteiro IDispath, que nada mais é que uma referência para um COM/OLE Object, permitindo a execução e automação do Excel, por exemplo.

*Importante: wxAtomationObject é uma classe exclusiva para wxMSW, ou seja, você só conseguirá compilar os exemplos no Sistema Operacional Windows.

Para entendermos a estrutura das classes, vamos entender como é estruturado um arquivo do Excel.


No diagrama podemos ver claramente cada objeto que iremos utilizar:

A instância do programa seria o Excel que está sendo executado na memória naquele momento, seria o Excel.exe sendo executado.

O Workbook é a pasta de trabalho ou o arquivo em si.

Dentro de um Workbook podemos ter uma ou mais planilhas, que no diagrama vemos como Sheet ou Worksheet, por padrão, ao iniciarmos um novo Workbook o mesmo conterá 3 planilhas (Sheet).

E as células, que são os locais onde iremos inserir ou ler os dados que queremos.

Talvez as coisas fiquem mais claras com a imagem abaixo.



Em 1, temos o Excel em execução, é ele que vai gerenciar a automação e execução dos procedimentos e propriedades.

Em 2 temos a pasta de trabalho, é nosso arquivo em si, ele que vai conter todas as nossas planilhas, usaremos o mesmo para salvar o documento ou inserirmos e deletarmos planilhas.

Em 3 temos as planilhas que irão conter as células, podemos alterar seu nome, por exemplo, e gerenciar as células existentes.

Em 4, as células, elas irão conter os valores, como data, textos, números, etc... podemos alterar suas propriedades também, como a cor de fundo, tipo de borda...

Agora que temos de forma clara como é a estrutura de um arquivo Excel, assim como de sua instância, vamos iniciar com os códigos. Criaremos 2 arquivos para armazenar as classes, um chamado mexcel.h e outro mexcel.cpp.

Primeiro iremos trabalhar com uma classe que vai representar o Excel em si, vou chamá-la de wxAutomationExcel e ela será derivada de wxAutomationObject, ele será aqui na nossa estrutura de desenvolvimento, a “Instância”.

No arquivo mexcel.h digite:

#include <wx/wx.h>
#include <wx/msw/ole/automtn.h>

class wxAutomationExcel: public wxAutomationObject
{
public:
          wxAutomationExcel();
          ~wxAutomationExcel();
private:
};

E no arquivo mexcel.cpp:

#include "mexcel.h"

wxAutomationExcel::wxAutomationExcel():wxAutomationObject()
{
}

wxAutomationExcel::~wxAutomationExcel()
{
}

No próximo tutorial vamos iniciar com as funções que irão fazer parte da classe.