A propriedade Hint do DBGrid é estática, isto é, o texto colocado lá aparece quando o mouse aponta para o Grid. Porém o que eu precisava era mostrar o conteúdo de uma célula no Hint. Isto é, muito útil quando a coluna possui uma largura pequena e o texto contido no registro é muito grande.


Para este exemplo utilizei um ClientDataSet apontando para o arquivo “C:\Arquivos de programas\Arquivos comuns\Borland Shared\Data\biolife.xml”. Portanto crie uma nova aplicação e adicione um ClientDataSet, um DataSource e um Grid no Form. Aponte o ClientDataSet para o arquivo “C:\Arquivos de programas\Arquivos comuns\Borland Shared\Data\biolife.xml” e o DataSource para o ClientDataSet e finalmente aponte o Grid para o DataSource.


Faça o Grid ocupar todo o Form configurando a propriedade Align para alClient. Para efeitos didáticos adicione os campos ao ClientDataSet exceto os campos “Notes” e “Graphic”. Ative o ClientDataSet para visualizar os dados.


Crie uma classe chamada TminhaJanelaHint conforme abaixo, esta será usada para substituir o hint padrão do Delphi.


type

   TMinhaJanelaHint = class(THintWindow)
   public
       procedure doActivateHint(Sender: TObject);
end;


E crie uma variável deste tipo na área public da unit:

MeuHint: TMinhaJanelaHint;


Temos que criar uma classe “amiga” para podermos acessar as propriedades do DBGrid que não são visíveis pelo objeto.


type

    TCellGrid = class(Grids.TCustomGrid);


Devemos definir o seguinte procedimento para mapear a posição do mouse para a coordenada relativa ao Grid:

procedure mouseToCell(X, Y: integer; var ACol, ARow: longint);


Que terá o código abaixo:


procedure TForm1.mouseToCell(X, Y: integer; var ACol, ARow: Integer);

var
   Coord: TGridCoord;
begin
   Coord := DbGrid1.MouseCoord(X,Y);
   ACol := Coord.X;
ARow := Coord.Y;
end;

Agora iremos definir um procedimento que calcula e posiciona a janela de hint personalizada substituindo a janela padrão de hint do Delphi. Esta função irá permitir inclusive que utilizemos mais de uma linha de texto. Ela deve ser definida como um procedimento da classe TminhaJanelaHint.

procedure TMinhaJanelaHint.doActivateHint(Sender: TObject);

var
   r : TRect;
   wdth_hint, hght_hint : integer;
begin
   if (Sender is TDbGrid) then
   begin
      // Calculo as dimensões necessárias à janela de Hint sendo o limite igual à 1/3 da tela
      r := CalcHintRect((Screen.Width div 3), (Sender as TDbGrid).Hint, nil);
      wdth_hint := r.Right - r.Left;
      hght_hint := r.Bottom - r.Top;
 
      // Reposiciono a janela do Hint para próximo da posição do mouse mantendo o tamanho
      // calculado pela rotina anterior
      r.Left := r.Left + mouse.CursorPos.X + 16;
      r.Top := r.Top + mouse.CursorPos.Y + 16;
      r.Right := r.Left + wdth_hint;
      r.Bottom := r.Top + hght_hint;

      // Executo o procedimento para exibição do Hint na tela

      ActivateHint(r,(Sender as TDbGrid).Hint);
   end;

end;

No DBGrid deve-se criar o evento OnMouseMove para controlar os movimentos do mouse e digitar o código abaixo:

procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);

var
   MColumn, MRow: Longint;
begin
   // A partir da posição do mouse obtemos a coordenada da célula do grid
   MouseToCell(X,Y,MColumn,MRow);
   // Se for uma célula válida ...
   if (MRow > 0) and (MColumn >0) and (Mcolumn <= DbGrid1.Columns.Count) then
   begin
      // Fazemos a coluna do Grid ser a coluna apontada pelo mouse, para isso usamos a classe amiga
      // definida no começo da unit
      TCellGrid(DBGrid1).Col := MColumn;
 
      // Movemos o DataSet para a linha apontada pelo mouse deslocando em relação à sua posição
      // anterior
      DBGrid1.DataSource.DataSet.MoveBy(MRow - TCellGrid(DBGrid1).Row);
 
      // Se o dado apontado não for do tipo String nem Variant não apresentamos o Hint
      if (DBGrid1.Columns[MColumn-1].Field.DataType <> ftString) and
         (DBGrid1.Columns[MColumn-1].Field.DataType <> ftVariant) then
      begin
         DBGrid1.Hint := '';
         MeuHint.ReleaseHandle;
         Exit;
      end;

      // Passamos o conteúdo do campo para o Hint do Grid e chamamos a função para exibi-lo

      DBgrid1.Hint := DBGrid1.Columns[MColumn-1].Field.AsString;
      MeuHint.doActivateHint(DBGrid1);
   end
else
   begin
      // Se não for célula válida limpo o Hint
      DBGrid1.Hint := '';
      MeuHint.ReleaseHandle;
    end;
end;

Finalmente no evento FormCreate do formulário instanciamos um objeto da classe TminhaJanelaHint.

procedure TForm1.FormCreate(Sender: TObject);

begin
   // Crio a minha janela de Hint
   MeuHint := TMinhaJanelaHint.Create(Self);
end;


Espero que este arquivo seja útil, um abraço a todos e até o próximo artigo.