Back-End

8 jan, 2007

API do Windows é sua amiga

Publicidade

Muitas vezes o programador acha que uma linguagem ou outra é fraca
ou limitada simplesmente porque não encontrou uma função
ou comando específico. Para escovadores de bits que já programaram
por exemplo em Mumps (não aconselho, mas se quiser conhecer: http://mumps.sourceforge.net/docs.html#COMMANDS),
sabem que as linguagens têm no máximo uns 30 comandos
o resto são bibliotecas que devem ser criadas na unha
e cada programador tinha sua caixa de ferramentas particular.
Com o passar do tempo e para facilitar a vida dos programadores,
as linguagem incorporaram mais e mais comandos e funções,
embora linguagens como Java e .NET na verdade são praticamente
bibliotecas de funções prontas que o programador
apenas utiliza como repositórios.

Quando uma função não existir, não
se desespere! Sempre tem um Activex, uma ffl ou até a
API do Windows para lhe ajudar. Olhe o exemplo que fizeram com
a GDI+ (http://www.gotdotnet.com/codegallery/codegallery.aspx?id=0826d7a6-1dab-4a71-8e70-f2170c3c1661).
Nada mais do que criar bibliotecas prontas para acessar a API
do Windows que trata exclusivamente do subsistema GDI+.

Então vamos pensar no seguinte problema: Quero saber
se a calculadora do Windows esta em execução para
informar ao meu usuário, por exemplo. Neste caso ao invés
de reclamara que essa ou aquela linguagem possui esta possibilidade
e a sua não, vamos ver o código abaixo:

#DEFINE
TH32CS_SNAPPROCESS  2
#DEFINE TH32CS_SNAPTHREAD   4
#DEFINE TH32CS_SNAPMODULE   8
#DEFINE MAX_PATH          260
#DEFINE PE32_SIZE  296

DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject

DECLARE INTEGER CreateToolhelp32Snapshot IN kernel32;
    INTEGER dwFlags, INTEGER th32ProcessID  

DECLARE
INTEGER Process32First IN kernel32;
    INTEGER hSnapshot, STRING @ lppe  

DECLARE
INTEGER Process32Next IN kernel32;
        INTEGER hSnapshot, STRING @ lppe  

LOCAL
hSnapshot, lcBuffer

hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS,
0)
lcBuffer = num2dword(PE32_SIZE) + Repli(Chr(0), PE32_SIZE-4)

IF
Process32First (hSnapshot, @lcBuffer) = 1
    * storing process properties to the cursor
    if VerProcessExec (lcBuffer,"calc.exe")
        =messagebox("Calculadora esta rodando")
    endif

    DO WHILE .T.
        IF Process32Next (hSnapshot,
@lcBuffer) = 1
                if VerProcessExec (lcBuffer,"calc.exe")
               =messagebox("Calculadora esta rodando")
                   endif
        ELSE
            EXIT
        ENDIF
    ENDDO
ELSE
* 87 – ERROR_INVALID_PARAMETER
ENDIF

= CloseHandle (hSnapshot)
RETURN  && main

function VerProcessExec(lcBuffer,lcExec)
    m.execname = SUBSTR(lcBuffer, 37)
    m.execname = SUBSTR(m.execname, 1, AT(Chr(0),m.execname)-1)
RETURN upper(m.lcExec)$m.execname

FUNCTION  num2dword (lnValue)
#DEFINE m0       256
#DEFINE m1     65536
#DEFINE m2  16777216
    LOCAL b0, b1, b2, b3
    b3 = Int(lnValue/m2)
    b2 = Int((lnValue – b3*m2)/m1)
    b1 = Int((lnValue – b3*m2 – b2*m1)/m0)
    b0 = Mod(lnValue, m0)
RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)

Com algumas chamadas ao Kernel32 podemos criar nossa própria
biblioteca para fazermos praticamente qualquer coisa que o Windows
permita realizar, mesmo tendo uma linguagem orientada a dados
como o VFP que não tem praticamente nenhuma chamada aos
subsistemas do sistema operacional.

Se você não conhece nada da API da Windows, faça
uma visita em www.news2news.com e
encontre mais de 1000 funções descritas e com fartos
exemplos das API win32 para que você possa realizar tudo
que sempre quis mesmo que o VFP não lhe ofereça
o suporte nativo.

Mãos a obra.