Cesar Romero

Delphi programming

madExcept 3.0k para Delphi 2010

Mathias Rauen (Aka madshi ), acabou de disponibilizar o madExcept versão 2.5.11.1 com suporte ao Delphi 2010.

Eu estava esperando esta versão para poder compilar o Xananews com o Delphi 2010.

A lista de alterações desde a última versão:

- added Delphi/BCB 2010 support
- added detection for Win2008, Win7, Win2008r2
- fixed: cleartext disassembly missed instruction labels
- fixed: cleartext instruction labels were sometimes wrong
- madListProcesses: added gdi/user object count
- added %exceptClass%
- only exe modules hook/protect new threads by default now
- added HookThreads/DontHookThreads to overwrite default
- undocumented OnExceptBoxDestroy callback added
- fixed: in certain situations bug report wasn’t saved
  • added Delphi/BCB 2010 support
  • added detection for Win2008, Win7, Win2008r2
  • fixed: cleartext disassembly missed instruction labels
  • fixed: cleartext instruction labels were sometimes wrong
  • madListProcesses: added gdi/user object count
  • added %exceptClass%
  • only exe modules hook/protect new threads by default now
  • added HookThreads/DontHookThreads to overwrite default
  • undocumented OnExceptBoxDestroy callback added
  • fixed: in certain situations bug report wasn’t saved

Referências

TSQLConnection.Params como ConnectionString

Pra quem está acostumado a trabalhar com as tecnologias de banco de dados da Microsoft como ADO, sabe que as configurações de conexão de banco de dados são passadas em uma propriedade chamada ConnectionString, uma linha única contendo todos os parâmetros da conexão separados por ponto e vírgula, diferente da propriedade Params do TSQLConnection, que é uma TStringList.
Ontem eu estava reescrevendo umas classes auxiliares para o TSQLConnection, que agora são especialização de uma classe que salva e carrega as configurações da aplicação em um único arquivo XML, onde cada Objeto é um nó do XML, e cada TSQLConnection tem seu nó XML reservado, mas salvar como TStrings, ficava muito estranho no XML, então fiz umas alterações na minha classe para simular a propriedade ConnectionString.

A primeira alteração foi no método SetSQLConnection, onde eu defino 2 propriedades do Params, “StrictDelimiter = True” e “Delimiter:= ‘;’”.

procedure TDBHelper.SetSQLConnection(SQLConnection: TSQLConnection);
begin
  FSQLConnection:= SQLConnection;
  if (FSQLConnection = nil) then
    Exit;
  CloseConnection;
  FSQLConnection.Params.StrictDelimiter:= True;
  FSQLConnection.Params.Delimiter:= ';';
  // <snip>
end;

Em seguida implementei os métodos GetConnectionString e SetConnectionString, interagindo com a propriedade DelimitedText do TStringList.

function TDBHelper.GetConnectionString: string;
begin
 Result:= FSQLConnection.Params.DelimitedText;
end;

procedure TDBHelper.SetConnectionString(const Value: string);
begin
  FSQLConnection.Params.DelimitedText:= Value;
end;

A propriedade ConnectionString salva em XML ficou assim:

<property name="ConnectionString">
  drivername=FIREBIRD;blobsize=-1;commitretain=False;
  database=D:\DB\HTMCDATA.FDB;localecode=0000;
  Password=masterkey;rolename=RoleName;sqldialect=3;
  isolationlevel=ReadCommitted;user_name=sysdba;waitonlocks=False;
  trim char=True;HostName=localhost;ServerCharSet=WIN1252
</property>

Meu próximo passo neste projeto é adicionar ao sistema, um editor de XML visual que comecei a escrever, ainda não está pronto, mas já me ajuda em algumas tarefas básicas.


XmlViewer


XmlViewer

Como Desativar/Ativar todas as Triggers de um Banco de Dados Firebird

