Integração com API do MS-Windows

O eDeveloper (e UniPaaS) possui recursos para integração com DLLs do MS-Windows (32 bits).
São as funções CALLDLL, CALLDLLS e CALLDLLF, e o comando: Call/Invoke UDP.
O comando é necessário quando algum parâmetro precisa ser passado por referência. Nos demais casos, pode-se usar as funções. A função correta a usar depende da ‘convenção de chamada’ da rotina compilada dentro da DLL: C, Standard (Pascal) ou Fast.
Porém, algumas APIs necessitam receber dados de um tipo não existente nativamente no eDeveloper / UniPaaS: Structs (ou “Records” em Pascal).
Ex:
typedef struct _MEMORYSTATUS {
DWORD dwLength;
DWORD dwMemoryLoad;
DWORD dwTotalPhys;
DWORD dwAvailPhys;
DWORD dwTotalPageFile;
DWORD dwAvailPageFile;
DWORD dwTotalVirtual;
DWORD dwAvailVirtual;
} MEMORYSTATUS, *LPMEMORYSTATUS;
Esta é uma “struct” recebida pela função do MS-Windows GlobalMemoryStatus, que retorna informações da memória da máquina.
Desde a versão 9.4 sp3 contudo, é possível criar-se “structs” no eDeveloper em variáveis BLOB. Para preencher os membros de uma “struct”, usam-se as funções BufSet???. Para ler o conteúdo de seus membros, as funções BufGet???. Uma leitura mais detalhada do ‘help’ do eDeveloper e UniPaaS é necessária, para compreender o uso correto destas funções.
Voltando ao caso acima, para obter informação da memória da máquina precisamos passar uma “struct” de 8 membros DWord. Um ‘DWord’ é um inteiro sem sinal, que ocupa 4 bytes. O primeiro membro deve ser preenchido com o tamanho da struct (8 x 4 = 32) e após a chamada, a função da API Windows preenche os demais membros com suas respectivas informações.
Para montarmos esta “struct” em uma variável (virtual de preferência) BLOB, usaremos a função BufSetNum (todos os membros são numéricos neste caso). Usaremos o código ‘2’ para ‘Storage ID’ (2 = Numérico Sem Sinal), usaremos o valor ‘4’ para informar o tamanho do dados (4 bytes), e teremos de calcular a posição de cada membro dentro da “struct”. As posições iniciam-se sempre pelo OffSet ‘1’. Então, ficaria assim (assumindo que a virtual BLOB é a variável “B”):
BufSetNum (‘B’VAR,1,32,2,4)  1º. Membro DWord [4 bytes], vale 32, offSet 1 (tamanho da struct)
BufSetNum (‘B’VAR,5,0,2,4)  2º. Membro DWord [4 bytes], vale 0, offSet 5 (1+4)
BufSetNum (‘B’VAR,9,0,2,4)  3º. Membro DWord [4 bytes], vale 0, offSet 9 (5+4)
BufSetNum (‘B’VAR,13,0,2,4)  4º. Membro DWord [4 bytes], vale 0, offSet 13 (9+4)
BufSetNum (‘B’VAR,17,0,2,4)  5º. Membro DWord [4 bytes], vale 0, offSet 17 (13+4)
BufSetNum (‘B’VAR,21,0,2,4)  6º. Membro DWord [4 bytes], vale 0, offSet 21 (17+4)
BufSetNum (‘B’VAR,25,0,2,4)  7º. Membro DWord [4 bytes], vale 0, offSet 25 (21+4)
BufSetNum (‘B’VAR,29,0,2,4)  8º. Membro DWord [4 bytes], vale 0, offSet 29 (25+4)
Na chamada da função, usamos o especificador de parâmetro ‘T’ para informar que o parâmetro é uma ‘struct’.
Como a função ‘GlobalMemoryStatus’ é um procedimento na verdade, usaremos o especificador ‘0’ para indicar que ela retorna um VOID (nada). Então sua chamada seria:
Call/Invoke UDP ‘@Kernel32.GlobalMemoryStatus’
Arg #1: ‘T0’
Arg #2 <BLOB>
Após a chamada, usaremos a função BufGetNum para recuperar os valores dos membros da “struct” (já atualizados). Fica assim:

O eDeveloper (e Magix xpa (UniPaaS)) possui recursos para integração com DLLs do MS-Windows (32 bits).

