Solved

Using THintInfo/THitWindow

Posted on 2000-02-20
16
991 Views
Last Modified: 2010-05-18
Hi all,

I'm programming a component to control a applications hint window. And thats no problem. But then i read something in the help file that i dont understand.
See THintInfo.CursorRect :
"The rectangle the user's mouse pointer must be in for the hint window to appear. The default value for CursorRect is the client rectangle of the control. Change this value so that a single control can be divided into several hint regions. When the user moves the mouse pointer outside the rectangle, the hint window disappears."

If it should be possible to "divide the control into several hint regions" it must also be possible to create several THintInfo records at create-time, right ??
That would be very useful - e.g. in a TStringGrid - to show different hint to the columns.

Today i'm using TApplication.OnShowHint to change the hint text.

Does anyone know or understand how to use/create additional THintInfo records ??

Regards
Peter
0
Comment
Question by:PeterLarsen
  • 6
  • 3
  • 3
  • +4
16 Comments
 
LVL 2

Author Comment

by:PeterLarsen
Comment Utility
Well, I ment "Using THintInfo/THintWindow"
0
 
LVL 2

Expert Comment

by:rene100
Comment Utility
listening.....
0
 
LVL 8

Accepted Solution

by:
ZifNab earned 200 total points
Comment Utility
mmm, don't know what you mean exactly, but is this what you want?


Specifically, the code:
1) Checks to see if the control in question is a TListBox using the is
operator

2) Determines which item the mouse is over using ItemAtPos. This is
used to exreact the string for the hint. The TopIndex is use to
determine the position of the cursor relative to the first item
displayed.

3) Checks the length of the string to see if a hint is necessary, using
the TextWidth method and the ClientWidth property of the TListBox.

4) Positions the hint over the item

5) Sets the CursorRect so the hint appears and disappears as necessary
when the mouse moves between items


{ .. In the form declaration ... }
procedure ShowCustomHint(var HintStr: string; var CanShow: Boolean; var HintInfo:
THintInfo);


{ In the implementation section }
procedure TForm1.ShowCustomHint(var HintStr: string; var CanShow: Boolean; var
HintInfo: THintInfo);
var
  cp : TPoint;
  lb : TListBox;
  item_num, item_height : integer;
begin
  if (HintInfo.HintControl is TListBox) then begin
    lb := TListBox(HintInfo.HintControl);
    cp := HintInfo.CursorPos;

    item_num := TListbox(HintInfo.HintControl).ItemAtPos(cp,true);
    if item_num = -1 then
      Exit;
    if lb.Canvas.TextWIdth(lb.Items[item_num]) < lb.ClientWidth then
begin
      CanShow := False;
      Exit;
    end;
    HintStr := lb.Items[item_num];

    item_num := item_num - lb.TopIndex;
    item_height := lb.ItemHeight;
    HintInfo.HintPos := lb.ClientToScreen(Point(0,item_num *
item_height));
    HintInfo.CursorRect := Rect(0,item_num *
item_height,lb.Width,(item_num + 1) * item_height);
  end;
end;

{ Remember to install the handler when the form is created }
{ The handler applies to all forms however }
procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnShowHint := ShowCustomHint;
end;

Regards, Zif
0
 
LVL 17

Expert Comment

by:inthe
Comment Utility
hello ,
example for stringgrid.
if you drop a stringgrid on a form and fill some cells with text the hint of each cell is the text of the current cell the mouse is over :

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure FormShowHint(var HintStr: String;
  var CanShow: Boolean; var HintInfo: THintInfo);

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormShowHint(var HintStr: String;
  var CanShow: Boolean; var HintInfo: THintInfo);
var ACol, ARow : integer;
begin
with HintInfo do
  if (HintControl is TStringGrid) then
    with (HintControl as TStringGrid) do begin
     CanShow := false;
     MouseToCell(CursorPos.X, CursorPos.Y, ACol, ARow);
    HintInfo.CursorRect := stringgrid1.CellRect(ACol, ARow);
   HintInfo.HintStr := stringgrid1.Cells[acol,arow];
  CanShow := true;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Application.OnShowHint := self.FormShowHint;
end;

end.

Regards Barry
0
 
LVL 2

Author Comment

by:PeterLarsen
Comment Utility
Thank you for your comments !!

This is not what i asked for. This is the way i'm doing it today.

If you take a button - lets say in a size of 100x100 pixels, and you want the hint box to appear when you move the mouse over the left side of the button (x:0-50, y:0-100).

When the OnShowHint event is called you change CursorRect to 0,0,50,100. That should make the hint box to disappear if you move the mouse in the range from x:51 to 100, right ??

What if it was possible to create two THintInfo records and assign the left side of the button to the first THintinfo and the right side of the button to the second THintInfo record. That would be an easy way to control the hint box.

I dont know if thats possible, but ... THintInfo is a record, thats makes it possible to create multiple instance of it. I can see that if i change CursorRect, THintInfo points to a different record in the system.

THintInfo also have the field HintData. But it is not in use anywhere - except if i override "function CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect; override;".
Why is it there (HintData) if i'm not allowed to create my own THintInfo and save a pointer there - like in TTreeWiew ??

Regards
Peter
0
 
LVL 2

Expert Comment

by:hubdog
Comment Utility
listening
0
 
LVL 10

Expert Comment

by:Lischke
Comment Utility
Hi Peter,

if you wanna make it right you need a different approach. I have written a control called TColorPickerButton (see my homepage at www.lischke-online.de) which does what you want here too. Instead of having 50 or so buttons for each color, I just maintain a list of rectangles and set the hint rect accordingly. The main question is WHERE to set it :-) Here's the code:

procedure TColorPopup.CMHintShow(var Message: TMessage);

// determine hint message (tooltip) and out-of-hint rect

var Index: Integer;
    r, g, b: Byte;
    Colors: TCombArray;

begin
  Colors := nil;
  with TCMHintShow(Message) do
  begin
    if not TColorPickerButton(Owner).ShowHint then Message.Result := 1
                                              else
    begin
      with HintInfo^ do
      begin
        // show that we want a hint
        Result := 0;
        // predefined colors always get their names as tooltip
        if FHoverIndex >= 0 then
        begin
          GetCellRect(FHoverIndex, CursorRect);
          if FHoverIndex < DefaultColorCount then HintStr := DefaultColors[FHoverIndex].Name
                                             else HintStr := SysColors[FHoverIndex - DefaultColorCount].Name;
        end
        else
          // both special cells get their hint either from the application by
          // means of the OnHint event or the hint string of the owner control
          if (FHoverIndex = DefaultCell) or
             (FHoverIndex = CustomCell) then
          begin
            HintStr := GetHint(FHoverIndex);
            if HintStr = '' then HintStr := TColorPickerButton(Owner).Hint
                            else
            begin
              // if the application supplied a hint by event then deflate the cursor rect
              // to the belonging button
              if FHoverIndex = DefaultCell then CursorRect := FDefaultTextRect
                                           else CursorRect := FCustomTextRect;
            end;
          end
          else
          begin
            // well, mouse is not hovering over one of the buttons, now check for
            // the ramp and the custom color areas
            if PtInRect(FSliderRect, Point(CursorPos.X, CursorPos.Y)) then
            begin
              // in case of the intensity slider we show the current intensity
              HintStr := Format('Intensity: %d%%', [Round(100 * FCenterIntensity)]);
              CursorRect := Rect(FSliderRect.Left, CursorPos.Y - 2,
                                 FSliderRect.Right, CursorPos.Y + 2);
              HintPos := ClientToScreen(Point(FSliderRect.Right, CursorPos.Y - 8));
              HideTimeout := 5000;
              CursorRect := Rect(FSliderRect.Left, CursorPos.Y,
                                 FSliderRect.Right, CursorPos.Y);
            end
            else
            begin
              Index := -1;
              if PtInRect(FBWCombRect, Point(CursorPos.X, CursorPos.Y)) then
              begin
                // considering black&white area...
                if csLButtonDown in ControlState then Index := -(FCustomIndex + 1)
                                                 else Index := FindBWArea(CursorPos.X, CursorPos.Y);
                Colors := FBWCombs;
              end
              else
                if PtInRect(FColorCombRect, Point(CursorPos.X, CursorPos.Y)) then
                begin
                  // considering color comb area...
                  if csLButtonDown in ControlState then Index := FCustomIndex - 1
                                                   else Index := FindColorArea(CursorPos.X, CursorPos.Y);
                  Colors := FColorCombs;
                end;

              if (Index > -1) and (Colors <> nil) then
              begin
                with Colors[Index] do
                begin
                  r := GetRValue(Color);
                  g := GetGValue(Color);
                  b := GetBValue(Color);
                end;
                HintStr := Format('red: %d, green: %d, blue: %d', [r, g, b]);
                HideTimeout := 5000;
              end
              else HintStr := GetHint(NoCell);

              // make the hint follow the mouse
              CursorRect := Rect(CursorPos.X, CursorPos.Y,
                                 CursorPos.X, CursorPos.Y);
            end;
          end;
      end;
    end;
  end;
