Mřížka, ach ta mřížka - Tooltip nad hlavičkou sloupce
Třída Header nemá vlastnost ToolTipText přesto někteří uživatelé vyžadují tooltipy nad hlavičkou sloupce mřížky.
Dnešní článek ukáže jak to zařídit pro verze VFP 3.0-7.0.
Od verze VFP 8.0 mají vlastnost ToolTipText všechny vizuální objekty.
Použil jsem způsob, kdy objekt třidy Timer testuje objekt pod ukazatelem myši.
Má to dvě výhody:
toto lze použít na mřížky, které mají nastaveno ColumnCount = -1
nemusí se vkládat kód do objektu headerX či do vlastních odvozených tříd
Vlastní výkonný kód je uložen v události Timer(), pro generování výsledného tooltipu se volá metoda SetToolTip().
Tooltip je zobrazen pomocí dynamického objektu třídy shape (je kompletně průhledný o velikost 3x3 pixely).
Jak to pracuje?
Timer nejdříve zjistí pomocí funkce SYS(1270) objekt pod ukazatelem myši.
loObj=SYS(1270)
Pokud to není objekt nebo to není objekt třídy Column (toto je nejhlouběji uložená třída v mřížce, která výše uvedená funkce vrácí), vymaže se interní informace o posledním sloupci, nad kterým se pohybovala myš.
Pokud byl již Shape vytvořen, skryje se.
* Pokud to není objekt, nebo není třídy column
IF !(TYPE("loObj")="O" AND !ISNULL(loObj) AND UPPER(loObj.BaseClass)="COLUMN")
* Pokud existuje, tím se zabrání tomu, aby shape neblikal (zobrazil,skryl,zobrazil)
IF !ISNULL(This.LinkObj)
* Pak otestuj, zda není aktivní ten shape
loParent=EVAL(This.LinkObj+".Parent.Parent")
IF TYPE("loObj")="O" AND !ISNULL(loObj) AND ;
UPPER(SYS(1272,loObj))==UPPER(SYS(1272,EVAL("loParent."+This.ShapeName)))
* Pokud je, pak je vse OK
RETURN
ENDIF
* Pokud to není Shape, pak Shape skryj
STORE .F. TO ("loParent."+This.ShapeName+".Visible")
ENDIF
This.LinkObj=.NULL. && Vyčisti vlastnost
RETURN && Vypadni
ENDIF
Pak se snaží najít objekt základní třídy Header.
Pokud ho nenajde, vyskočí ven, jinak pokračuje dál.
* Nyní musím identifikovat, zda jsem nad headerem
FOR lii=1 TO loObj.ControlCount
* Je to objekt třídy header ?
IF UPPER(loObj.Controls(lii).BaseClass)="HEADER"
* ANO
loHeader=loObj.Controls(lii)
EXIT && Ukonči smyčku
ENDIF
NEXT
IF lii>loObj.ControlCount && Pokud nic nenašel (třeba tam není)
RETURN && Vypadni ven
ENDIF
Dále se testuje, zda je ukazatel myši na místem, kde je hlavička sloupce.
Používá se na to funkce OBJTOCLIENT().
Tato funkce převádí pozici (i velikost) objektu na pozice vůči formuláři.
Pro určení pozice myši na formulářem se používají funkce MCOL() a MROW(), kde první parametr je název formuláře a druhý je 3 (vrácená pozice je v pixelech).
Pokud je myš mimo hlavičku, objekt Shape se skryje (byl-li) a vymaže s interní link o posledním sloupci.
IF !(BETWEEN(MROW(Thisform.Name,3),OBJTOCLIENT(loHeader,1),OBJTOCLIENT(loHeader,1)+OBJTOCLIENT(loHeader,4));
AND;
BETWEEN(MCOL(Thisform.Name,3),OBJTOCLIENT(loHeader,2),OBJTOCLIENT(loHeader,2)+OBJTOCLIENT(loHeader,3)))
* Ne jsem mimo
* Pokud existuje
IF !ISNULL(This.LinkObj)
STORE .F. TO (This.LinkObj+".Parent.Parent."+This.ShapeName+".Visible")
ENDIF
This.LinkObj=.NULL.
RETURN && Vypadni
ENDIF
Pokud je myš nad tím samým místě (v rámci hlavičky), pak se přesune objekt Shape na nové místo a nic více se neděje.
* Pokud už nějaký objekt aktivoval
IF !ISNULL(This.LinkObj)
* Pak musis provest test na stejné objekty
IF UPPER(SYS(1272,loObj))==UPPER(SYS(1272,EVAL(This.LinkObj)))
* Je to ten samý sloupec, přesuň Shape na nové místo
loShape=EVAL("loParent."+This.ShapeName) && Přeber objekt
loShape.Move(MCOL(Thisform.Name,3)-1,MROW(Thisform.Name,3)-1,3,3)
RETURN
ENDIF
ENDIF
Zapíše se link na aktuální sloupec.
This.LinkObj=UPPER(SYS(1272,loObj)) && Ulož si cestu k objektu
Pokud objekt Shape neexistuje, pak se založí a nastaví se mu průhledný styl.
IF TYPE("loParent."+This.ShapeName)="U"
loParent.AddObject(This.ShapeName,"_shpTipHeader")
loShape=loParent.Controls(loParent.ControlCount)
* Žádný okraj, průhledné pozadí, průhledný okraj
loShape.ZOrder(0) && Posuň ho dopředu
ELSE
loShape=EVAL("loParent."+This.ShapeName) && Přeber objekt
ENDIF
Následně se mu (Shapeu) nastaví vlastnost ToolTipText pomocí metody SetToolTip(), pozice,velikost a zobrazí se.
* Ulož cestu ke sloupci také na Shape pro přesměrování událostí
loShape.LinkObj=UPPER(SYS(1272,loHeader))
* Nastav tooltip
loShape.ToolTipText=This.SetToolTip(loObj)
* Nastav pozici a velikost, přesně pod myš
* Musí se také počítat s tím, že grid může být součástí konteinerové třídy
* V tom případě se odečítají pozice Top a Left parenta objektu od pozice myši nad formulářem
loShape.Move(MCOL(Thisform.Name,3)-OBJTOCLIENT(loParent,2) -1,;
MROW(Thisform.Name,3)-OBJTOCLIENT(loParent,1)-1,3,3)
loShape.Visible=.T. && Zobraz Shape
Metoda SetToolTip() přebírá parametr, který ukazuje na sloupec pod ukazatelem myši.
LPARAM loObj
* loObj - Objekt Sloupce
RETURN "Můj ToolTip: "+loObj.Name+"("+loObj.ControlSource+")"
Nutné podmínky:
Název (vlastnost Name) formuláře musí odpovídat PUBLIC referenci formuláře (DO FORM TEST LINKED NAME TEST)
V událostech Activate() a Deactivate() formuláře je nutno povolit (Activate()) a zakázat (Deactivate()) timer
K dispozici je ke stáhnutí
program s třídou
tmrTipHeader, ukázkovým formulářem a tabulkou.