30
May 08

jQuery.Colors

:: news :: by Gilberto Saraiva

Camaradas,

É com muita felicidade que informo que o plugin jQuery.Colors encontra-se na 7ª posição dos plugins mais populares do jQuery.
http://plugins.jquery.com/most_popular

A página do plugin no jQuery.com:
http://plugins.jquery.com/project/jQueryColors

Vamos ver se os outros também vão pra frente, pois acho que eles têm o mesmo peso na facilitação do desenvolvimento, principalmente o jQuery.CssRule.

Abraço a todos



28
May 08

jQuery: Release 1.2.6

:: news :: by Gilberto Saraiva

Folks,

Updated to release 1.2.6
http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.2.6.min.js

Thanks



28
May 08

jQuery: Release 1.2.6

:: news :: by Gilberto Saraiva

Camaradas,

jQuery atualizado para release 1.2.6.
http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.2.6.min.js

Abraço a todos



23
May 08

jQuery: jQuery.Animator

:: articles :: by Gilberto Saraiva

Folks,

I wrote a plugin to make our life easy! the new jQuery.Animator.

the example:

 HTML |  copy code |? 
01
02
<html>
03
<head>
04
<title></title>
05
<script type="text/javascript" src="jquery-1.2.5.js"></script>
06
<script type="text/javascript" src="jquery.animator.js"></script>
07
<script language="JavaScript">
08
<!--
09
  function AnimateWalker(Walker, GoEnd){
10
    newLeft = parseInt(Walker.css("left")) + 5;
11
    if(GoEnd) newLeft = 400;
12
    Walker.css("left", newLeft);
13
    return (newLeft < 400);
14
  }
15
 
16
  function AnimateWalker3(Walker, GoEnd){
17
    // GoEnd can't be calculated, it's a infinite animation
18
    newLeft = parseInt(Walker.css("left")) + 10;
19
    if(newLeft > 400) newLeft = 0;
20
    Walker.css("left", newLeft);
21
    return true; // infinte
22
  }
23
 
24
  $(function(){
25
    $("#Walker").animator(10, AnimateWalker);
26
    $("#Walker2").animator(10, AnimateWalker);
27
    $("#Walker3").animator(10, AnimateWalker3);
28
  });
29
//-->
30
</script>
31
<body>
32
<div id="Walker" style="position:relative;left:0;width:100px;height:50px;background:#000;color:#fff">Animation Test</div>
33
<div id="Walker2" style="position:relative;left:50;width:100px;height:50px;background:#0F0;color:#fff">Animation Test</div>
34
<div id="Walker3" style="position:relative;left:100;width:100px;height:50px;background:#00F;color:#fff">Animation Test</div>
35
</body>
36
</html>
37

The effect will be like this:

Animation Test
Animation Test
Animation Test

Crazzy uhm?!

jQuery.Animator plugin page

Hugs for all



21
May 08

Delphi: SetTimer

:: articles :: by Gilberto Saraiva

Camaradas,

O SetTimer é uma função disponibilizada pela plataforma Windows ( API ) que consiste em criar um Temporizador que notifica um Objeto Windows ( Handle ) sempre que atingir o términio do tempo estipulado. Um temporizador desse tipo é gerenciado pelo Windows, ou seja, não será relacionado com o processamento do seu aplicativo, ficando assim com uma precisão boa mesmo enquanto seu aplicativo processa alguma coisa.

Um detalhe muito importante sobre o processamento da notificação do temporizador ( Timer ), é que como a notificação padrão é feita via mensagem, a WM_TIMER, e mensagens são administradas pela VCL através do Objeto TApplication application, em 2 respectivos locais, o primeiro em ProcessMessages que processa a fila inteira de mensagens que a aplicação possuí, e o segundo HandleMessage que processa apenas a primeira mensagem da fila, se existir alguma, sinaliza o Evento OnIde e aguarda uma nova mensagem (em caso de fila a liberação é instantanea), você podera perder a precisão do temporizador por falta de manipulação da recepção de mensagens. Já vi muita gente reclamando a precisão do SetTimer na utilização dentro de um aplicativo Delphi, mas nunca vi essa reclamação de um programador C, pois o mesmo tem o trabalho de gerênciar as notificações para o objeto receptor.

