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)

 
BlogBlogs.Com.Br