You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3417 lines
78 KiB
3417 lines
78 KiB
|
|
{
|
|
|
|
Funções
|
|
|
|
Versao 2.11 - 13/05/2016
|
|
|
|
- Juntar elementos de lista
|
|
|
|
Versao 2.10 - 20/04/2010
|
|
|
|
- Formatar CEP, CPF e CNPJ
|
|
|
|
Versão 2.9 - 08/07/2006
|
|
|
|
- Funções para controle de serviços
|
|
|
|
Versão 2.8 - 08/03/2006
|
|
|
|
- criada GetUserName
|
|
|
|
- criada GetComputerName
|
|
|
|
- criada GetIdeDiskSerialNumber
|
|
|
|
Versão 2.7.1 - 29/08/2005
|
|
|
|
- criada a função LerCampoWeb
|
|
|
|
Versão 2.7.0 - 24/09/2003
|
|
|
|
- function MinToHr(min: integer): String;
|
|
|
|
- Acerto no cálculo - formato de saída hhh:mm
|
|
|
|
- function DecToMin(dec:real): integer;
|
|
|
|
- Acerto no cálculo
|
|
|
|
- function HrToMin(hora: String): Integer;
|
|
|
|
- Para os formatos hhh:mm e hh:mm
|
|
|
|
Versão 2.6.0 - 21/05/2003
|
|
|
|
- Inclusão da função fillspacesl, inserir espaços à esquerda
|
|
|
|
|
|
Versão 2.5.0 - 06/03/2003
|
|
|
|
- Inclusão das funções
|
|
|
|
function datetoyyyymmdd
|
|
|
|
function datetoddmmyyyy
|
|
|
|
|
|
Versão 2.4.1 - 22/01/2003
|
|
|
|
- Acerto no roundprecise e roundprecise2
|
|
para converter os valores recebidos
|
|
por causa de um erro que não convertia
|
|
3.015 para 3.02, somente quando o valor
|
|
vinha no parâmetro precisamente
|
|
|
|
Versão 2.4.0 - 15/01/2003
|
|
|
|
- RoundValue corigida para
|
|
arredondar xx,9 para xx+1
|
|
|
|
Versão 2.3.0 - 09/01/2003
|
|
|
|
- Implementação das funções bancárias
|
|
|
|
Versão 2.2.0 - 08/01/2003
|
|
|
|
- Implementação das conversões de horas
|
|
|
|
Versão 2.1.0 - 02/01/2003
|
|
|
|
- DateToDDMMYY corrigido o ano
|
|
- Replace corrigido
|
|
- RoundValue corrigida
|
|
|
|
Versão 2.0 - 20/10/2002
|
|
|
|
- Implementação das funções básicas
|
|
|
|
}
|
|
|
|
|
|
unit uFuncoes;
|
|
|
|
interface
|
|
|
|
uses SysUtils, Controls, Classes, Windows, Dialogs, Registry,
|
|
ActiveX, ComObj, ShlObj, Winsock, WinSvc, ShellAPI, Variants,
|
|
WinInet, Mapi, Forms;
|
|
|
|
|
|
type
|
|
TShortcut = (scDesktop, scQuickLaunch, scSendTo, scStart, scPrograms);
|
|
|
|
|
|
//
|
|
// Internet
|
|
//
|
|
|
|
function ConectadoInternet: Boolean;
|
|
|
|
function EnviarEmail(Endereco: String; Assunto: String = ''; Texto: String = '';
|
|
stlAnexo: TStringList = nil; AEnviarDireto: boolean = False): Boolean;
|
|
|
|
//
|
|
// Bancárias
|
|
//
|
|
|
|
function fatorvencimento(data: TDateTime): string;
|
|
|
|
function mod10(valor: string): string;
|
|
|
|
function mod11(valor: string): string;
|
|
function mod11barsantander(valor: string): string;
|
|
function mod11santander(valor: string): string;
|
|
function mod11bradesco(valor: string): string;
|
|
|
|
function dacbarcode(tmp: string):string;
|
|
|
|
function reprnumerica(tmp: string):string;
|
|
|
|
//
|
|
// Valores
|
|
//
|
|
|
|
function StrToCurrency(s: string): real;
|
|
|
|
function RoundInteger(value: real):integer;
|
|
|
|
function RoundCurrency(value: currency):currency;
|
|
|
|
function RoundValue(value: real):real;
|
|
|
|
function ValToCurr(tmp: string): real;
|
|
|
|
|
|
|
|
//
|
|
// Strings
|
|
//
|
|
|
|
function LerCampoWeb(msg,campo,default,tipo: string): string;
|
|
|
|
function PlainText(s: string): string;
|
|
|
|
function OnlyNumbers(s: string): string;
|
|
|
|
function replace(tag:string; s1, s2:char):string;
|
|
|
|
function ReplaceStr(S,Localizar,Substituir : string) : string;
|
|
|
|
function blockjustify(s: string; tam:integer):string;
|
|
|
|
function center(s: string; l: integer): string;
|
|
|
|
function fillspaces(tmp: string; count: integer):string;
|
|
|
|
function fillspacesl(tmp: string; count: integer):string;
|
|
|
|
function fillzeros(tmp: string; count: integer):string;
|
|
|
|
function fillcurrency(tmp: currency; count: integer):string;
|
|
|
|
function replicate(tmp: string; count: integer): string;
|
|
|
|
function getword(tmp: string; pos:integer):string;
|
|
|
|
function RightStr(const str: string; size: word): String;
|
|
|
|
function MidStr(const str: string; from, size: word): String;
|
|
|
|
function LeftStr(const str: string; size: word): String;
|
|
|
|
procedure ParseDelimited(const sl : TStrings; const value : string; const delimiter : string) ;
|
|
|
|
function HexToInt(const HexStr: string): longint;
|
|
|
|
function ExtractIP(Path: string): string;
|
|
|
|
function RemoveIP(Path: string): string;
|
|
|
|
function FormatarCEP(const CEP: string): string;
|
|
|
|
function FormatarCPF(const CPF: string): string;
|
|
|
|
function FormatarCNPJ(const CNPJ: string): string;
|
|
|
|
//
|
|
// Datas
|
|
//
|
|
|
|
function DataUtilAleatoria(dt_inicio, dt_fim: TDateTime): TDateTime;
|
|
|
|
function DiaSemana(Data: TDateTime): String;
|
|
|
|
function day(data: TDate): Word;
|
|
|
|
function month(data: TDate): Word;
|
|
|
|
function year(data: TDate): Word;
|
|
|
|
function firstday(month, year: word): TDateTime;
|
|
|
|
function lastday(month, year: word): TDateTime;
|
|
|
|
function ddmmyytodate(tmp: string): TDateTime;
|
|
|
|
function ddmmyyyytodate(tmp: string):TDate;
|
|
|
|
function datetoddmmyy(tmp: TDateTime):string;
|
|
|
|
function datetoddmmyyyy(tmp: TDateTime):string;
|
|
|
|
function datetoyyyymmdd(tmp: TDateTime):string;
|
|
|
|
//Retorna uma data reduzida de "xMeses" meses, podendo ser corrido ou não
|
|
function DiminuiMes (dData : TDateTime; xMeses : Integer; lCorrido : Boolean) : TDateTime;
|
|
|
|
//Retorna uma data acrescida de "xMeses" meses, podendo ser corrido ou não
|
|
function SomaMes (dData : TDateTime; xMeses : Integer; lCorrido : boolean) : TDateTime;
|
|
|
|
//Retorna o último dia útil caso a data informada caia em um fim de semana
|
|
function DiaUtilAnterior (dData : TDateTime) : TDateTime;
|
|
|
|
//Retorna o próximo dia útil caso a data informada caia em um fim de semana
|
|
function ProximoDiaUtil (dData : TDateTime) : TDateTime;
|
|
|
|
//Verifica se uma data informada cai em um final de semana
|
|
function IsWeekEnd (dData : TDateTime) : boolean;
|
|
|
|
//Retorna data do último dia do mês, ou último dia útil, de uma data informada
|
|
function LastDayOfMonth (Data : TDateTime; lSabDom : Boolean) : TDateTime;
|
|
|
|
//Retorna data do primeiro dia do mês, ou primeiro dia útil, de uma data informada
|
|
function FirstDayOfMonth (Data : TDateTime; lSabDom : Boolean) : TDateTime;
|
|
|
|
//Retorna uma data no Mês seguinte a uma data informada
|
|
function NextMonth (Data : TDateTime) : TDateTime;
|
|
Function PriorMonth (Data : TDateTime) : TDateTime;
|
|
|
|
//Retorna a data válida imediatamente posterior a uma data inválida
|
|
function ProxDataValida (Ano, Mes, Dia : Word) : TDateTime;
|
|
|
|
//Retorna a data válida imediatamente anterior a uma data inválida
|
|
function UltDataValida (Ano, Mes, Dia : Word) : TDateTime;
|
|
|
|
|
|
//
|
|
// Horas
|
|
//
|
|
|
|
function HrToMin(hora: String): Integer;
|
|
|
|
function MinToHr(min: integer): String;
|
|
|
|
function MinToDec(min:real): real;
|
|
|
|
function DecToMin(dec:real): integer;
|
|
|
|
|
|
//
|
|
// Verificação
|
|
//
|
|
|
|
function VerificaCPF(Value: string): Boolean;
|
|
|
|
function VerificaCNPJ(Value: string): Boolean;
|
|
|
|
|
|
//
|
|
// Arquivos
|
|
//
|
|
|
|
procedure CopyFile(const sourcefilename, targetfilename: string);
|
|
|
|
procedure CopyFileType(const sourcefilename, targetfilename, filetype: string);
|
|
|
|
procedure DeleteDir(hHandle:THandle; Const sPath:String);
|
|
|
|
procedure Deltree(cPath: string);
|
|
|
|
function FileInUse(FileName: string): Boolean;
|
|
|
|
|
|
//
|
|
// Sistema
|
|
//
|
|
|
|
function GetUserName: string;
|
|
|
|
function GetComputerName: string;
|
|
|
|
function GetComputerIP: string;
|
|
|
|
function GetIdeDiskSerialNumber: string;
|
|
|
|
function FindVolumeSerial(const Drive : PChar): string;
|
|
|
|
function GetBiosSerial: string;
|
|
|
|
function GetBiosInfoAsText: string;
|
|
|
|
function GetBiosCheckSum: string;
|
|
|
|
//function GetHashedBiosInfo: string;
|
|
|
|
function GetFileVersion(const FileName: TFileName; var Major, Minor, Release, Build: word): boolean;
|
|
|
|
function CreateShortcut(aTarget,startDir,aCaption,aGroup: string; aLoc: TShortcut; silent: Boolean): Boolean;
|
|
|
|
procedure PostKeyEx32(key: Word; const shift: TShiftState; specialkey: Boolean);
|
|
|
|
function ServiceStopped(sMachine, sService: string): boolean;
|
|
|
|
function ServiceRunning(sMachine, sService: string): boolean;
|
|
|
|
function ServiceGetStatus(sMachine, sService: string): DWord;
|
|
|
|
function ServiceStart(sMachine, sService: string): boolean;
|
|
|
|
function ServiceStop(sMachine, sService: string): boolean;
|
|
|
|
procedure RunOnStartUp(ApTitle, ApPathFile: string; RunOnce: Boolean);
|
|
|
|
procedure RemoveFromStartUp(ApTitle: string);
|
|
|
|
function CheckStartUp(ApTitle: string): boolean;
|
|
|
|
procedure SetRegistryData(RootKey: HKEY; Key, Value: string; RegDataType: TRegDataType; Data: variant);
|
|
|
|
function GetRegistryData(RootKey: HKEY; Key, Value: string): variant;
|
|
|
|
procedure AcertarData(data: TDateTime);
|
|
|
|
// Function GetNetUserName: string;
|
|
|
|
//
|
|
// Arrays
|
|
//
|
|
|
|
function join(const separator: string; const pieces: array of String): string;
|
|
|
|
//
|
|
// Criptografia
|
|
//
|
|
|
|
function Crypt(Opcao: String; Dados: String): String;
|
|
|
|
function NumAleatorio(Qtd: Integer):string;
|
|
|
|
implementation
|
|
|
|
|
|
function ConectadoInternet: Boolean;
|
|
const
|
|
INTERNET_CONNECTION_MODEM = 1;
|
|
INTERNET_CONNECTION_LAN = 2;
|
|
INTERNET_CONNECTION_PROXY = 4;
|
|
INTERNET_CONNECTION_MODEM_BUSY = 8;
|
|
var
|
|
dwConnectionTypes : DWORD;
|
|
begin
|
|
dwConnectionTypes := INTERNET_CONNECTION_MODEM + INTERNET_CONNECTION_LAN + INTERNET_CONNECTION_PROXY;
|
|
If InternetGetConnectedState(@dwConnectionTypes,0) then
|
|
Result := True
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
function FormatarCEP(const CEP: string): string;
|
|
var
|
|
I: integer;
|
|
begin
|
|
Result := '';
|
|
for I := 1 to Length(CEP) do
|
|
if CEP[I] in ['0'..'9'] then
|
|
Result := Result + CEP[I];
|
|
if Length(Result) <> 8 then
|
|
result := CEP
|
|
else
|
|
Result :=
|
|
Copy(Result, 1, 5) + '-' +
|
|
Copy(Result, 6, 3);
|
|
end;
|
|
|
|
function FormatarCPF(const CPF: string): string;
|
|
var
|
|
I: integer;
|
|
begin
|
|
Result := '';
|
|
for I := 1 to Length(CPF) do
|
|
if CPF[I] in ['0'..'9'] then
|
|
Result := Result + CPF[I];
|
|
if Length(Result) <> 11 then
|
|
result := CPF
|
|
else
|
|
Result :=
|
|
Copy(Result, 1, 3) + '.' +
|
|
Copy(Result, 4, 3) + '.' +
|
|
Copy(Result, 7, 3) + '-' +
|
|
Copy(Result, 10, 2);
|
|
end;
|
|
|
|
function FormatarCNPJ(const CNPJ: string): string;
|
|
var
|
|
I: integer;
|
|
begin
|
|
Result := '';
|
|
for I := 1 to Length(CNPJ) do
|
|
if CNPJ[I] in ['0'..'9'] then
|
|
Result := Result + CNPJ[I];
|
|
if Length(Result) <> 14 then
|
|
result := CNPJ
|
|
else
|
|
Result :=
|
|
Copy(Result, 1, 2) + '.' +
|
|
Copy(Result, 3, 3) + '.' +
|
|
Copy(Result, 6, 3) + '/' +
|
|
Copy(Result, 9, 4) + '-' +
|
|
Copy(Result, 13, 2);
|
|
end;
|
|
|
|
|
|
procedure AcertarData(data: TDateTime);
|
|
var SystemTime: TSystemTime;
|
|
begin
|
|
|
|
with SystemTime do
|
|
begin
|
|
// Definindo o dia do sistema
|
|
wYear := StrToInt(FormatDateTime('yyyy', data));
|
|
wMonth := StrToInt(FormatDateTime('mm', data));
|
|
wDay := StrToInt(FormatDateTime('dd', data));
|
|
// Definindo a hora do sistema
|
|
wHour := StrToInt(FormatDateTime('hh', data));
|
|
wMinute := StrToInt(FormatDateTime('nn', data));
|
|
wSecond := StrToInt(FormatDateTime('ss', data));
|
|
end;
|
|
|
|
//Colocar a hora e data do sistema
|
|
SetLocalTime(SystemTime);
|
|
|
|
end;
|
|
|
|
|
|
function DataUtilAleatoria(dt_inicio, dt_fim: TDateTime): TDateTime;
|
|
{Retorna uma data aleatória em dia útil entre 2 datas limites}
|
|
var dt_sorteio: TDateTime;
|
|
nr_intervalo, nr_dias: integer;
|
|
begin
|
|
|
|
Randomize;
|
|
|
|
// Calcula os números de dias entre as datas
|
|
|
|
nr_intervalo := Trunc(dt_fim - dt_inicio);
|
|
|
|
// Pega um intervalo qualquer e calcula a nova data
|
|
|
|
nr_dias := Random(nr_intervalo);
|
|
|
|
dt_sorteio := dt_inicio + nr_dias;
|
|
|
|
// Se for Sábado ou Domingo tira 2
|
|
|
|
if (DayOfWeek(dt_sorteio) = 1) or (DayOfWeek(dt_sorteio) = 7) then
|
|
dt_sorteio := dt_sorteio - 2;
|
|
|
|
Result := dt_sorteio;
|
|
|
|
end;
|
|
|
|
|
|
function ExtractIP(Path: string): string;
|
|
begin
|
|
|
|
result := copy(path, 1, pos(':', path)-1);
|
|
|
|
end;
|
|
|
|
|
|
function RemoveIP(Path: string): string;
|
|
begin
|
|
|
|
result := copy(path, pos(':', path)+1, length(path));
|
|
|
|
end;
|
|
|
|
|
|
function HexToInt(const HexStr: string): longint;
|
|
var
|
|
iNdx: integer;
|
|
cTmp: Char;
|
|
begin
|
|
result := 0;
|
|
for iNdx := 1 to Length(HexStr) do
|
|
begin
|
|
cTmp := HexStr[iNdx];
|
|
case cTmp of
|
|
'0'..'9': Result := 16 * Result + (Ord(cTmp) - $30);
|
|
'A'..'F': Result := 16 * Result + (Ord(cTmp) - $37);
|
|
'a'..'f': Result := 16 * Result + (Ord(cTmp) - $57);
|
|
else
|
|
raise EConvertError.Create('Illegal character in hex string');
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure CopyFile(const sourcefilename, targetfilename: string);
|
|
var S, T: TFileStream;
|
|
begin
|
|
S := TFileStream.Create( sourcefilename, fmOpenRead );
|
|
try
|
|
T := TFileStream.Create( targetfilename, fmOpenWrite or fmCreate );
|
|
try
|
|
T.CopyFrom(S, S.Size ) ;
|
|
finally
|
|
T.Free;
|
|
end;
|
|
finally
|
|
S.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure CopyFileType(const sourcefilename, targetfilename, filetype: string);
|
|
var
|
|
intFound: Integer;
|
|
SearchRec: TSearchRec;
|
|
begin
|
|
{
|
|
intFound := FindFirst(sourcefilename+filetype, faAnyFile, SearchRec);
|
|
|
|
while intFound = 0 do
|
|
begin
|
|
|
|
CopyFile(sourcefilename+SearchRec.Name, targetfilename+SearchRec.Name);
|
|
|
|
intFound := FindNext(SearchRec);
|
|
|
|
end;
|
|
|
|
FindClose(SearchRec);
|
|
}
|
|
end;
|
|
|
|
procedure DeleteDir( hHandle : THandle; Const sPath : String );
|
|
var
|
|
OpStruc: TSHFileOpStruct;
|
|
FromBuffer, ToBuffer: Array[0..128] of Char;
|
|
begin
|
|
fillChar( OpStruc, Sizeof(OpStruc), 0 );
|
|
FillChar( FromBuffer, Sizeof(FromBuffer), 0 );
|
|
FillChar( ToBuffer, Sizeof(ToBuffer), 0 );
|
|
StrPCopy( FromBuffer, sPath);
|
|
With OpStruc Do
|
|
Begin
|
|
Wnd:= hHandle;
|
|
wFunc:=FO_DELETE;
|
|
pFrom:= @FromBuffer;
|
|
pTo:= @ToBuffer;
|
|
fFlags:= FOF_NOCONFIRMATION;
|
|
fAnyOperationsAborted:=False;
|
|
hNameMappings:=nil;
|
|
//lpszProgressTitle:=nil;
|
|
End;
|
|
ShFileOperation(OpStruc);
|
|
end;
|
|
|
|
procedure Deltree(cPath: string);
|
|
//
|
|
// Remove um diretorio
|
|
//
|
|
var
|
|
search: TSearchRec;
|
|
nFiles: integer;
|
|
begin
|
|
nFiles:=FindFirst( cPath + '\*.*', faAnyFile, search );
|
|
while nFiles=0 do
|
|
begin
|
|
if Search.Attr = faDirectory then
|
|
begin
|
|
if (Search.Name<>'.') and (Search.Name<>'..') then
|
|
begin
|
|
Deltree( cPath + '\' + Search.Name );
|
|
RMDir( cPath + '\' + Search.Name );
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
SysUtils.DeleteFile(cPath + '\' + Search.Name);
|
|
end;
|
|
nFiles:=FindNext( Search );
|
|
end;
|
|
SysUtils.FindClose(Search);
|
|
RMDir(cPath);
|
|
end;
|
|
|
|
function LerCampoWeb(msg,campo,default,tipo: string): string;
|
|
var i: integer;
|
|
msglist: TStringList;
|
|
s: string;
|
|
begin
|
|
|
|
// Delimita o campo
|
|
|
|
campo := campo + ':';
|
|
|
|
msglist := TStringList.Create;
|
|
|
|
msglist.Text := msg;
|
|
|
|
result := '';
|
|
|
|
// Percorre as linhas procurando a variável
|
|
|
|
for i := 0 to msglist.Count-1 do
|
|
begin
|
|
|
|
if copy(msglist.strings[i], 1, length(campo)) = campo then
|
|
begin
|
|
|
|
result := copy(msglist.strings[i], length(campo)+2, length(msglist.strings[i])-length(campo)+1);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
if trim(result) = '' then result := default;
|
|
|
|
|
|
// Se o campo for tarifa, troca os pontos '.' por vírgulas ','
|
|
|
|
if tipo = 'tarifa' then
|
|
begin
|
|
Replace(result, '.', ',');
|
|
end;
|
|
|
|
// Verifica se o campo é numérico e tira os pontos '.'
|
|
|
|
if default = '0' then
|
|
begin
|
|
s := result;
|
|
while Pos('.', s) > 0 do Delete(s,Pos('.', s),1);
|
|
result := s;
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
//
|
|
// Bancárias
|
|
//
|
|
|
|
function fatorvencimento(data: TDateTime): string;
|
|
{O fator de vencimento é a quantidade de dias entre 07/Nov/1997 e a data de vencimento do título}
|
|
begin
|
|
|
|
if data >= EncodeDate(1997,10,07) then
|
|
|
|
result := IntToStr(Trunc(data - EncodeDate(1997,10,07)))
|
|
|
|
else
|
|
|
|
result := '0000';
|
|
|
|
end;
|
|
|
|
function mod10(valor: String) : string;
|
|
{
|
|
Rotina usada para cálculo de alguns dígitos verificadores
|
|
Pega-se cada um dos dígitos contidos no parâmetro VALOR, da direita para a
|
|
esquerda e multiplica-se por 2121212...
|
|
Soma-se cada um dos subprodutos. Caso algum dos subprodutos tenha mais de um
|
|
dígito, deve-se somar cada um dos dígitos. (Exemplo: 7*2 = 14 >> 1+4 = 5)
|
|
Divide-se a soma por 10.
|
|
Faz-se a operação 10-Resto da divisão e devolve-se o resultado dessa operação
|
|
como resultado da função Modulo10.
|
|
Obs.: Caso o resultado seja maior que 9, deverá ser substituído por 0 (ZERO).
|
|
}
|
|
var
|
|
Auxiliar : string;
|
|
Contador, Peso : integer;
|
|
Digito : integer;
|
|
begin
|
|
Auxiliar := '';
|
|
Peso := 2;
|
|
for Contador := Length(Valor) downto 1 do
|
|
begin
|
|
Auxiliar := IntToStr(StrToInt(Valor[Contador]) * Peso) + Auxiliar;
|
|
if Peso = 1 then
|
|
Peso := 2
|
|
else
|
|
Peso := 1;
|
|
end;
|
|
|
|
Digito := 0;
|
|
for Contador := 1 to Length(Auxiliar) do
|
|
begin
|
|
Digito := Digito + StrToInt(Auxiliar[Contador]);
|
|
end;
|
|
Digito := 10 - (Digito mod 10);
|
|
if (Digito > 9) then
|
|
Digito := 0;
|
|
Result := IntToStr(Digito);
|
|
end;
|
|
|
|
|
|
function mod11(Valor: string): string;
|
|
{
|
|
Rotina muito usada para calcular dígitos verificadores
|
|
Pega-se cada um dos dígitos contidos no parâmetro VALOR, da direita para a
|
|
esquerda e multiplica-se pela seqüência de pesos 2, 3, 4 ... até BASE.
|
|
Por exemplo: se a base for 9, os pesos serão 2,3,4,5,6,7,8,9,2,3,4,5...
|
|
Se a base for 7, os pesos serão 2,3,4,5,6,7,2,3,4...
|
|
Soma-se cada um dos subprodutos.
|
|
Divide-se a soma por 11.
|
|
Faz-se a operação 11-Resto da divisão e devolve-se o resultado dessa operação
|
|
como resultado da função Modulo11.
|
|
Obs.: Caso o resultado seja maior que 9, deverá ser substituído por 0 (ZERO).
|
|
}
|
|
var
|
|
Soma : integer;
|
|
Contador, Peso, Digito, resto : integer;
|
|
begin
|
|
|
|
// Bancos
|
|
//
|
|
// Real
|
|
// Itau
|
|
// Caixa Econômica
|
|
// Unibanco - Para COD BARRAS se dig - 0/1/10 entao dig = 1
|
|
// para NOSSO NUMERO se dig - 0/1/10 entao dig = 0
|
|
|
|
Soma := 0;
|
|
Peso := 2;
|
|
for Contador := Length(Valor) downto 1 do
|
|
begin
|
|
Soma := Soma + (StrToInt(Valor[Contador]) * Peso);
|
|
if Peso < 9 then
|
|
Peso := Peso + 1
|
|
else
|
|
Peso := 2;
|
|
end;
|
|
|
|
resto := (soma mod 11);
|
|
|
|
digito := 11 - resto;
|
|
|
|
if (digito = 0) then digito := 1;
|
|
if (digito = 1) then digito := 1;
|
|
if (digito > 9) then digito := 1;
|
|
|
|
result := IntToStr(digito);
|
|
|
|
end;
|
|
|
|
function mod11santander(valor: string): string;
|
|
{
|
|
Rotina muito usada para calcular dígitos verificadores
|
|
Pega-se cada um dos dígitos contidos no parâmetro VALOR, da direita para a
|
|
esquerda e multiplica-se pela seqüência de pesos 2, 3, 4 ... até BASE.
|
|
Por exemplo: se a base for 9, os pesos serão 2,3,4,5,6,7,8,9,2,3,4,5...
|
|
Se a base for 7, os pesos serão 2,3,4,5,6,7,2,3,4...
|
|
Soma-se cada um dos subprodutos.
|
|
Divide-se a soma por 11.
|
|
Faz-se a operação 11-Resto da divisão e devolve-se o resultado dessa operação
|
|
como resultado da função Modulo11.
|
|
Obs.: Caso o resultado seja maior que 9, deverá ser substituído por 0 (ZERO).
|
|
}
|
|
var soma : integer;
|
|
contador, peso, digito, resto : integer;
|
|
begin
|
|
|
|
Soma := 0;
|
|
Peso := 2;
|
|
|
|
for Contador := Length(Valor) downto 1 do
|
|
begin
|
|
Soma := Soma + (StrToInt(Valor[Contador]) * Peso);
|
|
if Peso < 9 then
|
|
Peso := Peso + 1
|
|
else
|
|
Peso := 2;
|
|
end;
|
|
|
|
resto := (soma mod 11);
|
|
|
|
digito := 11 - resto;
|
|
|
|
if (resto = 0) then digito := 0;
|
|
if (resto = 1) then digito := 0;
|
|
if (resto > 9) then digito := 1;
|
|
|
|
result := IntToStr(digito);
|
|
|
|
end;
|
|
|
|
|
|
function mod11barsantander(valor: string): string;
|
|
{
|
|
Rotina muito usada para calcular dígitos verificadores
|
|
Pega-se cada um dos dígitos contidos no parâmetro VALOR, da direita para a
|
|
esquerda e multiplica-se pela seqüência de pesos 2, 3, 4 ... até BASE.
|
|
Por exemplo: se a base for 9, os pesos serão 2,3,4,5,6,7,8,9,2,3,4,5...
|
|
Se a base for 7, os pesos serão 2,3,4,5,6,7,2,3,4...
|
|
Soma-se cada um dos subprodutos.
|
|
Divide-se a soma por 11.
|
|
Faz-se a operação 11-Resto da divisão e devolve-se o resultado dessa operação
|
|
como resultado da função Modulo11.
|
|
Obs.: Caso o resultado seja maior que 9, deverá ser substituído por 0 (ZERO).
|
|
}
|
|
var soma : integer;
|
|
contador, peso, digito, resto : integer;
|
|
begin
|
|
|
|
Soma := 0;
|
|
Peso := 2;
|
|
|
|
for Contador := Length(Valor) downto 1 do
|
|
begin
|
|
Soma := Soma + (StrToInt(Valor[Contador]) * Peso);
|
|
if Peso < 9 then
|
|
Peso := Peso + 1
|
|
else
|
|
Peso := 2;
|
|
end;
|
|
|
|
resto := (soma mod 11);
|
|
|
|
digito := 11 - resto;
|
|
|
|
if (resto = 0) then digito := 1;
|
|
if (resto = 1) then digito := 1;
|
|
if (resto > 9) then digito := 1;
|
|
|
|
result := IntToStr(digito);
|
|
|
|
end;
|
|
|
|
function mod11bradesco(valor: string): string;
|
|
|
|
{
|
|
Rotina muito usada para calcular dígitos verificadores
|
|
Pega-se cada um dos dígitos contidos no parâmetro VALOR, da direita para a
|
|
esquerda e multiplica-se pela seqüência de pesos 2, 3, 4 ... até BASE.
|
|
Por exemplo: se a base for 9, os pesos serao 2,3,4,5,6,7,8,9,2,3,4,5...
|
|
Se a base for 7, os pesos serao 2,3,4,5,6,7,2,3,4...
|
|
Soma-se cada um dos subprodutos.
|
|
Divide-se a soma por 11.
|
|
Faz-se a operaçao 11-Resto da divisao e devolve-se o resultado dessa operaçao
|
|
como resultado da funçao Modulo11.
|
|
Obs.: Caso o resultado seja maior que 9, deverá ser substituído por 0 (ZERO).
|
|
|
|
}
|
|
|
|
var Soma : integer;
|
|
Contador, Peso, Digito : integer;
|
|
|
|
begin
|
|
|
|
Soma := 0;
|
|
Peso := 2;
|
|
|
|
for Contador := Length(valor) downto 1 do
|
|
begin
|
|
|
|
Soma := Soma + (StrToInt(Copy(valor,Contador,1)) * Peso);
|
|
|
|
if (Peso < 7) and (Peso >= 2) then
|
|
Peso := Peso + 1
|
|
else
|
|
Peso := 2;
|
|
|
|
end; // for
|
|
|
|
Digito := (Soma * 10) mod 11;
|
|
|
|
if (Digito > 9) then
|
|
result:='P'
|
|
else
|
|
result := IntToStr(Digito);
|
|
|
|
end;
|
|
|
|
|
|
function reprnumerica(tmp:string): string;
|
|
var campo1, campo2, campo3, campo4, campo5: string;
|
|
begin
|
|
|
|
campo1 := copy(tmp,1,9);
|
|
campo2 := copy(tmp,10,10);
|
|
campo3 := copy(tmp,20,10);
|
|
campo4 := copy(tmp,30,1);
|
|
campo5 := copy(tmp,31,14);
|
|
|
|
campo1 := campo1 + mod10(campo1);
|
|
campo2 := campo2 + mod10(campo2);
|
|
campo3 := campo3 + mod10(campo3);
|
|
|
|
result := copy(campo1,1,5)+'.'+copy(campo1,6,5)+' '+
|
|
copy(campo2,1,5)+'.'+copy(campo2,6,6)+' '+
|
|
copy(campo3,1,5)+'.'+copy(campo3,6,6)+' '+
|
|
campo4+' '+campo5;
|
|
end;
|
|
|
|
|
|
function dacbarcode(tmp: string):string;
|
|
begin
|
|
|
|
result := copy(tmp,1,4) + mod11(tmp) + copy(tmp,5,39);
|
|
|
|
end;
|
|
|
|
//
|
|
// Valores
|
|
//
|
|
|
|
function RoundInteger(value: real):integer;
|
|
// Arredonda para cima se for >= 0.5 e arredonda para baixo se for <= 0.4
|
|
begin
|
|
|
|
result := trunc(value+0.5);
|
|
|
|
end;
|
|
|
|
|
|
function RoundCurrency(value: currency):currency;
|
|
// Arredonda para cima se for >= 0.5 e arredonda para baixo se for <= 0.4
|
|
begin
|
|
|
|
// value := strtofloat(floattostr(value));
|
|
|
|
result := trunc((value*100)+0.5)/100;
|
|
|
|
end;
|
|
|
|
|
|
function fillspaces(tmp: string; count: integer):string;
|
|
begin
|
|
|
|
result := copy(trim(tmp)+StringOfChar(' ',count),1,count);
|
|
|
|
end;
|
|
|
|
function fillspacesl(tmp: string; count: integer):string;
|
|
begin
|
|
|
|
tmp := trim(tmp);
|
|
|
|
result := StringOfChar(' ',count-length(tmp)) + tmp;
|
|
|
|
end;
|
|
|
|
function fillzeros(tmp: string; count: integer):string;
|
|
begin
|
|
|
|
fillzeros := copy(StringOfChar('0',count)+tmp,length(tmp)+1,count);
|
|
|
|
end;
|
|
|
|
|
|
function fillcurrency(tmp: currency; count: integer):string;
|
|
var s, inteiro, decimal: string;
|
|
begin
|
|
|
|
s := formatfloat('0.00',tmp);
|
|
inteiro := copy(s,1,length(s)-3);
|
|
decimal := copy(s,length(s)-1,2);
|
|
|
|
fillcurrency := fillzeros(inteiro,count-2)+decimal;
|
|
|
|
end;
|
|
|
|
function datetoddmmyy(tmp: TDateTime):string;
|
|
begin
|
|
result := FormatDateTime('ddmmyy', tmp);
|
|
// result := copy(DateToStr(tmp),1,2)+copy(DateToStr(tmp),4,2)+copy(DateToStr(tmp),length(DateToStr(tmp))-1,2);
|
|
end;
|
|
|
|
function datetoddmmyyyy(tmp: TDateTime):string;
|
|
begin
|
|
result := FormatDateTime('ddmmyyyy', tmp);
|
|
end;
|
|
|
|
function datetoyyyymmdd(tmp: TDateTime):string;
|
|
begin
|
|
result := FormatDateTime('yyyymmdd', tmp);
|
|
end;
|
|
|
|
function ddmmyytodate(tmp: string):TDateTime;
|
|
var Year, Month, Day: word;
|
|
begin
|
|
if (length(trim(tmp)) = 0) or (tmp = '000000') then
|
|
begin
|
|
result := 0;
|
|
end
|
|
else begin
|
|
Year := StrToInt(copy(tmp,5,2));
|
|
Month := StrToint(copy(tmp,3,2));
|
|
Day := StrToInt(copy(tmp,1,2));
|
|
// Y2K
|
|
if year > 50 then
|
|
Year := Year + 1900
|
|
else
|
|
Year := Year + 2000;
|
|
result := EncodeDate(Year, Month, Day);
|
|
end;
|
|
end;
|
|
|
|
function ddmmyyyytodate(tmp: string):TDate;
|
|
var Year, Month, Day: word;
|
|
begin
|
|
if (length(trim(tmp)) = 0) or (tmp = '00000000') then
|
|
begin
|
|
result := 0;
|
|
end
|
|
else begin
|
|
Day := StrToInt(copy(tmp,1,2));
|
|
Month := StrToint(copy(tmp,3,2));
|
|
Year := StrToInt(copy(tmp,5,4));
|
|
result := EncodeDate(Year, Month, Day);
|
|
end;
|
|
end;
|
|
|
|
|
|
function valtocurr(tmp: string): real;
|
|
begin
|
|
|
|
ValToCurr := StrToInt(copy(tmp,1,11)) + (StrToInt(copy(tmp,12,2))/100);
|
|
|
|
end;
|
|
|
|
|
|
function PlainText(s: string): string;
|
|
var i: integer;
|
|
begin
|
|
|
|
for i := 1 to length(s) do
|
|
begin
|
|
|
|
case s[i] of
|
|
|
|
'á','à','â','ä','ã': s[i] := 'a';
|
|
'é','è','ê','ë' : s[i] := 'e';
|
|
'í','ì','î','ï' : s[i] := 'i';
|
|
'ó','ò','ô','ö','õ': s[i] := 'o';
|
|
'ú','ù','û','ü' : s[i] := 'u';
|
|
'ç' : s[i] := 'c';
|
|
|
|
'Á','À','Â','Ä','Ã': s[i] := 'A';
|
|
'É','È','Ê','Ë' : s[i] := 'E';
|
|
'Í','Ì','Î','Ï' : s[i] := 'I';
|
|
'Ó','Ò','Ô','Ö','Õ': s[i] := 'O';
|
|
'Ú','Ù','Û','Ü' : s[i] := 'U';
|
|
'Ç' : s[i] := 'C';
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
PlainText := s;
|
|
|
|
end;
|
|
|
|
|
|
function StrToCurrency(s: string): real;
|
|
begin
|
|
|
|
// ShowMessage(onlynumbers(s));
|
|
|
|
// ShowMessage(replace(onlynumbers(s),'.',','));
|
|
|
|
result := StrToFloatDef(replace(onlynumbers(s),'.',','),0);
|
|
|
|
end;
|
|
|
|
|
|
function OnlyNumbers(s: string): string;
|
|
var i: byte;
|
|
begin
|
|
|
|
result := '';
|
|
for i := 1 To Length(s) do
|
|
if s[i] in ['0'..'9'] then
|
|
result := result + s[i];
|
|
|
|
{
|
|
while pos('</vNF>', s) > 0 do delete(s, pos('</vNF>', s), 6);
|
|
|
|
while pos('.', s) > 0 do delete(s, pos('.', s), 1);
|
|
|
|
while pos('-', s) > 0 do delete(s, pos('-', s), 1);
|
|
|
|
while pos('/', s) > 0 do delete(s, pos('/', s), 1);
|
|
|
|
while pos('(', s) > 0 do delete(s, pos('(', s), 1);
|
|
|
|
while pos(')', s) > 0 do delete(s, pos(')', s), 1);
|
|
|
|
while pos(' ', s) > 0 do delete(s, pos(' ', s), 1);
|
|
|
|
while pos('<', s) > 0 do delete(s, pos('<', s), 1);
|
|
|
|
while pos('>', s) > 0 do delete(s, pos('>', s), 1);
|
|
|
|
while pos('R$', s) > 0 do delete(s, pos('R$', s), 2);
|
|
}
|
|
|
|
//result := s;
|
|
|
|
end;
|
|
|
|
|
|
function firstday(month, year: word): TDateTime;
|
|
begin
|
|
|
|
result := EncodeDate(year, month, 1);
|
|
|
|
end;
|
|
|
|
|
|
function lastday(month, year: word): TDateTime;
|
|
var ndia, nmes, nano: word;
|
|
data: TDate;
|
|
begin
|
|
|
|
data := EncodeDate(year, month, 28);
|
|
|
|
while TRUE do
|
|
begin
|
|
|
|
data := data + 1;
|
|
DecodeDate(data, nano, nmes, ndia);
|
|
if (nmes <> month) then break;
|
|
|
|
end;
|
|
|
|
lastday := data - 1;
|
|
|
|
end;
|
|
|
|
|
|
function replace(tag:string; s1, s2:char):string;
|
|
var i: integer;
|
|
begin
|
|
|
|
for i := 1 to length(tag) do
|
|
begin
|
|
|
|
if tag[i] = s1 then tag[i] := s2;
|
|
|
|
end;
|
|
|
|
replace := tag;
|
|
|
|
end;
|
|
|
|
|
|
function ReplaceStr (S,Localizar,Substituir : string) : string;
|
|
var
|
|
Retorno: String;
|
|
Posicao: Integer;
|
|
begin
|
|
Retorno := S;
|
|
//Obtendo a posição inicial da substring Localizar na string Localizar.
|
|
Posicao := Pos (Localizar, Retorno);
|
|
if Posicao <> 0 then // Verificando se a substring Localizar existe.
|
|
begin
|
|
// Excluindo a Localizar.
|
|
Delete(Retorno, Posicao, Length (Localizar));
|
|
// Inserindo a string do parâmetro Substituir
|
|
Insert(Substituir, Retorno , Posicao);
|
|
end;
|
|
Result := Retorno;
|
|
end;
|
|
|
|
function getword(tmp: string; pos:integer):string;
|
|
var c,i : integer;
|
|
s: string;
|
|
begin
|
|
|
|
c := 0;
|
|
|
|
s := '';
|
|
|
|
i := 1;
|
|
|
|
while i <= length(tmp) do
|
|
begin
|
|
|
|
if tmp[i] <> ' ' then
|
|
begin
|
|
|
|
while (tmp[i] <> ' ') and (i <= length(tmp)) do
|
|
begin
|
|
|
|
s := s + tmp[i];
|
|
|
|
i := i + 1;
|
|
|
|
end;
|
|
|
|
c := c + 1;
|
|
|
|
if (c = pos) or (i = length(tmp)) then
|
|
begin
|
|
|
|
result := s;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
s := '';
|
|
|
|
end;
|
|
|
|
i := i + 1;
|
|
|
|
end;
|
|
|
|
result := '';
|
|
|
|
end;
|
|
|
|
|
|
function DiaSemana(Data: TDateTime): String;
|
|
{Retorna o dia da semana em Extenso de uma determinada data}
|
|
const
|
|
Dias : Array[1..7] of String[07] = ('dom', 'seg', 'ter','qua','qui', 'sex', 'sab');
|
|
begin
|
|
Result := Dias[DayOfWeek(Data)];
|
|
end;
|
|
|
|
|
|
function blockjustify(s: string; tam:integer):string;
|
|
var i: integer;
|
|
begin
|
|
|
|
i := length(s);
|
|
|
|
while length(s) < tam do
|
|
begin
|
|
|
|
if (s[i] = ' ') then insert(' ',s,i);
|
|
i := i - 1;
|
|
|
|
end;
|
|
|
|
blockjustify := s;
|
|
|
|
end;
|
|
|
|
//
|
|
// arredonda valor no formato 0.0123
|
|
//
|
|
|
|
function roundvalue(value: real):real;
|
|
var svalor: string;
|
|
v: integer;
|
|
c: string;
|
|
i: integer;
|
|
begin
|
|
|
|
if value = round(value) then
|
|
begin
|
|
result := value;
|
|
exit;
|
|
end;
|
|
|
|
//
|
|
// Verifica se a casa depois da virgula
|
|
// é nove e torna o número inteiro mais um
|
|
//
|
|
|
|
svalor := FloatToStr(value)+'0000';
|
|
|
|
if copy(svalor, pos(',', svalor)+1, 1) = '9' then
|
|
begin
|
|
result := trunc(value)+1;
|
|
exit;
|
|
end;
|
|
|
|
//
|
|
// Faz o arredondamento desde o final
|
|
//
|
|
|
|
for i := 5 downto 5 do
|
|
begin
|
|
|
|
if StrToInt(svalor[i]) >= 5 then
|
|
begin
|
|
|
|
if StrToInt(svalor[i-1]) < 9 then
|
|
begin
|
|
v := StrToInt(svalor[i-1])+1;
|
|
c := IntToStr(v);
|
|
svalor[i-1] := c[1];
|
|
end
|
|
else
|
|
begin
|
|
v := StrToInt(copy(svalor,i-2,2))+1;
|
|
c := IntToStr(v);
|
|
svalor[i-1] := c[2];
|
|
svalor[i-2] := c[1];
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
result := StrToFloat(copy(svalor,1,4));
|
|
|
|
end;
|
|
|
|
function day(data: TDate): Word;
|
|
var dia, mes, ano: word;
|
|
begin
|
|
|
|
Decodedate(data, ano, mes, dia);
|
|
|
|
result := dia;
|
|
|
|
end;
|
|
|
|
|
|
function month(data: TDate): Word;
|
|
var dia, mes, ano: word;
|
|
begin
|
|
|
|
DecodeDate( data, ano, mes, dia);
|
|
|
|
result := mes;
|
|
|
|
end;
|
|
|
|
|
|
function year(data: TDate): Word;
|
|
var dia, mes, ano: word;
|
|
begin
|
|
|
|
Decodedate(data, ano, mes, dia);
|
|
|
|
result := ano;
|
|
|
|
end;
|
|
|
|
|
|
function center(s: string; l: integer): string;
|
|
var spc: integer;
|
|
begin
|
|
|
|
if length(s) > l then s := copy(s,1,l);
|
|
|
|
spc := (l-length(s)) div 2;
|
|
|
|
center := StringOfChar(' ',spc)+s;
|
|
|
|
end;
|
|
|
|
|
|
//
|
|
// Horas
|
|
//
|
|
|
|
|
|
function HrToMin(hora: String): Integer;
|
|
var p: integer;
|
|
begin
|
|
|
|
p := pos(':', hora);
|
|
|
|
if p > 0 then
|
|
result := (StrToInt(copy(hora,1,p-1))*60) + StrToInt(copy(hora,p+1,2))
|
|
else
|
|
result := 0;
|
|
|
|
end;
|
|
|
|
|
|
function MinToHr(min: integer): String;
|
|
var m: integer;
|
|
begin
|
|
|
|
m := DecToMin((min/60)-int(min/60));
|
|
|
|
result := fillspacesl(inttostr(trunc(min/60)),3)+':'+fillzeros(inttostr(m),2);
|
|
|
|
if length(trim(result)) = 4 then result := ' 0'+trim(result);
|
|
|
|
end;
|
|
|
|
|
|
function MinToDec(min:real): real;
|
|
begin
|
|
|
|
result := min / 60;
|
|
|
|
end;
|
|
|
|
|
|
function DecToMin(dec:real): integer;
|
|
begin
|
|
|
|
result := trunc((dec/1.666666) * 100);
|
|
|
|
end;
|
|
|
|
function VerificaCPF(Value: string): Boolean;
|
|
var
|
|
localCPF : string;
|
|
localResult : boolean;
|
|
digit1, digit2 : integer;
|
|
ii,soma : integer;
|
|
|
|
begin
|
|
|
|
localCPF := '';
|
|
localResult := False;
|
|
|
|
{analisa CPF no formato 999.999.999-00}
|
|
if Length(Value) = 14 then
|
|
if (Copy(Value,4,1)+Copy(Value,8,1)+Copy(Value,12,1) = '..-') then
|
|
begin
|
|
localCPF := Copy(Value,1,3) + Copy(Value,5,3) + Copy(Value,9,3) +
|
|
Copy(Value,13,2);
|
|
localResult := True;
|
|
end;
|
|
|
|
{analisa CPF no formato 99999999900}
|
|
if Length(Value) = 11 then
|
|
begin
|
|
localCPF := Value;
|
|
localResult := True;
|
|
end;
|
|
|
|
{comeca a verificacao do digito}
|
|
if localResult then
|
|
try
|
|
{1° digito}
|
|
soma := 0;
|
|
for ii := 1 to 9 do Inc(soma, StrToInt(Copy(localCPF, 10-ii, 1))*(ii+1));
|
|
digit1 := 11 - (soma mod 11);
|
|
if digit1 > 9 then digit1 := 0;
|
|
|
|
{2° digito}
|
|
soma := 0;
|
|
for ii := 1 to 10 do Inc(soma, StrToInt(Copy(localCPF, 11-ii, 1))*(ii+1));
|
|
digit2 := 11 - (soma mod 11);
|
|
if digit2 > 9 then digit2 := 0;
|
|
|
|
{Checa os dois dígitos}
|
|
if (Digit1 = StrToInt(Copy(localCPF, 10, 1))) and
|
|
(Digit2 = StrToInt(Copy(localCPF, 11, 1))) then
|
|
localResult := True
|
|
else
|
|
localResult := False;
|
|
except
|
|
localResult := False;
|
|
end;
|
|
|
|
result := localResult;
|
|
|
|
end;
|
|
|
|
function VerificaCNPJ(Value: string): Boolean;
|
|
|
|
var
|
|
localCGC : string;
|
|
localResult : boolean;
|
|
digit1, digit2 : integer;
|
|
ii,soma : integer;
|
|
|
|
begin
|
|
|
|
localCGC := '';
|
|
localResult := False;
|
|
|
|
{analisa CNPJ no formato 99.999.999/9999-00}
|
|
if Length(Value) = 18 then
|
|
if (Copy(Value,3,1)+Copy(Value,7,1)+Copy(Value,11,1)+Copy(Value,16,1) = '../-') then
|
|
begin
|
|
localCGC := Copy(Value,1,2) + Copy(Value,4,3) + Copy(Value,8,3) +
|
|
Copy(Value,12,4) + Copy(Value,17,2);
|
|
localResult := True;
|
|
end;
|
|
|
|
{analisa CGC no formato 99999999999900}
|
|
if Length(Value) = 14 then
|
|
begin
|
|
localCGC := Value;
|
|
localResult := True;
|
|
end;
|
|
|
|
{comeca a verificacao do digito}
|
|
if localResult then
|
|
try
|
|
{1° digito}
|
|
soma := 0;
|
|
for ii := 1 to 12 do
|
|
begin
|
|
if ii < 5 then
|
|
Inc(soma, StrToInt(Copy(localCGC, ii, 1))*(6-ii))
|
|
else
|
|
Inc(soma, StrToInt(Copy(localCGC, ii, 1))*(14-ii))
|
|
end;
|
|
digit1 := 11 - (soma mod 11);
|
|
if digit1 > 9 then digit1 := 0;
|
|
|
|
{2° digito}
|
|
soma := 0;
|
|
for ii := 1 to 13 do
|
|
begin
|
|
if ii < 6 then
|
|
Inc(soma, StrToInt(Copy(localCGC, ii, 1))*(7-ii))
|
|
else
|
|
Inc(soma, StrToInt(Copy(localCGC, ii, 1))*(15-ii))
|
|
end;
|
|
digit2 := 11 - (soma mod 11);
|
|
if digit2 > 9 then digit2 := 0;
|
|
|
|
{Checa os dois dígitos}
|
|
if (Digit1 = StrToInt(Copy(localCGC, 13, 1))) and
|
|
(Digit2 = StrToInt(Copy(localCGC, 14, 1))) then
|
|
localResult := True
|
|
else
|
|
localResult := False;
|
|
except
|
|
localResult := False;
|
|
end;
|
|
|
|
result := localResult;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function replicate(tmp: string; count: integer): string;
|
|
var i: integer;
|
|
str: string;
|
|
begin
|
|
|
|
str := '';
|
|
|
|
for i:= 1 to count do str:= str + tmp;
|
|
|
|
result := Str;
|
|
|
|
end;
|
|
|
|
function GetFileVersion(const FileName: TFileName;
|
|
var Major, Minor, Release, Build: word): boolean;
|
|
// Returns True on success and False on failure.
|
|
var
|
|
size, len: longword;
|
|
handle: THandle;
|
|
buffer: pchar;
|
|
pinfo: ^VS_FIXEDFILEINFO;
|
|
|
|
begin
|
|
|
|
Result := False;
|
|
size := GetFileVersionInfoSize(Pointer(FileName), handle);
|
|
if size > 0 then begin
|
|
GetMem(buffer, size);
|
|
if GetFileVersionInfo(Pointer(FileName), 0, size, buffer)
|
|
then
|
|
if VerQueryValue(buffer, '\', pointer(pinfo), len) then begin
|
|
Major := HiWord(pinfo.dwFileVersionMS);
|
|
Minor := LoWord(pinfo.dwFileVersionMS);
|
|
Release := HiWord(pinfo.dwFileVersionLS);
|
|
Build := LoWord(pinfo.dwFileVersionLS);
|
|
Result := True;
|
|
end;
|
|
FreeMem(buffer);
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
function GetComputerName: string;
|
|
var pcComputer: PChar;
|
|
dwCSize: DWORD;
|
|
begin
|
|
|
|
dwCSize := MAX_COMPUTERNAME_LENGTH + 1;
|
|
|
|
GetMem(pcComputer, dwCSize );
|
|
|
|
try
|
|
|
|
if Windows.GetComputerName(pcComputer, dwCSize ) then
|
|
|
|
Result := pcComputer;
|
|
|
|
finally
|
|
|
|
FreeMem(pcComputer);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
function GetIdeDiskSerialNumber: String;
|
|
type
|
|
TSrbIoControl = packed record
|
|
HeaderLength : ULONG;
|
|
Signature : Array[0..7] of Char;
|
|
Timeout : ULONG;
|
|
ControlCode : ULONG;
|
|
ReturnCode : ULONG;
|
|
Length : ULONG;
|
|
end;
|
|
SRB_IO_CONTROL = TSrbIoControl;
|
|
PSrbIoControl = ^TSrbIoControl;
|
|
|
|
TIDERegs = packed record
|
|
bFeaturesReg : Byte; // especificar "comandos" SMART
|
|
bSectorCountReg : Byte; // registro de contador de setor
|
|
bSectorNumberReg : Byte; // registro de número de setores
|
|
bCylLowReg : Byte; // valor de cilindro (byte mais baixo)
|
|
bCylHighReg : Byte; // valor de cilindro (byte mais alto)
|
|
bDriveHeadReg : Byte; // registro de drive/cabeça
|
|
bCommandReg : Byte; // comando IDE
|
|
bReserved : Byte; // reservado- tem que ser zero
|
|
end;
|
|
IDEREGS = TIDERegs;
|
|
PIDERegs = ^TIDERegs;
|
|
|
|
TSendCmdInParams = packed record
|
|
cBufferSize : DWORD;
|
|
irDriveRegs : TIDERegs;
|
|
bDriveNumber : Byte;
|
|
bReserved : Array[0..2] of Byte;
|
|
dwReserved : Array[0..3] of DWORD;
|
|
bBuffer : Array[0..0] of Byte;
|
|
end;
|
|
SENDCMDINPARAMS = TSendCmdInParams;
|
|
PSendCmdInParams = ^TSendCmdInParams;
|
|
|
|
TIdSector = packed record
|
|
wGenConfig : Word;
|
|
wNumCyls : Word;
|
|
wReserved : Word;
|
|
wNumHeads : Word;
|
|
wBytesPerTrack : Word;
|
|
wBytesPerSector : Word;
|
|
wSectorsPerTrack : Word;
|
|
wVendorUnique : Array[0..2] of Word;
|
|
sSerialNumber : Array[0..19] of Char;
|
|
wBufferType : Word;
|
|
wBufferSize : Word;
|
|
wECCSize : Word;
|
|
sFirmwareRev : Array[0..7] of Char;
|
|
sModelNumber : Array[0..39] of Char;
|
|
wMoreVendorUnique : Word;
|
|
wDoubleWordIO : Word;
|
|
wCapabilities : Word;
|
|
wReserved1 : Word;
|
|
wPIOTiming : Word;
|
|
wDMATiming : Word;
|
|
wBS : Word;
|
|
wNumCurrentCyls : Word;
|
|
wNumCurrentHeads : Word;
|
|
wNumCurrentSectorsPerTrack : Word;
|
|
ulCurrentSectorCapacity : ULONG;
|
|
wMultSectorStuff : Word;
|
|
ulTotalAddressableSectors : ULONG;
|
|
wSingleWordDMA : Word;
|
|
wMultiWordDMA : Word;
|
|
bReserved : Array[0..127] of Byte;
|
|
end;
|
|
PIdSector = ^TIdSector;
|
|
|
|
const
|
|
IDE_ID_FUNCTION = $EC;
|
|
IDENTIFY_BUFFER_SIZE = 512;
|
|
DFP_RECEIVE_DRIVE_DATA = $0007c088;
|
|
IOCTL_SCSI_MINIPORT = $0004d008;
|
|
IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501;
|
|
DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;
|
|
BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize;
|
|
W9xBufferSize = IDENTIFY_BUFFER_SIZE+16;
|
|
var
|
|
hDevice : THandle;
|
|
cbBytesReturned : DWORD;
|
|
pInData : PSendCmdInParams;
|
|
pOutData : Pointer; // PSendCmdOutParams
|
|
Buffer : Array[0..BufferSize-1] of Byte;
|
|
srbControl : TSrbIoControl absolute Buffer;
|
|
|
|
procedure ChangeByteOrder( var Data; Size : Integer );
|
|
var ptr : PChar;
|
|
i : Integer;
|
|
c : Char;
|
|
begin
|
|
ptr := @Data;
|
|
for i := 0 to (Size shr 1)-1 do
|
|
begin
|
|
c := ptr^;
|
|
ptr^ := (ptr+1)^;
|
|
(ptr+1)^ := c;
|
|
Inc(ptr,2);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Result := '';
|
|
FillChar(Buffer,BufferSize,#0);
|
|
if Win32Platform=VER_PLATFORM_WIN32_NT then
|
|
// Windows NT, Windows 2000, Windows XP
|
|
begin
|
|
// recuperar handle da porta SCSI
|
|
hDevice := CreateFile('\\.\Scsi0:',
|
|
// Nota: '\\.\C:' precisa de privilégios administrativos
|
|
GENERIC_READ or GENERIC_WRITE,
|
|
FILE_SHARE_READ or FILE_SHARE_WRITE,
|
|
nil, OPEN_EXISTING, 0, 0);
|
|
if hDevice=INVALID_HANDLE_VALUE then Exit;
|
|
try
|
|
srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
|
|
System.Move('SCSIDISK',srbControl.Signature,8);
|
|
srbControl.Timeout := 2;
|
|
srbControl.Length := DataSize;
|
|
srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
|
|
pInData := PSendCmdInParams(PChar(@Buffer)
|
|
+SizeOf(SRB_IO_CONTROL));
|
|
pOutData := pInData;
|
|
with pInData^ do
|
|
begin
|
|
cBufferSize := IDENTIFY_BUFFER_SIZE;
|
|
bDriveNumber := 0;
|
|
with irDriveRegs do
|
|
begin
|
|
bFeaturesReg := 0;
|
|
bSectorCountReg := 1;
|
|
bSectorNumberReg := 1;
|
|
bCylLowReg := 0;
|
|
bCylHighReg := 0;
|
|
bDriveHeadReg := $A0;
|
|
bCommandReg := IDE_ID_FUNCTION;
|
|
end;
|
|
end;
|
|
if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT,
|
|
@Buffer, BufferSize, @Buffer, BufferSize,
|
|
cbBytesReturned, nil ) then Exit;
|
|
finally
|
|
CloseHandle(hDevice);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// Windows 95 OSR2, Windows 98, Windows ME
|
|
hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil,
|
|
CREATE_NEW, 0, 0 );
|
|
if hDevice=INVALID_HANDLE_VALUE then Exit;
|
|
try
|
|
pInData := PSendCmdInParams(@Buffer);
|
|
pOutData := @pInData^.bBuffer;
|
|
with pInData^ do
|
|
begin
|
|
cBufferSize := IDENTIFY_BUFFER_SIZE;
|
|
bDriveNumber := 0;
|
|
with irDriveRegs do
|
|
begin
|
|
bFeaturesReg := 0;
|
|
bSectorCountReg := 1;
|
|
bSectorNumberReg := 1;
|
|
bCylLowReg := 0;
|
|
bCylHighReg := 0;
|
|
bDriveHeadReg := $A0;
|
|
bCommandReg := IDE_ID_FUNCTION;
|
|
end;
|
|
end;
|
|
if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA,
|
|
pInData, SizeOf(TSendCmdInParams)-1, pOutData,
|
|
W9xBufferSize, cbBytesReturned, nil ) then Exit;
|
|
finally
|
|
CloseHandle(hDevice);
|
|
end;
|
|
end;
|
|
with PIdSector(PChar(pOutData)+16)^ do
|
|
begin
|
|
ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
|
|
SetString(Result,sSerialNumber,SizeOf(sSerialNumber));
|
|
end;
|
|
|
|
end;
|
|
|
|
function GetUserName(): string;
|
|
var vErrorCode: Variant;
|
|
pcNetworkName: PChar;
|
|
cBufferSize: Cardinal;
|
|
me: Array [0..256] of Char;
|
|
begin
|
|
|
|
cBufferSize := 127; // size of the buffer for the name
|
|
|
|
pcNetworkName := ''; // pchar of the network name
|
|
|
|
vErrorCode := WNetGetUser(pcNetworkName, me, cBufferSize); // i holds
|
|
|
|
// error messages, me is assigned loginnamr
|
|
|
|
result := string(me);
|
|
|
|
end;
|
|
|
|
|
|
function GetBiosSerial: string;
|
|
var
|
|
sMainBoardBiosCopyright,
|
|
sMainBoardBiosDate,
|
|
sMainBoardBiosName,
|
|
sMainBoardBiosSerialNo: string;
|
|
begin
|
|
|
|
try
|
|
sMainBoardBiosName := string(PChar(Ptr($FE061))); // Bios name
|
|
sMainBoardBiosCopyright := string(PChar(Ptr($FE091))); // Bios copyright
|
|
sMainBoardBiosDate := string(PChar(Ptr($FFFF5))); // Bios date
|
|
sMainBoardBiosSerialNo := string(PChar(Ptr($FEC71))); // Bios serial number
|
|
except
|
|
sMainBoardBiosName := 'Unsupported';
|
|
sMainBoardBiosCopyright := 'Unsupported';
|
|
sMainBoardBiosDate := 'Unsupported';
|
|
sMainBoardBiosSerialNo := 'Unsupported';
|
|
end;
|
|
|
|
result := sMainBoardBiosSerialNo;
|
|
|
|
end;
|
|
|
|
function GetBiosCheckSum: string;
|
|
var
|
|
s: int64;
|
|
i: longword;
|
|
p: PChar;
|
|
begin
|
|
i := 0;
|
|
s := 0;
|
|
p := PChar($F0000);
|
|
repeat
|
|
inc(s, Int64(Ord(p^)) shl i);
|
|
if i < 64 then inc(i) else i := 0;
|
|
inc(p);
|
|
until p > PChar($FFFFF);
|
|
Result := IntToHex(s,16);
|
|
end;
|
|
|
|
|
|
function GetBiosInfoAsText: string;
|
|
var
|
|
p, q: pchar;
|
|
begin
|
|
q := nil;
|
|
p := PChar(Ptr($FE000));
|
|
repeat
|
|
if q <> nil then begin
|
|
if not (p^ in [#10, #13, #32..#126, #169, #184]) then begin
|
|
if (p^ = #0) and (p - q >= 8) then begin
|
|
Result := Result + TrimRight(String(q)) + #13#10;
|
|
end;
|
|
q := nil;
|
|
end;
|
|
end else
|
|
if p^ in [#33..#126, #169, #184] then
|
|
q := p;
|
|
inc(p);
|
|
until p > PChar(Ptr($FFFFF));
|
|
Result := TrimRight(Result);
|
|
end;
|
|
|
|
|
|
function FindVolumeSerial(const Drive : PChar) : string;
|
|
var
|
|
VolumeSerialNumber : DWORD;
|
|
MaximumComponentLength : DWORD;
|
|
FileSystemFlags : DWORD;
|
|
SerialNumber : string;
|
|
begin
|
|
Result:='';
|
|
|
|
GetVolumeInformation(
|
|
Drive,
|
|
nil,
|
|
0,
|
|
@VolumeSerialNumber,
|
|
MaximumComponentLength,
|
|
FileSystemFlags,
|
|
nil,
|
|
0) ;
|
|
SerialNumber :=
|
|
IntToHex(HiWord(VolumeSerialNumber), 4) +
|
|
'-' +
|
|
IntToHex(LoWord(VolumeSerialNumber), 4) ;
|
|
|
|
Result := SerialNumber;
|
|
|
|
end; (*FindVolumeSerial*)
|
|
|
|
|
|
|
|
//--------------------------------------------------
|
|
//Funções para manipulação de datas
|
|
//
|
|
|
|
//Retorna a data válida imediatamente anterior a uma data inválida
|
|
Function UltDataValida (Ano, Mes, Dia : Word) : TDateTime;
|
|
Var Continua : Boolean;
|
|
DataAux : TDateTime;
|
|
begin
|
|
Continua := True;
|
|
DataAux := date;
|
|
while Continua do
|
|
Try
|
|
DataAux := EncodeDate (Ano, Mes, Dia);
|
|
Continua := False;
|
|
Except
|
|
Dec (Dia);
|
|
End;
|
|
UltDataValida := DataAux;
|
|
end;
|
|
|
|
//Retorna a data válida imediatamente posterior a uma data inválida
|
|
Function ProxDataValida (Ano, Mes, Dia : Word) : TDateTime;
|
|
Var Continua : Boolean;
|
|
DataAux : TDateTime;
|
|
begin
|
|
Continua := True;
|
|
DataAux := date;
|
|
while Continua do
|
|
Try
|
|
DataAux := EncodeDate (Ano, Mes, Dia);
|
|
Continua := False;
|
|
Except
|
|
Inc(Dia);
|
|
End;
|
|
ProxDataValida := DataAux;
|
|
end;
|
|
|
|
//Retorna uma data no Mês seguinte a uma data informada
|
|
Function NextMonth (Data : TDateTime) : TDateTime;
|
|
var Ano, Mes, Dia : word;
|
|
begin
|
|
DecodeDate(Data, Ano, Mes, Dia);
|
|
if Mes = 12 Then begin
|
|
Mes := 1;
|
|
Inc (Ano);
|
|
end else
|
|
Inc (Mes);
|
|
NextMonth := UltDataValida (Ano, Mes, Dia);
|
|
end;
|
|
|
|
//Retorna uma data no Mês anterior a uma data informada
|
|
function PriorMonth (Data : TDateTime) : TDateTime;
|
|
var
|
|
Ano, Mes, Dia : word;
|
|
begin
|
|
DecodeDate(Data, Ano, Mes, Dia);
|
|
|
|
if Mes = 1 then
|
|
begin
|
|
Mes := 12;
|
|
Dec(Ano);
|
|
end else
|
|
Dec(Mes);
|
|
|
|
PriorMonth := UltDataValida (Ano, Mes, Dia);
|
|
end;
|
|
|
|
//Retorna data do primeiro dia do mês, ou primeiro dia útil, de uma data informada
|
|
function FirstDayOfMonth(Data : TDateTime; lSabDom : Boolean): TDateTime;
|
|
var
|
|
Ano, Mes, Dia : word;
|
|
DiaDaSemana : Integer;
|
|
begin
|
|
DecodeDate (Data, Ano, Mes, Dia);
|
|
Dia := 1;
|
|
if lSabDom then
|
|
begin
|
|
DiaDaSemana := DayOfWeek (Data);
|
|
|
|
if DiaDaSemana = 1 then
|
|
Dia := 2
|
|
else if DiaDaSemana = 7 then
|
|
Dia := 3;
|
|
end;
|
|
|
|
FirstDayOfMonth := EncodeDate (Ano, Mes, Dia);
|
|
|
|
end;
|
|
|
|
//Retorna data do último dia do mês, ou último dia útil, de uma data informada
|
|
Function LastDayOfMonth (Data : TDateTime; lSabDom : Boolean) : TDateTime;
|
|
var Ano, Mes, Dia : word;
|
|
AuxData : TDateTime;
|
|
DiaDaSemana : Integer;
|
|
begin
|
|
AuxData := FirstDayOfMonth (NextMonth (Data), False) - 1;
|
|
if lSabDom Then begin
|
|
DecodeDate (Auxdata, Ano, Mes, Dia);
|
|
DiaDaSemana := DayOfWeek (AuxData);
|
|
if DiaDaSemana = 1 Then
|
|
Dia := Dia - 2
|
|
else
|
|
if DiaDaSemana = 7 Then
|
|
Dec (Dia);
|
|
AuxData := EnCodeDate (Ano, Mes, Dia);
|
|
end;
|
|
LastDayOfMonth := AuxData;
|
|
end;
|
|
|
|
//Verifica se uma data informada cai em um final de semana
|
|
Function IsWeekEnd (dData : TDateTime) : boolean;
|
|
begin
|
|
result := false;
|
|
if (DayOfWeek(dData) = 1) or (DayOfWeek(dData) = 7) Then
|
|
result := true;
|
|
end;
|
|
|
|
//Retorna o próximo dia útil caso a data informada caia em um fim de semana
|
|
Function ProximoDiaUtil (dData : TDateTime) : TDateTime;
|
|
begin
|
|
if DayOfWeek(dData) = 7 then
|
|
dData := dData + 2
|
|
else if DayOfWeek(dData) = 1 then
|
|
dData := dData + 1;
|
|
ProximoDiaUtil := dData;
|
|
end;
|
|
|
|
//Retorna o último dia útil caso a data informada caia em um fim de semana
|
|
Function DiaUtilAnterior (dData : TDateTime) : TDateTime;
|
|
begin
|
|
if DayOfWeek(dData) = 7 then
|
|
dData := dData - 1
|
|
else if DayOfWeek(dData) = 1 then
|
|
dData := dData - 2;
|
|
DiaUtilAnterior := dData;
|
|
end;
|
|
|
|
//Retorna uma data acrescida de "xMeses" meses, podendo ser corrido ou não
|
|
Function SomaMes (dData : TDateTime; xMeses : Integer; lCorrido : boolean) : TDateTime;
|
|
var Ano, Mes, Dia : word;
|
|
DataAux : TDateTime;
|
|
begin
|
|
DecodeDate(dData, Ano, Mes, Dia);
|
|
Mes := Mes + xMeses;
|
|
Ano := Ano + (Mes DIV 12);
|
|
Mes := Mes mod 12;
|
|
DataAux := UltDataValida (Ano, Mes, Dia);
|
|
if not lCorrido Then
|
|
DataAux := DataAux - 1;
|
|
SomaMes := DataAux;
|
|
end;
|
|
|
|
//Retorna uma data reduzida de "xMeses" meses, podendo ser corrido ou não
|
|
Function DiminuiMes (dData : TDateTime; xMeses : Integer; lCorrido : Boolean) : TDateTime;
|
|
var Ano, Mes, Dia : word;
|
|
DataAux : TDateTime;
|
|
xMes : SmallInt;
|
|
begin
|
|
DecodeDate(dData, Ano, Mes, Dia);
|
|
Ano := Ano - (xMeses DIV 12);
|
|
xMeses := xMeses mod 12;
|
|
xMes := Mes - xMeses;
|
|
if xMes > 0 Then
|
|
Mes := xMes
|
|
else begin
|
|
Ano := Ano -1;
|
|
Mes := xMes + 12;
|
|
end;
|
|
DataAux := UltDataValida (Ano, Mes, Dia);
|
|
if not lCorrido then
|
|
DataAux := DataAux + 1;
|
|
DiminuiMes := DataAux;
|
|
end;
|
|
|
|
{
|
|
//--------------------------------------------------
|
|
|
|
function CreateShortcut(SourceFileName: string; // the file the shortcut points to
|
|
Location: ShortcutType; // shortcut location
|
|
SubFolder, // subfolder of location
|
|
WorkingDir, // working directory property of the shortcut
|
|
Parameters,
|
|
Description: string): // description property of the shortcut
|
|
string;
|
|
const
|
|
SHELL_FOLDERS_ROOT = 'Software\MicroSoft\Windows\CurrentVersion\Explorer';
|
|
QUICK_LAUNCH_ROOT = 'Software\MicroSoft\Windows\CurrentVersion\GrpConv';
|
|
var
|
|
MyObject: IUnknown;
|
|
MySLink: IShellLink;
|
|
MyPFile: IPersistFile;
|
|
Directory, LinkName: string;
|
|
WFileName: WideString;
|
|
Reg: TRegIniFile;
|
|
begin
|
|
|
|
MyObject := CreateComObject(CLSID_ShellLink);
|
|
MySLink := MyObject as IShellLink;
|
|
MyPFile := MyObject as IPersistFile;
|
|
|
|
MySLink.SetPath(PChar(SourceFileName));
|
|
MySLink.SetArguments(PChar(Parameters));
|
|
MySLink.SetDescription(PChar(Description));
|
|
|
|
LinkName := ChangeFileExt(SourceFileName, '.lnk');
|
|
LinkName := ExtractFileName(LinkName);
|
|
|
|
// Quicklauch
|
|
if Location = scQUICKLAUNCH then
|
|
begin
|
|
Reg := TRegIniFile.Create(QUICK_LAUNCH_ROOT);
|
|
try
|
|
Directory := Reg.ReadString('MapGroups', 'Quick Launch', '');
|
|
finally
|
|
Reg.Free;
|
|
end;
|
|
end
|
|
else
|
|
// Other locations
|
|
begin
|
|
Reg := TRegIniFile.Create(SHELL_FOLDERS_ROOT);
|
|
try
|
|
case Location of
|
|
scOTHERFOLDER : Directory := SubFolder;
|
|
scDESKTOP : Directory := Reg.ReadString('Shell Folders', 'Desktop', '');
|
|
scSTARTMENU : Directory := Reg.ReadString('Shell Folders', 'Start Menu', '');
|
|
scSENDTO : Directory := Reg.ReadString('Shell Folders', 'SendTo', '');
|
|
end;
|
|
finally
|
|
Reg.Free;
|
|
end;
|
|
end;
|
|
|
|
if Directory <> '' then
|
|
begin
|
|
|
|
if (SubFolder <> '') and (Location <> scOTHERFOLDER) then
|
|
WFileName := Directory + '\' + SubFolder + '\' + LinkName
|
|
else
|
|
WFileName := Directory + '\' + LinkName;
|
|
|
|
|
|
if WorkingDir = '' then
|
|
MySLink.SetWorkingDirectory(PChar(ExtractFilePath(SourceFileName)))
|
|
else
|
|
MySLink.SetWorkingDirectory(PChar(WorkingDir));
|
|
|
|
MyPFile.Save(PWChar(WFileName), False);
|
|
|
|
Result := WFileName;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
function GetProgramDir: string;
|
|
var
|
|
reg: TRegistry;
|
|
begin
|
|
reg := TRegistry.Create;
|
|
try
|
|
reg.RootKey := HKEY_CURRENT_USER;
|
|
reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', False);
|
|
Result := reg.ReadString('Programs');
|
|
reg.CloseKey;
|
|
finally
|
|
reg.Free;
|
|
end;
|
|
end;
|
|
}
|
|
|
|
{
|
|
function CreateAShortcut(aTarget,startDir,aCaption,aGroup: string;
|
|
aLoc: TShortcut; silent: Boolean): Boolean;
|
|
|
|
HISTORY: Original version by
|
|
======== - Jon E. Scott
|
|
web: http://members.xoom.com/jescott ("Delphi Code Tips")
|
|
email: jescott@xoommail.com
|
|
|
|
Some improvements and comments 1999-06-18 by
|
|
Bjorn Mossberg: mossberg@mindspring.com
|
|
|
|
PURPOSE: To create a shortcut on the desktop, start menu,
|
|
======== in a program group, in the SendTo folder,
|
|
or in the SysTray region.
|
|
|
|
REQUIRES:
|
|
=========
|
|
uses ShlObj, ComObj, Registry, ActiveX; // and others
|
|
|
|
type
|
|
TShortcut = (sc_Desktop, sc_QuickLaunch, sc_SendTo,
|
|
sc_Start, sc_Programs);
|
|
|
|
PARAMETERS:
|
|
===========
|
|
|
|
aTarget: The full path to the executable file
|
|
for which a shortcut is to be created.
|
|
|
|
startDir: String specifying the folder that is to be made
|
|
current before aTarget executes. May be blank.
|
|
|
|
aCaption: String specifying the "legend" to be written
|
|
under the icon. May be left blank, in which
|
|
case the name of the executable file minus
|
|
its extension is used.
|
|
Caution: Use only legal file characters!
|
|
|
|
aGroup: Meaningful only when aLoc=sc_Programs,
|
|
sc_Desktop, or sc_SendTo.
|
|
Specifies the name of the subfolder to
|
|
which the shortcut is to be added.
|
|
Should already exist.
|
|
|
|
aLoc: One of the values of type ShortcutType:
|
|
|
|
}
|
|
|
|
function CreateShortcut(aTarget,startDir,aCaption,aGroup: string;
|
|
aLoc: TShortcut; silent: Boolean): Boolean;
|
|
var
|
|
anObject: IUnknown;
|
|
|
|
function MergedPath(rootDir,subDir: String): String;
|
|
var
|
|
n: Integer;
|
|
begin
|
|
n := Length(rootDir);
|
|
if n=0 then Result := subDir
|
|
else begin
|
|
if rootDir[n]='\' then Delete(rootDir,n,1);
|
|
n := Length(subDir);
|
|
if n=0 then Result := rootDir
|
|
else begin
|
|
if subDir[1]='\' then Delete(subDir,1,1);
|
|
Result := rootDir + '\' + subDir;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function SaveLinkFile(aCap,aFldr: String): Boolean;
|
|
var
|
|
aPFile: IPersistFile;
|
|
s,fName: String;
|
|
wName: WideString;
|
|
i: Integer;
|
|
begin
|
|
{Save a copy of the object as a link file.
|
|
Try up to 3 times, using tails " (2)" and " (3)".}
|
|
Result := False;
|
|
aPFile := anObject as IPersistFile;
|
|
s := EmptyStr;
|
|
for i:=1 to 3 do begin
|
|
fName := aCap + s + '.lnk';
|
|
wName := MergedPath(aFldr,fName);
|
|
Result := S_OK=aPFile.Save(PWChar(wName), False);
|
|
if Result then Break;
|
|
s := Format(' (%d)',[i]);
|
|
end;
|
|
end;
|
|
|
|
|
|
const
|
|
BaseKey = 'Software\MicroSoft\Windows\CurrentVersion';
|
|
Shell_Folders = 'Shell Folders';
|
|
VDesktop = 'Desktop';
|
|
ProgramMenu = '"Start | Programs" menu';
|
|
var
|
|
aDir,aVar: String;
|
|
aDesc: String;
|
|
dskTop: String;
|
|
s,msg: String;
|
|
begin
|
|
Result := False;
|
|
if NOT (CoInitialize(nil) in [S_OK,S_FALSE]) then begin
|
|
//ShowMessage('Could not initialize OLE COM Library');
|
|
Exit;
|
|
end;
|
|
|
|
{Create an object that can be used as a shortcut
|
|
and later saved as a customized ???.lnk file.}
|
|
anObject := CreateComObject(CLSID_ShellLink);
|
|
try
|
|
with anObject as IShellLink do begin
|
|
{Write in "Target" in the link file:
|
|
The full path of the executable file}
|
|
SetPath(PChar(aTarget));
|
|
|
|
{If supplied, write in "Start In" in the link file:
|
|
The folder to be made current before executing "Target".}
|
|
if (Length(startDir)>0) AND DirectoryExists(startDir) then
|
|
SetWorkingDirectory(PChar(startDir));
|
|
end;
|
|
|
|
{If aCaption is supplied we use that as the caption
|
|
under the icon representing the shortcut.
|
|
Otherwise we simply strip the extension
|
|
from the name of the target file.
|
|
NOTE: The name of the link file is "aCaption.lnk". }
|
|
if Length(aCaption)=0 then
|
|
aCaption := ExtractFileName(aTarget);
|
|
//aCaption := ReplaceAll(aCaption,'/','-'); {May need other fixing.}
|
|
aCaption := ChangeFileExt(aCaption, EmptyStr);
|
|
|
|
aVar := EmptyStr;
|
|
aDesc := EmptyStr;
|
|
case aLoc of
|
|
scStart: aVar := 'Start Menu';
|
|
scPrograms: begin
|
|
aVar := 'Programs';
|
|
aDesc := ProgramMenu;
|
|
end;
|
|
scSendTo: begin
|
|
aVar := 'SendTo';
|
|
aDesc := aVar + ' menu';
|
|
end;
|
|
scQuickLaunch:
|
|
with TRegIniFile.Create(BaseKey+'\GrpConv') do try
|
|
aVar := 'Quick Launch'; {Need aVar for msg later}
|
|
aDir := ReadString('MapGroups',aVar,EmptyStr);
|
|
aDesc := aVar + ' (SysTray) area';
|
|
finally
|
|
Free;
|
|
end;
|
|
else
|
|
aVar := VDesktop; {Default}
|
|
end;
|
|
if Length(aDesc)=0 then
|
|
aDesc := aVar;
|
|
|
|
with TRegIniFile.Create(BaseKey+'\Explorer') do try
|
|
{Always get the path to the Desktop as a fallback.}
|
|
dskTop := ReadString(Shell_Folders,VDesktop,EmptyStr);
|
|
if Length(aDir)=0 then begin
|
|
{Here for all cases except _QUICKLAUNCH}
|
|
if Length(aVar)>0 then {Paranoid check}
|
|
aDir := ReadString(Shell_Folders,aVar,EmptyStr);
|
|
if Length(aDir)=0 then {Should never happen, but ...}
|
|
aDir := dskTop;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
|
|
if Length(aDir)=0 then
|
|
{Hard to imagine that we'll ever be here.}
|
|
//ShowMessage('Could not determine where to create new shortcut!')
|
|
else begin
|
|
msg := Format('Added shortcut "%s" to the %s',[aCaption,aDesc]);
|
|
{Subfolders do not make sense for the SysTray or StartMenu.}
|
|
if (Length(aGroup)>0) AND
|
|
(aLoc in [scDesktop,scSendTo,scPrograms]) then
|
|
begin
|
|
{The caller is suggesting a subfolder which
|
|
we hope exists. Use it only if it does!}
|
|
s := MergedPath(aDir,aGroup);
|
|
if DirectoryExists(s) then begin
|
|
aDir := s;
|
|
AppendStr(msg,Format(' in the subfolder "%s"',[aGroup]));
|
|
end else
|
|
msg := Format('"%s" is not a subfolder of the %s.'
|
|
+' Added the shortcut directly instead.',[aGroup,aDesc]);
|
|
end;
|
|
|
|
{Save a copy of the object as a link file.
|
|
Try up to 3 times, using tails " (2)" and " (3)".}
|
|
Result := SaveLinkFile(aCaption,aDir);
|
|
|
|
if NOT Result then
|
|
msg := 'Could not create shortcut to ' + aTarget;
|
|
if NOT Result OR NOT silent then
|
|
ShowMessage(msg);
|
|
|
|
if (Length(dskTop)>0) AND (aDir<>dskTop) AND
|
|
{Since the dskTop folder is well defined, and not the
|
|
one we just added the shortcut to, we offer to add a
|
|
copy of the shortcut to the Desktop as well.
|
|
We do this whether we failed above or not.}
|
|
(mrYes=MessageDlg('Would you like to add a copy'+
|
|
' of the shortcut to the desktop?',
|
|
mtConfirmation,[mbYes,mbNo],0)) then
|
|
begin
|
|
{Don't reset Result unless we are successful!}
|
|
msg := 'esktop shortcut to '+aTarget;
|
|
if SaveLinkFile(aCaption,dskTop) then begin
|
|
Result := True;
|
|
msg := 'D'+msg+' successfully created!';
|
|
end else
|
|
msg := 'Could not create d'+msg;
|
|
if NOT Result OR NOT silent then
|
|
ShowMessage(msg);
|
|
end;
|
|
end;
|
|
finally
|
|
// TComObject(anObject).Free; {Cannot do this! Memory leak???}
|
|
CoUninitialize;
|
|
end;
|
|
end;
|
|
|
|
function GetComputerIP: String;
|
|
var
|
|
WSAData: TWSAData;
|
|
HostEnt: PHostEnt;
|
|
Name,IP:string;
|
|
begin
|
|
|
|
WSAStartup(2, WSAData);
|
|
SetLength(Name, 255);
|
|
Gethostname(PChar(Name), 255);
|
|
SetLength(Name, StrLen(PChar(Name)));
|
|
HostEnt := gethostbyname(PChar(Name));
|
|
|
|
with HostEnt^ do
|
|
begin
|
|
IP := Format('%d.%d.%d.%d',
|
|
[Byte(h_addr^[0]),Byte(h_addr^[1]),
|
|
Byte(h_addr^[2]),Byte(h_addr^[3])]);
|
|
end;
|
|
|
|
result := IP;
|
|
|
|
WSACleanup;
|
|
|
|
end;
|
|
|
|
|
|
procedure PostKeyEx32(key: Word; const shift: TShiftState; specialkey: Boolean);
|
|
{************************************************************
|
|
* Procedure PostKeyEx32
|
|
*
|
|
* Parameters:
|
|
* key : virtual keycode of the key to send. For printable
|
|
* keys this is simply the ANSI code (Ord(character)).
|
|
* shift : state of the modifier keys. This is a set, so you
|
|
* can set several of these keys (shift, control, alt,
|
|
* mouse buttons) in tandem. The TShiftState type is
|
|
* declared in the Classes Unit.
|
|
* specialkey: normally this should be False. Set it to True to
|
|
* specify a key on the numeric keypad, for example.
|
|
* Description:
|
|
* Uses keybd_event to manufacture a series of key events matching
|
|
* the passed parameters. The events go to the control with focus.
|
|
* Note that for characters key is always the upper-case version of
|
|
* the character. Sending without any modifier keys will result in
|
|
* a lower-case character, sending it with [ssShift] will result
|
|
* in an upper-case character!
|
|
// Code by P. Below
|
|
************************************************************}
|
|
type
|
|
TShiftKeyInfo = record
|
|
shift: Byte;
|
|
vkey: Byte;
|
|
end;
|
|
byteset = set of 0..7;
|
|
const
|
|
shiftkeys: array [1..3] of TShiftKeyInfo =
|
|
((shift: Ord(ssCtrl); vkey: VK_CONTROL),
|
|
(shift: Ord(ssShift); vkey: VK_SHIFT),
|
|
(shift: Ord(ssAlt); vkey: VK_MENU));
|
|
var
|
|
flag: DWORD;
|
|
bShift: ByteSet absolute shift;
|
|
i: Integer;
|
|
begin
|
|
for i := 1 to 3 do
|
|
begin
|
|
if shiftkeys[i].shift in bShift then
|
|
keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0), 0, 0);
|
|
end; { For }
|
|
if specialkey then
|
|
flag := KEYEVENTF_EXTENDEDKEY
|
|
else
|
|
flag := 0;
|
|
|
|
keybd_event(key, MapvirtualKey(key, 0), flag, 0);
|
|
flag := flag or KEYEVENTF_KEYUP;
|
|
keybd_event(key, MapvirtualKey(key, 0), flag, 0);
|
|
|
|
for i := 3 downto 1 do
|
|
begin
|
|
if shiftkeys[i].shift in bShift then
|
|
keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0),
|
|
KEYEVENTF_KEYUP, 0);
|
|
end; { For }
|
|
end; { PostKeyEx32 }
|
|
|
|
|
|
|
|
|
|
//-------------------------------------
|
|
// return TRUE if the specified
|
|
// service is running, defined by
|
|
// the status code SERVICE_RUNNING.
|
|
// return FALSE if the service
|
|
// is in any other state, including
|
|
// any pending states
|
|
//
|
|
function ServiceRunning(
|
|
sMachine,
|
|
sService : string ) : boolean;
|
|
begin
|
|
Result := SERVICE_RUNNING =
|
|
ServiceGetStatus(
|
|
sMachine, sService );
|
|
end;
|
|
|
|
|
|
//-------------------------------------
|
|
// return TRUE if the specified
|
|
// service was stopped, defined by
|
|
// the status code SERVICE_STOPPED.
|
|
//
|
|
function ServiceStopped(
|
|
sMachine,
|
|
sService : string ) : boolean;
|
|
begin
|
|
Result := SERVICE_STOPPED =
|
|
ServiceGetStatus(
|
|
sMachine, sService );
|
|
end;
|
|
|
|
|
|
//-------------------------------------
|
|
// get service status
|
|
//
|
|
// return status code if successful
|
|
// -1 if not
|
|
//
|
|
// return codes:
|
|
// SERVICE_STOPPED
|
|
// SERVICE_RUNNING
|
|
// SERVICE_PAUSED
|
|
//
|
|
// following return codes
|
|
// are used to indicate that
|
|
// the service is in the
|
|
// middle of getting to one
|
|
// of the above states:
|
|
// SERVICE_START_PENDING
|
|
// SERVICE_STOP_PENDING
|
|
// SERVICE_CONTINUE_PENDING
|
|
// SERVICE_PAUSE_PENDING
|
|
//
|
|
// sMachine:
|
|
// machine name, ie: \SERVER
|
|
// empty = local machine
|
|
//
|
|
// sService
|
|
// service name, ie: Alerter
|
|
//
|
|
function ServiceGetStatus(sMachine, sService: string): DWord;
|
|
var
|
|
//
|
|
// service control
|
|
// manager handle
|
|
schm,
|
|
//
|
|
// service handle
|
|
schs : SC_Handle;
|
|
//
|
|
// service status
|
|
ss : TServiceStatus;
|
|
//
|
|
// current service status
|
|
dwStat : integer;
|
|
|
|
begin
|
|
|
|
dwStat := -1;
|
|
|
|
// connect to the service
|
|
// control manager
|
|
schm := OpenSCManager(
|
|
PChar(sMachine),
|
|
Nil,
|
|
SC_MANAGER_CONNECT);
|
|
|
|
// if successful...
|
|
if(schm > 0)then
|
|
begin
|
|
// open a handle to
|
|
// the specified service
|
|
schs := OpenService(
|
|
schm,
|
|
PChar(sService),
|
|
// we want to
|
|
// query service status
|
|
SERVICE_QUERY_STATUS);
|
|
|
|
// if successful...
|
|
if(schs > 0)then
|
|
begin
|
|
// retrieve the current status
|
|
// of the specified service
|
|
if(QueryServiceStatus(
|
|
schs,
|
|
ss))then
|
|
begin
|
|
dwStat := ss.dwCurrentState;
|
|
end;
|
|
|
|
// close service handle
|
|
CloseServiceHandle(schs);
|
|
end;
|
|
|
|
// close service control
|
|
// manager handle
|
|
CloseServiceHandle(schm);
|
|
end;
|
|
|
|
Result := dwStat;
|
|
end;
|
|
|
|
|
|
//
|
|
// start service
|
|
//
|
|
// return TRUE if successful
|
|
//
|
|
// sMachine:
|
|
// machine name, ie: \SERVER
|
|
// empty = local machine
|
|
//
|
|
// sService
|
|
// service name, ie: Alerter
|
|
//
|
|
function ServiceStart(sMachine, sService: string ): boolean;
|
|
var
|
|
//
|
|
// service control
|
|
// manager handle
|
|
schm,
|
|
//
|
|
// service handle
|
|
schs : SC_Handle;
|
|
//
|
|
// service status
|
|
ss : TServiceStatus;
|
|
//
|
|
// temp char pointer
|
|
psTemp : PChar;
|
|
//
|
|
// check point
|
|
dwChkP : DWord;
|
|
|
|
begin
|
|
|
|
ss.dwCurrentState := 0;
|
|
|
|
// connect to the service
|
|
// control manager
|
|
schm := OpenSCManager(
|
|
PChar(sMachine),
|
|
Nil,
|
|
SC_MANAGER_CONNECT);
|
|
|
|
// if successful...
|
|
if(schm > 0)then
|
|
begin
|
|
// open a handle to
|
|
// the specified service
|
|
schs := OpenService(
|
|
schm,
|
|
PChar(sService),
|
|
// we want to
|
|
// start the service and
|
|
SERVICE_START or
|
|
// query service status
|
|
SERVICE_QUERY_STATUS);
|
|
|
|
// if successful...
|
|
if(schs > 0)then
|
|
begin
|
|
psTemp := Nil;
|
|
if(StartService(
|
|
schs,
|
|
0,
|
|
psTemp))then
|
|
begin
|
|
// check status
|
|
if(QueryServiceStatus(
|
|
schs,
|
|
ss))then
|
|
begin
|
|
while(SERVICE_RUNNING
|
|
<> ss.dwCurrentState)do
|
|
begin
|
|
//
|
|
// dwCheckPoint contains a
|
|
// value that the service
|
|
// increments periodically
|
|
// to report its progress
|
|
// during a lengthy
|
|
// operation.
|
|
//
|
|
// save current value
|
|
//
|
|
dwChkP := ss.dwCheckPoint;
|
|
|
|
//
|
|
// wait a bit before
|
|
// checking status again
|
|
//
|
|
// dwWaitHint is the
|
|
// estimated amount of time
|
|
// the calling program
|
|
// should wait before calling
|
|
// QueryServiceStatus() again
|
|
//
|
|
// idle events should be
|
|
// handled here...
|
|
//
|
|
Sleep(ss.dwWaitHint);
|
|
|
|
if(not QueryServiceStatus(
|
|
schs,
|
|
ss))then
|
|
begin
|
|
// couldn't check status
|
|
// break from the loop
|
|
break;
|
|
end;
|
|
|
|
if(ss.dwCheckPoint <
|
|
dwChkP)then
|
|
begin
|
|
// QueryServiceStatus
|
|
// didn't increment
|
|
// dwCheckPoint as it
|
|
// should have.
|
|
// avoid an infinite
|
|
// loop by breaking
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// close service handle
|
|
CloseServiceHandle(schs);
|
|
end;
|
|
|
|
// close service control
|
|
// manager handle
|
|
CloseServiceHandle(schm);
|
|
end;
|
|
|
|
// return TRUE if
|
|
// the service status is running
|
|
Result :=
|
|
SERVICE_RUNNING =
|
|
ss.dwCurrentState;
|
|
end;
|
|
|
|
|
|
//
|
|
// stop service
|
|
//
|
|
// return TRUE if successful
|
|
//
|
|
// sMachine:
|
|
// machine name, ie: \SERVER
|
|
// empty = local machine
|
|
//
|
|
// sService
|
|
// service name, ie: Alerter
|
|
//
|
|
function ServiceStop(
|
|
sMachine,
|
|
sService : string ) : boolean;
|
|
var
|
|
//
|
|
// service control
|
|
// manager handle
|
|
schm,
|
|
//
|
|
// service handle
|
|
schs : SC_Handle;
|
|
//
|
|
// service status
|
|
ss : TServiceStatus;
|
|
//
|
|
// check point
|
|
dwChkP : DWord;
|
|
begin
|
|
// connect to the service
|
|
// control manager
|
|
schm := OpenSCManager(
|
|
PChar(sMachine),
|
|
Nil,
|
|
SC_MANAGER_CONNECT);
|
|
|
|
// if successful...
|
|
if(schm > 0)then
|
|
begin
|
|
// open a handle to
|
|
// the specified service
|
|
schs := OpenService(
|
|
schm,
|
|
PChar(sService),
|
|
// we want to
|
|
// stop the service and
|
|
SERVICE_STOP or
|
|
// query service status
|
|
SERVICE_QUERY_STATUS);
|
|
|
|
// if successful...
|
|
if(schs > 0)then
|
|
begin
|
|
if(ControlService(
|
|
schs,
|
|
SERVICE_CONTROL_STOP,
|
|
ss))then
|
|
begin
|
|
// check status
|
|
if(QueryServiceStatus(
|
|
schs,
|
|
ss))then
|
|
begin
|
|
while(SERVICE_STOPPED
|
|
<> ss.dwCurrentState)do
|
|
begin
|
|
//
|
|
// dwCheckPoint contains a
|
|
// value that the service
|
|
// increments periodically
|
|
// to report its progress
|
|
// during a lengthy
|
|
// operation.
|
|
//
|
|
// save current value
|
|
//
|
|
dwChkP := ss.dwCheckPoint;
|
|
|
|
//
|
|
// wait a bit before
|
|
// checking status again
|
|
//
|
|
// dwWaitHint is the
|
|
// estimated amount of time
|
|
// the calling program
|
|
// should wait before calling
|
|
// QueryServiceStatus() again
|
|
//
|
|
// idle events should be
|
|
// handled here...
|
|
//
|
|
Sleep(ss.dwWaitHint);
|
|
|
|
if(not QueryServiceStatus(
|
|
schs,
|
|
ss))then
|
|
begin
|
|
// couldn't check status
|
|
// break from the loop
|
|
break;
|
|
end;
|
|
|
|
if(ss.dwCheckPoint <
|
|
dwChkP)then
|
|
begin
|
|
// QueryServiceStatus
|
|
// didn't increment
|
|
// dwCheckPoint as it
|
|
// should have.
|
|
// avoid an infinite
|
|
// loop by breaking
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// close service handle
|
|
CloseServiceHandle(schs);
|
|
end;
|
|
|
|
// close service control
|
|
// manager handle
|
|
CloseServiceHandle(schm);
|
|
end;
|
|
|
|
// return TRUE if
|
|
// the service status is stopped
|
|
Result :=
|
|
SERVICE_STOPPED =
|
|
ss.dwCurrentState;
|
|
end;
|
|
|
|
function FileInUse(FileName: string): Boolean;
|
|
var hFileRes: HFILE;
|
|
begin
|
|
Result := False;
|
|
if not FileExists(FileName) then exit;
|
|
hFileRes := CreateFile(PChar(FileName),
|
|
GENERIC_READ or GENERIC_WRITE,
|
|
0,
|
|
nil,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
0);
|
|
Result := (hFileRes = INVALID_HANDLE_VALUE);
|
|
if not Result then
|
|
CloseHandle(hFileRes);
|
|
end;
|
|
|
|
{
|
|
|
|
You can write a value to one of two keys in the Windows Registry
|
|
under the HKEY_LOCAL_MACHINE root key:
|
|
|
|
Software\Microsoft\Windows\CurrentVersion\RunOnce:
|
|
the application will start just ONCE, on the next startup of Windows.
|
|
Afterwards, the new registry key is deleted automatically.
|
|
|
|
Software\Microsoft\Windows\CurrentVersion\Run:
|
|
in this case, the application will start on EVERY Windows startup.
|
|
The registry key that was created will stay in the registry, until you delete it.
|
|
|
|
}
|
|
|
|
procedure RunOnStartUp(ApTitle, ApPathFile: string; RunOnce: Boolean);
|
|
var
|
|
Reg: TRegistry;
|
|
TheKey: string;
|
|
begin
|
|
Reg := TRegistry.Create;
|
|
Reg.RootKey := HKEY_LOCAL_MACHINE;
|
|
TheKey := 'Software\Microsoft\Windows\CurrentVersion\Run';
|
|
if RunOnce then TheKey := TheKey + 'Once';
|
|
// Open key, or create it if it doesn't exist
|
|
Reg.OpenKey(TheKey, True);
|
|
Reg.WriteString(ApTitle, ApPathFile);
|
|
Reg.CloseKey;
|
|
Reg.Free;
|
|
end;
|
|
|
|
{
|
|
|
|
Here's the Delphi source code for deleting an
|
|
entry from the Software\Microsoft\Windows\CurrentVersion\Run key,
|
|
located in the HKEY_LOCAL_MACHINE root key:
|
|
|
|
}
|
|
|
|
procedure RemoveFromStartUp(ApTitle: string);
|
|
var
|
|
Reg: TRegistry;
|
|
TheKey: string;
|
|
ListOfEntries: TStringList;
|
|
i: integer;
|
|
begin
|
|
Reg := TRegistry.Create;
|
|
Reg.RootKey := HKEY_LOCAL_MACHINE;
|
|
TheKey := 'Software\Microsoft\Windows\CurrentVersion\Run';
|
|
// Check if key exist...
|
|
// ...if yes, try to delete the entry for ApTitle
|
|
if not Reg.OpenKey(TheKey, False) then
|
|
ShowMessage('Key not found')
|
|
else begin
|
|
if Reg.DeleteValue(ApTitle) then
|
|
// ShowMessage('Removed: ' + ApTitle)
|
|
else
|
|
// ShowMessage('Not found: ' + ApTitle);
|
|
end;
|
|
Reg.CloseKey;
|
|
Reg.Free;
|
|
end;
|
|
|
|
|
|
function CheckStartUp(ApTitle: string): boolean;
|
|
var
|
|
Reg: TRegistry;
|
|
TheKey: string;
|
|
value: string;
|
|
ListOfEntries: TStringList;
|
|
i: integer;
|
|
begin
|
|
|
|
Reg := TRegistry.Create;
|
|
Reg.RootKey := HKEY_LOCAL_MACHINE;
|
|
TheKey := 'Software\Microsoft\Windows\CurrentVersion\Run';
|
|
|
|
// Check if key exist...
|
|
|
|
if Reg.OpenKey(TheKey, False) then
|
|
begin
|
|
|
|
value := Reg.ReadString(ApTitle);
|
|
|
|
if value = '' then
|
|
result := False
|
|
else
|
|
result := True;
|
|
|
|
end
|
|
else
|
|
begin
|
|
|
|
result := False
|
|
|
|
end;
|
|
|
|
Reg.CloseKey;
|
|
Reg.Free;
|
|
|
|
end;
|
|
|
|
|
|
//
|
|
// SetRegistryData(HKEY_LOCAL_MACHINE,
|
|
// '\Software\Microsoft\Windows\CurrentVersion',
|
|
// 'RegisteredOrganization', rdString, 'Latium Software');
|
|
//
|
|
|
|
procedure SetRegistryData(RootKey: HKEY; Key, Value: string;
|
|
RegDataType: TRegDataType; Data: variant);
|
|
var
|
|
Reg: TRegistry;
|
|
s: string;
|
|
begin
|
|
Reg := TRegistry.Create(KEY_WRITE);
|
|
try
|
|
Reg.RootKey := RootKey;
|
|
if Reg.OpenKey(Key, True) then begin
|
|
try
|
|
if RegDataType = rdUnknown then
|
|
RegDataType := Reg.GetDataType(Value);
|
|
if RegDataType = rdString then
|
|
Reg.WriteString(Value, Data)
|
|
else if RegDataType = rdExpandString then
|
|
Reg.WriteExpandString(Value, Data)
|
|
else if RegDataType = rdInteger then
|
|
Reg.WriteInteger(Value, Data)
|
|
else if RegDataType = rdBinary then begin
|
|
s := Data;
|
|
Reg.WriteBinaryData(Value, PChar(s)^, Length(s));
|
|
end else
|
|
raise Exception.Create(SysErrorMessage(ERROR_CANTWRITE));
|
|
except
|
|
Reg.CloseKey;
|
|
raise;
|
|
end;
|
|
Reg.CloseKey;
|
|
end else
|
|
raise Exception.Create(SysErrorMessage(GetLastError));
|
|
finally
|
|
Reg.Free;
|
|
end;
|
|
end;
|
|
|
|
function GetRegistryData(RootKey: HKEY; Key, Value: string): variant;
|
|
var
|
|
Reg: TRegistry;
|
|
RegDataType: TRegDataType;
|
|
DataSize, Len: integer;
|
|
s: string;
|
|
label cantread;
|
|
begin
|
|
Reg := nil;
|
|
try
|
|
Reg := TRegistry.Create(KEY_QUERY_VALUE);
|
|
Reg.RootKey := RootKey;
|
|
if Reg.OpenKeyReadOnly(Key) then begin
|
|
try
|
|
RegDataType := Reg.GetDataType(Value);
|
|
if (RegDataType = rdString) or
|
|
(RegDataType = rdExpandString) then
|
|
Result := Reg.ReadString(Value)
|
|
else if RegDataType = rdInteger then
|
|
Result := Reg.ReadInteger(Value)
|
|
else if RegDataType = rdBinary then begin
|
|
DataSize := Reg.GetDataSize(Value);
|
|
if DataSize = -1 then goto cantread;
|
|
SetLength(s, DataSize);
|
|
Len := Reg.ReadBinaryData(Value, PChar(s)^, DataSize);
|
|
if Len <> DataSize then goto cantread;
|
|
Result := s;
|
|
end else
|
|
cantread:
|
|
raise Exception.Create(SysErrorMessage(ERROR_CANTREAD));
|
|
except
|
|
s := ''; // Deallocates memory if allocated
|
|
Reg.CloseKey;
|
|
raise;
|
|
end;
|
|
Reg.CloseKey;
|
|
end else
|
|
raise Exception.Create(SysErrorMessage(GetLastError));
|
|
except
|
|
Reg.Free;
|
|
raise;
|
|
end;
|
|
Reg.Free;
|
|
end;
|
|
|
|
|
|
function RightStr(Const Str: String; Size: Word): String;
|
|
begin
|
|
if Size > Length(Str) then Size := Length(Str) ;
|
|
RightStr := Copy(Str, Length(Str)-Size+1, Size)
|
|
end;
|
|
|
|
function MidStr(Const Str: String; From, Size: Word): String;
|
|
begin
|
|
MidStr := Copy(Str, From, Size)
|
|
end;
|
|
|
|
function LeftStr(Const Str: String; Size: Word): String;
|
|
begin
|
|
LeftStr := Copy(Str, 1, Size)
|
|
end;
|
|
|
|
//
|
|
// Usage (fills in Memo1) :
|
|
// ParseDelimited(Memo1.lines,'Zarko;Gajic;;DelphiGuide',';')
|
|
//
|
|
|
|
procedure ParseDelimited(const sl : TStrings; const value : string; const delimiter : string) ;
|
|
var
|
|
dx : integer;
|
|
ns : string;
|
|
txt : string;
|
|
delta : integer;
|
|
begin
|
|
delta := Length(delimiter) ;
|
|
txt := value + delimiter;
|
|
sl.BeginUpdate;
|
|
sl.Clear;
|
|
try
|
|
while Length(txt) > 0 do
|
|
begin
|
|
dx := Pos(delimiter, txt) ;
|
|
ns := Copy(txt,0,dx-1) ;
|
|
sl.Add(ns) ;
|
|
txt := Copy(txt,dx+delta,MaxInt) ;
|
|
end;
|
|
finally
|
|
sl.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
|
|
//
|
|
// Enviar Email Pelo Outlook
|
|
//
|
|
|
|
function EnviarEmail(Endereco: String; Assunto: String = ''; Texto: String = '';
|
|
stlAnexo: TStringList = nil; AEnviarDireto: boolean = False): Boolean;
|
|
type
|
|
TAttachAccessArray = array [0..0] of TMapiFileDesc;
|
|
PAttachAccessArray = ^TAttachAccessArray;
|
|
var
|
|
MapiMessage: TMapiMessage;
|
|
MError: Cardinal;
|
|
Sender: TMapiRecipDesc;
|
|
PRecip, Recipients: PMapiRecipDesc;
|
|
|
|
Attachments: PAttachAccessArray;
|
|
x: integer;
|
|
begin
|
|
|
|
Result := False;
|
|
MapiMessage.nRecipCount := 1;
|
|
GetMem( Recipients, MapiMessage.nRecipCount * Sizeof(TMapiRecipDesc) );
|
|
Attachments := nil;
|
|
|
|
try
|
|
with MapiMessage do
|
|
begin
|
|
{ Assunto e Texto }
|
|
ulReserved := 0;
|
|
lpszSubject := PAnsichar(PChar( Assunto ));
|
|
lpszNoteText := PAnsichar(PChar( Texto ));
|
|
|
|
lpszMessageType := nil;
|
|
lpszDateReceived := nil;
|
|
lpszConversationID := nil;
|
|
flFlags := 0;
|
|
Sender.ulReserved := 0;
|
|
Sender.ulRecipClass := MAPI_ORIG;
|
|
Sender.lpszName := PAnsichar(PChar( '' ));
|
|
Sender.lpszAddress := PAnsichar(PChar( '' ));
|
|
Sender.ulEIDSize := 0;
|
|
Sender.lpEntryID := nil;
|
|
lpOriginator := @Sender;
|
|
|
|
{ Endereço }
|
|
PRecip := Recipients;
|
|
PRecip^.ulReserved := 0;
|
|
PRecip^.ulRecipClass := MAPI_TO;
|
|
|
|
PRecip^.lpszName := PAnsichar(PChar( Endereco ));
|
|
PRecip^.lpszAddress := StrNew( PAnsichar(PChar('SMTP:' + Endereco ) ));
|
|
|
|
PRecip^.ulEIDSize := 0;
|
|
PRecip^.lpEntryID := nil;
|
|
//Inc( PRecip );
|
|
lpRecips := Recipients;
|
|
|
|
{ Anexa os arquivos }
|
|
if stlAnexo = nil then
|
|
begin
|
|
stlAnexo := TStringList.Create;
|
|
stlAnexo.Clear;
|
|
end;
|
|
|
|
{ Deleta do stlAnexo os arquivos que não existem }
|
|
for x := 0 to stlAnexo.Count - 1 do
|
|
if not FileExists( stlAnexo.Strings[x] ) then
|
|
stlAnexo.Delete(x);
|
|
|
|
{ Anexa os arquivos }
|
|
if stlAnexo.Count > 0 then
|
|
begin
|
|
GetMem(Attachments, SizeOf(TMapiFileDesc) * stlAnexo.Count);
|
|
for x := 0 to stlAnexo.Count - 1 do
|
|
begin
|
|
Attachments[x].ulReserved := 0;
|
|
Attachments[x].flFlags := 0;
|
|
Attachments[x].nPosition := ULONG($FFFFFFFF);
|
|
Attachments[x].lpszPathName := StrNew( PAnsichar(PChar(stlAnexo.Strings[x]) ));
|
|
Attachments[x].lpszFileName :=
|
|
StrNew( PAnsichar(PChar( ExtractFileName(stlAnexo.Strings[x]) ) ));
|
|
Attachments[x].lpFileType := nil;
|
|
end;
|
|
end
|
|
{endif};
|
|
nFileCount := stlAnexo.Count;
|
|
lpFiles := @Attachments^;
|
|
end;
|
|
|
|
{ Enviando o e-mail }
|
|
if not AEnviarDireto then
|
|
MError := MapiSendMail(0, Application.Handle, MapiMessage, MAPI_DIALOG or MAPI_LOGON_UI or MAPI_NEW_SESSION, 0)
|
|
else
|
|
MError := MapiSendMail(0, Application.Handle, MapiMessage, MAPI_LOGON_UI or MAPI_NEW_SESSION or MAPI_SENT, 0);
|
|
|
|
case MError of
|
|
MAPI_E_USER_ABORT: ;
|
|
{ Mostra mensagem que o envio do e-mail foi abortado pelo usuário.
|
|
Portanto, não será mostrado nada }
|
|
|
|
SUCCESS_SUCCESS:
|
|
Result := True;
|
|
else
|
|
MessageDlg( 'Ocorreu um erro inesperado!'#13'Código: ' +
|
|
IntToStr(MError), mtError, [mbOk], 0);
|
|
end;
|
|
finally
|
|
PRecip := Recipients;
|
|
StrDispose( PRecip^.lpszAddress );
|
|
//Inc( PRecip );
|
|
|
|
FreeMem( Recipients, MapiMessage.nRecipCount * Sizeof(TMapiRecipDesc) );
|
|
for x := 0 to stlAnexo.Count - 1 do
|
|
begin
|
|
StrDispose( Attachments[x].lpszPathName );
|
|
StrDispose( Attachments[x].lpszFileName );
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Procedure - join //
|
|
// Author - Ronald Buster //
|
|
// Added by - Felipe Ramos //
|
|
// Added at - 05/2016 //
|
|
// //
|
|
// Returns a string containing a string representation of all the array //
|
|
// elements in the same order, with the separator string between each element.//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function join(const separator: string; const pieces: array of String): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
for I := 0 to High(Pieces) do
|
|
if Pieces[i] <> '' then
|
|
Result := Result + separator + Pieces[I];
|
|
Delete(Result, 1, Length(separator));
|
|
end;
|
|
|
|
{Função para criptografar e descriptografar uma string}
|
|
function Crypt(Opcao : String; Dados : String): String;
|
|
var
|
|
I : Integer;
|
|
Key : Word;
|
|
Res : String;
|
|
const
|
|
C1 = 33598;
|
|
C2 = 24219;
|
|
Chave = 16854;
|
|
begin
|
|
Key := Chave;
|
|
for I := 1 to length(Dados) do
|
|
begin
|
|
Res := Res + Char(Byte(Dados[I]) xor (Key shr 8));
|
|
if Opcao = 'CRYPT' then
|
|
Key := (Byte(Res[I]) + Chave) * C1 + C2;
|
|
if Opcao = 'DECRYPT' then
|
|
Key := (Byte(Dados[I]) + Chave) * C1 + C2;
|
|
end;
|
|
Result := Res;
|
|
end;
|
|
|
|
function NumAleatorio(Qtd: Integer):string;
|
|
var
|
|
I, A, P : Integer;
|
|
Num: array of Integer;
|
|
begin
|
|
Result := '';
|
|
|
|
SetLength(Num,Qtd);// Recebe a quantidade de suportes
|
|
|
|
Randomize;
|
|
|
|
for I := 0 to Qtd - 1 do
|
|
Num[I] := I+1;
|
|
for I := Qtd - 1 downto 0 do
|
|
begin
|
|
P := Random(I+1);
|
|
A := Num[I];
|
|
Num[I] := Num[P];
|
|
Num[P] := A;
|
|
end;
|
|
|
|
for I := 0 to Qtd - 1 do
|
|
Result := Result + IntToStr(Num[I]);
|
|
end;
|
|
{
|
|
//Para Capturar o usuário Logado no Windows
|
|
function GetNetUserName: string;
|
|
var
|
|
NetUserNameLength: DWord;
|
|
begin
|
|
NetUserNameLength:=50;
|
|
SetLength(Result, NetUserNameLength);
|
|
GetUserName(pChar(Result),NetUserNameLength);
|
|
SetLength(Result, StrLen(pChar(Result)));
|
|
end;
|
|
}
|
|
end.
|
|
|
|
|
|
{
|
|
|
|
EXEMPLOS
|
|
|
|
|
|
if( ServiceStart(
|
|
'\ComputerName',
|
|
'alerter' ) )then
|
|
begin
|
|
// "alerter" service on \ComputerName
|
|
// was started
|
|
// take appropriate action here
|
|
end;
|
|
|
|
// stop "alerter" service
|
|
// running on the local
|
|
// computer
|
|
if( ServiceStop(
|
|
'',
|
|
'alerter' ) )then
|
|
begin
|
|
end;
|
|
|
|
|
|
----------------
|
|
|
|
if( ServiceRunning(
|
|
'\ComputerName',
|
|
'alerter' ) )then
|
|
begin
|
|
// "alerter" service on \ComputerName
|
|
// is running
|
|
// take appropriate action here
|
|
end;
|
|
|
|
if( ServiceRunning(
|
|
'',
|
|
'alerter' ) )then
|
|
begin
|
|
// "alerter" service on the
|
|
// local computer is running
|
|
end;
|
|
|
|
if( ServiceStopped(
|
|
'',
|
|
'alerter' ) )then
|
|
begin
|
|
// "alerter" service on the
|
|
// local computer is in the
|
|
// "stopped" state (not running)
|
|
end;
|
|
|
|
|
|
}
|