São as funções CALLDLL, CALLDLLS e CALLDLLF, e o comando: Call/Invoke UDP.

O comando é necessário quando algum parâmetro precisa ser passado por referência. Nos demais casos, pode-se usar as funções. A função correta a usar depende da ‘convenção de chamada’ da rotina compilada dentro da DLL: C, Standard (Pascal) ou Fast.

Porém, algumas APIs necessitam receber dados de um tipo não existente nativamente no eDeveloper / Magic xpa: Structs (ou “Records” em Pascal).

Ex:

typedef struct _MEMORYSTATUS {

DWORD dwLength;

DWORD dwMemoryLoad;

DWORD dwTotalPhys;

DWORD dwAvailPhys;

DWORD dwTotalPageFile;

DWORD dwAvailPageFile;

DWORD dwTotalVirtual;

DWORD dwAvailVirtual;

} MEMORYSTATUS, *LPMEMORYSTATUS;

Esta é uma “struct” recebida pela função do MS-Windows GlobalMemoryStatus, que retorna informações da memória da máquina.

Desde a versão 9.4 sp3 contudo, é possível criar-se “structs” no eDeveloper em variáveis BLOB. Para preencher os membros de uma “struct”, usam-se as funções BufSet???. Para ler o conteúdo de seus membros, as funções BufGet???. Uma leitura mais detalhada do ‘help’ do eDeveloper e Magic xpa é necessária, para compreender o uso correto destas funções.

Voltando ao caso acima, para obter informação da memória da máquina precisamos passar uma “struct” de 8 membros DWord. Um ‘DWord’ é um inteiro sem sinal, que ocupa 4 bytes. O primeiro membro deve ser preenchido com o tamanho da struct (8 x 4 = 32) e após a chamada, a função da API Windows preenche os demais membros com suas respectivas informações.

Para montarmos esta “struct” em uma variável (virtual de preferência) BLOB, usaremos a função BufSetNum (todos os membros são numéricos neste caso). Usaremos o código ‘2’ para ‘Storage ID’ (2 = Numérico Sem Sinal), usaremos o valor ‘4’ para informar o tamanho do dados (4 bytes), e teremos de calcular a posição de cada membro dentro da “struct”. As posições iniciam-se sempre pelo OffSet ‘1’. Então, ficaria assim (assumindo que a virtual BLOB é a variável “B”):

BufSetNum (‘B’VAR,1,32,2,4) => 1º. Membro DWord [4 bytes], vale 32, offSet 1 (tamanho da struct)

BufSetNum (‘B’VAR,5,0,2,4) => 2º. Membro DWord [4 bytes], vale 0, offSet 5 (1+4)

BufSetNum (‘B’VAR,9,0,2,4) => 3º. Membro DWord [4 bytes], vale 0, offSet 9 (5+4)

BufSetNum (‘B’VAR,13,0,2,4) => 4º. Membro DWord [4 bytes], vale 0, offSet 13 (9+4)

BufSetNum (‘B’VAR,17,0,2,4) => 5º. Membro DWord [4 bytes], vale 0, offSet 17 (13+4)

BufSetNum (‘B’VAR,21,0,2,4) => 6º. Membro DWord [4 bytes], vale 0, offSet 21 (17+4)

BufSetNum (‘B’VAR,25,0,2,4) => 7º. Membro DWord [4 bytes], vale 0, offSet 25 (21+4)

BufSetNum (‘B’VAR,29,0,2,4)  8º. Membro DWord [4 bytes], vale 0, offSet 29 (25+4)

Na chamada da função, usamos o especificador de parâmetro ‘T’ para informar que o parâmetro é uma ‘struct’.

Como a função ‘GlobalMemoryStatus’ é um procedimento na verdade, usaremos o especificador ‘0’ para indicar que ela retorna um VOID (nada). Então sua chamada seria:

Call/Invoke UDP ‘@Kernel32.GlobalMemoryStatus’

Arg #1: ‘T0’

Arg #2 <BLOB>

Após a chamada, usaremos a função BufGetNum para recuperar os valores dos membros da “struct” (já atualizados). Fica assim:

img1
E o resultado é este:
img2
Este projeto (seu código fonte em eDev 9.4) está disponível para download aqui
Manoel Frederico - Gerente de Produto e Magic Evangelista
Manoel Frederico – Gerente de Produto e Magic Evangelista

 

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *