Postagens

Mostrando postagens com o rótulo delphi

6 maneiras de fazer a mesma coisa, o que é considerado boas práticas?

As vezes tem tantas maneiras diferentes de fazer o mesmo código que nós ficamos na dúvida quanto a qual maneira usar. O que seria considerado "boa prática" pela comunidade e o que sua equipe entenderia melhor. Suponhamos que você esteja trabalhando dentro de um método de um Domain Service chamado UmDomainServiceChique(objetoDoDominio) que será chamado por uma API. Você tem uma regra de negócio chique para ser verificada que por enquanto chamarei de VerificaMinhaRegraChiqueComplexa(). Você chama UmDomainServiceChique(objetoDoDominio) e caso VerificaMinhaRegraChiqueComplexa() retorne true você vai querer que UmDomainServiceChique faça o que tem que fazer e a api retornar Ok 200, caso contrário você quer que a API responda um erro qualquer, tipo BadRequest, e retornar uma mensagem dizendo que VerificaMinhaRegraChiqueComplexa deu ruim. Eu vejo 6 maneiras de fazer isso, gostaria de saber a opinião de outrs devs sobre qual seria a maneira menos gambiarr...

Duas maneiras de se fazer split no Delphi XE2 parecido com a função split do C#

Imagem
Para se fazer uma função split no Delphi basta usar array dinâmico ou list de string. O exemplo abaixo mostra como. function split(original: string; separador: string) : TStringArray; var idx: integer; tmp, item: string; resultado: TStringArray; begin idx:=0; SetLength(resultado, idx); tmp := original; while Pos(separador, tmp) > 0 do begin SetLength(resultado, length(resultado)+1); item := Copy(tmp, 1, Pos(separador, tmp)-1); tmp := Copy(tmp, Pos(separador, tmp) + length(separador), length(tmp) + Pos(separador, tmp) - length(separador)); resultado[idx] := item; inc(idx); end; SetLength(resultado, length(resultado)+1); resultado[idx] := tmp; Result := resultado; end; function split2(original: string; separador: string) : TList ; var tmp, item: string; begin result := TList .Create; tmp := original; while Pos(separador, tmp) > 0 do begin Result.Add( Copy(tmp, 1, Pos(separador, tmp)-1)); tmp := Copy(tmp, Po...

Como ordenar o conteúdo de um Memo com regras personalizadas

Recentemente um colega delpheiro me perguntou como ordenar um memo não pelo seu conteúdo, mas por alguma regra especial. No caso dele, ele tinha no memo várias strings separadas por ":" com números do outro lado. Algo assim: A:3 B:5 C:1 Devendo ficar: C:1 A:3 B:5 Para isso podemos usar a função CustomSort do memo, passando como argumento uma função. Essa é uma função especial que aceita uma lista como parâmetro, dois índices da lista e retorna um integer. Assim ela pode comparar dois itens da lista e retornar 1 se o primeiro for maior, 0 se os itens forem iguais ou -1 se o segundo for maior. Essa função é que fará todo o trabalho de comparação, portanto você decide como os itens serão comparados. A função CustomSort saberá que deve chamar a sua função para decidir, na varredura, qual item é maior porque você passará o nome da sua função, como se fosse um delegate ou ponteiro para função, como argumento para  a função customsort. Os memos podem ser usados como...

Delphi Prism, porque não vale a pena

Update O Prism nunca foi da Embarcadero, ele pertence a Rem Objects, que tinha um contrato com a Embarcadero até esse ano, mas esse contrato já expirou e as duas empresas vão seguir seus caminhos. O último Delphi Prism foi a versão XE3, se não me engano, mas o Rad Studio XE4 não virá com o Prism, como diz o Andreano Lanusse e o próprio pessoal da Rem Objects. O Prism foi descontinuado na Embarcadero, mas continuará a evoluir na Rem Objects sob o nome de Oxygene (seu verdadeiro nome). http://www.andreanolanusse.com/pt/delphi-xe4-conheca-as-novidades-para-ios-e-mais/ http://blogs.remobjects.com/blogs/mh/2013/04/17/p5822 http://www.itwriting.com/blog/7338-no-more-delphi-for-net-prism-removed-from-rad-studio-xe4.html A partir desse momento a Embarcadero e a RemObjects não são mais parceiras, mas sim concorrentes, mas acredito que o Prism agora irá evoluir, implantando melhorias que não poderia antes devido às políticas da Embarcadero. Sobre o velho assunto da "Morte do Delphi...

Interfaces no Delphi e destruição prematura de objetos / access violation

Recentemente me perguntaram no site da DevMedia se é correto ou não misturar interfaces e objetos em uma conversão temporária, como esta abaixo: var C: TCarro; begin C := TCarro.Create; //tenho um objeto, mas C não conta referencias C.Placa := 'ABC1234'; (C as ICarro).Rodar; //converte e roda na mesma linha, mas zera o contador de referencias na proxima linha C.Parar; //isso dá erro Segue links da Thread: http://www.devmedia.com.br/poo-dominando-o-uso-de-interfaces-revista-clube-delphi-134/22569 http://www.vitorrubio.com.br/downloads/TesteInterfaces.zip http://www.vitorrubio.com.br/downloads/CD134_Interfaces_V2_Reformulado.zip Isso por causa do problema de se zerar o contador de referências em interfaces tendo mais uma referência ao objeto em uma variável do tipo objeto e destruir esse objeto prematuramente. Basicamente nesses casos o comportamento esperado seria um erro. Pode acontecer de o objeto continuar acessível na memória, ou pelo menos alguns méto...

Criando um lookup que chame uma de suas forms

Um leitor deu a dica de fazer um lookup que chame uma das forms do projeto. Há várias maneiras de se fazer isso, mas uma que encontrei foi usar formulários registrados com RegisterClass. Depois é só usar FindClass para encontrar o formulário, e FindComponent para encontrar o componente onde reside o valor a ser trazido. Se o componente for um TPersistentField, melhor ainda. Ele pode ser achado, e com um typecast para TField seu valor (o valor encontrado e escolhido no formulario de procura/cadastro padrão) pode ser trazido para o keyvalue. Abaixo um exemplo de como isso pode ser feito. Primeiro o registro do formulario: initialization RegisterClass(TfrmConsulta); Depois a chamada dele. Repare que ele é desconhecido para o formulário principal: não está no uses. procedure TfrmPrincipal.Button1Click(Sender: TObject); var NewFormClass: TFormClass; NewForm: TForm; begin NewFormClass := TFormClass(FindClass( 'TFrmConsulta' )); //detalhe: esse string 'TFrmConsu...

Bancos de dados gratuitos parte 2

Imagem
Saiu na Clube Delphi 132 a parte 2 do artigo sobre bancos de dados gratuitos . Espero que todos gostem. Esta edição ainda traz um artigo sobre Nota Fiscal Eletrônica 2.0, muito útil. Não se esqueça que agora os códigos GTIN (códigos de barra a serem preenchidos nos campos cEAN e cEANTrib) agora são obrigatórios. Um artigo que eu lerei com bastante curiosidade é o artigo sobre Morfik, que permite desenvolvimento par Web com Object Pascal, semelhante ao Delphi. Mas com o Morfik você também desenvolve código "client-side". Espero que todos tenham boa leitura!

Artigos sobre bancos de dados gratuitos e lookups

Imagem
Saiu na revista Clube Delphi 131 dois artigos meus: um sobre bancos de dados gratuitos e outro sobre a criação de um componente lookup genérico . Lokups são campos utilizados para fazer a ligação entre duas entidades, duas tabelas. Em uma tabela de venda, por exemplo, há informações sobre o código do cliente para quem a venda está sendo feita, o código da forma de pagamento, e assim por diante. Um formulário não deve ter campos para se digitar os códigos diretamente, e sim campos lookup, que possam ser usados para procurar a forma de pagamento, o cliente e as outras informações em questão pelo nome e não pelo código. Neste artigo fizemos um lookup, usando um ButtonedEdit e um formulário com grid,  que pode funcionar em múltiplos bancos de dados e que traz os registros filtrando-os, usando para isso uma instrução SQL montada sob demanda. Isso ajuda a diminuir o tempo de abertura dos formulários e o tempo de carregamento dos lookups, bem como a quantidade de registros trazida n...

erro "ora-12154: tns: não foi possível resolver o identificador de conexão especificado"

Para se conectar uma aplicação Delphi no Oracle é necessário editar o arquivo tsnames.ora, geralmente na pasta  C:\oraclexe\app\oracle\product\10.2.0\server\NETWORK\ADMIN caso seu oracle seja o XE. Esse erro pode acontecer tanto em runtime como em design-time, com qualquer tipo de componente: DBX, ADO e assim por diante. É mais comum que aconteça em tempo de design em um windows de 64 bit.  Em alguns casos onde essa mensagem de erro aparece é porque o arquivo não existe ou está em uma pasta que o Delphi ou o seu aplicativo não tem permissão de acesso.  Na grande maioria dos casos o erro ocorre apenas em design-time e nunca em runtime. Se esse é o seu caso   então provavelmente a culpa é do windows de 64 bit, mais especificamente o fato de o Delphi estar instalado na pasta "Arquivos de Programas (x86)". Explicando, o driver de conexão ao oracle não suporta caminhos contendo parênteses "()", esses que tem no "(x86)". Ele não consegue encontrar nem o drive...

Key Violation em nested datasets

Resolva de uma vez por todas o problema de "key violation" em datasets "detail" ligados a datasetfileds através de providers. Cenário: você tem duas tabelas num relacionamento 1:n tipo mestre-detalhe no seu banco de dados, por exemplo Pedidos e ItensDoPedido. A chave primária de ambas as tabelas é auto-numerada, por exemplo com ajuda de um generator do firebird. A Tabela itens tem uma chave estrangeira PedCodigo, que é o código do pedido, mas para controle interno também tem uma chave primária CodItem, autonumerada. Você colocou no formulário dois SQLDatasets, um fazendo o select em Pedidos e outro fazendo o select em ItensDoPedido, com um "where CodPedido = :CodPedido" para fazer a "ligação". Você ligou o SQLDataset detalhe (ItensDoPedido) a um datasource ligado ao SQLDataset mestre. Você ligou também um DatasetProvider ao SQLDataset de Pedidos e ligou um ClientDataset cdsPedidos a esse provider, criando um dataset field (campo do tipo datas...

O que você melhoraria no Delphi? - parte 2

Na parte 1 desse post , há muito tempo, fiz uma pequena descrição do que eu acho que poderia ser melhorado no Delphi. Resumindo: 1) Alguns componentes e bibliotecas mais comuns "nativos" em vez de "incorporados". 2) Literatura orientada mais a POO e a boas práticas da Engenharia de Software do que a RAD. A literatura disponível nos helps, exemplos, snippets e consequentemente nos blogs e fóruns é toda voltada a RAD, arrastar e  soltar componentes. E como todos sabemos RAD é bom para protótipos e projetos pequenos, ou com requisitos fixos, com baixa frequencia de manutenção. 3) O aspecto que eu acho mais importante é (a falta de) um framework de persistência nativo da Embarcadero, para se fazer o mapeamento objeto relacional de maneira padronizada e ao mesmo tempo rápida. Continuando, uma coisa que eu acho muito importante são as ações de marketing. No Brasil parece que o Delphi está queimado justamente com quem mais deveria acreditar nele: os professores. D...

