quinta-feira, 21 de fevereiro de 2008

Erro no processamento de XML: declaração xml não está

Erro no processamento de XML: declaração xml não está no início da entidade externa

Probleminha bizonho esse!
Essa mensagem de erro estava retornando ao acessar a URL do RSS de um site. Pra piorar, lá pelas tantas observei que o XML gerado, pelo script PHP, funcionava no IE, contudo, no Mozila, não. No inicio imaginei logo que pudesse ser incompatibilidade com o Mozila, tipo alguma tag que estava usando buggava o bagulho ... Mas, que nada ....


Para resolver o problema:

Veja o código fonte do XML que o seu script de servidor (seja JSP, PHP, ASP, ou mesmo Delphi) gerou (chame a URL http://SeuXMLouRSS ... o Browser vai exibir a mensagem de erro e veja o fonte) e verifique se há espaços em branco ou outras coisas esquisitas antes da declaração:
  
"<?xml version=....".


Caso verdadeiro, se houver, o Firefox não vai conseguir interpretar o XML. A mensagem de erro é bem clara:

Posição: [tal ...]
Número da linha 1, Coluna 2:

Portanto, verifique que vai haver linhas em branco no fonte. No meu caso, o fonte estava assim:


.
.
//Aqui tem espaço em braco
<?xml version="1.0" encoding="ISO-8859-1" ?>




<rss version="2.0">
<channel>
.
.


Depois de uma pesquisa rápida no Google, num Fórum um louco mencionou a questão das linhas em branco. Quando consegui fazer com que o script PHP fizesse isso:



<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="2.0">
<channel>
<title>Blablablah- Notícias</title>
<link>http://www.bleng.com.br</link>
.
.


Sucesso!! O bagulho funfou!!!
Veja como ficou o script PHP .....


<?
header("Content-type: application/xml"); echo "<?xml version=\"1.0\"
encoding=\"ISO-8859-1\" ?>\n";
include("../../Conn/ZN_Conexao.php");
$sql = "SELECT
blah, Bleng, Landjah
FROM
Wandjah
WHERE
blah = '2'
ORDER by bleng DESC
LIMIT 5";
$query = mysql_query($sql);

?>
.
.
.

Artigo completo (View Full Post)

segunda-feira, 18 de fevereiro de 2008

Cifra

Pré-requisito:

Para um entendimento pleno do sistema de notação musical “Cifra” e necessário o conhecimento prévio dos seguintes assuntos:

* Intervalo.
* Escala Diatônica:
o Maior.
o Menor Natural.
o Menor Harmônica.
o Menor Melódica.
* Ciclo de Quartas e de Quintas.


Definição:

Trata-se de uma simbologia universal desenvolvida para representar um acorde e/ou uma situação harmônica. Ela não deve, de modo geral, induzir ou mesmo predeterminar qualquer informação sobre a posição do acorde, exceto quando se refere a uma inversão do baixo, ou em alguns casos específicos (esses casos devem ser tratado como exceção, não como forma geral). Até hoje na música ainda não foi definido um padrão único de cifragem. Teóricos e estudiosos, ainda lutam pela adoção e difusão de um padrão mais homogêneo. Por isso, e bastante comum encontrarmos divergência de opiniões e simbologias diferentes para cifragem. Um nome de destaque nesse contexto é o professor Ian Guest.

Objetivo:

A Cifra traz na sua essência o objetivo de indicar o “modo” do acorde, a escala e a função harmônica do momento. Com o uso da Cifra evita-se a notação do acorde em pauta, com isso ganhamos em legibilidade e interpretação do trecho musical. Além disso, a utilização da Cifra enfatiza a criatividade do músico, na medida em que ela da liberdade para o mesmo escolher a posição do acorde mais favorável a sua sensibilidade em relação ao tema, o qual executa, bem como os recursos delimitados por seu instrumento.

Devemos evitar ao Cifrar um acorde:

1) Over informação.

Utilização de símbolos que possam, a primeira vista, confundir o leitor, provocando um interpretação equivocada do acorde.

2) Dispensa-se: O emprego de sinais matemáticos ou quaisquer outros que não possuam sentido musical. Exemplo: Operador de soma “+” e operador de subtração “–”.

Uma cifragem de difícil entendimento, bem como as que foram escritas com over informação, não significam um alto nível de conhecimento de harmonia. Muito pelo contrário, justamente porque a inteligência do emprego da cifragem é refletido na fácil visualização e interpretação do significado lógico dos movimentos harmônicos.
É fundamental que a programação visual de uma música cifrada seja clara, de fácil entendimento.


Cifrando Acordes:
Usamos as sete primeiras letras, maiúsculas, do alfabeto para representar as sete notas musicais. Partindo da nota Lá até a nota Sol, respectivamente:

  1. Lá = A
  2. Si = B
  3. Dó = C
  4. Ré = D
  5. Mi = E
  6. Fá = F
  7. Sol = G


Na Cifra, a letra maiúscula que indica o carde, informa quem é a nota fundamental do acorde. Ou seja, a nota mais grave (que dá nome ao acrode) quando o acorde se encontrar no estado fundamental. Quando a fundamental for uma nota acidentada acrescentamos a letra Maiúscula um sinal de sustenido (#) ou bemol (b) imediatamente a direita da mesma. Exemplo:

* C# (Dó sustenido)
* Eb (Mi bemol)

Quanto ao modo do acorde

Acorde Maior: Simplesmente não é usado nenhum símbolo que indique isso. Ou seja, é usado somente a letra maiúscula. Em caso de acidente, como mencionado acima, usamos o sustenido e o bemol imediatamente a direita da letra.

Acorde Menor: Para isso usamos a letra “m”, em minúsculo, imediatamente a direita da letra (e o símbolo de acidente, se for o caso). Exemplo:

Cm (Dó menor)

Fm (Fá menor)

Bbm (Si bemol menor)

C#m (Dó sustenido menor)


OBS: Todo acorde subentende uma ou mais escalas, na cifragem de acordes é imprescindível que a simbologia usada deixe muito claro qual a escala (ou quais são as escalas) sobre a qual se estrutura o acorde cifrado.

Notas adicionais nos acordes:

Para indicar a amplitude de um acorde podemos usar algarismos. Os números representam o grau da nota adicional. Embora não seja obrigatório o uso desse recurso, pois o uso de notas adicionais pode ser feito implicitamente. Lembre-se que a Cifra não se ocupa de informar a forma ou quantidade de notas no acorde, pois como foi dito anteriormente a liberdade para o músico montar o acorde cifrado é precedente. Toda via, em muitos casos é conveniente fazer isso explicitamente, principalmente quando a presença da nota adicional não for uma coisa obvia.

Cifras para notas adicionais explicitas:

* Sétimo Grau: A classificação para o sétimo grau define dois intervalos: Refere-se ao sétimo grau da escala sobre a qual o acorde é construído.
A) Sétima Maior: Usa-se o algarismo “7” sucedido da letra “M” maiúsculo. Exemplo:

+ C7M – Dó maior com sétima maior (Escala mior).
+ F#7M – Fá sustenido maior com sétima maior (Escala maior).
+ Ebm7M - Mi bemol menor com 7 maior (escalas menor harmônica ou melódica).

B) Sétima Menor: Usa-se apenas o algarismo “7”. Exemplo:

+ C7 – Dó maior com sétima menor (Escala maior).
+ F#7 – Fá sustenido maior com sétima menor (Escala Maior).
+ Em7 – Mi menor com sétima menor (Escala menor natural).


* Nono Grau: A classificação para o nono grau define três intervalos: Referem-se ao nono grau da escala sobre a qual o acorde é construído.
A) Nona Maior: Usa-se apenas o algarismo “9”. Exemplo:
  + D9 – Ré maior com nona maior (Escala Maior).

