Text Box

The location of the Text Box follows the chart by reading the properties of the chart.   I think you will like the characteristics of this implementation.

procedure ShowPrices;
var
  i,sc,mk,row,col: integer;
  symb: string;
  h,l,c,v: real;
  f: TForm;
begin
  i:=XtoIndex(PtX);    // Convert the mouse X coordinate to a chart bar Index
  h:=High(i); l:=Low(i); c:=Last(i);
  sc:=GetVariable(eScaleFactor);
  mk:=GetVariable(eMarket);
  symb:=GetVariable(eSymbol);

  f := screen.Forms[Window-1]; row:=f.Top+22; col:=f.Left;
  if FindWindow(eText)=0 then TextBox('',col,row,40,100);

  SetFocus;
  f := ActiveMDIChild; f.Left:=col; f.Top:=row;
  TextCaption(symb);
  TextClear;
  TextAdd('Last '+FormatPrice(c,true,sc,mk),false);
  TextAdd('High '+FormatPrice(h,true,sc,mk),false);
  TextAdd('Low '+FormatPrice(l,true,sc,mk),false);
end;

{----- MAIN PROGRAM -----}
begin
  if Who=66 then ShowPrices;
  if Who=2 then AlertEvent(eMouse,66);
  if Who=3 then AlertEvent(eMouse,0);
end;

The FindWindow statement looks to see if there is already a TextBox on the screen, and if NOT found, then it creates a textbox.   If you do not test to find one first, then multiple alerts will create multiple TextBoxes all stacked on top of each other.

If the current text box is underneath a chart, it can be brought to the surface with a SetFocus statement before you start writing content to the text box.   The SetFocus statement is the solution to the situation you are asking about.

The use of SetFocus in the above script has two effects:  The advantage is that is keeps the TextBox form on top of the chart, but is in so doing, the chart cannot get focus to that draw tools and studies can be added to the chart.   This later effect is a real penalty.  Therefore, I consider the following a better solution to display the data you have in mind.

procedure ShowPrices;
var
  i,sc,mk,row,col: integer;
  symb: string;
  h,l,c,v: real;
  f: TForm;
begin
  i:=XtoIndex(PtX);    // Convert the mouse X coordinate to a chart bar Index
  h:=High(i); l:=Low(i); c:=Last(i);
  sc:=GetVariable(eScaleFactor);
  mk:=GetVariable(eMarket);
  SetPen(clWhite); Rectangle(0,0,80,39);
  TextOut(2,1,'Last '+FormatPrice(c,true,sc,mk));
  TextOut(2,13,'High '+FormatPrice(h,true,sc,mk));
  TextOut(2,25,'Low '+FormatPrice(l,true,sc,mk));
end;

{----- MAIN PROGRAM -----}
begin
  if Who=66 then ShowPrices;
  if Who=2 then AlertEvent(eMouse,66);
  if Who=3 then AlertEvent(eMouse,0);
end;

The script is using an AlertEvent where one can assign a value that Who will have when the Alert Event executes the script.   Since Who values are preassigned for use with values through 56 as you correctly observe, we arbitrarily chose any value above 56 since 57 through 999 are available.

This statement makes the assignment so the eMouse event will call the script with a Who value of  66.

  if Who=2 then AlertEvent(eMouse,66);

Setting the assigned value for an eMouse event back to zero cancels the alert event.