Hoje um amigo me pediu umas dicas para recuperar um banco de dados, e no final ele precisava desativar todas as Triggers para transferir os dados para um novo banco, pesquisamos um pouco na internet e conseguimos montar os códigos:

Para desativar

SELECT 'ALTER TRIGGER ' || Trim(RDB$TRIGGER_NAME) || ' INACTIVE;'
  FROM RDB$TRIGGERS
 WHERE RDB$TRIGGER_SOURCE IS NOT NULL

Para ativar

SELECT 'ALTER TRIGGER ' || Trim(RDB$TRIGGER_NAME) || ' ACTIVE;'
  FROM RDB$TRIGGERS
 WHERE RDB$TRIGGER_SOURCE IS NOT NULL

Este código, vai gerar as instruções SQL para desativar/ativar todas as Triggers de todas as Tabelas.

Atenção
Estou usando a função Trim, disponível no Firebird 2.1 e acho que também no 2.0, sei que não tem no Firebird 1.5.x ou anteriores, mas não tem problema, se você uma versão que não suporta o Trim, basta remover que o código vai funcionar também, o Trim é apenas para melhorar a estética do resultado.

Como comparar 2 Imagens

O código a seguir, está comparando 2 bitmaps, mas a idéia pode ser utilizada para comparar outros formatos de imagem, arquivos, ou qualquer conteúdo salvo em TMemoryStream.

function IsSameBitmap(Bitmap1, Bitmap2: TBitmap): boolean;
var
 Stream1, Stream2: TMemoryStream;
begin
  Assert((Bitmap1 <> nil) and (Bitmap2 <> nil),
    'Params can''t be nil');
  Result:= False;
  if (Bitmap1.Height <> Bitmap2.Height)
    or (Bitmap1.Width <> Bitmap2.Width) then
     Exit;
  Stream1:= TMemoryStream.Create;
  try
    Bitmap1.SaveToStream(Stream1);
    Stream2:= TMemoryStream.Create;
    try
      Bitmap2.SaveToStream(Stream2);
      if Stream1.Size = Stream2.Size Then
        Result:= CompareMem(Stream1.Memory,
          Stream2.Memory, Stream1.Size);
    finally
      Stream2.Free;
    end;
  finally
    Stream1.Free;
  end;
end;

Aqui uma outra versão usando scanline, postada por RRUZ no stackoverflow.com

function IsSameBitmapUsingScanLine(Bitmap1, Bitmap2: TBitmap):
  boolean;
var
 I: Integer;
 ScanBytes: Integer;
begin
  Result:= (Bitmap1 <> nil) and (Bitmap2 <> nil);
  if not Result then exit;
  Result:=(Bitmap1.Width = Bitmap2.Width) and
    (Bitmap1.Height = Bitmap2.Height) and
    (Bitmap1.PixelFormat = Bitmap2.PixelFormat) ;
  if not Result then exit;

  ScanBytes:= Abs(Integer(Bitmap1.Scanline[1]) -
    Integer(Bitmap1.Scanline[0]));
  for I:= 0 to Bitmap1.Height -1 do
  begin
    Result:= CompareMem(Bitmap1.ScanLine[I],
       Bitmap2.ScanLine[I], ScanBytes);
    if not Result then exit;
  end;
end

Analista, só com diploma. Bom ou mau?

O site baguete.com.br publicou um artigo interessante sobre a Lei de regulamentação da profissão de analista de sistemas, nele há análise da Lei, opinião de profissionais da área e um podcast.

Referência:

Regulamentação da Profissão de Analista de Sistemas

Geralmente me mantenho fora destes assuntos, mas não dá se omitir neste momento, os senadores estão para aprovar uma Lei que vai prejudicar muitos bons profissionais da nossa área, temos de defender nossos interesses e entrar em contato com os senadores de nossos estados.

Vou citar alguns pontos importantes levantados em uma lista de discussão sobre o tema, os textos em itálico são fragmentos da Lei.