B) Nona Menor: Usa-se o algarismo “9” precedido do símbolo de bemol “b”
entre parênteses. Exemplo:

+ D7(b9) – Ré maior com sétima menor e bemol nove (Escala menor
harmônica ou melódica).
+ Ab7(b9) – Lá bemol maior com sétima menor e bemol nove (Escala menor
harmônica ou melódica).
C) Nona Aumentada: Exclusiva para acordes dominantes. Usa-se o algarismo “9” precedido do símbolo de sustenido “#” entre parênteses. Exemplo:
  + D7(#9) – Ré maior com sétima menor e nona aumentada (Escala menor harmônica ou
melódica).
+ Ab7(#9) – Lá bemol maior com sétima menor e nona aumentada (Escala menor
harmônica ou melódica).

* Quarto Grau: A classificação para o quarto grau define dois intervalos: Refere-se ao quarto ou décimo primeiro grau da escala sobre a qual o acorde é construído, convencionalmente para acorde maiores usamos o quarto grau como referência, ao passo que para acordes menores usamos o décimo primeiro.
A) Quarta Justa: Usa-se o algarismo “4” ou “11”. Exemplo:
  + C4 – Dó maior com Quarta (Escala maior, implicitamente define a supressão do
terceiro grau nesta escala neste acorde).
+ F#4 – Fá sustenido maior com sétima maior (Escala maior, implicitamente
define a supressão do terceiro grau da escala neste acorde).
+ Ebm11 - Mi bemol menor com décima primeira maior (escalas menor
harmônica, melódica ou natural).

B) Quarta Aumentada: Exclusivamente só aparece em acordes maiores. Usa-se
apenas o algarismo “#11” entre parêntese. Exemplo:
  + C7(#11) – Dó maior com sétima menor e décima primeira aumentada (Escala menor
melódica).
+ F#7M(#11) – Fá sustenido maior com sétima Maior e décima primeira aumentada
(Escala Maior).

* Décimo terceiro: Refere-se ao sexto ou décimo terceiro grau da escala sobre a qual o acorde é construído, convencionalmente para acordes maiores dominantes usamos o décimo terceiro grau como referência, ao passo que para os demais acordes (não dominantes) usamos o sexto. A classificação para o décimo terceiro grau define dois intervalos:
A) Décima terceira ou sexta: Usa-se o algarismo “6” ou “13”. Exemplo:
   + C6 – Dó maior com sexta (Escala maior, função harmônica não dominante).
+ Ab13 – Lá bemol treze (Escala maior ou menor harmônica, função harmônica
dominante, significa o mesmo que C7(13)).
+ Dm6 – Ré menor com sexta (escala menor natural, ou melódica).

B) Décima terceira Menor ou Bemol treze, sexta menor ou bemol seis: Exclusivo
para acordes menores ou maiores com função harmônica dominante. Usa-se o algarismo “6” ou “13” sucedido do sinal de bemol “b” entre parêntese. Exemplo:
    + Cm(b6) – Dó menor com sexta menor, ou bemol seis (Escala menor, natural ou
harmônica).
+ Ab7(b13) – Lá bemol com sétima menor e bemol treze (Escala menor, natural
ou harmônica).


Considerações finais:

* Toda alteração ou acidentes sobre qualquer grau da escala, numa cifragem deverá ser grafado entre parênteses. Exemplo:

