GARANTIR DESCONTO

Fórum Problema com string (problemático) #174363

11/08/2003

0

Boa tarde a todos!

Pessoal, estou com uma grande dificuldade em desenvolver um aplicativo para ser servidor para um terminal de consulta de preço (gertec tc504).
Vamos lá.
Este terminal é concetado via cabo de rede e funciona como uma estação comum inclusive podento configurar ip gatway e tudo mais para que ele funcione, bem ao passar o código do produto no leitor ele gera uma chamada para o servidor, o qual recebe esta chamada em forma de string e faz a busca no banco de dados pelo produto, se encotra ele armazena as informações do produto em ma string para enviar para o terminal, bem, até aí nada de errado ou complicado, o problema está com strings maiores que 88 caracteres utilizando fonte lucida no tamanho 12 (padrão do terminal) pois ele envia a string para o terminal mais ele não mostra nada (o tc 504 tem uma telinha de 320 X 240 de cristal líquido) na tela pois a string é muito grande.
Tendo isto em vista eu preciso então criar um procedimento que teste o tamanho da string antes de enviá-la ao terminal e se caso ela for maior que 88 caracteres, subdivida a string em duas ou mais até que possa mostrar toda ela e não ultrapasse os 88 caracteres, e utilize a função para enviar a string para o terminal, o problema é que eu não posso declarar as variáveis necessária pois eu não sei quantas vezes terei que dividir a string até que toda ela seja mostrada e não ultrapasse os benditos 88 caracteres.
abaixo coloquei a função que envia o texto para o terminal:

straux := DM.TblGertecdescricao.Value; // armazena a informação na string
posx := 160 - ((Length(straux)*16) div 2); //posição da fonte

StrPCopy(@strtogo,StrAux);
StrPCopy(@strfont,´\fonts\courn8.bmp´); //estabelece a fonte
EnviaTexto(ID, -->>envia o texto para o terminal
posx, //PosX
StrToInt(´10´), //PosY
strtogo,
strfont,
StrColorToInt(´Blue´),
StrColorToInt(´White´));

bem como vocês podem ver acima para cada string ou texto que eu quero mandar para o terminal eu preciso utilizar o bloco de código acima alterando apenas o nome da string e a sua posição X e Y para que não mostre todas as string sobrepostas. Resuminido eu preciso testar a string se for maior que 88 então eu divido ela em duas (por exemplo) utilizo o código acima para mandar cada uma das strings, ou seja caso a string seja dividida em 6 então eu tenho que utilizar a função acima 6x e só para lembrar esta divisão precisa respeitar as palavras ou seja, não pode dividir palavras em duas senão vai ficar muito estranho no terminal.
Aí está pessoal, essa realmente - ao menos para mim - é de quebrar a cabeça...

Valeu !


Angelo


Angelo

Angelo

Responder

Posts

11/08/2003

Manoelnasc

veja isto:

procedure quebrastr(str: string; saida: tipodasuasaida);
var
str2: string[88]; //88 é o tamanho maximo
begin
  str2:=str;
...
  sua rotina, mas com str2
...
  if length(str) > 88 then
     quebrastr(copy(str,89,length(str)-88),saida); recursividade:
end;


At.
Manoel Nascimento


Responder

Gostei + 0

11/08/2003

Allen74

Manoel, sua função ainda não lida com a quebra de palavras. Da forma como está ela pode fazer com que a palavra seja quebrada no meio, ficando parte dos caracteres no final de uma linha e a segunda parte no início da linha seguinte.

Angelo, tenho a seguinte dúvida sobre este terminal. Quantos caracteres do seu texto são possíveis de escrever em uma única linha com a fonte padrão deste terminal? os parâmetros PosX e PosY são coordenadas dentro da resolução de 320x240?

Pergunto isso porque numa resolução desta não é possível imprimir 88 caracteres por linha. O terminal faz a quebra de linha automaticamente?


Responder

Gostei + 0

12/08/2003

Allen74

Angelo,

Após ler o manual do produto que você me enviou por e-mail, implementei uma solução que deve resolver seu problema. Em primeiro lugar alguns esclarecimentos.

Como a resolução da tela de cristal líquido é de 320x240 pixels, a quantidade de colunas de texto que serão passíveis de exibição em uma única linha depende exclusivamente da largura da fonte escolhida.

A fonte que você está utilizando possui 8 pixels de largura e 10 de altura. Sendo assim, o máximo que conseguiremos será 40 colunas e 24 linhas.

A função que criei para quebrar uma string longa em várias linhas com uma determinada quantidade máxima de caracteres em cada linha é a seguinte:

function QuebraTexto (txt : String; Colunas : Integer) : TStringList;
var
  pos : integer;
  lst : TStringList;
begin
  lst := TStringList.Create;
  while Length(txt) > Colunas do begin
    pos := Colunas;

    // procurando por caracteres de espaço/controle anteriores
    // ao limite de colunas para realizar a quebra de palavras
    while (pos > 0) and (txt[pos] > 32) do pos := pos -1;

    if pos = 0
    then begin
      // Não existe espaço no primeiro trecho da string. Forçar a quebra.
      lst.Add(Copy(txt,1,Colunas));
      Delete (txt,1,Colunas);
    end
    else begin
      // Encontrou espaço entre palavras. Realizar quebra
      lst.Add(Copy(txt,1,pos));
      Delete (txt,1,pos);
    end;
  end;
  // insere o restante da string caso tenha sobrado
  if Length(txt) > 0
  then lst.Add (txt);
  result := lst;
end;


Esta função recebe como primeiro parâmetro a string que você pretende quebrar. O segundo parâmetro indica a quantidade máxima de caracteres para cada linha.

O retorno desta função é um TStringList. Uma lista de strings contendo as linhas quebradas. Você pode colocar esta função na sua unit ou em uma unit de bibliotecas, desde que acrescente as units Classes e System ao Uses.

Neste código não me preocupei com a remoção de espaços excedentes (à direita e à esquerda de cada linha), pois não sei de suas necessidades de preservação do espaçamento para alinhar o texto.

Para testar o código acima, crie um novo projeto contendo um Edit, um botão e um Memo. Cole o código da função e escreva o seguinte código no evento OnClick do botão:

procedure TForm1.Button1Click(Sender: TObject);
var
  Txt : TStringList;
begin
  Txt := QuebraTexto (Edit1.Text, 40);
  Memo1.Lines.Assign(Txt);
  Txt.Free;
end;


Este código serve para lembrar uma coisa importante. A função QuebraTexto retorna um TStringList já instanciado. Por isso, na primeira linha não é necessário escrever Txt := TStringList.Create. E por este mesmo motivo, você não pode se esquecer de liberar a memória (Txt.Free) quando terminar de utilizar a lista de strings.

Para utilizar as linhas agora contidas na StringList e já imprimir as linhas alinhadas à direita e uma abaixo da outra no terminal de consulta:

procedure PrintText (YOrigem,Altura: Integer; CorFonte,CorFundo,Fonte: string; Linhas : TStringList);
var
  strtogo,strfont : PChar;
  i : integer;
begin
  if (YOrigem < 0) or (Altura < 8) then exit;
  StrPCopy (@strfont, Fonte);

  for i := 0 to Linhas.Count - 1 do
  begin
    StrPCopy (@strtogo, Linhas.Strings[i]);
    EnviaTexto (ID, 0, YOrigem, Altura, strtogo, strfont,
      StrColorToInt (CorFonte), StrColorToInt (CorFundo));
    YOrigem := YOrigem + Altura;
    if YOrigem > 240 - Altura
    then break;
  end;
end;


O parâmetro YOrigem é a coordenada de início da impressão do texto. Altura corresponde à altura da linha em pixels. Você pode informar uma altura maior que a altura da fonte para tornar o texto mais legível se precisar. Se você informar uma altura menor que a altura da fonte, as linhas irão se sobrepor em um certo nível.

Os outros três parâmetros são bem descritivos e o quarto, logicamente é onde passará como parâmetro a lista de strings a apresentar.

Um exemplo de utilização dos códigos acima seria o trecho:

  // Chama função para limpar a tela
  Txt := QuebraTexto (Texto_descritivo, 40);
  PrintText (0, 10, ´Branco´, ´Preto´, ´\fonts\courn8.bmp´, Txt);
  Txt.Free;



Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar