Okay I found a way to make this with a listView. Its rather complex and heavy just for a tooltip but maybe in the end you may decide if its worth it:
PS: I left more code than necessary to include other provided example by the kind contributors in posts above
In my real script it looks like this and it is shown on WM_MOUSEMOVE if hWnd = a Row # static ctrl
Code: Select all
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#SingleInstance, Force ; Prevent double execution of this script
#Persistent
; Faking what are normally dynamic variables (changing with different calculations)
Qt_1 := 2
, Mt_1 := 100000.00
, RawTs_1 := 4000.35
, RawTq_1 := 8000.68
; Prepare the values to display in the tooltip
Line := []
, Line.OverRowNumb := 1
, OverRowNumb := Line.OverRowNumb
, Line.Quantite := Qt_%OverRowNumb%
, Line.PrixUnitaire := Mt_%OverRowNumb%
, Line.TPSUnitaire := RawTs_%OverRowNumb%
, Line.TVQUnitaire := RawTq_%OverRowNumb%
, Line.TotalHorsTx := (Line.PrixUnitaire - (Line.TPSUnitaire + Line.TVQUnitaire)) * Line.Quantite
, Line.TotalTPS := Line.TPSUnitaire * Line.Quantite
, Line.TotalTVQ := Line.TVQUnitaire * Line.Quantite
, Line.TotalTAXES := Line.TotalTPS + Line.TotalTVQ
, Line.TotalAvecTx := Line.PrixUnitaire * Line.Quantite
; _________________________________________________________
, Line.StrLen := StrLen(Line.TotalAvecTx) + 3
, Line._ := ""
Loop, % Line.StrLen {
Line._ .= "_"
}
;/*
;-----------------------------------------------------------------------------------------------------------------------------------------
TT_ListView(Line)
;-----------------------------------------------------------------------------------------------------------------------------------------
*/
/*
data=
(
"Calcul Line #%OverRowNumb% :
"`nSous-total hors taxes,%Ligne_TotalHorsTx%,"$ ( %Ligne_PrixUnitaire%$ * Quantité = %Ligne_TotalAvecTx%$ - Taxes )"
" + TPS","%Ligne_TotalTPS%","$ ( %Ligne_TPSUnitaire%$ * Quantité )"
" + TVQ","%Ligne_TotalTVQ%","$ ( %Ligne_TVQUnitaire%$ * Quantité )"
"_____________________ "
"Sous-total avec taxes","%Ligne_TotalAvecTx%","$"
)
ToolTipFont("s10 q5", "Consolas")
TT_Tip := st_columnize(data, "csv", 1,, " ") ; 1=gauche, 2=right, 3=center
*/
;ToolTip, % TT_Tip, % A_ScreenWidth//3, % A_ScreenHeight // 2.5 ; Show the ToolTip
SetTimer, ToolTipOff, -5000 ; Set the Timer to automatically turn off tooltip after number of ms ;*[Untitled1]
Return
ToolTipOff:
Tooltip ; Off
ExitApp
;-----------------------------------------------------------------------------------------------------------------------------------------
TT_ListView(ByRef Line) { ; Pass an Object by Reference
;-----------------------------------------------------------------------------------------------------------------------------------------
Gui, TT_ListView:New, -Caption ; Creates a new GUI, destroying any existing GUI with that name and sets it as the default for the current thread.
Gui, Margin, 0, 0
Gui, Add, ListView, w800 r8 +Grid -hdr, % "Calcul Line #"Line.OverRowNumb "| | | "
LV_Add( "", "Calcul Line #"Line.OverRowNumb " :")
, LV_Add( "") ; EMPTY
, LV_Add( "", " Sous-total hors taxes", Line.TotalHorsTx " $ ", " Formule : ( Quantité x PRIX ) - TAXES ", " ( " Line.Quantite " x " Line.PrixUnitaire " $ ) - " Line.TotalTAXES " $" )
, LV_Add( "", " + TPS" , Line.TotalTPS " $ ", " Formule : ( Quantité x TPS ) " , " ( " Line.Quantite " x " Line.TPSUnitaire " $ ) " )
, LV_Add( "", " + TVQ" , Line.TotalTVQ " $ ", " Formule : ( Quantité x TVQ ) " , " ( " Line.Quantite " x " Line.TVQUnitaire " $ ) " )
, LV_Add( ""," _________________ " , Line._ )
, LV_Add( "", " Sous-total avec taxes", Line.TotalAvecTx " $ ")
, LV_ModifyCol(1, "AutoHDR")
, LV_ModifyCol(2, "AutoHDR Right")
, LV_ModifyCol(3, "AutoHDR Left")
, LV_ModifyCol(4, "AutoHDR Left")
Gui, Show
}
; provided by ahk7
ToolTipFont(Options := "", Name := "", hwnd := "") {
static hfont := 0
if (hwnd = "")
hfont := Options="Default" ? 0 : _TTG("Font", Options, Name), _TTHook()
else
DllCall("SendMessage", "ptr", hwnd, "uint", 0x30, "ptr", hfont, "ptr", 0)
}
ToolTipColor(Background := "", Text := "", hwnd := "") {
static bc := "", tc := ""
if (hwnd = "") {
if (Background != "")
bc := Background="Default" ? "" : _TTG("Color", Background)
if (Text != "")
tc := Text="Default" ? "" : _TTG("Color", Text)
_TTHook()
}
else {
VarSetCapacity(empty, 2, 0)
DllCall("UxTheme.dll\SetWindowTheme", "ptr", hwnd, "ptr", 0
, "ptr", (bc != "" || tc != "") ? &empty : 0)
if (bc != "")
DllCall("SendMessage", "ptr", hwnd, "uint", 1043, "ptr", bc, "ptr", 0)
if (tc != "")
DllCall("SendMessage", "ptr", hwnd, "uint", 1044, "ptr", tc, "ptr", 0)
}
}
_TTHook() {
static hook := 0
if !hook
hook := DllCall("SetWindowsHookExW", "int", 4
, "ptr", RegisterCallback("_TTWndProc"), "ptr", 0
, "uint", DllCall("GetCurrentThreadId"), "ptr")
}
_TTWndProc(nCode, _wp, _lp) {
Critical 999
;lParam := NumGet(_lp+0*A_PtrSize)
;wParam := NumGet(_lp+1*A_PtrSize)
uMsg := NumGet(_lp+2*A_PtrSize, "uint")
hwnd := NumGet(_lp+3*A_PtrSize)
if (nCode >= 0 && (uMsg = 1081 || uMsg = 1036)) {
_hack_ = ahk_id %hwnd%
WinGetClass wclass, %_hack_%
if (wclass = "tooltips_class32") {
ToolTipColor(,, hwnd)
ToolTipFont(,, hwnd)
}
}
return DllCall("CallNextHookEx", "ptr", 0, "int", nCode, "ptr", _wp, "ptr", _lp, "ptr")
}
_TTG(Cmd, Arg1, Arg2 := "") {
static htext := 0, hgui := 0, WM_CTLCOLORSTATIC := 0x138, WM_GETFONT := 0x31, WS_CHILD := 0x40000000
if !htext {
Gui _TTG: +hwndhgui +%WS_CHILD%
Gui _TTG: Add, Text, hwndhtext
}
Gui _TTG: %Cmd%, %Arg1%, %Arg2%
if (Cmd = "Font") {
GuiControl _TTG: Font, %htext%
SendMessage, WM_GETFONT, 0, 0,, ahk_id %htext%
return ErrorLevel
}
if (Cmd = "Color") {
hdc := DllCall("GetDC", "ptr", htext, "ptr")
SendMessage, WM_CTLCOLORSTATIC, hdc, htext,, ahk_id %hgui%
clr := DllCall("GetBkColor", "ptr", hdc, "uint")
DllCall("ReleaseDC", "ptr", htext, "ptr", hdc)
return clr
}
}
/* ; from string things by Tidbit
st_columnize
Take a set of data with a common delimiter (csv, tab, |, "a string", anything) and
nicely organize it into a column structure, like an EXCEL spreadsheet.
data = [String] Your input data to be organized.
delim = [Optional] What separates each set of data? It can be a string or it can
be the word "csv" to treat it as a CSV document.
justify = [Optional] Specify 1 to align the data to the left of the column, 2 for
aligning to the right or 3 to align centered. You may enter a
string such as "2|1|3" to adjust columns specifically. Columns are
separeted by |.
pad = [Optional] The string that should fill in shorter column items to match
the longest item.
colsep = [Optional] What string should go between every column?
example:
data=
(
"Date","Pupil","Grade"
----,-----,-----
"25 May","Bloggs, Fred","C"
"25 May","Doe, Jane","B"
"15 July","Bloggs, Fred","A"
"15 April","Muniz, Alvin ""Hank""","A"
)
output:=Columnize(data, "csv", 2)
output:
Date | Pupil | Grade
---- | ----- | -----
25 May | Bloggs, Fred | C
25 May | Doe, Jane | B
15 July | Bloggs, Fred | A
15 April | Muniz, Alvin "Hank" | A
*/
st_columnize(data, delim="csv", justify=1, pad=" ", colsep=" | ")
{
widths:=[]
dataArr:=[]
if (instr(justify, "|"))
colMode:=strsplit(justify, "|")
else
colMode:=justify
; make the arrays and get the total rows and columns
loop, parse, data, `n, `r
{
if (A_LoopField="")
continue
row:=a_index
if (delim="csv")
{
loop, parse, A_LoopField, csv
{
dataArr[row, a_index]:=A_LoopField
if (dataArr.maxindex()>maxr)
maxr:=dataArr.maxindex()
if (dataArr[a_index].maxindex()>maxc)
maxc:=dataArr[a_index].maxindex()
}
}
else
{
dataArr[a_index]:=strsplit(A_LoopField, delim)
if (dataArr.maxindex()>maxr)
maxr:=dataArr.maxindex()
if (dataArr[a_index].maxindex()>maxc)
maxc:=dataArr[a_index].maxindex()
}
}
; get the longest item in each column and store its length
loop, %maxc%
{
col:=a_index
loop, %maxr%
if (strLen(dataArr[a_index, col])>widths[col])
widths[col]:=strLen(dataArr[a_index, col])
}
; the main goodies.
loop, %maxr%
{
row:=a_index
loop, %maxc%
{
col:=a_index
stuff:=dataArr[row,col]
len:=strlen(stuff)
difference:=abs(strlen(stuff)-widths[col])
; generate a repeating string about the length of the longest item
; in the column.
loop, % ceil(widths[col]/((strlen(pad)<1) ? 1 : strlen(pad)))
padSymbol.=pad
if (isObject(colMode))
justify:=colMode[col]
; justify everything correctly.
; 3 = center, 2= right, 1=left.
if (strlen(stuff)<widths[col])
{
if (justify=3)
stuff:=SubStr(padSymbol, 1, floor(difference/2)) . stuff
. SubStr(padSymbol, 1, ceil(difference/2))
else
{
if (justify=2)
stuff:=SubStr(padSymbol, 1, difference) stuff
else ; left justify by default.
stuff:= stuff SubStr(padSymbol, 1, difference)
}
}
out.=stuff ((col!=maxc) ? colsep : "")
}
out.="`r`n"
}
stringTrimRight, out, out, 2 ; remove the last blank newline
return out
}