Biblioteca MadCollection

Imagem
Saiu na edição 129 da Revista Clube Delphi meu artigo sobre a madCollection. Francamente não sei como não é distribuída juntamente com o Delphi, ou com qualquer outra linguagem / IDE, uma biblioteca tão útil. Explico: ela te permite fazer o que as vezes nem a API do windows permite. Neste artigo dei algumas pinceladas, mas a biblioteca é muito maior do que eu demonstrei. Mencionando os artigos que estou lendo AGORA: o artigo dbExpress 4 do Fabrício Kawata e o Padrões Criacionais do Rafael Stavarengo chamaram muito minha atenção. Boa leitura.

Clube Delphi 128

Imagem
Saiu a Clube Delphi 128, e dessa vez o meu artigo é capa! Agradeço ao Guinther Pauli , editor da revista, pela paciência que tem com meus atrasos :p Meu artigo sobre interoperabilidade  explica como integrar sistemas Delphi Win32, .Net e talvez outros através de DLLs, COM, WebServices e troca de mensagens pela API do windows. Mostro nesse artigo como consumir uma DLL feita em Delphi através do .Net, como consumir pelo Delphi uma DLL .Net através da integração COM, como consumir pelo Delphi um webservice feito em .Net e como fazer as aplicações se comunicarem via API do windows. Lógico, sobre interoperabilidade fiquei devendo, por questões de tempo e espaço, algumas coisinhas que pretendo mencionar em artigos futuros, na revista e/ou neste blog: .Net consumindo webservice em Delphi  Introdução do Lazarus na brincadeira  Integração por sockets  Integração por xml, json e txt Por enquanto não vejo a hora de ler os artigos sobre programação Android com fre...