o A7M(#11) – Lá maior com sétima maior e décima primeira aumentada.
o Ebm7(b5) – Mi bemol menor com quita diminuta e sétima menor (Ou Mi bemol
menor meio diminuto).
o G7(b13) – Sol maior com sétima menor e bemol treze.

* É proibido cifragem de inversão de acorde com notas de tensão no baixo, pois essa simbologia não define nenhuma função harmônica, ou na maioria das vezes o som do acorde significa algum outro acorde convencional. Exemplo:

o G7M(#11) /F#
As notas que compõem essa cifra significam um F#m11(b9) ou um F#4(b9).


Como você pôde observar, uma correta interpretação de um trecho harmônico cifrado em muitas situações vai depender de um sólido conhecimento prévio de analise harmônica.

Artigo completo (View Full Post)

sexta-feira, 15 de fevereiro de 2008

Syntax Highlight para Bloggers

What about, this?

Yes, we have!!! Not banana, however ...


Syntax Highlight é uma funcionalidade, presente em alguns editores de texto, que tem a finalidade de tornar o conteúdo digitado nele mais legível (textos e códigos mais inteligíveis). O que ele faz é formatar o texto automaticamente, no imediato momento em que ele esta sendo digitado, com cores, fontes e estilos diferentes de maneira a destacar a categoria das palavras, diferenciando símbolos, sinais ou números digitados uns dos outros. Isso é um auxílio fundamental para programadores, porque essa funcionalidade destaca a estrutura tanto das linguagens de programação, quanto as de marcação. Alem destacar também os erros de sintaxe que podem eventualmente ocorrer durante a implementação de um programa.
Portanto, devemos considerar que o Syntax Highlight é uma forma estratégica, que explora um recurso didático para prover maior legibilidade destacando o contexto do código digitado num editor. Isso é extremamente conveniente para para outros contextos extra editores de texto também. Como no caso de web pages, pois formatar texto no HTML cru, na base do ponteiro e da marreta, não é tarefa pra qqr um. Isso, sem comentar o fato que mesmo assim fica uma "M" (hehehehh).


Já faz algum tempo que tenho conversado com o Felipe sobre conseguirmos um para o Estação ZN. Essa coisa de ficar manualmente destacando as palavras reservadas e comentários, estava me dando um trabalho absurdo. Eu sei que maluquice minha fazer isso, mas agora eu posso ver o meu código formatadinho, sem overhead de trabalho, e isso faz mto feliz!! Hehhehehe ....

Indo ao que interessa:
Eu usei o componente do “uncle Google”: SyntaxHighlighter. Como vocês poderão ver, ele é totalmente escrito em Javascript e CSS, muito simples de implementar, bem fácil de entender e o melhor de tudo: É eficiente, funciona, e suporta diversas linguagens!!!
Aqui vc poderá encontrar um tutorial de como usar no seu blog evitando um probleminha de inconpatibilidade com o a tag "
" em função da formatação de estilo do "Blogger" (embora , baste para isso vc dar uma olhada no fonte do Estação ZN -- últimas linhas).
Eu simplesmente, descaradamente, copiei o que ele descreveu (hehhehe ... cara, I just don’t have enough time).
O Felipe postou um comentário sobre e colocou exemplos.
Ah! vc vai precisar fazer upload dos fontes do componente para algum servidor. Eu usei o Google Pages ("uncle Google" patrocinado geral) .
So ... enjoy yourself!!!





Artigo completo (View Full Post)

quarta-feira, 13 de fevereiro de 2008

Olha aí a galera do Estação ZN trabalhando

Olá novamente caros amigos do blog.

Com 1 ano de vida o ZN está melhorando a cada dia. Agora nossa novidade é Syntax Highlight! Gerson meus parabéns! Ficou ótimo. E foi uma honra pra mim ver a ferramenta funcionando primeiro em meus posts.

Agora nossos códigos postados no ZN vão ficar assim:

Delphi

function Soma(const a: Integer; const b: Integer): Integer;
begin
Result := a + b;
end;


C#

public int Somar(int a, int b) {
return a + b;
}


Java

public int somar(int a, int b) {
return a + b;
}


XML

<dados>
<codigo>1</codigo>
<nome>Felipe</nome>
</dados>


O ZN que já era muito bom (hehe) agora ficou ainda melhor. Mais uma vez valeu e parabéns Gersão! Grande abraço para todos

Artigo completo (View Full Post)

domingo, 10 de fevereiro de 2008

Apresentando dados em XML com XSL

Olá a todos novamente. Depois de um bom tempo fora as coisas se ajeitaram e o tempo acabou sobrando.

Comemoramos 1 ano do Estação ZN - Parabéns aos que postam e muitíssimo obrigado aos que dedicam um pedaço de seu tempo para ler.

O projeto começou com o intuito de ajudar a nós mesmos e também todos que compartilham das idéias, dúvidas e do material apresentado aqui.

Bem, agora vamos falar do assunto do post: Exibindo um documento XML formatado com folhas de estilo XSL

A maneira padrão de apresentar informações para o usuário na Web é o HTML. Esta linguagem começou orientada à formatação do texto a ser exibido para o usuário. Atualmente, com CSS o foco mudou um pouco: agora o objetivo é a informação, e usamos os estilos adequados à entidade que queremos exibir. Então, nas nossas páginas dinâmicas, nós produzimos HTML já formatado via código para exibir os dados.

Está se tornando cada vez mais comum o uso de WebServices (aplicações remotas invocadas através de HTTP e usando o padrão XML para troca de informações) para integrar aplicações na Web, além de outras tecnologias e paradigmas que usam o formato XML para compor resultados vindos do banco de dados. A questão é: como vamos exibir para o usuário as informações que ele quer/precisa ver de forma que ele entenda e que se "encaixe" no layout do site? Simples, vamos "destrinchar" o XML e a partir dele criar um documento HTML formatado, tudo via código. Brincadeira! Hehe...

É aqui que entra em cena as folhas de estilo para XML, as XSL ou XSLT (dois nomes, mesma coisa). Estas folhas de estilo diferem um pouco do CSS porque, enquanto o CSS criar regras de formatação para alguns elementos e classes para serem aplicadas, o XSL funciona como um "documento de apresentação", ou seja, um documento HTML onde indicamos onde cada elemento do documento XML vai aparecer. Como assim? Vamos ver na prática as duas implementações:

HTML:

folha de estilos: estilos.css


p {
font: normal 11px arial;
color: black;
}

.info-cliente {
font: bold arial 15px;
color: red;
}

#grid {
background: #eaeaea;
}


documento HTML: doc.html


<html>
<head>
<style type="text/css">
@import url(estilos.css);
</style>
</head>

<body>
<p>Parágrafo</p>

<div class="info-cliente">Formatação info-cliente</div>

<div id="grid">Grid</div>
</body>
</html>



Aqui o foco do documento é o layout e a informação é disposta junto com o ele.

Vamos ver agora um exemplo de XML com XSL:

folha de estilos: dados_cliente.xsl


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='html' version='1.0' encoding='iso-8859-1' indent='yes'/>
<xsl:template match="/">
<html>
<h1>Dados do cliente</h1>

<b>Código:</b> <xsl:value-of select="cliente/codigo"/><br>
<b>Nome:</b> <xsl:value-of select="cliente/nome"/>
</html>
</xsl:template>
</xsl:stylesheet>


documento xml: dados_cliente.xml


<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="dados_cliente.xsl"?>
<cliente>
<codigo>1</codigo>
<nome>Felipe Guerço</nome>
</cliente>


Usando XML + XSL nosso documento de dados contém apenas a informação. Tudo relacionado à formatação entra na folha de estilos, que deixa de ser um arquivo só com definições de fontes, cores e outras formatações e passa a ser um documento completo de formatação dos dados.

Com XSL podemos fazer várias coisas legais. Ele nos oferece bastante recursos para exibir informações inclusive fazendo loop de vários "registros" dentro do XML.

Como o objetivo do post é dar uma visão geral sobre a tecnologia e mostrar suas vantagens, fico por aqui. Mas em breve trarei mais posts sobre recursos e aplicações práticas. Aquele abraço e até a próxima.

Artigo completo (View Full Post)

segunda-feira, 10 de dezembro de 2007

Recuperando informações sobre a versão e o Build do Executável

A função VerQueryValue retorna as informações correntes no “version-information” resorce. No Delphi, no menu “Project/Options” (Shif + Ctrl + F11), você define várias configurações sobre o seu projeto. As definições sobre a versão do seu programa é definida na aba “Version Info”, basta você marcar a opção para incluir informação sobre a versão no projeto (Includ version infomation in projetct).





Essa função deve trabalhar em conjunto com a GetFileInformationInfo, pois esta última é quem recupera propriamente o valor desejado do “version-information”.
Todas as duas funções são chamadas a API do sistema operacional Windows. No Delphi 7 elas estão definidas na unit “Windows”.

Analisado a Função:

function VerQueryValue; external version name ‘VerQueryValueA’;


function VerQueryValue(

const LPVOID pBlock, // Endereço do buffer para o “version resource”.
LPTSTR lpSubBlock, // Endereço para o valor a ser recuperado
LPVOID *lplpBuffer, // Ponteiro para o endereço do buffer onde esta armazenado as informações.
PUINT puLen // Endereço do versio-value length buffer
);

Parameters

pBlock

Points to the buffer containing the version-information resource
returned by GetFileVersionInfo.

lpSubBlock

Points to a zero-terminated string specifying which version-information value to
retrieve. The string consists of names separated by backslashes (\) and can have
one of the following forms:

Form Description
\ Specifies the root block. The function retrieves a pointer to the
VS_FIXEDFILEINFO structure for the version-information resource.
\VarFileInfo\Translation Specifies the translation table in the
variable information structure. The function retrieves a pointer to an
array of language and character-set identifiers. An application uses
these identifiers to create the name of a language-specific structure in
the version-information resource.
\StringFileInfo\lang-charset\string-name
Specifies a value in a language-specific structure.
The lang-charset name is a concatenation of a language and character-set
identifier pair found in the translation table for the resource.
The lang-charset name must be specified as a hexadecimal string.
The string-name name is one of the predefined strings described in the
following Remarks section.


lplpBuffer

Points to a buffer that receives a pointer to the version-information value.

puLen

Points to a buffer that receives the length, in characters, of the
version-information value. (retirado de Win32 Programming Techniques)

Existem em vários exemplos sobre o uso dessa função na web, basta “googar” buscando bor “VerQueryValue” e retornará uma série de links. Vou colocar um exemplo simples aqui somente a título de documentação:

Adicione num Form dois componentes “TLabel” (Label1 e Label2)e um TListBox (ListBox1). No Evento "OnCreate" do From1 digite como exemplificado abaixo:


procedure TForm1.FormCreate(Sender: TObject);
const
AExa = '041604E4';
AFileInfo = '\StringFileInfo\';
var
ApplicationExeName: String;
ReservedSpace, VLength: Cardinal;
MyBuff: PChar;
VersionBuild, CommentBuild: String;
begin
ApplicationExeName := Application.ExeName;
ListBox1.Items.Add(ApplicationExeName);

ReservedSpace := GetFileVersionInfoSize(PChar(ApplicationExeName),
ReservedSpace);

ListBox1.Items.Add(Format(ApplicationExeName + '- Tamanho Alocado = %d',
[ReservedSpace]));

if (ReservedSpace > 0) then
begin
MyBuff := AllocMem(ReservedSpace);
GetFileVersionInfo(PChar(ApplicationExeName),0, ReservedSpace, MyBuff);
VerQueryValue(MyBuff, PChar(AFileInfo + AExa+ '\FileVersion'),
Pointer(VersionBuild), VLength);
Label1.Caption := VersionBuild;

VerQueryValue(MyBuff, PChar(AFileInfo + AExa+ '\Comments'),
Pointer(CommentBuild), VLength);
Label2.Caption := CommentBuild;

end;
end;


Antes de executar o programa no menu “Project” ▶ Options” (Alt, P, O), na aba “Version Info”.no Grid de valores chaves, na linha Comments adicione um comentário. Conforme exemplificado abaixo.



Execute o programa e teste ...



Artigo completo (View Full Post)

sábado, 8 de dezembro de 2007

The Police no Maracanã

A ficha ainda não caiu ....

Já estou aquecendo os motores, vamos botar pra jogo pra ver o que rola.

Segue, um idéia de como o bagulho funfa


Message in a Bottle





De quebra ainda vai ter Paralamas!!!




Artigo completo (View Full Post)

Construção de Componentes V – Parte B

Gerenciador Dinâmico de Layout para DBGrids

Daremos continuidade ao artigo sobre a construção de um componente que permite ao usuário configurar várias propriedades de um DBGrid em tempo de execução. Anteriormente, desenvolvemos de um pequeno exemplo da utilização do commponetne, pudemos experimentar a facilidade de usabilidade, tanto do ponto de vista do usuário, quanto do desenvolvedor. Também comentamos as vantagens obtidas decorrente da abordagem de componentização em projetos de software.

Neste artigo, trataremos da funcionalidade de retornar a visibilidade as colunas que o usuário desejou torna-las invisíveis. Recapitulando:

Fluxo alternativo B

1 – Usuário, com o botão direto do mouse, sobre o DBGrid, seleciona
“Ver Colunas Escondidas”.

2 - Gerenciador de Layout de Grid exibe interface listando apenas as colunas
do DGGrid, as quais foram, pelo usuário, definidas como invisíveis
previamente. A partir das configurações originais, definidas em tempo de
projeto pelo programador, o Gerenciador de Layout de Grid deverá identificar
quais foram originalmente definidas como invisíveis para nunca permitir que
estas sejam listadas nesta interface.

3 – Usuário seleciona dentre as colunas listadas a que deseja tornar visível.
Confirmando em seguida a operação.

4 - Gerenciador de Layout de Grid grava as alterações e re-carrega o grid
com o que foi modificado.


Form SetupVisibilityColumnFrm:

Adicione ao pakage mais um TForm e manipule as propriedades do mesmo segundo listagem abaixo:

Name = SetupVisibilityColumnFrm( :TSetupVisibilityColumnFrm)
Left = 526
Top = 266
Caption = 'Visibilidade das Colunas'
ClientHeight = 560
ClientWidth = 495

Salve a unit como “SetupVisibilityColumnForm”.

Adicione ao form “SetupVisibilityColumnFrm” os componentes listados abaixo, obedecendo os valores respectivamente defindos na listagem:





1 - Name = PnlBtn (:TPanel)
Align = alBottom
BevelOuter = bvNone

Dentro do PnlBtn

1.1 Name = BtnSave: TBitBtn
Left = 12
Top = 12
Width = 75
Height = 25
TabOrder = 0
Kind = bkOK

1.2 Name = btnCancel( :TBitBtn)
Left = 392
Top = 12
Width = 75
Height = 25
TabOrder = 1
Kind = bkCancel

2 – Name = AdsVisibilityColumn ( :TADODataSet)
CursorType = ctStatic
LockType = ltBatchOptimistic

Adicione os TFields abaixo ao AdsVisibilityColumn

2.1 Name = AdsVisibilityColumnTitleColumn (:TStringField)
DisplayLabel = 'Título da Coluna'
FieldName = 'TitleColumn'
Size = 80

2.2 NAme = AdsVisibilityColumnVisibleColumn (:TBooleanField)
DisplayLabel = 'Visível'
FieldName = 'VisibleColumn'

2.3 Name = AdsVisibilityColumnFieldName (:TStringField)
FieldName = 'FieldName'
Size = 90

3 – Name = AdsProFileClone (:TADODataSet)
LockType = ltBatchOptimistic

4 – Name = dsDados (:TDataSource)
DataSet = AdsVisibilityColumn



5 - Name = GrdConfigColumn (:TDBGrid)
Align = alClient
DataSource = dsDados
Uma importate configuração a ser feita para nosso exemplo funcionar, é setar a
propriedade dgEditing para “false” nas opções do GrdConfigColumn.
Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs,
dgConfirmDelete, dgCancelOnExit]
ReadOnly = True
TabOrder = 1