end;


This way you don't need to store several hint records but just retrieve what's need on demand (and here also an application callback is provided to get a specific hint string or the code uses the control's hint string if needed).

The hint data pointer can only be used in descentants of THintWindow. I used this stuff for my virtual tree control which needs to show wide string (Unicode) hints and I can't pass these via the normal hint string (so I do it via the hint data pointer).

Ciao, Mike
0
 
LVL 3

Expert Comment

by:gandalf_the_white
Comment Utility
listening...
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 2

Author Comment

by:PeterLarsen
Comment Utility
Thank you for your time.

Your samples are very fine but i already know how to do that.
Maybe there are no answer to my question.

In exchange for your time i can offer you a hint component - if you like.

When this component i placed on a form, it will take control over the applications hint window - re-shape it or what else you like to do with it. It also include the possibilities to add a picture to the hint window.

Regards and again - thanks for participating.
Peter
0
 
LVL 10

Expert Comment

by:Lischke
Comment Utility
Mmh, your question was how to create several hint records at run time. As this is without true sense I showed you how to use the hint stuff correctly. If you know all this, then why have you asked your original question, although it is obvious that this makes no sense?

Time wasted... :-/

Ciao, Mike
0
 
LVL 2

Author Comment

by:PeterLarsen
Comment Utility
Hi Mike,

Again - i'm very sorry. Please dont say that you have wasted your time - i dont think you'r doing this for the points.

If you think something is possible, and it turns out that it is not - i may seem that it is a waste of time - but i dont think it is.

I know that you (and the others experts) have spent some time with this and therefore i also want to give something back to you.

Regards
Peter
0
 
LVL 10

Expert Comment

by:Lischke
Comment Utility
When I say I wasted my time then I mean that I made the wrong assumptions and put my working power/time into this without true interest of you (or any other, for that matter).

Don't care about sending your hint control. I prefer the system standard and if I need more information about a particular item then I consult the help file (usually, if there's one ;-)).

Ciao, Mike

0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
0
 
LVL 2

Author Comment

by:PeterLarsen
Comment Utility
I would like to keep this discussion at EE. To do that i have to accept one of your comments.

ZifNab was there first, so if you all can agree with this i will accept he's answer.

/Peter
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
I don't mind :-). You could also restart a new q'n.
0
 
LVL 2

Author Comment

by:PeterLarsen
Comment Utility
Nee ZifNab, I dont think i get closer to the answer by forming the lines into a new question.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now