Então o fato é, temporizadores não são ruins, são ótimas opções para criação de simuladores de interação, Inteligências artificiais em alguns pontos, e até mesmo para criação de cronometros e agendamentos.

 Delphi |  copy code |? 
1
{$EXTERNALSYM SetTimer}
2
function SetTimer(hWnd: HWND; nIDEvent, uElapse: UINT;
3
  lpTimerFunc: TFNTimerProc): UINT; stdcall;

O 1º parametro é referente ao Objeto Windows ( Handle ) receptor, qualquer objeto com Handle ( Objeto Windows ).
O 2º parametro é referente ao índice controlado pelo programador, servirá como identificador na hora do processamento da notificação WM_TIMER.
O 3º parametro indica o intervalo, em milisegundos, em que o temporizador notificará o objeto.
O 4º parametro é nosso cargo chefe, deve ser analizado como primeira opção sempre pois utilizando este parametro deixaremos a necessidade de utilizar a VCL ou qualquer ou controle de Objetos Windows para a recepção da notificação.

Chegando neste ponto, podemos perceber que possuímos 2 caminhos, o primerio através de um Objeto Windows e o outro através de um Callback, a escolha é você quem faz na hora da utilização, vou exemplificar as duas maneiras de utilização, então preste atenção, pois é bastante interessante :D .

Como utilizar um temporizador através de um Objeto Windows?

Para facilitar o entendimento e não aprofundar muito em matérias que não são a questão do artigo, vamos utilizar a VCL para administrar nosso Objeto Windows.

 Delphi |  copy code |? 
01
02
  TfrmTest = class(TForm)
03
    btnStart: TButton;
04
    procedure btnStartClick(Sender: TObject);
05
  private
06
    { Private declarations }
07
  public
08
    procedure WMTimer(var Msg: TWMTimer); message WM_TIMER;
09
  end;
10

Declaramos o a manipulação da mensagem WM_TIMER para o nosso “TForm” frmTest. No frmTest colocamos também um TButton btnStart para criamos o temporizador através de seu evento OnClick.

 Delphi |  copy code |? 
1
procedure TfrmTest.btnStartClick(Sender: TObject);
2
begin
3
  SetTimer(Handle, 0, 1000, nil);
4
end;