Adicione duas colunas ao GrdConfigColumn:

5. 1 Coluna [0]
FieldName = 'TitleColumn'
Width = 300
Visible = True

5. 2 Coluna [1]
FieldName = 'VisibleColumn'
Width = 52
Visible = True


Observe que um dos fields do dataset associado ao Grid é bolleano, portanto vamos manipular o valor deles através de um check box. Um check box por linha do Grid. A princípio vamos criar estes checkboxes no muque, via código. Eu não gosto disso, detesto código extra, mas com o intuito de tornar nosso conteúdo mais acessível vou fazer assim por enquanto.

Antes de prosseguir apague a instância da classe do form, SetupVisibilityColumnFrm, criada automaticamante pelo Delphi. Ela deverá estar bem abaixo da primeira palavra reservada “var” na unit do form que criamos. Apague, tanto a palavra reservada “var”, quanto a variável “SetupVisibilityColumnFrm”.

Codificando os eventos do “GrdConfigColumn”

1) OnCellClick = GrdConfigColumnCellClick

procedure TSetupVisibilityColumnFrm.GrdConfigColumnCellClick(
Column: TColumn);
begin
if GrdConfigColumn.SelectedField.DataType = ftBoolean then
SaveBoolean;
end;

Não compile ainda, falta codificarmos o “SaveBoolean”:
1.1 Método privado SaveBoolean:

procedure TSetupVisibilityColumnFrm.SaveBoolean;
begin
with GrdConfigColumn do
begin
SelectedField.DataSet.Edit;
SelectedField.AsBoolean := not SelectedField.AsBoolean;
SelectedField.Dataset.Post;
end;
end;



Neste ponto a sua unit “.pas” deve estar semelhante ao trecho abaixo:

unit SetupVisibilityColumnForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, StdCtrls, Buttons, ExtCtrls, Grids, DBGrids;

TSetupVisibilityColumnFrm = class(TForm)
GrdConfigColumn: TDBGrid;
PnlBtn: TPanel;
BtnSave: TBitBtn;
btnCancel: TBitBtn;
AdsProFileClone: TADODataSet;
dsDados: TDataSource;
AdsVisibilityColumn: TADODataSet;
AdsVisibilityColumnTitleColumn: TStringField;
AdsVisibilityColumnVisibleColumn: TBooleanField;
AdsVisibilityColumnFieldName: TStringField;
procedure GrdConfigColumnCellClick(Column: TColumn);
private
procedure SaveBoolean;
public
{ Public declarations }
end;

(*apagamos a declaração da instância bem aqui ....*)

implementation

{$R *.dfm}

procedure TSetupVisibilityColumnFrm.GrdConfigColumnCellClick(Column: TColumn);
begin
if GrdConfigColumn.SelectedField.DataType = ftBoolean then
SaveBoolean;
end;

procedure TSetupVisibilityColumnFrm.SaveBoolean;
begin
with GrdConfigColumn do
begin
SelectedField.DataSet.Edit;
SelectedField.AsBoolean := not SelectedField.AsBoolean;
SelectedField.Dataset.Post;
end;
end;

end.



2) Evento OnDrawColumnCell do Grid (GrdConfigColumn): GrdConfigColumnDrawColumnCell


