Muitas vezes encontramos funções na API do Windows que possuem parâmetros do tipo LPTSTR. Veja um exemplo:
BOOL GetUserName(
LPTSTR lpBuffer,
LPDWORD lpnSize
);
Esta função é usada para obter o nome do usuário atualmente logado no sistema. Note que ela possui dois parâmetros:
lpBuffer - Um ponteiro para um buffer de caracteres que receberá o nome do usuário;
lpnSize - Este parâmetro informa, na entrada, o tamanho do buffer de caracteres e, na saída, informa a quantidade de caracteres copiados para o buffer.
Mas, como podemos usar esta função a partir do Delphi se não temos este tipo de dados (LPTSTR) em Delphi?
Para o tipo LPTSTR nós podemos fornecer uma string terminada em null (#0). E a melhor de forma de se fazer isso é declarando uma matriz de Char. Veja:
procedure TForm1.Button1Click(Sender: TObject);
var
buffer: array[0..255] of Char; // um buffer de 256 caracteres
tamanho: DWORD;
begin
// vamos informar ao Windows o tamanho do buffer
tamanho := 256;
// vamos chamar a função da API do Windows
if GetUserName(buffer, tamanho) then
begin
ShowMessage('O nome de usuário é: ' + buffer);
// informa a quantidade de caracteres usados. Note que
// o caractere de término da string também é informado
ShowMessage('A função usou: ' + IntToStr(tamanho) +
' caracteres');
end
else
ShowMessage('Não foi possível obter o nome do usuário');
end;
Um cuidado que devemos ter é nunca fornecer um buffer muito pequeno para as funções da API do Windows que esperam um ponteiro para strings do tipo LPTSTR. Experimente, por exemplo, fornecer uma matriz de apenas dois caracteres para a função GetUserName(). A menos que o nome de usuário no seu computador tenha apenas uma letra, a chamada à função falhará.
Em Delphi o tipo PChar é um ponteiro para uma string terminada em null. Podemos usá-la também, mas, neste caso, somos responsáveis por alocar memória para a string usando a procedure GetMem() e liberá-la explicitamente usando FreeMem(). Veja;
procedure TForm1.Button1Click(Sender: TObject);
var
buffer: PChar; // um buffer do tipo PChar
tamanho: DWORD;
begin
// vamos informar ao Windows o tamanho do buffer
tamanho := 256;
// vamos alocar a memória suficiente para receber o nome
// do usuário
GetMem(buffer, tamanho);
// vamos chamar a função da API do Windows
if GetUserName(buffer, tamanho) then
begin
ShowMessage('O nome de usuário é: ' + buffer);
// informa a quantidade de caracteres usados. Note que
// o caractere de término da string também é informado
ShowMessage('A função usou: ' + IntToStr(tamanho) +
' caracteres');
end
else
ShowMessage('Não foi possível obter o nome do usuário');
// vamos liberar o buffer alocado dinamicamente
FreeMem(buffer);
end;
Finalmente podemos declarar o buffer como String, usar a procedure SetLength() para ajustar seu tamanho e convertê-la para PChar antes de enviá-la à função GetUserName(). Veja como isso pode ser feito:
procedure TForm1.Button1Click(Sender: TObject);
var
buffer: String; // um buffer que será convertido para PChar
tamanho: DWORD;
begin
// vamos informar ao Windows o tamanho do buffer
tamanho := 256;
// aqui há um truque interessante. como não vamos precisar
// de 256 caracteres para guardar o nome de usuário e não podemos
// correr o risco de enviar uma string muito pequena, a saída
// é usar o retorno de GetUserName() para ajustar o tamanho
// da string depois de enviá-la à função.
// vamos ajustar o tamanho da string
SetLength(buffer, tamanho);
GetUserName(PChar(buffer), tamanho);
// agora tamanho guarda a quantidade de caracteres usados na função
SetLength(buffer, tamanho); // comente esta linha para ver o resultado
// se o valor de tamanho for 0, então a função falhou
if tamanho > 0 then
begin
ShowMessage('O nome de usuário é: ' + buffer);
// informa a quantidade de caracteres usados. Note que
// o caractere de término da string também é informado
ShowMessage('A função usou: ' + IntToStr(tamanho) +
' caracteres');
end
else
ShowMessage('Não foi possível obter o nome do usuário');
end;
Para fins de compatibilidade, esta dica foi escrita usando Delphi 2009.