A API GetuserNameEx

Imagem
Primeiro de tudo, a função GetUserNameEx se encontra na dll Secur32.dll e, como outras funções da API do windows, possui duas versões, uma ANSI (GetUserNameExA) e uma WIDE (GetUserNameExW). Abaixo segue o cabeçalho para importação dessas duas funções. function GetUserNameExA(NameFormat: TEXTENDED_NAME_FORMAT; lpBuffer: PAnsiChar; var nSize: DWORD): BOOL; stdcall external 'Secur32.dll' name 'GetUserNameExA'; function GetUserNameExW(NameFormat: TEXTENDED_NAME_FORMAT; lpBuffer: PWideChar; var nSize: DWORD): BOOL; stdcall external 'Secur32.dll' name 'GetUserNameExW'; Atenção especial para o parâmetro NameFormat do tipo TEXTENDED_NAME_FORMAT . Ele é na verdade um Enum com alguns valores fixos. (no C também é um enum, e usa-se um ponteiro para ele) TEXTENDED_NAME_FORMAT = ( NameUnknown = 0, NameFullyQualifiedDN = 1, NameSamCompatible = 2, NameDisplay = 3, NameUniqueId = 6, NameCanonic...

Api hooking para mudar o usuário logado

Já está nas bancas a revista Clube Delphi 127 com meu primeiro artigo sobre a madShi Collection. Neste artigo eu explico o básico sobre API Hooking. Neste post falarei sobre um exemplo que não se encontra no artigo, que é o hooking da API GetUserName. Os motivos que levam a hookar essa API podem ser variados, e todos eles nada éticos a meu ver. Você pode desde tentar enganar um produto registrado para um usuário acessando-o como outro usuário ou simplesmente para tapear um usuário administrador, que quando olhar quem está logado verá um nome diferente (supondo que isso funcione, não testei). A idéia é que dá para mudar a resposta que outros programas recebem quando perguntam quem é o usuário logado. Para isso é necessário conhecer quais são as api's que fazem isso e como interceptá-las. O código dessa postagem mostra como usar a madCodeHook para interceptar a api GetUserName da api do windows. Primeiro de tudo criei um programa que mostra o nome do usuário corrente: fu...

Leitura obrigatória sobre strings

A maior facilidade das strings do Delphi em relação ao C e C++ é que elas não são baseadas em operações de "baixo nível" com ponteiros. Elas são facilmente quebradas, concatenadas ou copiadas. No caso das cópias, elas podem ser copiadas com performance pois mantém um contador de referências. Em comparação com as linguagens interpretadas, gerenciadas e com "coletores de lixo" as strings nessas linguagens não são tão performáticas. Cópias de strings não são cópias de referências, mas da string completa mesmo, sem reference counting. Tratando - se de concatenação de strings então, o .Net Framework, até a versão 2.0, que eu saiba, encorajava o uso de StringBuilder em vez de strings dentro de um loop para montar um relatório ou tabela na web, por exemplo. Isso porque ao se concatenar duas strings o .Net Framework cria uma nova string com o conteúdo das duas, destruindo as outras duas, gerando um overhead. Imagine quantas operações dentro de um loop não acontecem quan...

madShi collection

Imagem
Saiu na revista Clube Delphi 127  meu artigo sobre a madShi Collection, uma coleção de bibliotecas muito úteis e interessante. Elas vão além do basicão fornecendo aos programadores funcionalidades bastante inusitadas, como api hooking, e funcionalidades que são uma mão na roda na hora de distribuir seu software ou na hora de encontrar bugs persistentes. O madExcept é um gerenciador de exceções que automaticamente gera um log com nome da unit e até a linha do código que disparou o erro. Seu usuário pode simplesmente clicar em um botão para te enviar o relatório de erros. Espero que gostem do artigo. Boa leitura :)