procedure TSetupVisibilityColumnFrm.GrdConfigColumnDrawColumnCell(
Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
Const
CtrlState : array[Boolean] of Integer = (DFCS_BUTTONCHECK,
DFCS_BUTTONCHECK or DFCS_CHECKED);
var
CheckBoxRectangle : TRect;
begin
if Column.Field.DataType = ftBoolean then
begin
GrdConfigColumn.Canvas.FillRect(Rect);
CheckBoxRectangle.Left := Rect.Left + 2;
CheckBoxRectangle.Right := Rect.Right - 2;
CheckBoxRectangle.Top := Rect.Top + 2;
CheckBoxRectangle.Bottom := Rect.Bottom - 2;
DrawFrameControl(GrdConfigColumn.Canvas.Handle, CheckBoxRectangle,
DFC_BUTTON, CtrlState[Column.Field.AsBoolean]);
end;

end;


3) Criando Propriedades no From

Na seção “public” contruiremos o meio de comunicação deste módulo com a classe TMangerGridZn. Primeiro as propriedades, digite conforme o trecho abaixo:


public
property FieldEnabledVisibilityName: String
read FFieldEnabledVisibilityName write FFieldEnabledVisibilityName;
property TitleColumnFieldName: String
read FTitleColumnFieldName write FTitleColumnFieldName;
property VisibleFieldName: String
read FVisibleFieldName write FVisibleFieldName;
property FieldNameFieldName: String
read FFieldNameFieldName write FFieldNameFieldName;
property FieldNameGridName: String
read FFieldNameGridName write FFieldNameGridName;
end;


Use o class complete (Ctrl + shift + c) para autocampletar e criar os campos privados referentes a cada propriedade na classe TSetupVisibilityColumnFrm.

4) Recuperando as colunas do DBGrid associado a classe TManagerGridZn que previamente foram definadas como invisíveis pelo usuário. Estas colunas deverão ser listadas na inbterface para que o usuário possa selecionar qual delas desejará tornar visível.

Método privado “LoadAds”:
Este método Carrega o dataset que permitirá ao usuário visualizar as colunas que ele definiu como invisíveis. Podendo então, torná-las visíveis.

function TSetupVisibilityColumnFrm.LoadAds(AdsDadosOriginais,
AdsProfileGrid: TADODataSet): Boolean;
var
AuxValues: String;
AuxFieldsLocate: String;
begin
(* Retorna verdadeiro caso existam colunas a serem listadas.
AdsDadosOriginais:
armazena as cofigurações definidas em design time
pelo desenvolvedor no DBGrid associado a TManagerGridZn
AdsProfileGrid:
armazena as cofigurações definidas em run time
pelo usuário no DBGrid associado a TManagerGridZn*)

(* Este método Carrega o dataset que permitirá ao usuário visualizar as
colunas que ele definiu como invisíveis. Podendo então, torná-las visíveis. *)

Result := AdsVisibilityColumn.Active;
if not Result then Exit;

(* Limpando possível lixo*)
if not AdsVisibilityColumn.IsEmpty then
begin
AdsVisibilityColumn.First;
while not AdsVisibilityColumn.Eof do
AdsVisibilityColumn.Delete;
end;
AdsDadosOriginais.First;
while not (AdsDadosOriginais.Eof) do
begin

(* O campo FFieldEnabledVisibilityName corresponde ao informação original
do grid, se o desenvolvedor permitiu visibilidade ao usuário, ou não. *)
if AdsDadosOriginais.FieldByName(FFieldEnabledVisibilityName).AsBoolean then
begin
(* recuperando valores para o locate *)
AuxValues := AdsDadosOriginais.FieldByName(FFieldNameFieldName).AsString;

AuxFieldsLocate := FFieldNameFieldName;

if AdsProfileGrid.Locate(AuxFieldsLocate, AuxValues, []) then
begin
if not AdsProfileGrid.FieldByName(FVisibleFieldName).AsBoolean then
begin
AdsVisibilityColumn.Append;
AdsVisibilityColumnTitleColumn.AsString :=
AdsProfileGrid.FieldByName(FTitleColumnFieldName).AsString;
AdsVisibilityColumnVisibleColumn.AsBoolean :=
AdsProfileGrid.FieldByName(FVisibleFieldName).AsBoolean;
AdsVisibilityColumnFieldName.AsString :=
AdsProfileGrid.FieldByName(FFieldNameFieldName).AsString;
AdsVisibilityColumn.Post;
end;
end;
end;

AdsDadosOriginais.Next;
end;

Result := not AdsVisibilityColumn.IsEmpty;
end;



5 – Retornando as alterações efetuadas pelo usuário a partir do que foi listado na iterface:
Este método já é o output deste módulo, após implementa-lo (segundo trecho abaixo) cuidaremos do principal método de comunicação do nosso form.


procedure TSetupVisibilityColumnFrm.SetUpdates(AdsProfileGrid: TADODataSet);
begin
try
AdsVisibilityColumn.DisableControls;
AdsVisibilityColumn.First;
while not AdsVisibilityColumn.Eof do
begin
AdsProfileGrid.Filter := FFieldNameFieldName + ' = ' +
QuotedStr(AdsVisibilityColumnFieldName.AsString);
AdsProfileGrid.Filtered := True;
AdsProfileGrid.First;
while not AdsProfileGrid.Eof do
begin
AdsProfileGrid.Edit;
AdsProfileGrid.FieldByName(FVisibleFieldName).AsBoolean :=
AdsVisibilityColumnVisibleColumn.AsBoolean;
AdsProfileGrid.Post;
AdsProfileGrid.Next;
end;
AdsVisibilityColumn.Next;
end;
finally
AdsProfileGrid.Filter := '';
AdsProfileGrid.Filtered := False;
AdsVisibilityColumn.EnableControls;
end;
end;



6 – I/O do módulo TSetupVisibilityColumnFrm:
O método público “Execute” é o meio pelo qual implementaremos a lógica de entrada e saída do módulo que acabamos de construir.

function TSetupVisibilityColumnFrm.Execute(AdsSetupOriginal,
AdsProfileGrid: TADODataSet): Boolean;
begin
if FFieldEnabledVisibilityName = '' then
raise Exception.Create('O Campo FieldEnabledVisibilityName não foi atribuido.');
(* Connfigurando exibição do Form *)
Self.BorderStyle := bsDialog;
Self.Position := poScreenCenter;
Self.FormStyle := fsNormal;

(* Carrega o Dataset com as colunas que estão invisíveis *)
Result := LoadAds(AdsSetupOriginal, AdsProfileGrid);
(* Caso nenhum regitro de coluna invisível tenha sido carregado
cancela a execução do módulo, garantido que a propriedade "ModalResult"
do form seja igual a mrCancel *)
if not Result then
btnCancel.Click;
(* Copia os dados do Dataset que contem as configurações do profile*)
AdsProFileClone.Clone(AdsProfileGrid);
Result := (Self.ShowModal = mrOk);
if Result then
SetUpdates(AdsProfileGrid);

end;


7 – BtnOk OnClikc:
O BtnOk esta configurado como ModalResult = mrOk desta forma podemos recuperar ao término da execução do método ShowModal, se o usuário confirmou ou não a operação realizada.


procedure TSetupVisibilityColumnFrm.BtnSaveClick(Sender: TObject);
begin
if dsDados.DataSet.State in [dsEdit, dsInsert] then
dsDados.DataSet.Post;
end;


8 - BtnCancel OnClikc:
Da mesma forma, posso testar a se o usuário cancelou o processo porque o BtnCancel tem a propriedade ModalResult = mrCancel.


procedure TSetupVisibilityColumnFrm.btnCancelClick(Sender: TObject);
begin
if dsDados.DataSet.State in [dsEdit, dsInsert] then
dsDados.DataSet.Cancel;
end;


9 - Ainda falta ativar o dataset que armazenará os dados sobre as colunas que serão listadas na interface (SetupVisibilityColumnFrm). Evento OnCreate do form:

procedure TSetupVisibilityColumnFrm.FormCreate(Sender: TObject);
begin
AdsVisibilityColumn.CreateDataSet;
end;


Neste ponto finalizamos a implementação da funcionalidade pretendida neste artigo. Resta agora retornarmos a classe TManagerGridZn para codificarmos a chamada a este módulo. Por garantia segue o código completo das units contruidas até agora.

10 – Fontes Completos

10.1 SetupVisibilityColumnForm.pas


unit SetupVisibilityColumnForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, StdCtrls, Buttons, ExtCtrls, Grids, DBGrids;

type
TSetupVisibilityColumnFrm = class(TForm)
GrdConfigColumn: TDBGrid;
PnlBtn: TPanel;
BtnSave: TBitBtn;
btnCancel: TBitBtn;
AdsProFileClone: TADODataSet;
dsDados: TDataSource;
AdsVisibilityColumn: TADODataSet;
AdsVisibilityColumnTitleColumn: TStringField;
AdsVisibilityColumnVisibleColumn: TBooleanField;
AdsVisibilityColumnFieldName: TStringField;
procedure FormCreate(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
procedure BtnSaveClick(Sender: TObject);
procedure GrdConfigColumnDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
procedure GrdConfigColumnCellClick(Column: TColumn);
private
FFieldNameGridName: String;
FFieldEnabledVisibilityName: String;
FTitleColumnFieldName: String;
FFieldNameFieldName: String;
FVisibleFieldName: String;
procedure SaveBoolean;
function LoadAds(AdsDadosOriginais, AdsProfileGrid: TADODataSet): Boolean;
procedure SetUpdates(AdsProfileGrid: TADODataSet);
public
function Execute(AdsSetupOriginal, AdsProfileGrid: TADODataSet): Boolean;

property FieldEnabledVisibilityName: String
read FFieldEnabledVisibilityName write FFieldEnabledVisibilityName;
property TitleColumnFieldName: String
read FTitleColumnFieldName write FTitleColumnFieldName;
property VisibleFieldName: String
read FVisibleFieldName write FVisibleFieldName;
property FieldNameFieldName: String
read FFieldNameFieldName write FFieldNameFieldName;
property FieldNameGridName: String
read FFieldNameGridName write FFieldNameGridName;
end;


implementation

{$R *.dfm}

procedure TSetupVisibilityColumnFrm.btnCancelClick(Sender: TObject);
begin
if dsDados.DataSet.State in [dsEdit, dsInsert] then
dsDados.DataSet.Cancel;
end;

procedure TSetupVisibilityColumnFrm.BtnSaveClick(Sender: TObject);
begin
if dsDados.DataSet.State in [dsEdit, dsInsert] then
dsDados.DataSet.Post;
end;

function TSetupVisibilityColumnFrm.Execute(AdsSetupOriginal,
AdsProfileGrid: TADODataSet): Boolean;
begin
if FFieldEnabledVisibilityName = '' then
raise Exception.Create('O Campo FieldEnabledVisibilityName não foi atribuido.');
(* Connfigurando exibição do Form *)
Self.BorderStyle := bsDialog;
Self.Position := poScreenCenter;
Self.FormStyle := fsNormal;

(* Carrega o Dataset com as colunas que estão invisíveis *)
Result := LoadAds(AdsSetupOriginal, AdsProfileGrid);
(* Caso nenhum regitro de coluna invisível tenha sido carregado
cancela a execução do módulo, garantido que a propriedade "ModalResult"
do form seja igual a mrCancel *)
if not Result then
btnCancel.Click;
(* Copia os dados do Dataset que contem as configurações do profile*)
AdsProFileClone.Clone(AdsProfileGrid);
Result := (Self.ShowModal = mrOk);
if Result then
SetUpdates(AdsProfileGrid);

end;

procedure TSetupVisibilityColumnFrm.FormCreate(Sender: TObject);
begin
AdsVisibilityColumn.CreateDataSet;
end;

procedure TSetupVisibilityColumnFrm.GrdConfigColumnCellClick(Column: TColumn);
begin
if GrdConfigColumn.SelectedField.DataType = ftBoolean then
SaveBoolean;
end;

procedure TSetupVisibilityColumnFrm.GrdConfigColumnDrawColumnCell(
Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
Const
CtrlState : array[Boolean] of Integer = (DFCS_BUTTONCHECK,
DFCS_BUTTONCHECK or DFCS_CHECKED);
var
CheckBoxRectangle : TRect;
begin
if Column.Field.DataType = ftBoolean then
begin
GrdConfigColumn.Canvas.FillRect(Rect);
CheckBoxRectangle.Left := Rect.Left + 2;
CheckBoxRectangle.Right := Rect.Right - 2;
CheckBoxRectangle.Top := Rect.Top + 2;
CheckBoxRectangle.Bottom := Rect.Bottom - 2;
DrawFrameControl(GrdConfigColumn.Canvas.Handle, CheckBoxRectangle,
DFC_BUTTON, CtrlState[Column.Field.AsBoolean]);
end;

end;

function TSetupVisibilityColumnFrm.LoadAds(AdsDadosOriginais,
AdsProfileGrid: TADODataSet): Boolean;
var
AuxValues: String;
AuxFieldsLocate: String;
begin
(* Retorna verdadeiro caso existam colunas a serem listadas.
AdsDadosOriginais:
armazena as cofigurações definidas em design time
pelo desenvolvedor no DBGrid associado a TManagerGridZn
AdsProfileGrid:
armazena as cofigurações definidas em run time
pelo usuário no DBGrid associado a TManagerGridZn*)

(* Este método Carrega o dataset que permitirá ao usuário visualizar as
colunas que ele definiu como invisíveis. Podendo então, torná-las visíveis. *)

Result := AdsVisibilityColumn.Active;
if not Result then Exit;

(* Limpando possível lixo*)
if not AdsVisibilityColumn.IsEmpty then
begin
AdsVisibilityColumn.First;
while not AdsVisibilityColumn.Eof do
AdsVisibilityColumn.Delete;
end;
AdsDadosOriginais.First;
while not (AdsDadosOriginais.Eof) do
begin

(* O campo FFieldEnabledVisibilityName corresponde ao informação original
do grid, se o desenvolvedor permitiu visibilidade ao usuário, ou não. *)
if AdsDadosOriginais.FieldByName(FFieldEnabledVisibilityName).AsBoolean then
begin
(* recuperando valores para o locate *)
AuxValues := AdsDadosOriginais.FieldByName(FFieldNameFieldName).AsString;

AuxFieldsLocate := FFieldNameFieldName;

if AdsProfileGrid.Locate(AuxFieldsLocate, AuxValues, []) then
begin
if not AdsProfileGrid.FieldByName(FVisibleFieldName).AsBoolean then
begin
AdsVisibilityColumn.Append;
AdsVisibilityColumnTitleColumn.AsString :=
AdsProfileGrid.FieldByName(FTitleColumnFieldName).AsString;
AdsVisibilityColumnVisibleColumn.AsBoolean :=
AdsProfileGrid.FieldByName(FVisibleFieldName).AsBoolean;
AdsVisibilityColumnFieldName.AsString :=
AdsProfileGrid.FieldByName(FFieldNameFieldName).AsString;
AdsVisibilityColumn.Post;
end;
end;
end;

AdsDadosOriginais.Next;
end;

Result := not AdsVisibilityColumn.IsEmpty;
end;

procedure TSetupVisibilityColumnFrm.SaveBoolean;
begin
with GrdConfigColumn do
begin
SelectedField.DataSet.Edit;
SelectedField.AsBoolean := not SelectedField.AsBoolean;
SelectedField.Dataset.Post;
end;
end;

procedure TSetupVisibilityColumnFrm.SetUpdates(AdsProfileGrid: TADODataSet);
begin
try
AdsVisibilityColumn.DisableControls;
AdsVisibilityColumn.First;
while not AdsVisibilityColumn.Eof do
begin
AdsProfileGrid.Filter :=
FFieldNameFieldName + ' = ' + QuotedStr(AdsVisibilityColumnFieldName.AsString);
AdsProfileGrid.Filtered := True;
AdsProfileGrid.First;
while not AdsProfileGrid.Eof do
begin
AdsProfileGrid.Edit;
AdsProfileGrid.FieldByName(FVisibleFieldName).AsBoolean :=
AdsVisibilityColumnVisibleColumn.AsBoolean;
AdsProfileGrid.Post;
AdsProfileGrid.Next;
end;
AdsVisibilityColumn.Next;
end;
finally
AdsProfileGrid.Filter := '';
AdsProfileGrid.Filtered := False;
AdsVisibilityColumn.EnableControls;
end;
end;

end.


10.2SetupVisibilityColumnForm.dfm


object SetupVisibilityColumnFrm: TSetupVisibilityColumnFrm
Left = 526
Top = 266
Caption = 'Visibilidade das Colunas'
ClientHeight = 560
ClientWidth = 495
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object GrdConfigColumn: TDBGrid
Left = 0
Top = 0
Width = 495
Height = 509
Align = alClient
DataSource = dsDados
Options = [dgTitles, dgIndicator, dgColumnResize,
dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit]
ReadOnly = True
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
OnCellClick = GrdConfigColumnCellClick
OnDrawColumnCell = GrdConfigColumnDrawColumnCell
Columns = < expanded =" False" fieldname =" 'TitleColumn'"
charset =" DEFAULT_CHARSET" color =" clWindowText" height =" -11"
name =" 'MS" style =" [fsBold]" width =" 300" visible =" True"
expanded =" False" fieldname =" 'VisibleColumn'" alignment =" taCenter"
charset =" DEFAULT_CHARSET" color =" clWindowText" height =" -11"
name =" 'MS" style =" [fsBold]" width =" 52" visible =" True">
end
object PnlBtn: TPanel
Left = 0
Top = 509
Width = 495
Height = 51
Align = alBottom
BevelOuter = bvNone
TabOrder = 1
ExplicitTop = 482
ExplicitWidth = 487
object BtnSave: TBitBtn
Left = 12
Top = 12
Width = 75
Height = 25
TabOrder = 0
OnClick = BtnSaveClick
Kind = bkOK
end
object btnCancel: TBitBtn
Left = 392
Top = 12
Width = 75
Height = 25
TabOrder = 1
OnClick = btnCancelClick
Kind = bkCancel
end
end
object AdsProFileClone: TADODataSet
LockType = ltBatchOptimistic
Parameters = <>
Left = 96
Top = 204
end
object dsDados: TDataSource
DataSet = AdsVisibilityColumn
Left = 132
Top = 68
end
object AdsVisibilityColumn: TADODataSet
CursorType = ctStatic
LockType = ltBatchOptimistic
FieldDefs = <>
Parameters = <>
StoreDefs = True
Left = 212
Top = 68
object AdsVisibilityColumnTitleColumn: TStringField
DisplayLabel = 'Título da Coluna'
FieldName = 'TitleColumn'
Size = 80
end
object AdsVisibilityColumnVisibleColumn: TBooleanField
DisplayLabel = 'Visí'vel'
FieldName = 'VisibleColumn'
end
object AdsVisibilityColumnFieldName: TStringField
FieldName = 'FieldName'
Size = 90
end
end
end


11 - Na classe TManagerGridZn codificaremos a chamada ao form “TSetupVisibilityColumnFrm”. Antes, declare na seção “uses” da “implementatio” a unit do módulo que criamos acima.




procedure TManagerGridZn.ConfigurarGridViewColumnLayoutClick(Sender: TObject);
var
FrmVisibilityConfig: TSetupVisibilityColumnFrm;
AuxPath: String;
AdsOrigConfigMemmento: TADODataSet;
begin
try
AdsOrigConfigMemmento :=
DmMangerGridZn.GetDefaultConfiguration(FGrid.Name, FGrid.Owner.Name);
FrmVisibilityConfig := TSetupVisibilityColumnFrm.Create(Self);
FrmVisibilityConfig.FieldEnabledVisibilityName :=
DmMangerGridZn.AdsOriginalConfigUpdateVisibility.FieldName;
FrmVisibilityConfig.TitleColumnFieldName :=
DmMangerGridZn.AdsOriginalConfigColumnTitleCaption.FieldName;
FrmVisibilityConfig.VisibleFieldName :=
DmMangerGridZn.AdsOriginalConfigColumnVisible.FieldName;
FrmVisibilityConfig.FieldNameFieldName :=
DmMangerGridZn.AdsOriginalConfigColumnFieldName.FieldName;
FrmVisibilityConfig.FieldNameGridName :=
DmMangerGridZn.AdsOriginalConfigGridName.FieldName;

if FrmVisibilityConfig.Execute(AdsOrigConfigMemmento,
DmMangerGridZn.AdsDados) then
begin
AuxPath := BuildFilePathComplete;
DmMangerGridZn.SaveToFile(AuxPath);
end;
finally
FrmVisibilityConfig.Free;
AdsOrigConfigMemmento.Close;
FreeAndNil(AdsOrigConfigMemmento);
LoadFileProfile;
end;

end;

O próximo passo é retornar a método que monta o menu popup para acrescentar a chamada ao método “ConfigurarLayoutGridClick” ao item de menu específico.


procedure TManagerGridZn.BuildMenuPopup;
var
i: Integer;
MyMenuitem: TMenuItem;
begin
(* Verifco se o componente encontra-se em run time*)
if not (csDesigning in Self.ComponentState) then
begin
if Assigned(FPopupMenu) then
begin
for i := 0 to High(PopupMenuItemName) do
begin
if (FPopupMenu.Items.Count > 0) and (i = 0) then
CreatePopupMenuItem(PopupMenuItemName[i], '-');

if (i = 1) then
CreatePopupMenuItem(PopupMenuItemName[i], 'Configurar Layuot do &Grid');

if (i = 2) then
CreatePopupMenuItem(PopupMenuItemName[i], '&Ver Colunas Invisíveis');

if (i = 3) then
CreatePopupMenuItem(PopupMenuItemName[i],
'&Restaurar Configuração Orignal');
end;

MyMenuitem := TMenuItem(Self.FindComponent(PopupMenuItemName[1]));
if assigned(MyMenuitem) then
MyMenuitem.OnClick := ConfigurarLayoutGridClick;
(* A linha comentada com "//" será implementada mais tarde *)
MyMenuitem := TMenuItem(Self.FindComponent(PopupMenuItemName[2]));
if assigned(MyMenuitem) then
MyMenuitem.OnClick := ConfigurarGridViewColumnLayoutClick;

end;
end;

end;


Por hora chega!!!! Recompile a package e execute o programa de teste que fizemos no artigo anterior. Teste o componente e experimente a nova funcionalidade. O Embreve teminaremos, espero, a funcionalidade para restaurar as configurações default.

Artigo completo (View Full Post)

terça-feira, 20 de novembro de 2007

Over Kill (Men at Work)


Momento anos 80 …
Bem, o tom da gravação original foi em Mi maior. A versão violão e voz do Colin Hay foi um tom abixo (Ré maior), também houve uma mudança sensível na harmonia nas partes referentes aos solos.

Over Kill (Men at Work)



Introdução: || C#m7 | C#m7 | Bsus4 | Bsus4 ||

E B/D#
I can’t get sleep
D A/C#
I think about the implications
E B/D#
Of diving in to deep
D A/C#
And possibly the complications

E B/D#
Especially at night
D A/C#
I worry over situations
E B/D#
I know will be alright
D A/C#
Perhaps it’s just my imagination

C#m7 Bsus4 B7
Day after day reappears
C#m7 Bsus4 B7
Night after night my heartbeats
G#sus4 G#7
Shows the fear
A7M G#sus4 G#7 A7M
Ghosts appear and fade away


E B/D#
Alone between the sheets
D A/C#
Only brings exasperation
E B/D#
It’s time to walk the streets
D A/C#
Smell the desperation

E B/D#
At least there’s pretty lights
D A/C#
And though there’s little variation
E B/D#
It nullifies the night
D A/C#
From over kill

C#m7 Bsus4 B7
Day after day reappears
C#m7 Bsus4 B7
Night after night my heartbeats
G#sus4 G#7
Shows the fear
A7M G#sus4 G#7 A7M
Ghosts appear and fade away

Solos

I can’t get sleep
I think about the implications
Of diving in to deep
And possibly the complications

Especially at night
I worry over situations
I know will be alright
It’s just over kill

C#m7 Bsus4 B7
Day after day reappears
C#m7 Bsus4 B7
Night after night my heartbeats
G#sus4 G#7
Shows the fear
A7M G#sus4 G#7 A7M
Ghosts appear and fade away….

A7M G#sus4 G#7 A7M
Ghosts appear and fade away





Artigo completo (View Full Post)

Construção de Componentes V – Parte A

No artigo anterior começamos a construir o componente Gerenciador de Layout de Grid, TManagerGridZn. Vimos como fazer uma package no Delphi 2006, associar outras units a ela e etc. Como fazer isso no Delphi 7 também já foi exemplificado nos primeiros artigos sobre o assunto. Para programarmos um pequeno módulo a fim de testarmos o novo componente precisamos instalar a package, para fazer isso basta clickar com o botão direto sobre ela, no Project Manager e selecionar a opção “Install”.



Projeto teste Gerenciador de Layout de Grid (TesteGerencLayoutGrid.bdsproj): Inicie uma nova aplicação no Delphi, no From1 adicione os seguintes componentes:
1 – TClientDataSet
Name = CdsDados

1.1 Adicione dois TFields ao CdsDados;

TIntegerField
Name = CdsDadosID_Dado
Field Kind = fkData

TStringField
Name = CdsDadosDescDado
Field Kind = fkData


TStringField
Name = CdsDadosCoisas
Field Kind = fkData



2 – TdataSource (Data Access)
Name = DsDados
DataSet = CdsDados

3 - TDBGrid (Data Controls):
Name = DDGrid1
Align = alBottom
DataSource = DsDados

3.1 – Adicione duas colunas ao Grid, correspondentes aos três
TFields do CdsDados

4 -TManagerGridZn (Estação ZN)
Grid = DBGrid1

5 - TBitBtn (Addititional)
Name = BtnActivar
Caption = 'Ativar'

cerifique-se de que o ManagerGridZn (TManagerGridZn), esteja associado ao DBGrid1. O DBGrid tem que estar associado ao DsDados(TDataSource), que deve estar associado ao CdsDados(TClientDataSet).

No evento OnClick do BtnAtivar codifique:


procedure TForm1.BtnActivarClick(Sender: TObject);
var
i: Integer;
begin
(* Ativa o Dataset*)
if not CdsDados.Active then
CdsDados.CreateDataSet;
//Preenche o DataSet
for i := 0 to 30 do
begin
CdsDados.InsertRecord([i, Format('Dado %d', [i]), 'Bla!!!!']);
end;
end;


Pronto!! That’s it!!!
Chega de código .... tá bom??? Também acho ... hehehe

Note que para trabalhar com a classe que criamos nào foi necessário NENHUMA linha código.

Execute o programa e teste conforme os screenshots abaixo:

Primeiro carregue os dados clickando no botão “Ativar”. Com o botão direito do mouse, chame o menu popup que o componente TManagerGridZn criou e associou ao grid. Selecione a 1° opção.



Altere as propriedades da coluna sobre a qual vc clickou.



Ok, fácil? Agora você pode intuitivamente manter um layout personalizado para qualquer grid, em qualquer um dos seus projetos.





Podemos concluir, a partir deste exemplo, que um programa bem modularizado, onde o grau de acoplamento é reduzido ao máximo, propicia o reuso de maneira eficiente. Também, que é possível a construção de componentes de fácil consumo (mínima curva de aprendizado por parte do desenvolvedor que vai usar o componente em seus programas).
Outro ponto importante a destacar é que com essa abordagem podemos desenvolver novas funcionalidades para sistemas que foram construídos por outros (sistemas antigos, legados), que precisam sofrer manutenção, demandando para isso um grau mínimo de intervenção no código dos desenvolvedores originais. Sobretudo porque, a maioria deles são extremamente sensíveis a qualquer intervenção, mínima que seja, em seus fontes.

A seguir, finalizaremos a implementação do componente “TManagerGridZn”, pois ainda faltam ser codificadas as funcionalidades de recuperar as colunas que o usuário definir como invisíveis, “Ver Colunas Escondidas” (Invisíveis), e o restore default values “Restaurar configuração original”.

Código completo da unit1.pas



unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, DB, DBClient, Grids, DBGrids, ManagerGridZn;

type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
CdsDados: TClientDataSet;
dsDados: TDataSource;
CdsDadosID_Dado: TIntegerField;
CdsDadosDescDado: TStringField;
BtnActivar: TBitBtn;
ManagerGridZn1: TManagerGridZn;
CdsDadosCoisas: TStringField;
procedure BtnActivarClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BtnActivarClick(Sender: TObject);
var
i: Integer;
begin
if not CdsDados.Active then
CdsDados.CreateDataSet;

for i := 0 to 30 do
begin
CdsDados.InsertRecord([i, Format('Dado %d', [i]), 'Bla']);
end;

end;

end.



unit1.dfm


object Form1: TForm1
Left = 223
Top = 168
Caption = 'Form1'
ClientHeight = 375
ClientWidth = 531
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object DBGrid1: TDBGrid
Left = 0
Top = 80
Width = 531
Height = 295
Align = alBottom
DataSource = dsDados
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
Columns = < expanded =" False" fieldname =" 'ID_Dado'" visible =" True" expanded =" False" fieldname =" 'DescDado'" visible =" True" expanded =" False" fieldname =" 'Coisas'" visible =" True">
end
object BtnActivar: TBitBtn
Left = 408
Top = 8
Width = 75
Height = 25
Caption = 'Ativar'
TabOrder = 1
OnClick = BtnActivarClick
end
object CdsDados: TClientDataSet
Aggregates = <>
Params = <>
Left = 316
Top = 40
object CdsDadosID_Dado: TIntegerField
FieldName = 'ID_Dado'
end
object CdsDadosDescDado: TStringField
FieldName = 'DescDado'
Size = 30
end
object CdsDadosCoisas: TStringField
FieldName = 'Coisas'
end
end
object dsDados: TDataSource
DataSet = CdsDados
Left = 388http://www.blogger.com/img/blank.gif
Top = 44
end
object ManagerGridZn1: TManagerGridZn
Grid = DBGrid1
Left = 80
Top = 12
end
end



Continuação da série Construção de Componentes

Artigo completo (View Full Post)

 
BlogBlogs.Com.Br