Art. 2º Poderão exercer a profissão de Analista de Sistemas no país:

I ??? os possuidores de diploma de nível superior em Análise de Sistemas, Ciência da Computação ou Processamento de Dados, expedido por escolas oficiais ou reconhecidas;

II ??? os diplomados por escolas estrangeiras reconhecidas pelas leis de seu País e que revalidarem seus diplomas de acordo com a legislação em vigor;

III ??? os que, na data de entrada em vigor desta Lei, tenham exercido, comprovadamente, durante o período de, no mínimo, cinco anos, a função de Analista de Sistemas;

O Parágrafo III foi excluído do Texto final aprovado, então, somente quem tiver diploma poderá exercer a profissão, então quem tem formação em outra área, especialização na área e anos de experiência como eu, está fora.

Se você acha que não será afetado, pois bem o texto também é claro, quando entrar em vigor, somente quem tem diploma poderá fornecer um Orçamento de um Projeto de Software.

Algo curioso:

Art. 6º A jornada de trabalho dos profissionais de que trata esta Lei   não   excederá   quarenta   horas   semanais,   facultada   a compensação   de horários e a redução da jornada, mediante acordo ou convenção coletiva de trabalho.

Parágrafo   único.   A   jornada   de   trabalho   dos   profissionais submetidos a atividades que demandem esforço repetitivo será de vinte horas

Então programador vai trabalhar somente 20 horas/semana?

Baixem e leiam o texto na íntegra vejam que a maioria dos artigos versa sobre a regulamentação e criação dos conselhos e sobre quem vai participar dos conselhos. Isto deixa claro, qual é o verdadeiro interesse da aprovação desta Lei.

O projeto é do senador Expedito Junior (PR-RO).
Email: expedito.junior@senador.gov.br

Me dou ao trabalho de postar sobre este assunto, por que serei um dos prejudicados por esta Lei, sou formado em Ciências Contábeis pela UFPR e Pós Graduado em Desenvolvimento de Software Orientado a Objectos pela PUC-PR, trabalho na área desde 1996, com empresa formal desde 2001, desde 2000 trabalho como consultor, beta tester e analista de sistemas para empresas dos EUA e UK, além das atividades da minha empresa no Brasil. Meu último vinculo com instituição de ensino foi como Coordenador do Curso de Pós Graduação e Professor no curso de Desenvolvimento de Sistemas Web de uma Faculdade Particular de Curitiba. Assim como eu, há vários profissionais qualificados que de alguma forma serão afetados negativamente se esta Lei entrar em vigor.

Hoje enviei email para os Senadores do meu Estado, detalhando meu ponto de vista, peço que você faça o mesmo.

Veja neste link a lista dos Senadores e seus emails.

Amanhã vou pessoalmente procurar alguns políticos, e expor minha preocupação,  fique a vontade para entrar em contato comigo para discutir sobre este assunto e expor seu ponto de vista.

Americanas.com Telefone sem fio

americanas.com enganando o consumidor

Este post é apenas para que outros consumidores conheçam o produto antes de comprar, já que o site da americanas.com não informa como o produto realmente é.

Comprei um telefone sem fio na americanas.com OREGON OS-6014, anunciado por R$ 59,00. Foi entregue no sábado, dia 15 de agosto de 2009 e de cara notei um problema o identificador de chamadas não funciona.

Eu tenho outro identificador de chamadas que funciona perfeitamente, então alguma coisa errada tem ai, no site e no manual dizem que é “Identificador de Chamadas (padrões FSK / DTMF)” eu não quero saber que padrão é, quero que funcione como o meu outro identificador.

Então, entrei em contato com a oregon e eles disseram que para funcionar preciso de um conversor de sinalização “Conversor de sinalização DTMF/FSK” que custa R$ 30,00. Anunciam um produto a R$ 59,00 que pra funcionar como anunciado, precisa de um conversor que custa mais R$ 30,00.