Artigo sobre WordPress publicado na Clube Delphi 126

Imagem
Já está disponível no site da Dev Media a algum tempo, e logo chegará nas bancas a revista Clube Delphi edição 126. Nesta edição saiu um artigo meu sobre o WordPress, como integra-lo com uma aplicação Delphi para postagens ou monitoria do que se fala sobre sua marca. Esse artigo foi uma pincelada no assunto. A integração ainda pode se dar via RSS, webservices e outros tipos de customização. Além disso o que foi apresentado não se aplica apenas ao WordPress, mas ao Magento e Joomla também. Gostaria de destacar o artigo do Rodrigo Araújo sobre Expressões Regulares. Sempre quisemos ter isso no Delphi e agora temos nativo, o que é muito bom. Padrão Strategy do Rafael Stavarengo é um dos que eu recomendo fortemente a leitura. Aliás, todos os artigos do Rafael Stavarengo são fortemente recomendados. O cara manja muito de POO eDesign Patterns. O Datasnap XE é O DATASNAP. Tudo o que você esperava de melhorias nessa tecnologia agora estão aí, disponíveis. E o Rodrigo Carreiro Mourão...

Criando um arquivo unicode com BOM a partir do Delphi 7

Hoje um colega que leu meu post sobre quebra de linhas no Delphi 7 e no Delphi novo teve uma dúvida: Ele não estava conseguindo criar um arquivo de conexão UDL válido. Todos eles davam erro ao abrir. Ele me disse que usar widestring não resolveu. Fiquei surpreso do porque ele precisaria gerar o udl pelo Delphi, já que é possível apenas criar um arquivo de texto vazio, renomear ara .udl, e o arquivo será criado normalmente. Mas, ele tinha essa necessidade. Uma das coisas que descobri hoje é que este arquivo, além de começar com [oledb], deve obrigatoriamente ter o "comentário" abaixo. Ou seja, não é apenas um comentario. [oledb] ; Everything after this line is an OLE DB initstring O conteúdo deve ser idêntico a esse. Mas não é apenas o conteúdo. Mesmo que se grave os cabeçalhos corretamente e as strings de conexão, e mesmo que as strings sejam widestrings de dois bytes (unicode) o arquivo em si ainda precisa de alguma coisa. Essa alguma coisa é o BOM: Abrindo um ar...

Qual é sua segunda linguagem? E sua terceira?

Imagem
Bom pessoAll, antes de mais nada, minha primeira linguagem é Delphi/Lazarus/Object Pascal e ponto final. Tirando o Delphi a que eu mais gosto e respeito é C/C++, porém nunca arrumei um projeto, pago ou hobby, nessas linguagens. Só coisa acadêmica mesmo. Todos os posts que discutem sobre linguagens geram bastante polêmica, por mais bobo que seja o assunto. Eu gosto de olhar o site da TIOBE freqüentemente  http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html Position Feb 2011 Position Feb 2010 Delta in Position Programming Language Ratings Feb 2011 Delta Feb 2010 Status 1 1 Java 18.482% +1.13%   A 2 2 C 14.986% -1.62%   A 3 4 C++ 8.187% -1.26%   A 4 7 Python 7.038% +2.72%   A 5 3 PHP 6.973% -3.03%   A 6 6 C# 6.809% +1.79%   A 7 5 (Visual) Basic 4.924% -2.13%   A 8 12 Objective-C 2.571% +0.79%   A 9 10 JavaScript 2.558% -0.08%   A 10 8 Perl 1.907% -1.69%  ...