- Declare a função abaixo antes da palavra implementation:
function RegisterServiceProcess(dwProcessID, dwType: Integer):
Integer; stdcall; external 'KERNEL32.DLL';
- Coloque dois botões no Form;
- No evento OnClick do Button1 coloque:
RegisterServiceProcess(GetCurrentProcessID, 1);
- No evento OnClick do Button2 coloque:
RegisterServiceProcess(GetCurrentProcessID, 0);
=== Para testar ===
Clique no Button1 e pressione CTRL+ALT+DEL. O seu programa
não aparecerá na lista.
Clique no Button2 e pressione CTRL+ALT+DEL. Agora seu programa
aparecerá na lista.
quinta-feira, 8 de setembro de 2011
Ocultar aplicação da lista de tarefas - CTRL+ALT+DEL
quarta-feira, 7 de setembro de 2011
Mudar a cor do Edit ao receber o foco
Alguns programas mostram o Edit que está com o foco em uma cor diferente dos demais.
Como fazer isto em Delphi?
Na seção private do form declare o procedimento abaixo:
private
procedure MudancaDeFoco(Sender: TObject);
public
end;
Na seção implementation, escreva o código do procedimento:
{ Esta rotina será chamada através do evento OnExit (perda do foco)
de todos os componentes do tipo TEdit que existirem no form. }
procedure TForm1.MudancaDeFoco(Sender: TObject);
var
I: integer;
Ed: TEdit;
begin
{ Percorre a matriz de componentes do form }
for I := 0 to ComponentCount - 1 do
{ Se o componente é do tipo TEdit... }
if Components[I] is TEdit then
begin
{ Faz um type-casting pata o tipo TEdit }
Ed := Components[I] as TEdit;
{ Se o Edit está com o foco... }
if Ed.Focused then
Ed.Color := clYellow { Amarelo }
else
Ed.Color := clWhite; { Branco }
end;
end;
No evento OnCreate do Form, coloque o código abaixo:
procedure TForm1.FormCreate(Sender: TObject);
var
I: integer;
begin
{ Percorre a lista de componentes do form (matriz de componentes)
e verifica cada componente para saber se é um TEdit. Se for,
associa o evento OnExit do componente com a procedure
"MudancaDeFoco". }
for I := 0 to ComponentCount - 1 do
if Components[I] is TEdit then
(Components[I] as TEdit).OnExit := MudancaDeFoco;
end;
No evento OnActivate coloque:
procedure TForm1.FormActivate(Sender: TObject);
begin
{ Esta chamada é necessária para que o estado inicial seja
controlado. }
MudancaDeFoco(nil);
end;
Observações
Existem outras técnicas mais profissionais para resolver o problema proposto. Uma alternativa excelente é a criação de um novo componente herdado da classe TEdit (ou TCustomEdit) que implemente a mudança de cor no método DoEnter e DoExit.
Arredondamento financeiro
{ x receberá o valor de y arredondado para 2 casas após o separador. }
x := Round(y * 100) / 100;
{ z receberá o valor de y arredondado para 3 casas após o separador. }
z := Round(y * 1000) / 1000;
No entanto dois problemas poderão aparecer com os exemplos acima:- O arredondamento feito pelo Delphi difere daquele feito pelas calculadores financeiras, bem como bancos de dados como InterBase e FireBird.
- poderão ocorrer pequenos arredondamentos devido ao modo como o Delphi trata números reais, tais como aparecer 3.9999999... em vez de 4.
{ Esta função faz arredondamento de valores reais para "n" casas
decimais após o separador decimal, seguindo os critérios das
calculadoras financeiras e dos bancos de dados InterBase e FireBird.
}
function TBRound(Value: Extended; Decimals: integer): Extended;
var
Factor, Fraction: Extended;
begin
Factor := IntPower(10, Decimals);
{ A conversão para string e depois para float evita
erros de arredondamentos indesejáveis. }
Value := StrToFloat(FloatToStr(Value * Factor));
Result := Int(Value);
Fraction := Frac(Value);
if Fraction >= 0.5 then
Result := Result + 1
else if Fraction <= -0.5 then
Result := Result - 1;
Result := Result / Factor;
end;
Consultar por mês de um campo data
Problema:
Tenho um cadastro de clientes com Codigo, Nome, DataNasc, etc.
Preciso fazer uma consulta onde apareceão apenas os clientes
que fazem aniversário em determinado mês. Como fazer?
Solução:
Use uma Query como abaixo:
- Coloque no form os seguintes componentes:
* TQuery
* TDataSource
* TDBGrid
* TEdit
* TButton
- Altere as propriedades dos componentes como abaixo:
* Query1.DatabaseName = (alias do BDE)
* DataSource1.DataSet = Query1
* DBGrid1.DataSource = DataSource1
- Coloque o código abaixo no evento OnClick de Button1:
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select * from dCli');
Query1.SQL.Add('where extract(month from DataNasc) = :Mes');
Query1.ParamByName('Mes').AsInteger := StrToInt(Edit1.Text);
Query1.Open;
- Execute. Digite um número de 1 a 12 no Edit e clique no
botão.
Observações
Os números de 1 a 12 representam, respectivamente, os meses de Janeiro a Dezembro. Este exemplo foi testado com Delphi4, BDE5 e tabela Paradox7.
DBGrid zebrado
Programe o evento OnDrawColumnCell do DBGrid como abaixo:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
begin
if State = [] then
begin
if Table1.RecNo mod 2 = 1 then
DBGrid1.Canvas.Brush.Color := clAqua
else
DBGrid1.Canvas.Brush.Color := clWhite;
end;
DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
Observação:
O objeto Table1 é da classe TTable (relativa ao BDE), mas esta dica poderá
ser usada com outros DataSet's, tais como IBDataSet, ClientDataSet, etc.
domingo, 4 de setembro de 2011
Usando funções no MySQL
Fonte: www.activedelphi.com.br
Vou tentar passar aqui, um pequeno exemplo de como usar funções do MySQL em nossas instruções SQL.
Em primeiro lugar, certifique-se que você possua instalado uma versão a partir da 5.x do MySQL em seu micro.
No nosso exemplo, criaremos e utilizaremos uma função que retornará a idade do cliente
Crie uma pequena tabela com a seguinte estrutura:
CREATE TABLE `clientes` (
`ID` int(11) NOT NULL auto_increment,
`NOME` varchar(45) default NULL,
`DATANASC` date default NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Inclua as linhas abaixo na tabela, ou digite suas próprias informações:
INSERT I NTO `clientes` (`ID`, `NOME`, `DATANASC`) VALUES
(1, 'SILVIO SANTOS', '1971-09-18'),
(2, 'SILLAS SANTOS', '1993-04-27');
Agora, crie a função conforme o exemplo abaixo:
CREATE FUNCTION `idade`(pDATA DATE)
RETURNS varchar(15) CHARSET latin1
NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER
COMMENT ''
Begin
DECLARE vIDADE varchar(30);
IF DATE_FORMAT(NOW( ),'00-%m-%d') >= DATE_FORMAT(pDATA,'00-%m-%d') THEN
SET @idade=DATE_FORMAT(NOW( ),'%Y')-DATE_FORMAT(pDATA,'%Y');
ELSE
SET @idade=DATE_FORMAT(NOW( ),'%Y')-DATE_FORMAT(pDATA,'%Y')-1;
END IF;
RETURN(concat(@idade,' anos'));
end;
Esta função, retornará a idade da pessoa de acordo com o campo DATANASC, da tabela ‘clientes’.
Veja que a função receberá um valor (pDATA, que no nosso exemplo será o campo ‘DATANASC’ de nossa tabela) e fará a subtração da “dat a corrente” pela data do campo DATANASC.
Dentro da função, criamos uma variável (vIDADE), onde armazenaremos o valor a ser retornado pela função. Note também que a função possui retorno do tipo String (RETURNS varchar(30)), que deverá ter o tamanho suficiente para comportar o resultado retornado. Ou seja, se o valor retornado tiver 15 caracteres, o ‘RETURNS’ da função precisa ter tamanho de 15 ou mais caracteres, senão, pode acontecer de não retornar nenhum valor.
Após ter criado a tabela, inserido as linhas na mesma e criado a função, execute a seguinte instrução:
SELECT NOME, idade(DATANASC) IDADE FROM clientes;
No SQL acima, a consulta irá retornar o Nome, e a idade assim: “XX anos”, para cada cliente.
Como você viu, utilizar funções dentro do banco de dados por ser muito mais prático do que fazê-lo dentro da aplicação (me refiro a funções para retorno de dados, claro).
Lembrando que este exemplo é apenas uma base, pois podemos criar funções para qualquer necessdiade, como: calculo de preços, juros de mora, datas, horas, concatenação de campos complexos, junções de tabelas (como nos inner, left e right joins (desde que precise retornar apenas um valor), e muito mais.
Em primeiro lugar, certifique-se que você possua instalado uma versão a partir da 5.x do MySQL em seu micro.
No nosso exemplo, criaremos e utilizaremos uma função que retornará a idade do cliente
Crie uma pequena tabela com a seguinte estrutura:
CREATE TABLE `clientes` (
`ID` int(11) NOT NULL auto_increment,
`NOME` varchar(45) default NULL,
`DATANASC` date default NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Inclua as linhas abaixo na tabela, ou digite suas próprias informações:
INSERT I NTO `clientes` (`ID`, `NOME`, `DATANASC`) VALUES
(1, 'SILVIO SANTOS', '1971-09-18'),
(2, 'SILLAS SANTOS', '1993-04-27');
Agora, crie a função conforme o exemplo abaixo:
CREATE FUNCTION `idade`(pDATA DATE)
RETURNS varchar(15) CHARSET latin1
NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER
COMMENT ''
Begin
DECLARE vIDADE varchar(30);
IF DATE_FORMAT(NOW( ),'00-%m-%d') >= DATE_FORMAT(pDATA,'00-%m-%d') THEN
SET @idade=DATE_FORMAT(NOW( ),'%Y')-DATE_FORMAT(pDATA,'%Y');
ELSE
SET @idade=DATE_FORMAT(NOW( ),'%Y')-DATE_FORMAT(pDATA,'%Y')-1;
END IF;
RETURN(concat(@idade,' anos'));
end;
Esta função, retornará a idade da pessoa de acordo com o campo DATANASC, da tabela ‘clientes’.
Veja que a função receberá um valor (pDATA, que no nosso exemplo será o campo ‘DATANASC’ de nossa tabela) e fará a subtração da “dat a corrente” pela data do campo DATANASC.
Dentro da função, criamos uma variável (vIDADE), onde armazenaremos o valor a ser retornado pela função. Note também que a função possui retorno do tipo String (RETURNS varchar(30)), que deverá ter o tamanho suficiente para comportar o resultado retornado. Ou seja, se o valor retornado tiver 15 caracteres, o ‘RETURNS’ da função precisa ter tamanho de 15 ou mais caracteres, senão, pode acontecer de não retornar nenhum valor.
Após ter criado a tabela, inserido as linhas na mesma e criado a função, execute a seguinte instrução:
SELECT NOME, idade(DATANASC) IDADE FROM clientes;
No SQL acima, a consulta irá retornar o Nome, e a idade assim: “XX anos”, para cada cliente.
Como você viu, utilizar funções dentro do banco de dados por ser muito mais prático do que fazê-lo dentro da aplicação (me refiro a funções para retorno de dados, claro).
Lembrando que este exemplo é apenas uma base, pois podemos criar funções para qualquer necessdiade, como: calculo de preços, juros de mora, datas, horas, concatenação de campos complexos, junções de tabelas (como nos inner, left e right joins (desde que precise retornar apenas um valor), e muito mais.
JSON e Generics - Serializando Objetos
Fonte: www.activedelphi.com.br
Desta vez vou demonstrar duas novas tecnologias que estão sendo muito melhoradas no Delphi desde a versão 2009 até a ultima versão o Delphi XE. Generics é uma forma de poder
...passar parâmetro de tipos para classes e métodos, possibilitando assim reutilização de código, por exemplo e, JSON (JavaScript Object Notation) é uma forma de troca de dados entre aplicações, semelhante ao XML, porém com uma sintaxe bem mais simples e leve. O Delphi XE, como algumas versões anteriores, dá suporte a implementação usando JSON, e em nosso exemplo vamos criar um método totalmente genêrico que recebe um objeto e um tipo e usaremos o JSON para formatar este objeto e gravar no disco usando a nova classe de IO (input/output) do Delphi, e um método de leitura deste arquivo no formato JSON para retornar o mesmo a um Objeto, novamente passando o tipo do objeto e o caminho onde se encontra o arquivo.
Primeiro vamos criar uma nova classe do tipo TPessoa:
type
TPessoa = class
private
{ Private declarations }
FPessIden: Integer;
FPessNome: string;
public
{ Published declarations }
property PessIden: Integer read FPessIden write FPessIden;
property PessNome: string read FPessNome write FPessNome;
end;
Para conseguirmos desenvolver nossos métodos, temos antes que adicionar ao uses as unit’s citadas abaixo. Acima de cada unit tem a descrição de sua função no projeto:
uses
SysUtils,
{ Unit que contém os novos métodos de I/O }
IOUtils,
{ Unit's necessárioas para usar JSON }
DBXJSONReflect, DBXJSON,
{ Unit necessária para usar Generic }
Generics.Collections;
Agora vamos criar nossa classe que irá conter os métos necessários para carregar e salvar os dados no disco. O class antes da function indica que estes métodos serão estáticos, não sendo necessário instânciar a classe TJSONTools para usar estes métodos, e a descrição T : class, indica que este método recebe um tipo e que a variável obj passada por parâmetro é deste tipo e, na outra função que ela retorna o tipo especificado.
type
TJSONTools = class
public
{ Public declarations }
class function saveFileJSON(obj: T; const filePath: string): Boolean;
class function loadFileJSON(const filePath: string): T;
end;
Agora nosso método que irá gravar no disco o objeto da classe descrita acima.:
class function TJSONTools.saveFileJSON(obj: T; const filePath: string): Boolean;
var
Marshal: TJSONMarshal;
begin
Marshal := TJSONMarshal.Create(TJSONConverter.Create());
try
try
TFile.WriteAllText(filePath, (Marshal.Marshal(obj) as TObject).ToString);
Result := True;
except
Result := False;
end;
finally
FreeAndNil(Marshal);
end;
end;
Agora o método responsável por ler o arquivo e carregar novamente os dados para um objeto:
class function TJSONTools.loadFileJSON(const filePath: string): T;
var
Unmarshal: TJSONUnMarshal;
obj: TJSONObject;
begin
Unmarshal := TJSONUnMarshal.Create();
try
try
if not(FileExists(filePath)) then
Exit(nil);
obj := TJSONObject.ParseJSONValue(
TEncoding.ASCII.GetBytes(TFile.ReadAllText(filePath)),
0) as TJSONObject;
Result := T(Unmarshal.Unmarshal(obj));
except
Exit(nil);
end;
finally
FreeAndNil(Unmarshal);
end;
end;
Agora uma forma de poder usar nossas classes:
var
objPessoa: TPessoa;
begin
objPessoa:= TPessoa.Create();
objPessoa.PessIden := 1;
objPessoa.PessNome := 'Active Delphi';
if (TJSONTools.saveFileJSON<TPessoa>(objPessoa, 'C:\pessoa.txt')) then
ShowMessage('Criou o arquivo no caminho: ' + #13 + ' C:\pessoa.txt');
objPessoa := TJSONTools.loadFileJSON<TPessoa<('C:\pessoa.txt');
if (Assigned(objPessoa)) then
begin
ShowMessage(
'PessIden: ' + IntToStr(objPessoa.PessIden) + #13 +
'PessNome: ' + objPessoa.PessNome
);
end
else
ShowMessage('Não foi possivel des-serializar o objeto');
end;
Este foi apenas um exemplo didático usando JSON e Generics no Delphi. Estes métodos ainda podem ser refatorados e até criado validações para tratar possíveis erros de parâmetros, que podem ser identificados criando testes unitários sobres estes métodos.
Obrigado pela leitura e até a próxima!
Clique aqui para fazer o download do exemplo, feito com Delphi XE
...passar parâmetro de tipos para classes e métodos, possibilitando assim reutilização de código, por exemplo e, JSON (JavaScript Object Notation) é uma forma de troca de dados entre aplicações, semelhante ao XML, porém com uma sintaxe bem mais simples e leve. O Delphi XE, como algumas versões anteriores, dá suporte a implementação usando JSON, e em nosso exemplo vamos criar um método totalmente genêrico que recebe um objeto e um tipo e usaremos o JSON para formatar este objeto e gravar no disco usando a nova classe de IO (input/output) do Delphi, e um método de leitura deste arquivo no formato JSON para retornar o mesmo a um Objeto, novamente passando o tipo do objeto e o caminho onde se encontra o arquivo.
Primeiro vamos criar uma nova classe do tipo TPessoa:
type
TPessoa = class
private
{ Private declarations }
FPessIden: Integer;
FPessNome: string;
public
{ Published declarations }
property PessIden: Integer read FPessIden write FPessIden;
property PessNome: string read FPessNome write FPessNome;
end;
Para conseguirmos desenvolver nossos métodos, temos antes que adicionar ao uses as unit’s citadas abaixo. Acima de cada unit tem a descrição de sua função no projeto:
uses
SysUtils,
{ Unit que contém os novos métodos de I/O }
IOUtils,
{ Unit's necessárioas para usar JSON }
DBXJSONReflect, DBXJSON,
{ Unit necessária para usar Generic }
Generics.Collections;
Agora vamos criar nossa classe que irá conter os métos necessários para carregar e salvar os dados no disco. O class antes da function indica que estes métodos serão estáticos, não sendo necessário instânciar a classe TJSONTools para usar estes métodos, e a descrição T : class, indica que este método recebe um tipo e que a variável obj passada por parâmetro é deste tipo e, na outra função que ela retorna o tipo especificado.
type
TJSONTools = class
public
{ Public declarations }
class function saveFileJSON
class function loadFileJSON
end;
Agora nosso método que irá gravar no disco o objeto da classe descrita acima.:
class function TJSONTools.saveFileJSON
var
Marshal: TJSONMarshal;
begin
Marshal := TJSONMarshal.Create(TJSONConverter.Create());
try
try
TFile.WriteAllText(filePath, (Marshal.Marshal(obj) as TObject).ToString);
Result := True;
except
Result := False;
end;
finally
FreeAndNil(Marshal);
end;
end;
Agora o método responsável por ler o arquivo e carregar novamente os dados para um objeto:
class function TJSONTools.loadFileJSON
var
Unmarshal: TJSONUnMarshal;
obj: TJSONObject;
begin
Unmarshal := TJSONUnMarshal.Create();
try
try
if not(FileExists(filePath)) then
Exit(nil);
obj := TJSONObject.ParseJSONValue(
TEncoding.ASCII.GetBytes(TFile.ReadAllText(filePath)),
0) as TJSONObject;
Result := T(Unmarshal.Unmarshal(obj));
except
Exit(nil);
end;
finally
FreeAndNil(Unmarshal);
end;
end;
Agora uma forma de poder usar nossas classes:
var
objPessoa: TPessoa;
begin
objPessoa:= TPessoa.Create();
objPessoa.PessIden := 1;
objPessoa.PessNome := 'Active Delphi';
if (TJSONTools.saveFileJSON<TPessoa>(objPessoa, 'C:\pessoa.txt')) then
ShowMessage('Criou o arquivo no caminho: ' + #13 + ' C:\pessoa.txt');
objPessoa := TJSONTools.loadFileJSON<TPessoa<('C:\pessoa.txt');
if (Assigned(objPessoa)) then
begin
ShowMessage(
'PessIden: ' + IntToStr(objPessoa.PessIden) + #13 +
'PessNome: ' + objPessoa.PessNome
);
end
else
ShowMessage('Não foi possivel des-serializar o objeto');
end;
Este foi apenas um exemplo didático usando JSON e Generics no Delphi. Estes métodos ainda podem ser refatorados e até criado validações para tratar possíveis erros de parâmetros, que podem ser identificados criando testes unitários sobres estes métodos.
Obrigado pela leitura e até a próxima!
Clique aqui para fazer o download do exemplo, feito com Delphi XE
Assinar:
Postagens (Atom)