Este é o evento OnClick do TButton btnStart. Entendendo melhor o que acontece aqui:

  • Handle é o Handle do frmTest, como é Handle é Objeto Windows e pode receber mensagens.
  • 0 é o índice que eu informei para o temporizador, então sempre que eu receber um WM_TIMER vou verificar qual índice ele contém e poder estruturar tarefas em cima disso.
  • 1000 é o intervalo em milisegundos que o temporizador irá me notificar no Handle do frmTest. 1000 milisegundos = 1 segundo, logo 60000 milisegundos = 1 minuto.
  • nil é indicado como NIL pois queremos interagir com a mensagem através de mensagens.
  •  Delphi |  copy code |? 
    1
    2
    procedure TfrmTest.WMTimer(var Msg: TWMTimer);
    3
    begin
    4
      KillTimer(Handle, Msg.TimerID);
    5
      ShowMessage('Evento do temporizador: ' + IntToStr(Msg.TimerID));
    6
    end;

    Este procedimento é a parte fundamental no funcionamento de um temporizador via Objeto Windows. Perceba que já aparece uma nova função, a KillTimer, que nada mais é que a contra-API da SetTimer, ou seja, cria o temporizador com SetTimer, e destroí o mesmo com KillTimer.

     Delphi |  copy code |? 
    1
    {$EXTERNALSYM KillTimer}
    2
    function KillTimer(hWnd: HWND; uIDEvent: UINT): BOOL; stdcall;

    O 1º parametro é o Objeto Windows que recebe a notificação do temporizador, tem que ser igual ao que foi utilizado no SetTimer.
    O 2º parametro é o índice criado pelo programador, tem que ser igual ao que foi utilizado no SetTimer.

    Pois bem, já vimos que a utilização do temporizador através da VCL é fácil, e pode se extender a um universo infinito de possibilidades. Vou mostrar um exemplo prático:

     Delphi |  copy code |? 
    01
    02
    type
    03
      PTimerParam = ^TTimerParam;
    04
      TTimerParam = record
    05
        s: string;
    06
        i: integer;
    07
      end;
    08
     
    09
    procedure TfrmTest.btnStartClick(Sender: TObject);
    10
    var
    11
      Param: PTimerParam;
    12
    begin
    13
      New(Param);
    14
      Param^.s := 'Teste de título animado';
    15
      Param^.i := 1;
    16
      SetTimer(Handle, Integer(Param), 100, nil);
    17
    end;
    18
     
    19
    procedure TfrmTest.WMTimer(var Msg: TWMTimer);
    20
    begin
    21
      KillTimer(Handle, Msg.TimerID);
    22
      with PTimerParam(Msg.TimerID)^ do
    23
      begin
    24
        Caption := Copy(s, 1, i);
    25
        i := i + 1;
    26
        if i <= Length(s) then
    27
          SetTimer(Handle, Msg.TimerID, 100, nil)
    28
        else
    29
          Dispose(Pointer(Msg.TimerID));
    30
      end;
    31
    end;
    32

    Agora a segunda parte da história:

    Como utilizar um temporizador através de um Callback?

    Primeiramente, a utilização do SetTimer por Callback é mais eficiente em relação ao processo via Objeto Windows, pois não há dependência de objeto para que o reconhecimento da notificação do temporizador seja feita em relação a aplicação, pois o callback será chamado internamente pela DefWindowProc.

    Então vamos entender como declarar um procedimento no padrão do Callback TimerProc:

     C |  copy code |? 
    1
    2
    VOID CALLBACK TimerProc(      
    3
        HWND hwnd,
    4
        UINT uMsg,
    5
        UINT_PTR idEvent,
    6
        DWORD dwTime
    7
    );

    Esse modelo traduzido para Delphi:
     Delphi |  copy code |? 
    1
    procedure TimerProc(hwnd: HWND; uMsg, idEvent: UINT; dwTime: DWORD); stdcall;

    Então após entendermos a estrutura do último parametro do SetTimer podemos escrever um exemplo prático de resultado semelhante ao exemplo anterior:

     Delphi |  copy code |? 
    01
    02
    type
    03
      PTimerParam = ^TTimerParam;
    04
      TTimerParam = record
    05
        s: string;
    06
        i: integer;
    07
      end;
    08
     
    09
    procedure TimerProc(hwnd: HWND; uMsg, idEvent: UINT; dwTime: DWORD); stdcall;
    10
    begin
    11
      KillTimer(hwnd, idEvent);
    12
      with PTimerParam(idEvent)^ do
    13
      begin
    14
        frmMain.Caption := Copy(s, 1, i);
    15
        i := i + 1;
    16
        if i <= Length(s) then
    17
          SetTimer(hwnd, idEvent, 100, @TimerProc)
    18
        else
    19
        begin
    20
          Dispose(Pointer(idEvent));
    21
          DeallocateHWnd(hwnd);
    22
        end;
    23
      end;
    24
    end;
    25
     
    26
    procedure TfrmMain.btnRunClick(Sender: TObject);
    27
    var
    28
      Param: PTimerParam;
    29
    begin
    30
      New(Param);
    31
      Param^.s := 'Teste de título animado';
    32
      Param^.i := 1;
    33
      SetTimer(AllocateHWnd(nil), Integer(Param), 100, @TimerProc);
    34
    end;
    35

    Antes de analizar o código vou citar um detalhe importante:

    Veja que ao chamar o SetTimer eu utilizo o AllocateHWnd como primeiro parametro, o porquê disso é que o SetTimer opera de maneira diferente ao se indicar um Objeto Windows que não pertence à aplicação, a definição é a seguinte:
    Caso o Handle passado como parametro pertença a aplicação, mais especificamente a mesma Thread que chama a SetTimer. No caso do Handle ser igual a 0 ( zero ) ou não pertencer a aplicação, o parametro passado como índice do temporizador será ignorado e um novo índice será criado e o retorno da chamada ao SetTimer indicará o novo índice.

    Depois de entender esse detalhe importante podemos perceber porque fazemos a criação de um Objeto Windows utilizando o AllocateHWnd. A finalidade disso é não passar um Objeto Windows inválido e ter o índice, que no nosso caso indica um ponteiro que serve de parametro, resetado.

    Agora entendendo um pouco o código:

    Perceba que sempre que recebemos a notificação de términio do intervalo do temporizador, finalizamos o temporizador, e porque fazemos isso? Fazemos isso pois se dentro da notificação, seja na utilização do callback ou por mensagem ( WM_Timer ), o processo que escrevermos lá demorar mais do que o intervalo, criaremos uma fila de processamento, e que acaba por criar uma sequência de processamento e o efeito de execução por intervalo não será perceptível.

    Fluxograma para entendimento rápido:

    Qualquer dúvida fique avontade em perguntar!

    Abraço a todos



    20
    May 08

    Delphi: CreateThread

    :: articles :: by Gilberto Saraiva

    Camaradas,

    O CreateThread é uma função disponibilizada pela plataforma Windows ( API ) cedida pela Kernel32, ela é responsável pela criação de um objeto Thread no windows que efetua operações no processador sendo gerenciado pelo windows na parte da fila de processamento e outros eventos.

     Delphi |  copy code |? 
    1
    function CreateThread(lpThreadAttributes: Pointer;
    2
      dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine;
    3
      lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall;
    4
    {$EXTERNALSYM CreateThread}

  • O 1º parametro é responsável pela segurança e compartilhamento do Objeto Thread que vai ser criado.
  • O 2º parametro é responsável pela definição do tamanho do Stack, ou seja, você pode definir o tamanho que vai ser utilizado pela Thread nos operadores ASM, em todo caso, se lhe falta de entendimento específico sobre o assunto é bom deixar em 0 que ele assume o tamanho padrão 1MB.
  • O 3º parametro é responsável pela definição do endereço inicial da thread, pra entendimento rápido é o ponteiro de uma function do mesmo padrão abaixo:
     Delphi |  copy code |? 
    1
    type
    2
      TThreadStartProc = function (Parameter: Pointer): Integer; stdcall;
  • O 4º parametro é responsável pela definição da “chave mestra” no processo de criação de uma thread, o ponteiro do parametro, podendo esse parametro ser qualquer coisa desde que persista enquanto a thread existir ou até o inicio da mesma.
  • O 5º parametro é responsável pelo modo em que a thread vai ser criada, Suspensa (CREATE_SUSPENDED) ou Não suspensa (0), a API poderá receber outro parametro, o STACK_SIZE_PARAM_IS_A_RESERVATION, mas esse não é muito utilizado pois não tem funcionamento na plataforma Windows 2000.
  • O 6º parametro é responsável pela recepção do ID da Thread na lista de Objetos Thead do Windows, esse valor serve para processos de identificação de origem do processamento através da API GetCurrentThreadId.
  • O retorno da API CreateThread é o Handle da Thread, como sabemos Handles são números que identificam objetos Windows e através de APIs podemos controla-los com muita especialidade.

    Agora, se você chegou até aqui, é porque realmente está interessado em aprender a utilizar as tão famosas thread, e a primeira coisa que lhe digo:

  • É simples, não tem mito nem urucubaca sobre a criação de thread para processamentos específicos.
  • Lembre-se Processamentos Específicos, se você quiser uma interação com algum componente na interface gráfica você precisa de criar uma sincronia com a VCL.

    Então agora sem o susto, podemos iniciar a utilização:

    Primeiramente baixe o código-fonte abaixo, abra o delphi e compile. Execute o aplicativo, clique em Run e veja que alguns processos são disparados, mais especificamente 100 processos paralelos.

    Nesse teste eu criei um pequeno controle de sincronia boolean feita através da variável SimpleLock, perceba que ao iniciar o processo de adicionar linha no TMemo mmoLog eu coloco o valor dela em True, indicando que estou processando algo, e logo no final ao terminar o processo eu coloco o SimpleLock como false, indicando que já terminei o processo. Assim antes de iniciar o processo eu verifico se o SimpleLock está em True, e se estiver eu espero até que ele esteja em False para iniciar um novo processamento.

    Agora partindo para o entendimento direto do código

    Escrevi um record, que servira de parametro para a minha função da Thread, como preciso de passar o parametro como ponteiro ( Pointer ) escrevi o tipo PMyParallelParams que nada mais é que uma indicação que o podemos guardar um ponteiro do objeto TMyParallelParams.

     Delphi |  copy code |? 
    01
    02
    type
    03
      PMyParallelParams = ^TMyParallelParams;
    04
      TMyParallelParams = record
    05
        A, B: integer;
    06
        ThreadName: string;
    07
        Handle: THandle;
    08
        Callback: procedure(AParam: PMyParallelParams) of object;
    09
      end;
    10

    A variável A é responsável por guardar o tamanho do passo ( Step Size ) que deve ser feito para se atingir o valor da variável B.
    ThreadName o próprio nome já diz tudo, é aonde guardamos o nome que idenfica a thread das demais.
    Handle é o Handle do Objeto Thread para manipulação da própria Thread durante o processamento.
    Callback é o procedimento que a Thread deve chamar no final do seu processamento.

    Perceba que todos esses valores foram criados por mim, e não fazem parte de um Thread nativa, ou seja, o código foi estruturado para funcionar com essa estrutura e nenhum processo é automático, todas as variáveis tem sua razão de existir, coisa que você podera escrever também para seus processamento próprios sendo específico para cada tipo de finalidade desejada.

    A declaração da SimpleLock para sincronia e do procedimento de Callback que informaremos para a nossa Thread.

     Delphi |  copy code |? 
    1
    2
        ...
    3
      private
    4
        { Private declarations }
    5
      public
    6
        SimpleLock: boolean;
    7
        procedure ReceiveThreadEnd(AParam: PMyParallelParams);
    8
      end;
    9

    Como podemos notar a criação de uma Thread para uma finalidade específica que não dependa de outros processos se torna quase completamente paralela, então no meu caso, coloquei um nome na função bem em conchavo com a especialidade da mesma.

     Delphi |  copy code |? 
    01
    function MyParallelProc(AParam: PMyParallelParams): Integer; stdcall;
    02
    var
    03
      i: integer;
    04
    begin
    05
      i := 0;
    06
      while i < AParam^.B do
    07
      begin
    08
        i := i + AParam^.A;
    09
        Sleep(100);
    10
      end;
    11
      AParam^.Callback(AParam);
    12
      Dispose(AParam);
    13
      EndThread(0);
    14
      CloseHandle(AParam^.Handle);
    15
      Result := 0;
    16
    end;

    O código é bem simples, algumas notações da parte final devem ser feitas:

  • AParam^.Callback(AParam); é a chamada que fazemos ao Callback.
  • Dispose(AParam); Como não precisamos mais do Parametro, liberamos a memória dele para não ocorrer os comuns vazamentos de memória ( memory leaks ).
  • EndThread(0); Finalizamos o processamento da Thread perante o Windows, indicando que o processamento não obteve erros, indicado pelo parametro 0. Só é possível utilizar a API EndThread quando o GetCurrentThread for igual ao Thread que queremos finalizar, e como estamos na própria Thread não há possibilidades de valor diferente.
  • CloseHandle(AParam^.Handle); Fechamos o Objeto Thread no windows, finalizamos todos os espaços gastos pelo Windows para sua criação e persistência.
  •  Delphi |  copy code |? 
    01
    var
    02
      i: integer;
    03
      dwNull: DWORD;
    04
      Params: PMyParallelParams;
    05
    begin
    06
      SimpleLock := false;
    07
      lblStillRunning.Caption := '100';
    08
      for i := 1 to 100 do
    09
      begin
    10
        New(Params);
    11
        Randomize;
    12
        Params^.A := Random(10) + 1;
    13
        Params^.B := Random(100);
    14
        Params^.ThreadName := 'Thread' + IntToStr(i);
    15
        Params^.Callback := ReceiveThreadEnd;
    16
        Params^.Handle := CreateThread(nil, 0, @MyParallelProc, Params,
    17
          0, dwNull);
    18
      end;

    Esse é o código de quando clicamos no TButton btnRun. Este código é o coração de todo nosso processo de entendimento de como iniciar um processo paralelo com o CreateThread, então atenção as explicações (Em tópicos para facilitar).

  • Primeiro passamos o SimpleLock para false, para indicar que nenhum processo está sendo efetuado.
  • Depois colocamos o caption no Label que informa quantas thread estão ainda rodando. No caso iniciamos em 100 pois criaremos 100 processos paralelos.
  • Ai vem o Loop que cria as Threads, de 1 até 100, contruindo 100 Thread ao todo.
  • New(Params);. New inicia um ponteiro tipificado, no nosso caso teremos espaço na memória para guardar os dados que precisamos em Params: PMyParallelParams. Esta parte é estruturada juntamente com o Dispose na function MyParallelProc, que efetua a liberação da memória utilizada pelo ponteiro.
  • Executamos o Randomize para aumentar a possibilidade de não obtenção de resultados semelhantes na utilização do Random.
  • Iniciamos a configuração do Params, que será passado para a Thread na function MyParallelProc. A variável A é configurada com um número randomico de 1 até 11.
  • A variável B é configurada com um número randomico de 0 até 100.
  • Colocamos o nome da Thread que iremos criar de acordo com o contador do loop.
  • Configuramos o Callback, sendo esse o procedimento ReceiveThreadEnd
  • Fazemos a chamada da API CreateThread com os parametros necessários.
    nil para definir que não teremos configuração de segurança nem tampouco de compartilhamento.

    0 para indicar que o StackSize vai ser o padrão, 1Mb.

    @MyParallelProc para indicar aonde está a function MyParallelProc que será o inicío da Thread.

    Params para indicar que o parametro a ser passado é o ponteiro do nosso record. Lembre-se que pra cada passo no Loop criamos um novo Params, no uso do New(), então até que nenhuma Thread chegue ao seu términio teremos 100 objetos TMyParallelParams na memória.

    0 para indicar que a Thread deve ser iniciada imediatamente após retornar o Handle da mesma.

    dwNull como não utilizaremos o ThreadID em nada, não precisamos guardar este valor.

  • A estrutura básica então é essa, não vou comentar muito sobre a parte da sincronia com a VCL pois isso será assunto para um outro artigo.

    Qualquer dúvida, sugestão, crítica ou agradecimentos, fique avontade.

    Lembrando mais uma vez, se você possuí material interessante sobre Delphi e outros,
    você pode postar o site na CommunityLinks

    Abraço a todos



    20
    May 08

    jQuery: Release 1.2.4

    :: news :: by Gilberto Saraiva

    Folks,

    I want to inform that the site has been updated to the new release 1.2.4,
    as the link: http://projects.pro.br/javascripts/jquery/
    for all you that are using it.

    Hugs for all.



    20
    May 08

    jQuery: Release 1.2.4

    :: news :: by Gilberto Saraiva

    Camaradas,

    Quero informar que o site já está operando com o novo release 1.2.4,
    como também o link: http://projects.pro.br/javascripts/jquery/
    pra quem já está utilizando.

    Abraço a todos.



    20
    May 08

    Delphi: AdapterMacAddress

    :: articles :: by Gilberto Saraiva

    Camaradas,

    Muitos aqui devem ter vivido o problema de obter o endereço MAC de um adaptador de rede wireless, quando o mesmo está desativado.

    Eu escrevi uma pequena função que obtem o MAC Address mesmo que o adaptador indicado esteje desativado.
    Então vamos lá:

     Delphi |  copy code |? 
    01
    function AdapterMacAddress(AAdptNum: Cardinal): string;
    02
    type
    03
      PC = PCardinal;
    04
      PB = PByte;
    05
    var
    06
      hLib: HMODULE;
    07
      { Note: Type from IpHlpApi GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO;
    08
        var pOutBufLen: ULONG): DWORD; stdcall;
    09
      }
    10
      GetAdptInfo: function(A: Pointer; var B: ULONG): DWORD; stdcall;
    11
      i, Size, Buff: Cardinal;
    12
    begin
    13
      Result := '-----';
    14
      hLib := LoadLibrary('iphlpapi.dll');
    15
      if hLib <> 0 then
    16
        try
    17
          @GetAdptInfo := GetProcAddress(hLib, 'GetAdaptersInfo');
    18
          Size := 0;
    19
          if GetAdptInfo(nil, Size) = 111 then
    20
          begin
    21
            GetMem(Pointer(Buff), Size);
    22
            try
    23
              if GetAdptInfo(Pointer(Buff), Size) = 0 then
    24
                for I := PC(Buff + (640 * AAdptNum) + 400)^ - 1 downto 0 do
    25
                  Insert(IntToHex(PB(Buff + (640 * AAdptNum) + 404 + I)^, 2),
    26
                    Result, I + 1);
    27
            finally
    28
              FreeMem(Pointer(Buff));
    29
            end;
    30
          end;
    31
        finally
    32
          FreeLibrary(hLib);
    33
        end;
    34
    end;

    Escrevi esse código pra não ter dependências a outras Units, mas como alguns aqui devem saber,
    tudo que escrevi é baseado na Biblioteca em anexo, a IpHlpApi.

    Para os curiosos vale a pena dar uma olhada nessa Lib.

    Agora o mais interessante – Como usar a função acima?
    Adicione um TMemo no form(coloquei o name de ‘mmoMACs’).

     Delphi |  copy code |? 
    1
      mmoMACs.Lines.Add(AdapterMacAddress(0));
    2
      mmoMACs.Lines.Add(AdapterMacAddress(1));

    Nesse exemplo eu pego o MAC Address do primeiro e do segundo adaptador.
    O retorno aqui ficou:
    00-19-DB-9D-D0-4F
    00-03-0D-7A-5D-40

    Respectivamente, Placa de Rede a Cabo e Placa de Rede Wireless(Desativada no switch do notebook [OFF])

    Obs: Lembre-se que em programação iniciamos contagem do 0, então de 0 a 10 temos 11 elementos.

    Abraço a todos



    20
    May 08

    Animações de CounterStrike

    :: news :: by Gilberto Saraiva

    Camaradas,

    Hoje de manha, bem de manha mesmo antes de ir trabalhar, achei uma coisa interessante, Animações de CounterStrike, mesmo pra quem não conheçe o jogo fica bom de assistir, pois é bem criativo, pena que é curto:

    Esse site saiu na Smashing Magazine na área de tipografia, mas tem um conteúdo muito bem produzido.
    Epsódio 2: http://switchmw.com/works/cso_ep_2

    Epsódio 3: http://switchmw.com/works/cso_ep_3

    Bem interessante não é?

    Como bem informado pelo camarada e xará Gilberto Ximenes

    Os links estão bloqueados, não sei se temporariamente, teimosia do criador.

    O link pro site do cidadão é:http://switchmw.com/
    dentro do site é possível ver as duas animações assim como verificar que o link continua o mesmo, mas não funciona. Quem quiser reclamar com ele ^^.

    Vlw Ximenes

    Abraço a todos