Se você como eu, pensou em adquirir o telefone pelas qualidades e preço, deve levar em consideração que para que o identificar de chamadas funcione, você tem de comprar o conversor deles que custa mais R$ 30,00.

Depois de uns 5 dias de uso o aparelho começou a apresentar defeito, quando teclo 3 ou 6, ele simplesmente desliga, primeira coisa que fiz, foi verificar as baterias e no dia seguinte fui comprar novas, o problema continuou. Só então entrei em contato com a empresa OREGON descrevendo este problema e o problema do identificar de chamadas, eles mandavam uma resposta automática dizendo que o aparelho segue especificações da ANATEL e que era pra eu adquirir o conversor, mas ignoraram todas as mensagens sobre o defeito, sequer tocaram no assunto do defeito.

Na segunda-feira dia 24, entrei em contato com americanas.com e eles disseram que não podem me atender, por que já passaram 7 dias corridos da entrega, e agora o problema não é mais deles e sim da OREGON que se recusava a atender. Mandei mais emails para americanas.com, anexando os emails enviados para a OREGON, e hoje um atendente “André” da americanas.com me ligou dizendo que não podem fazer nada e era pra eu entrar em contato com a OREGON em um número de telefone específico de SP.

Pois bem, liguei e uma mulher identificada como Ingrid, me disse que era pra eu mudar a configurações de discagem que deveria estar desconfigurado, segui as intruções de acordo com o manual e o problema continua, liguei novamente para a Ingrid e ela então disse que o telefone deve ser enviado para uma assistencia ténica, isto mesmo 1 semana que tenho o aparelho e eles querem que vá pro conserto ao invés de trocar, mas que em Curitiba não tem assistência técnica, então devo enviar para SP.

Ela me mandou um email com o endereço e autorização pra eu enviar o SEDEX a cobrar, menos mal. Mas vou ficar sem o aparelho que comprei e paguei a vista com boleto.

A americanas.com, anuncia o produto sem especificar que pra ele funcionar é necessário um conversor que custa mais que 50% do valor do aparelho, não quer fazer a troca por que eu entrei em contato 9 dias após a compra, por que a OREGON me enrolou nos dias anteriores, fazendo eu perder o prazo.

Todos os prazos da americanas.com pra entrega e atendimento são especificados em dias úteis, mas quando se trata da garantia do produto, eles se recusam a seguir esta regra e contam o prazo em dias úteis.

Vou enviar o produto para a assitência técnica e quando tiver de volta vou postar aqui, a continuação da história, enquanto isto vou entrar em contato com o Procon e fazer uma consulta na ANATEL sobre o identificador de chamadas.

Atualização

No fim de semana eu entrei no site da americanas.com e postei no item “Comente aqui” sobre o que você acha do produto, coloquei que eles não descrevem que é necessário um conversor para que o identificador de chamadas funcione, até agora o meu comentário não apareceu.

Então fica claro a postura da americanas.com, só publica comentários se o cliente elogiar, esconde quando alguém encontra alguma divergencia no produto anunciado.

Minha dica, se um produto não tiver elogios, então é quase certo que tem reclamações.

Adicionei a reclamação ao site Reclame Aqui

Twitter API com Delphi

Guinther Pauli postou no Code Central um exemplo de como usar o Delphi para se comunicar com o Twitter.

O exemplo usa TIdHTTTP para se comunicar com o site e TXMLDocument para interagir com os campos.

Vale a pena verificar como é feito, pois pode ser utilizado para entender como se comunicar com outros sites Web.

Eu tenho utilizado muito o TWebBrowser para interagir com sites Web com sucesso, escrevi umas ferramentas e componentes para me auxiliar a debugar e montar as rotinas e tenho alguns componentes prontos em fase de homologação para comercializar, estes componentes são utilizados para emissão das guias de impostos do PR, a GRPR online e para se comunicar com a Equifax.

Eu tive de utilizar o TWebBrowser por que é necessário interagir com a página, disparando eventos programados na página, javascript, certificados para validar a comunicação, opções de segurança do IE, plugins, mas este já é assunto para outro post, só toquei no assunto aqui, para deixar claro que a solução do twitter podia utilizar o TWebBrowser.

Adicionando Mouse Wheel no TScrollBox

Uma forma simples tratar Mouse Wheel no TScrollBox.

O código a seguir foi escrito pelo Peter Bellow no newsgroup
embarcadero.public.delphi.vcl.components.using
Eu postei aqui o código com uma pequena correção, o  SB_LINEDOWN/SB_LINEUP estavam invertidos, e outras modificações pra adaptar ao meu código.

procedure TFormEquifaxMain.ScrollBoxMouseWheel(Sender: TObject;
  Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var
  Handled: Boolean);
var
  Msg: Cardinal;
  Code: Cardinal;
  I, ScrollLines: Integer;
begin
  if WindowFromPoint(Mouse.Cursorpos) = ScrollBox.Handle then
  begin
    Handled := True;
    Msg:= IfThen(ssShift in Shift, WM_HSCROLL, WM_VSCROLL);
    Code:= IfThen(WheelDelta < 0, SB_LINEDOWN, SB_LINEUP);
    ScrollLines:= Mouse.WheelScrollLines * 5;
    for I:= 1 to ScrollLines do
      ScrollBox.Perform(Msg, Code, 0);
    ScrollBox.Perform(Msg, SB_ENDSCROLL, 0);
  end;
end;

TFields em run time

Apenas um exemplo de código de como manipular TFields em run time.

  • Criar TFields sem utilizar TDataSet.FieldDefs
  • Clonar Fields
  • TDataSetField: Manipular TFields aninhados
procedure TFormDBUtils.ButtonCreateFieldsClick(Sender: TObject);
  function CreateField(DataSet: TDataSet; FieldClass: TFieldClass;
    const FieldName: string = ''): TField;
  begin
    Result:= FieldClass.Create(DataSet);
    Result.FieldName:= FieldName;
    if Result.FieldName = '' then
      Result.FieldName:= 'Field' + IntToStr(DataSet.FieldCount +1);
    Result.FieldKind := fkData;
    Result.DataSet:= DataSet;
    Result.Name:= DataSet.Name + Result.FieldName;
    if Result is TStringField then
      Result.Size:= 10; // apenas lembrar de definir TField.Size
  end;

  procedure CreateFields(DataSet: TDataSet; FieldClass:
    TFieldClass; Count: Integer);
  var
    I: Integer;
  begin
    for I := 1 to Count do
      CreateField(DataSet, FieldClass);
  end;

  procedure CloneFields(DS1, DS2: TDataSet);
  var
    I: Integer;
    F: TField;
  begin
    for I := 0 to DS1.FieldCount - 1 do
    begin
      F:= CreateField(DS2, TFieldClass(DS1.Fields[I].ClassType),
        DS1.Fields[I].FieldName);
      F.Size:= DS1.Fields[I].Size;
      if DS1.Fields[I] is TDataSetField then
        CloneFields(TDataSetField(DS1.Fields[I]).NestedDataSet,
          TDataSetField(DS2.Fields[I]).NestedDataSet);
    end;
  end;

var
  DS1, DS2: TClientDataSet;
  DSField: TDataSetField;
begin
  DS1:= TClientDataSet.Create(Self);
  CreateFields(DS1, TStringField, 10);
  DSField:= TDataSetField(CreateField(DS1, TDataSetField));
  CreateFields(DSField.NestedDataSet, TStringField, 5);

  // clone
  DS2:= TClientDataSet.Create(Self);
  CloneFields(DS1, DS2);

  DS1.CreateDataSet;
  DS2.CreateDataSet;
end;