;: Title: TT.ahk Object based ToolTip Library by HotKeyIt
;
; Function: TT() - Object based ToolTip Library by HotKeyIt
; Description:
; TT is based on AHK_L Objects and supports both, ANSI and UNICODE version, so to use it you will require Lexikos AutoHotkey_L.exe or other versions based on it that supports objects.
TT is used to work with ToolTip controls. You can create standalone ToolTips but also ToolTips for Controls of your GUI.
; Syntax: TTObj:=TT(Options,Text,Title)
; Parameters:
; TTObj - ToolTip Object to control ToolTip using its functions and ToolTip messages.
; Options - Description (If Options is a digit or hexadecimal number TT will assume this is the parent window)
; Options requiring a value - All these options need to be followed by = and a value. For example Parent=99
; GUI/PARENT - Parent HWND or Gui Id (Parent can be 1-99 as well). When no Parent or GUI ID is given, GUI +LastFound will be used, when you do not want to have a parent use PARENT=0 (OnShow,OnClick,OnClose is only possible if PARENT is an AutoHotkey window)
; AUTOPOP / INITIAL / RESHOW - Option for Control ToolTips.
AUTOPOP - How long to remain visible.
INITIAL - Delay showing.
RESHOW - Delay showing between tools.
For reference see TTM_SETDELAYTIME Message.
; MAXWIDTH - Maximum tooltip window width, or -1 to allow any width.
For reference see TTM_SETMAXTIPWIDTH Message.
; ICON - 0=none 1=info 2=warning 3=error (> 3 = hIcon). (!!! Use "" to show the image as icon from a jpg, bmp and other image files.
For reference see TTM_SETTITLE Message.
Since the Icon is in the title, it will appear only if there is a title.
; Color - RGB color for ToolTip text color.
For reference see TTM_SETTIPTEXTCOLOR Message.
; BackGround - RGB ToolTip background color.
For reference see TTM_SETTIPBKCOLOR Message.
; OnClose/OnClick - A function to be launched when a ToolTip was closed or a link was clicked. ParseLinks option will be set automatically.
Links are created using Text.
Your OnClick function can accept up to two parameters ToolTip_Message(action[,Tool]).
When action is not specified Text will be used.
Tool is your ToolTip object that you can access inside your function.
OnClose uses same parameters but first passed parameter will be empty.
; Options not requiring a value - HWND CENTER RTL SUB TRACK ABSOLUTE TRANSPARENT PARSELINKS - For reference see TOOLINFO Structure
- CloseButton for your ToolTip
- ClickTrough will enable clicking trough ToolTip
- Balloon ToolTip
- Style uses themed hyperlinks.
- NoFade disables fading in.
- NoAnimate disables sliding on Win2000.
- NoPrefix Prevents the system from stripping ampersand characters from a string or terminating a string at a tab character.
- AlwaysTip - Indicates that the tooltip control appears even if the tooltip control's owner window is inactive.
; ToolTip functions - All function beside Add, Del, Show, Color, Remove and Text are ToolTip messages, for reference see ToolTip Messages.
To call them use for example TTObj.TRACKACTIVATE(x,y)
; ToolTip.Add() - ToolTip.Add(Control[,text,uFlags/options,parent])
- Control can be text like Button1 or hwnd of control.
- Text to be displayed.
- uFlags/options can be a value or list of strings HWND CENTER RTL SUB TRACK ABSOLUTE TRANSPARENT PARSELINKS.
- Parent can be a parent window, default is set in TT function, see above.
To enable ToolTip for Static controls like Text and Picture add 0x100 to Controls options.
; ToolTip.Remove() - Removes a ToolTip object and all control associations. Call TT_Remove() to remove all ToolTips (will be called automatically when scripts exits).
; ToolTip.Del() - ToolTip.Del(Control)
Delete a ToolTip associated with a control only, other ToolTips will remain.
; ToolTip.Show() - ToolTip.Show([Text,x,y,title,icon,iconIdx])
Show a ToolTip. x and y can be TrayIcon to show ToolTip at TrayIcon coordinates of your app.
; ToolTip.Hide() - Hides a ToolTip. Same as ToolTip.TrackPosition(0).
Note NoFade only disables fade in, to have no fade out use ToolTip.Text("")!
; ToolTip.Color() - ToolTip.Color(textcolor,backgroundcolor)
Used to set both colors and string colors like White,Black,Yellow,Red,Blue.... You can also use wrapped message straight away: TTObj.SETTIPBKCOLOR(RGBValue) and ToolTip.SETTIPTEXTCOLOR(RGBValue)
; ToolTip.Font() - ToolTip.Font(Font)
Change Font of ToolTip. Example ToolTip.Font("S20 bold italic striceout underline, Arial")
; ToolTip.Text() - ToolTip.Text(text)
Update text for main ToolTip (created when TT() is called).
; ToolTip.Title() - ToolTip.Title([title,icon,iconIdx])
Update title and icon for ToolTip. Icon can be 0 - 3 or a hIcon or a file path and iconIdx if it is an exe,dll or cur file.
IconIdx must be an empty string ("") if you want to load an icon from jpg, png, bmp, gif or other supported files by gdi as well as from HEX string.
Otherwise associated icon for given file type will be loaded.
; ToolTip.Icon() - ToolTip.Icon([icon,iconIdx])
Update only icon for ToolTip. Icon can be a file path, see title function. TT_GetIcon can be used to get a hIcon. "" for iconIdx will load the image as icon from jpg, bmp ... file.
Since the Icon is in the title, it will appear only if there is a title.
; Return Value:
; TT returns a ToolTip object that can be used to perform all action on a ToolTip.
; Remarks:
; When no Parent is given when calling TT(), Gui +LastFound will be used, when first parameter of TT(0x283475) is digit or xdigit, it will be used as parent.
Options TRACK and NOPREFIX are forced by default, to disable use TRACK=0 NOPREFIX=0.
; Related:
; Example:
; file:TT_Example.ahk
;
;~ #Include
TT_Init(){ ;initialize structures function
global _TOOLINFO:="cbSize,uFlags,PTR hwnd,PTR uId,_RECT rect,PTR hinst,LPTSTR lpszText,PTR lParam,void *lpReserved"
,_RECT:="left,top,right,bottom"
,_NMTVGETINFOTIP:="HWND hwndFrom,UINT_PTR idFrom,UINT code,UINT uFlags,UInt link"
,_CURSORINFO:="cbSize,flags,HCURSOR hCursor,x,y"
,_ICONINFO:="fIcon,xHotspot,yHotSpot,HBITMAP hbmMask,HBITMAP hbmColor"
,_BITMAP:="LONG bmType,LONG bmWidth,LONG bmHeight,LONG bmWidthBytes,WORD bmPlanes,WORD bmBitsPixel,LPVOID bmBits"
,_SHFILEINFO:="HICON hIcon,iIcon,DWORD dwAttributes,TCHAR szDisplayName[260],TCHAR szTypeName[80]"
,_TBBUTTON:="iBitmap,idCommand,BYTE fsState,BYTE fsStyle,BYTE bReserved[" (A_PtrSize=8?6:2) "],DWORD_PTR dwData,INT_PTR iString"
,_RECT:="left,top,right,bottom"
}
TT(options="",text="",title=""){
global _RECT,_TOOLINFO
static temp:=TT_Init()
; Options
;WS_POPUP=0x80000000,TTS_ALWAYSTIP=0x1,TTS_NOPREFIX=0x2,TTS_USEVISUALSTYLE=0x100,TTS_NOFADE=0x20,TTS_NOANIMATE=0x10
static HWND_TOPMOST:=-1,SWP_NOMOVE=0x2, SWP_NOSIZE=0x1, SWP_NOACTIVATE=0x10
; Objects
static @:={},base:={Color:"TT_Color",Show:"TT_Show",Hide:"TTM_Trackactivate",Close:"TT_Close",Add:"TT_Add",AddTool:"TTM_AddTool"
,Del:"TT_Del",Title:"TTM_SetTitle",Text:"TT_Text",ACTIVATE:"TTM_ACTIVATE",Set:"TT_Set"
,ADDTOOL:"TTM_ADDTOOL",Remove:"TT_Remove",Icon:"TT_Icon",Font:"TT_Font",ADJUSTRECT:"TTM_ADJUSTRECT"
,DELTOOL:"TTM_DELTOOL",ENUMTOOLS:"TTM_ENUMTOOLS",GETBUBBLESIZE:"TTM_GETBUBBLESIZE"
,GETCURRENTTOOL:"TTM_GETCURRENTTOOL",GETDELAYTIME:"TTM_GETDELAYTIME",GETMARGIN:"TTM_GETMARGIN"
,GETMAXTIPWIDTH:"TTM_GETMAXTIPWIDTH",GETTEXT:"TTM_GETTEXT",GETTIPBKCOLOR:"TTM_GETTIPBKCOLOR"
,GETTIPTEXTCOLOR:"TTM_GETTIPTEXTCOLOR",GETTITLE:"TTM_GETTITLE",GETTOOLCOUNT:"TTM_GETTOOLCOUNT"
,GETTOOLINFO:"TTM_GETTOOLINFO",HITTEST:"TTM_HITTEST",NEWTOOLRECT:"TTM_NEWTOOLRECT",POP:"TTM_POP"
,POPUP:"TTM_POPUP",RELAYEVENT:"TTM_RELAYEVENT",SETDELAYTIME:"TTM_SETDELAYTIME",SETMARGIN:"TTM_SETMARGIN"
,SETMAXTIPWIDTH:"TTM_SETMAXTIPWIDTH",SETTIPBKCOLOR:"TTM_SETTIPBKCOLOR",SETTIPTEXTCOLOR:"TTM_SETTIPTEXTCOLOR"
,SETTITLE:"TTM_SETTITLE",SETTOOLINFO:"TTM_SETTOOLINFO",SETWINDOWTHEME:"TTM_SETWINDOWTHEME"
,TRACKACTIVATE:"TTM_TRACKACTIVATE",TRACKPOSITION:"TTM_TRACKPOSITION",UPDATE:"TTM_UPDATE"
,UPDATETIPTEXT:"TTM_UPDATETIPTEXT",WINDOWFROMPOINT:"TTM_WINDOWFROMPOINT"
,__Delete:"__Delete",_Insert:"_Insert",_Remove:"_Remove",_GetCapacity:"_GetCapacity",_SetCapacity:"_SetCapacity"
,_GetAddress:"_GetAddress",_MaxIndex:"_MaxIndex",_MinIndex:"_MinIndex",_NewEnum:"_NewEnum",_HasKey:"_HasKey"
,_Clone:"_Clone",Insert:"Insert",GetCapacity:"GetCapacity",SetCapacity:"SetCapacity"
,GetAddress:"GetAddress",MaxIndex:"MaxIndex",MinIndex:"MinIndex",NewEnum:"NewEnum",HasKey:"HasKey",Clone:"Clone"
,"base":{__Call:"TT_Set",__Delete:"TT_Delete"}}
Parent:="",Gui:="",ClickTrough:="",Style:="",NOFADE:="",NoAnimate:="",NOPREFIX:="",AlwaysTip:="",ParseLinks:="",CloseButton:="",Balloon:="",maxwidth:=""
,INITIAL:="",AUTOPOP:="",RESHOW:="",OnClick:="",OnClose:="",OnShow:="",ClickHide:="",HWND:="",Center:="",RTL:="",SUB:="",Track:="",Absolute:=""
,TRANSPARENT:="",Color:="",Background:="",icon:=""
If (options=-0x8000000000000000)
Return @
else if options is xdigit
Parent:=options
else If (options){
Loop,Parse,options,%A_Space%,%A_Space%
If istext {
If (SubStr(A_LoopField,0)="'")
%istext%:=string A_Space SubStr(A_LoopField,1,StrLen(A_LoopField)-1),istext:="",string:=""
else
string.= A_Space A_LoopField
} else If A_LoopField contains AUTOPOP,INITIAL,PARENT,RESHOW,MAXWIDTH,ICON,Color,BackGround,OnClose,OnClick,OnShow,GUI,NOPREFIX,TRACK
{
RegExMatch(A_LoopField,"^(\w+)=?(.*)?$",option)
If ((Asc(option2)=39 && SubStr(A_LoopField,0)!="'") && (istext:=option1) && (string:=SubStr(option2,2)))
Continue
%option1%:=option2
} else if A_LoopField
%A_LoopField% := 1
}
If (Parent && Parent<100 && !DllCall("IsWindow","PTR",Parent)){
Gui,%Parent%:+LastFound
Parent:=WinExist()
} else if (GUI){
Gui, %GUI%:+LastFound
Parent:=WinExist()
} else if (Parent=""){
Parent:=A_ScriptHwnd
}
T:=Object("base",base)
T.HWND := DllCall("CreateWindowEx", "UInt", (ClickTrough?0x20:0)|0x8, "str", "tooltips_class32", "PTR", 0
, "UInt",0x80000000|(Style?0x100:0)|(NOFADE?0x20:0)|(NoAnimate?0x10:0)|((NOPREFIX+1)?(NOPREFIX?0x2:0x2):0x2)|(AlwaysTip?0x1:0)|(ParseLinks?0x1000:0)|(CloseButton?0x80:0)|(Balloon?0x40:0)
, "int",0x80000000,"int",0x80000000,"int",0x80000000,"int",0x80000000, "PTR",Parent?Parent:0,"PTR",0,"PTR",0,"PTR",0,"PTR")
DllCall("SetWindowPos","PTR",T.HWND,"PTR",HWND_TOPMOST,"Int",0,"Int",0,"Int",0,"Int",0
,"UInt",SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE)
@.Insert(T)
T.SETMAXTIPWIDTH(MAXWIDTH?MAXWIDTH:A_ScreenWidth)
If !(AUTOPOP INITIAL RESHOW)
T.SETDELAYTIME()
else T.SETDELAYTIME(AUTOPOP?AUTOPOP*1000:-1),T.SETDELAYTIME(INITIAL?INITIAL*1000:-1),T.SETDELAYTIME(RESHOW?RESHOW*1000:-1)
T.fulltext:=text,T.maintext:=RegExReplace(text,"",">")
If ((T.OnClick:=OnClick)||(T.OnClose:=OnClose)||(T.OnShow:=OnShow)),T.OnClose:=OnClose,T.OnShow:=OnShow,T.ClickHide:=ClickHide
OnMessage(0x4e,"TT_OnMessage")
If OnClick
ParseLinks:=1
T.rc:=Struct(_RECT) ;for TTM_SetMargin
;Tool for Main ToolTip
T.P:=Struct(_TOOLINFO),P:=T.P,P.cbSize:=sizeof(_TOOLINFO)
P.uFlags:=(HWND?0x1:0)|(Center?0x2:0)|(RTL?0x4:0)|(SUB?0x10:0)|(Track+1?(Track?0x20:0):0x20)|(Absolute?0x80:0)|(TRANSPARENT?0x100:0)|(ParseLinks?0x1000:0)
P.hwnd:=Parent,P.uId:=Parent,P.lpszText[""]:=T.GetAddress("maintext")?T.GetAddress("maintext"):"",T.AddTool(P[])
If Color
T.SETTIPTEXTCOLOR(Color)
If Background
T.SETTIPBKCOLOR(BackGround)
T.SetTitle(T.maintitle:=title,icon)
; Sleep,100
Return T
}
TT_Delete(t=""){ ;delete all ToolTips (will be executed OnExit)
TT_Remove(),TT_GetIcon() ;delete ToolTips and Destroy all icon handles
}
TT_Remove(T=""){
static @:=TT(-0x8000000000000000) ;Get main object that holds all ToolTips
If !T
Loop % @.MaxIndex()
{
T:=@[A_Index]
@.Remove(A_Index)
for id,tool in T.T
T.DelTool(tool[])
T.DelTool(T.P[])
DllCall("DestroyWindow","PTR",T.HWND)
}
else
for id,Tool in @
{
If (T=Tool){
@[id]:=@[@.MaxIndex()],@.Remove(id)
for id,tools in Tool.T
Tool.DelTool(tools[])
Tool.DelTool(Tool.P[])
DllCall("DestroyWindow","PTR",Tool.HWND)
break
}
}
}
TT_OnMessage(wParam,lParam,msg,hwnd){
global _NMTVGETINFOTIP
static TTN_FIRST:=0xfffffdf8, @:=TT(-0x8000000000000000) ;Get main object that holds all ToolTips
,HDR:=Struct(_NMTVGETINFOTIP)
HDR[]:=lParam
If !InStr(".1.2.3.","." (m:= TTN_FIRST-HDR.code) ".")
Return
p:=HDR.hwndFrom
for id,T in @
{
If (p=T.hwnd)
break
}
text:=T.fulltext
If (m=1){ ;Show
If IsFunc(T.OnShow)
T.OnShow(T)
} else If (m=2){ ;Close
If IsFunc(T.OnClose)
T.OnClose(T)
T.TRACKACTIVATE(0,T.P[])
} else If InStr(text,"")
action:=SubStr(text,InStr(text,">")+1,InStr(text,"")-InStr(text,">")-1)
else action:=Trim(action:=SubStr(text,1,InStr(text,">")-1))
If IsFunc(T.OnClick)
T.OnClick(T,action)
}
Return true
}
TT_ADD(T,Control,Text="",uFlags="",Parent=""){
; uFlags http://msdn.microsoft.com/en-us/library/bb760256.aspx
; TTF_ABSOLUTE=0x80, TTF_CENTERTIP=0x0002, TTF_IDISHWND=0x1, TTF_PARSELINKS=0x1000 ,TTF_RTLREADING = 0x4
; TTF_SUBCLASS=0x10, TTF_TRAMsgCK=0x20, TTF_TRANSPARENT=0x100
global _TOOLINFO
DetectHiddenWindows:=A_DetectHiddenWindows
DetectHiddenWindows,On
if (Parent){
If (Parent && Parent<100 and !DllCall("IsWindow","PTR",Parent)){
Gui %Parent%:+LastFound
Parent:=WinExist()
}
T["T",Abs(Parent)]:=Struct(_TOOLINFO),Tool:=T["T",Abs(Parent)]
Tool.uId:=Parent,Tool.hwnd:=Parent,Tool.uFlags:=(0|16)
DllCall("GetClientRect","PTR",T.HWND,"PTR", T[Abs(Parent)].rect[])
T.ADDTOOL(T["T",Abs(Parent)][])
}
If text=
ControlGetText,text,%Control%,% "ahk_id " (Parent?Parent:T.P.hwnd)
If Control is not Xdigit
If Control is not digit
ControlGet,Control,Hwnd,,%Control%,% "ahk_id " (Parent?Parent:T.P.hwnd)
If uFlags
If uFlags is not digit
{
Loop,Parse,uflags,%A_Space%,%A_Space%
If A_LoopField
%A_LoopField% := 1
uFlags:=(HWND?0x1:HWND=""?0x1:0)|(Center?0x2:0)|(RTL?0x4:0)|(SUB?0x10:0)|(Track?0x20:0)|(Absolute?0x80:0)|(TRANSPARENT?0x100:0)|(ParseLinks?0x1000:0)
}
T["T",Abs(Control)]:=Tool:=Struct(_TOOLINFO)
Tool.cbSize:=sizeof(_TOOLINFO)
T[Abs(Control),"text"]:=RegExReplace(text,"",">")
Tool.uId:=Control,Tool.hwnd:=Parent?Parent:T.P.hwnd,Tool.uFlags:=uFlags?(uFlags|16):(1|16)
Tool.lpszText[""]:=T[Abs(Control)].GetAddress("text")
DllCall("GetClientRect","PTR",T.HWND,"PTR",Tool.rect[])
T.ADDTOOL(Tool[])
DetectHiddenWindows,%DetectHiddenWindows%
}
TT_DEL(T,Control){
If !Control
Return 0
If Control is not Xdigit
If Control is not digit
ControlGet,Control,Hwnd,,%Control%,% "ahk_id " t.P.hwnd
T.DELTOOL(T.T[Abs(Control)][]),T.T.Remove(Abs(Control))
}
TT_Color(T,Color="",Background=""){
static TTM_SETTIPBKCOLOR=0x413,TTM_SETTIPTEXTCOLOR=0x414
,Black=0x000000,Green=0x008000,Silver=0xC0C0C0,Lime=0x00FF00,Gray=0x808080,Olive=0x808000
,White=0xFFFFFF,Yellow=0xFFFF00,Maroon=0x800000,Navy=0x000080,Red=0xFF0000,Blue=0x0000FF
,Purple=0x800080,Teal=0x008080,Fuchsia=0xFF00FF,Aqua=0x00FFFF
If (Color!="")
T.SETTIPTEXTCOLOR(Color)
If (BackGround!="")
T.SETTIPBKCOLOR(BackGround)
}
TT_Text(T,text){
static TTM_UPDATETIPTEXT=0x400+(A_IsUnicode?57:12),TTM_UPDATE=0x400+29
T.fulltext:=text,T.maintext:=RegExReplace(text,"",">"),T.P.lpszText[""]:=text?T.GetAddress("maintext"):0
T.UPDATETIPTEXT()
}
TT_Icon(T,icon=0,icon#=1){
static TTM_SETTITLE = 0x400 + (A_IsUnicode ? 33 : 32)
If icon
If icon is not digit
icon:=TT_GetIcon(icon,icon#)
Return DllCall("SendMessage","PTR",T.HWND,"UInt",TTM_SETTITLE,"PTR",icon,"PTR",T.GetAddress("maintitle"),"PTR"),T.UPDATE()
}
TT_GetIcon(File="",Icon#=1){
global _ICONINFO,_SHFILEINFO
static hIcon:=Object(),AW:=A_IsUnicode?"W":"A",sfi:="",pToken:=0
,temp1:=DllCall( "LoadLibrary", "Str","gdiplus","PTR"),temp2:=VarSetCapacity(si, 16, 0) (si := Chr(1))
If !sfi {
sfi:=Struct(_SHFILEINFO),sfi_size:=sizeof(_SHFILEINFO)
SysGet, SmallIconSize, 49
DllCall("gdiplus\GdiplusStartup", "PTR*",pToken, "PTR",&si, "PTR",0)
}
If !File {
for file,obj in hIcon
If IsObject(obj){
for icon,handle in obj
DllCall("DestroyIcon","PTR",handle)
} else
DllCall("DestroyIcon","PTR",handle)
DllCall("gdiplus\GdiplusShutdown", "PTR",pToken),sfi:=""
Return
}
If (SubStr(file,-3)=".lnk")
{
FileGetShortcut,%File%,Fileto,,,,FileIcon,FileIcon#
File :=FileIcon ?FileIcon :Fileto
Icon#:=FileIcon#?FileIcon#:Icon#
}
If hIcon[File,Icon#]
Return hIcon[file,Icon#]
else if (hIcon[File] && !IsObject(hIcon[File]))
return hIcon[File]
SplitPath, File,,, Ext
if (hIcon[Ext] && !IsObject(hIcon[Ext]))
return hIcon[Ext]
If (ext="cur")
{
Return hIcon[file,Icon#]:=DllCall("LoadImage", "PTR", 0, "str", File, "uint", ext="cur"?2:1, "int", 0, "int", 0, "uint", 0x10,"PTR")
} else if InStr(",EXE,ICO,DLL,LNK,","," Ext ",")
{
DllCall("PrivateExtractIcons", "Str", File, "Int", Icon#-1, "Int", SmallIconSize, "Int", SmallIconSize, "PTR*", Icon, "PTR*", 0, "UInt", 1, "UInt", 0, "Int")
Return hIcon[File,Icon#]:=Icon
} else if (Icon#=""){
If !FileExist(File){
if File is xdigit ;assume Hex string
{
nSize := StrLen(File)//2
VarSetCapacity( Buffer,nSize )
Loop % nSize
NumPut( "0x" . SubStr(File,2*A_Index-1,2), Buffer, A_Index-1, "Char" )
} else Return
} else {
FileGetSize,nSize,%file%
FileRead,Buffer,*c %file%
}
hData := DllCall("GlobalAlloc", "UInt",2, "UInt", nSize,"PTR")
,pData := DllCall("GlobalLock", "PTR",hData,"PTR")
,DllCall( "RtlMoveMemory", "PTR",pData, "PTR",&Buffer, "UInt",nSize )
,DllCall( "GlobalUnlock", "PTR",hData )
,DllCall( "ole32\CreateStreamOnHGlobal", "PTR",hData, "Int",True, "PTR*",pStream )
,DllCall( "gdiplus\GdipCreateBitmapFromStream", "UInt",pStream, "PTR*",pBitmap )
,DllCall( "gdiplus\GdipCreateHBITMAPFromBitmap", "PTR",pBitmap, "PTR*",hBitmap, "UInt",0 )
,DllCall( "gdiplus\GdipDisposeImage", "PTR",pBitmap )
,ii:=Struct(_ICONINFO)
,ii.ficon:=1,ii.hbmMask:=hBitmap,ii.hbmColor:=hBitmap
return hIcon[File]:=DllCall("CreateIconIndirect","PTR",ii[],"PTR")
} else If DllCall("Shell32\SHGetFileInfo" AW, "str", File, "uint", 0, "PTR", sfi[], "uint", sfi_size, "uint", 0x101,"PTR")
Return hIcon[Ext] := sfi.hIcon
}
TT_Close(T){
T.text("")
}
TT_Show(T,text="",x="",y="",title="",icon="",icon#=1){
global _TBBUTTON,_BITMAP,_ICONINFO,_CURSORINFO,_RECT
static pcursor:= Struct(_CURSORINFO),init:=(pcursor.cbSize:=sizeof(_CURSORINFO))
,picon:=Struct(_ICONINFO) ,pbitmap:=Struct(_BITMAP)
,TB:=Struct(_TBBUTTON) ,RC:=Struct(_RECT)
xo:="",xs:="",yo:="",ys:=""
If Text!=
T.Text(text)
If (title!="")
T.SETTITLE(title,icon,icon#)
If (x="TrayIcon" || y="TrayIcon"){
DetectHiddenWindows,% (DetectHiddenWindows:=A_DetectHiddenWindows ? "On" : "On")
Process, Exist
PID:=ErrorLevel
hWndTray:=WinExist("ahk_class Shell_TrayWnd")
ControlGet,hWndToolBar,Hwnd,,ToolbarWindow321,ahk_id %hWndTray%
WinGet, procpid, PID,ahk_id %hWndToolBar%
DataH := DllCall( "OpenProcess", "uint", 0x38, "int", 0, "uint", procpid,"PTR") ;0x38 = PROCESS_VM_OPERATION+READ+WRITE
bufAdr := DllCall( "VirtualAllocEx", "PTR", DataH, "PTR", 0, "uint", sizeof(TB), "uint", MEM_COMMIT:=0x1000, "uint", PAGE_READWRITE:=0x4,"PTR")
max:=DllCall("SendMessage","PTR",hWndToolBar,"UInt",0x418,"PTR",0,"PTR",0,"PTR")
Loop % max
{
i:=max-A_Index
DllCall("SendMessage","PTR",hWndToolBar,"UInt",0x417,"PTR",i,"PTR",bufAdr,"PTR")
DllCall("ReadProcessMemory", "PTR", DataH, "PTR", bufAdr, "PTR", TB[""], "ptr", sizeof(TB), "ptr", 0)
DllCall("ReadProcessMemory", "PTR", DataH, "PTR", TB.dwData, "PTR", RC[""], "PTR", 8, "PTR", 0)
WinGet,BWPID,PID,% "ahk_id " NumGet(RC[""],0,"PTR")
If (BWPID!=PID)
continue
If (TB.fsState>7){
ControlGetPos,xc,yc,xw,yw,Button2,ahk_id %hWndTray%
xc+=xw/2, yc+=yw/4
} else {
DllCall("SendMessage","PTR",hWndToolBar,"UInt",0x41d,"PTR",i,"PTR",bufAdr,"PTR")
DllCall( "ReadProcessMemory", "PTR", DataH, "PTR", bufAdr, "PTR", RC[""], "PTR", sizeof(RC), "PTR", 0 )
ControlGetPos,xc,yc,,,ToolbarWindow321,ahk_id %hWndTray%
halfsize:=RC.bottom/2
xc+=RC.left + halfsize
yc+=RC.top + (halfsize/1.5)
}
WinGetPos,xw,yw,,,ahk_id %hWndTray%
xc+=xw,yc+=yw
break
}
If (!xc && !yc){
If A_OsVersion in Win_7,WIN_VISTA
ControlGetPos,xc,yc,xw,yw,Button1,ahk_id %hWndTray%
else
ControlGetPos,xc,yc,xw,yw,Button2,ahk_id %hWndTray%
xc+=xw/2, yc+=yw/4
WinGetPos,xw,yw,,,ahk_id %hWndTray%
xc+=xw,yc+=yw
}
DllCall( "VirtualFreeEx", "PTR", DataH, "PTR", bufAdr, "PTR", 0, "uint", MEM_RELEASE:=0x8000)
DllCall( "CloseHandle", "PTR", DataH )
DetectHiddenWindows % DetectHiddenWindows
If x=TrayIcon
x:=xc
If y=TrayIcon
y:=yc
}
If (x ""="" || y ""=""){
pCursor.cbSize:=sizeof(pCursor)
DllCall("GetCursorInfo", "ptr", pCursor[""])
DllCall("GetIconInfo", "ptr", pCursor.hCursor, "ptr", pIcon[""])
If picon.hbmColor
DllCall("DeleteObject", "ptr", pIcon.hbmColor)
DllCall("GetObject", "ptr", pIcon.hbmMask, "uint", sizeof(_BITMAP), "ptr", pBitmap[""])
hbmo := DllCall("SelectObject", "ptr", cdc:=DllCall("CreateCompatibleDC", "ptr", sdc:=DllCall("GetDC","ptr"),"ptr"), "ptr", pIcon.hbmMask)
w:=pBitmap.bmWidth,h:=pBitmap.bmHeight, h:= h=w*2 ? (h//2,c:=0xffffff,s:=32) : (h,c:=s:=0)
Loop % w {
xi := A_Index - 1
Loop % h {
yi := A_Index - 1 + s
if (DllCall("GetPixel", "ptr", cdc, "uint", xi, "uint", yi) = c) {
if (xo < xi)
xo := xi
if (xs = "" || xs > xi)
xs := xi
if (yo < yi)
yo := yi
if (ys = "" || ys > yi)
ys := yi
}
}
}
DllCall("ReleaseDC", "ptr", 0, "ptr", sdc)
DllCall("DeleteDC", "ptr", cdc)
DllCall("DeleteObject", "ptr", hbmo)
DllCall("DeleteObject", "ptr", picon.hbmMask)
If (y ""=""){
SysGet,yl,77
SysGet,yr,79
y:=pCursor.y-pIcon.yHotspot+ys+(yo-ys)-s+1
If y not between %yl% and %yr%
y:=y yr - 20)
y := yr - 20
}
If (x ""=""){
SysGet,xr,78
SysGet,xl,76
x:=pCursor.x-pIcon.xHotspot+xs+(xo-xs)+1
If x not between %xl% and %xr%
x:=x>8)&255)<<8)+(Color>>16) ; rgb -> bgr
Return DllCall("SendMessage","PTR",T.HWND,"UInt",TTM_SETTIPBKCOLOR,"PTR",color,"PTR",0,"PTR")
}
TTM_SETTIPTEXTCOLOR(T,color=0){
static TTM_SETTIPTEXTCOLOR = 0x414
,Black:=0x000000, Green:=0x008000, Silver:=0xC0C0C0, Lime:=0x00FF00
,Gray:=0x808080, Olive:=0x808000, White:=0xFFFFFF, Yellow:=0xFFFF00
,Maroon:=0x800000, Navy:=0x000080, Red:=0xFF0000, Blue:=0x0000FF
,Purple:=0x800080, Teal:=0x008080, Fuchsia:=0xFF00FF, Aqua:=0x00FFFF
If color is alpha
If (%color%)
Color:=%color%
Color := (StrLen(Color) < 8 ? "0x" : "") . Color
Color := ((Color&255)<<16)+(((Color>>8)&255)<<8)+(Color>>16) ; rgb -> bgr
Return DllCall("SendMessage","PTR",T.HWND,"UInt",TTM_SETTIPTEXTCOLOR,"PTR",color,"PTR",0,"PTR")
}
TTM_SETTITLE(T,title="",icon="",Icon#=1){
static TTM_SETTITLE = 0x400 + (A_IsUnicode ? 33 : 32)
If icon
If icon is not digit
icon:=TT_GetIcon(icon,Icon#)
T.maintitle := (StrLen(title) < 96) ? title : (Chr(A_IsUnicode ? 8230 : 133) SubStr(title, -97))
If Icon!=
lastIcon:=Icon
Return DllCall("SendMessage","PTR",T.HWND,"UInt",TTM_SETTITLE,"PTR",icon,"PTR",T.GetAddress("maintitle"),"PTR"),T.UPDATE(),lastIcon:=Icon
}
TTM_SETTOOLINFO(T,pTOOLINFO=0){
static TTM_SETTOOLINFO = A_IsUnicode?0x436:0x409
Return DllCall("SendMessage","PTR",T.HWND,"UInt",TTM_SETTOOLINFO,"PTR",0,"PTR",pTOOLINFO?pTOOLINFO:T.P[""],"PTR")
}
TTM_SETWINDOWTHEME(T,theme=""){
Return DllCall("SendMessage","PTR",T.HWND,"UInt",0x200b,"PTR",0,"PTR",&theme,"PTR")
}
TTM_TRACKACTIVATE(T,activate=0,pTOOLINFO=0){
Return DllCall("SendMessage","PTR",T.HWND,"UInt",0x411,"PTR",activate,"PTR",(pTOOLINFO)?(pTOOLINFO):(T.P[""]),"PTR")
}
TTM_TRACKPOSITION(T,x=0,y=0){
Return DllCall("SendMessage","PTR",T.HWND,"UInt",0x412,"PTR",0,"PTR",(x & 0xFFFF)|(y & 0xFFFF)<<16,"PTR")
}
TTM_UPDATE(T){
Return DllCall("SendMessage","PTR",T.HWND,"UInt",0x41D,"PTR",0,"PTR",0,"PTR")
}
TTM_UPDATETIPTEXT(T,pTOOLINFO=0){
static TTM_UPDATETIPTEXT = A_IsUnicode?0x439:0x40c
Return DllCall("SendMessage","PTR",T.HWND,"UInt",TTM_UPDATETIPTEXT,"PTR",0,"PTR",pTOOLINFO?pTOOLINFO:T.P[""],"PTR")
}
TTM_WINDOWFROMPOINT(T,pPOINT){
Return DllCall("SendMessage","PTR",T.HWND,"UInt",0x410,"PTR",0,"PTR",pPOINT,"PTR")
}