/* ########################################################################### # (@)PACKAGE:Win32::GUI::Tooltip # # $Id: Tooltip.xs,v 1.9 2006/08/30 21:57:58 robertemay Exp $ # ########################################################################### */ #include "GUI.h" void Tooltip_onPreCreate(NOTXSPROC LPPERLWIN32GUI_CREATESTRUCT perlcs) { perlcs->cs.lpszClass = TOOLTIPS_CLASS; perlcs->cs.style = TTS_ALWAYSTIP; perlcs->cs.dwExStyle = WS_EX_TOPMOST; } BOOL Tooltip_onParseOption(NOTXSPROC char *option, SV* value, LPPERLWIN32GUI_CREATESTRUCT perlcs) { BOOL retval = TRUE; if BitmaskOptionValue("-alwaystip", perlcs->cs.style, TTS_ALWAYSTIP) } else if BitmaskOptionValue("-noprefix", perlcs->cs.style, TTS_NOPREFIX ) } else if BitmaskOptionValue("-noanimate", perlcs->cs.style, TTS_NOANIMATE ) } else if BitmaskOptionValue("-noface", perlcs->cs.style, TTS_NOFADE ) } else if BitmaskOptionValue("-balloon", perlcs->cs.style, TTS_BALLOON ) } else retval= FALSE; return retval; } void Tooltip_onPostCreate(NOTXSPROC HWND myhandle, LPPERLWIN32GUI_CREATESTRUCT perlcs) { if(perlcs->clrForeground != CLR_INVALID) { SendMessage(myhandle, TTM_SETTIPTEXTCOLOR, (WPARAM) perlcs->clrForeground, (LPARAM) 0); perlcs->clrForeground = CLR_INVALID; // Don't Store } if(perlcs->clrBackground != CLR_INVALID) { SendMessage(myhandle, TTM_SETTIPBKCOLOR, (WPARAM) perlcs->clrBackground, (LPARAM) 0); perlcs->clrBackground = CLR_INVALID; // Don't Store } } BOOL Tooltip_onParseEvent(NOTXSPROC char *name, int* eventID) { BOOL retval = TRUE; if Parse_Event("NeedText", PERLWIN32GUI_NEM_CONTROL1) else if Parse_Event("Pop", PERLWIN32GUI_NEM_CONTROL2) else if Parse_Event("Show", PERLWIN32GUI_NEM_CONTROL3) else retval = FALSE; return retval; } int Tooltip_onEvent (NOTXSPROC LPPERLWIN32GUI_USERDATA perlud, UINT uMsg, WPARAM wParam, LPARAM lParam) { int PerlResult = 1; if ( uMsg == WM_NOTIFY ) { LPNMHDR notify = (LPNMHDR) lParam; switch(notify->code) { case TTN_NEEDTEXT : /* * (@)EVENT:NeedText(TOOL,FLAG) * Sent when a tooltip window needs to get the text for a tool * created with C<< -needtext => 1 >>. * * TOOL is the identifier of the tool: it is the window handle * of the tool if FLAG is TRUE, otherwise it is the tool ID. * * Return a string from the event handler containing the text * to be displayed. * (@)APPLIES_TO:Tooltip */ { LPTOOLTIPTEXT lptt = (LPTOOLTIPTEXT) lParam; lptt->lpszText = (LPTSTR) DoEvent_NeedText(NOTXSCALL perlud, PERLWIN32GUI_NEM_CONTROL1, "NeedText", PERLWIN32GUI_ARGTYPE_LONG, (LONG)lptt->hdr.idFrom, PERLWIN32GUI_ARGTYPE_LONG, (LONG)(lptt->uFlags & TTF_IDISHWND ? 1 : 0), -1); PerlResult = 1; } break; case TTN_POP: /* * (@)EVENT:Pop(TOOL,FLAG) * Sent whenever a tooltip window has just been hidden * * TOOL is the identifier of the tool: it is the window handle * of the tool if FLAG is TRUE, otherwise it is the tool ID. * (@)APPLIES_TO:Tooltip */ PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_CONTROL2, "Pop", PERLWIN32GUI_ARGTYPE_LONG, (LONG) wParam, PERLWIN32GUI_ARGTYPE_LONG, (LONG)(IsWindow((HWND)wParam) ? 1 : 0), -1); break; case TTN_SHOW: /* * (@)EVENT:Show(TOOL,FLAG) * Sent whenever a tooltip window is just about to be displayed * * TOOL is the identifier of the tool: it is the window handle * of the tool if FLAG is TRUE, otherwise it is the tool ID. * (@)APPLIES_TO:Tooltip */ PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_CONTROL3, "Show", PERLWIN32GUI_ARGTYPE_LONG, (LONG) wParam, PERLWIN32GUI_ARGTYPE_LONG, (LONG)(IsWindow((HWND)wParam) ? 1 : 0), -1); break; } } return PerlResult; } /* Given an SV* that we expect to be a TOOL (see documentation) * populate the hwnd and uId members of the passed TOOLINFO * structure */ void ToolInfoFromTool(NOTXSPROC HWND handle, SV* tool, TOOLINFO *ti) { AV* array; I32 alen; SV** value; if(SvROK(tool) && SvTYPE(SvRV(tool)) == SVt_PVAV) { /* Tool is an array reference */ array = (AV*)SvRV(tool); alen = av_len(array); if(alen > -1) { value = av_fetch(array, 0, 0); if(value) { ti->hwnd = handle_From(NOTXSCALL *value); } else { CROAK("Problem with TOOL array reference, index 0"); } if(alen > 0) { value = av_fetch(array, 1, 0); if(value) { ti->uId = (UINT)SvIV(*value); } else { CROAK("Problem with TOOL array reference, index 1"); } } else { ti->uId = (UINT)ti->hwnd; } } else { CROAK("TOOL array refence is empty"); } } else { /* Tool is Window or ID */ /* This is broken, as there is nothing stopping IDs and window * handles clashing, but kept for * (1) backwards compatability * (2) allowing the most common simple case of WINDOW */ ti->uId = (UINT)handle_From(NOTXSCALL tool); if(IsWindow((HWND)ti->uId)) { ti->hwnd = (HWND)ti->uId; } else { ti->hwnd = (HWND)GetWindowLong(handle, GWL_HWNDPARENT); } } return; } MODULE = Win32::GUI::Tooltip PACKAGE = Win32::GUI::Tooltip PROTOTYPES: DISABLE #pragma message( "*** PACKAGE Win32::GUI::Tooltip..." ) ########################################################################### # (@)METHOD:Activate([FLAG=TRUE]) # Activates or deactivates a tooltip control. A deactivated tooltip does # not show it's window when the mouse hovers over a tool. LRESULT Activate(handle, value=TRUE) HWND handle WPARAM value CODE: RETVAL = SendMessage(handle, TTM_ACTIVATE, value, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:AddTool(@OPTIONS) # (@)METHOD:Add(@OPTIONS) # Registers a tool with a Tooltip. When the house hovers over a tool, the # tooltip window is displayed. A tool is identified either by a window # (handle) alone, or by a window (handle) and an application defined id. # If identified by a window (handle) alone, then the associated area for # the mouse to hover is the whole client area of the window, and adjusts # automatically if the window changes size. Otherwise the rect # is fixed, as provided by the C<-rect> options (in client co-ordinates of # the window it is associated with) and must be adjusted manually if # necessary - See NewToolRect(). # # B<@OPTIONS>: # -window => HANDLE (default: owner window of tooltip control) # Window object or window handle for the tool. # -id => ID # application set ID for the tool. # # -rect => [LEFT,TOP,RIGHT,BOTTOM] (defult: client rect of -window) # Area of the tool (ignored unless ID is provided) # -text => STRING or ID # String containd the Tool text, or a resource ID (see -hinst) # -hinst => HINSTANCE # If -text contains a resource ID, then -hinst gives the instance # handle from which the string resource is loaded. Ignored otherwise. # -needtext => 0/1 (default: 0) # Use NeedText Event. Don't mix this and -text. # # -flags => FLAGS # Set of TTF_ bit flags. Better set using these options: # -absolute => 0/1 (default: 0) # Use with -track. Position the window at the co_ordinates # set using the TrackPosition() method. # -centertip => 0/1 (default: 0) # Center the window below the tool. # -idishwnd => 0/1 (default: 0 if -id used, 1 otherwise) # indicates that the tool applies to the whole window. # -rtlreading => 0/1 (default: 0) # indicates that text will be rendered in the opposite direction # to text in the parent window # -subclass => 0/1 (default: 0 if -track is used, 1 otherwise) # the tooltip control will arrange to get mouse messages from the # winodw containing the tool automatically. If this option is not # set then the application must relay mouse messages itself. # -track => 0/1 (default: 0) # Positions the ToolTip window next to the tool to which it # corresponds and moves the window according to coordinates # supplied by the TrackPosition() method. You must activate # this type of tool using the TrackActivate() method. # -transparent => 0/1 (default: 0) # Causes the ToolTip control to forward mouse event messages to the # parent window. This is limited to mouse events that occur within # the bounds of the ToolTip window. # # Returns true on success, false on failure. BOOL AddTool(handle,...) HWND handle ALIAS: Win32::GUI::Tooltip::Add = 1 PREINIT: TOOLINFO ti; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ti.hwnd = (HWND) GetWindowLong(handle, GWL_HWNDPARENT); ParseTooltipOptions(NOTXSCALL sp, mark, ax, items, 1, &ti); RETVAL = SendMessage(handle, TTM_ADDTOOL, 0, (LPARAM) &ti); OUTPUT: RETVAL ########################################################################### # (@)METHOD:AdjustRect(LEFT, TOP, RIGHT, BOTTOM, [LARGER=1]) # Adjust either a wanted text rect to a window rect (if C) or # a window rect to a text rect (if C). # # C, C, C, C identify the corners to the rect to # convert. # # C identifies whether the provided rect is a text rect (to be made # larger) if true, or a window rect otherwise. # # Returns a 4-element list containing the adjusted left, top, right and # bottom co-ordinates of the window on success, or an empty list on failure. void Adjustrect(handle, left, top, right, bottom, larger=1) HWND handle LONG left LONG top LONG right LONG bottom BOOL larger PREINIT: RECT r; CODE: r.left = left; r.top = top; r.right = right; r.bottom = bottom; if(SendMessage(handle,TTM_ADJUSTRECT,(WPARAM)larger,(LPARAM)&r)) { EXTEND(SP, 4); XST_mIV(0, r.left); XST_mIV(1, r.top); XST_mIV(2, r.right); XST_mIV(3, r.bottom); XSRETURN(4); } XSRETURN_EMPTY; ########################################################################### # (@)METHOD:DelTool(TOOL) # (@)METHOD:Del(TOOL) # Removes a tool from a Tooltip. # # C identifies the tool to use to calculate the window size. # C may be one of the following: # # ID - only for backwards compatibility with Win32::GUI v1.03 # and earlier. A tool id identifying a tool that occupies # part of a window. The associated window defaults to the # owner window of the tooltip control, as for the default # for the -window option of the AddTool() method. # See AddTool(). # WINDOW - a window object or window handle, identifying a tool # that occupies the whole window. # [WINDOW] - an array reference containing a window object or window # handle, identifying a tool that occupies the whole # window. # [WINDOW, ID] - an array reference containing a window object or window # handle and a tool id, identifying a tool that occupies # part of a window. # # C and/or C are the values used for the C<-window> and/or <-id> # options used with the AddTool() method. See AddTool(). BOOL DelTool(handle,tool) HWND handle SV* tool ALIAS: Win32::GUI::Tooltip::Del = 1 PREINIT: TOOLINFO ti; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ToolInfoFromTool(NOTXSCALL handle, tool, &ti); RETVAL = SendMessage(handle, TTM_DELTOOL, 0, (LPARAM) &ti); OUTPUT: RETVAL ########################################################################### # (@)METHOD:EnumTools(ENUM_ID, [BUFSIZE=0]) # Retrieves the information for a tool in a tooltip control, identified by # an enumerated number C, starting at 0. # # Returns a list of options and values on success, or an empty list on # failure (if C > GetToolCount()-1). For details of the possible # options see AddTool(). # # B sets the size of the buffer for retrieving the text associated # with the tool. By default this is zero, and the text is not retrieved. # As there is no way to automatically determine the size of the buffer # required, this is a potential security hole, as the text may overrun # the size of the buffer provided. B. # # Example: # # my $tt = Win32::GUI::Tooltip->new( ... ); # .... # require Data::Dump; # my $i=0; # while(my %h = $tt->EnumTools($i)) { # print "TOOL:$i\n"; # print Data::Dump::dump(\%h), "\n"; # ++$i; # } # my $j = $tt->GetToolCount()-1; # # Or: # # for my $k (0 .. $j) { # my %h = $tt->EnumTools($k); # print "TOOL:$k\n"; # print Data::Dump::dump(\%h), "\n"; # } void EnumTools(handle, enum_id, bufsize=0) HWND handle HWND enum_id int bufsize PREINIT: TOOLINFO ti; int count = 0; LPSTR tip = NULL; AV* rect; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); if (bufsize > 0) { Newz(0, tip, bufsize, CHAR); ti.lpszText = tip; } if (SendMessage(handle, TTM_ENUMTOOLS, (WPARAM) enum_id, (LPARAM) &ti)) { if(tip) { /* ensure tip is NULL terminated, even if we overran the buffer * to minimise damage - of course it may already be too late */ tip[bufsize-1] = 0; } EXTEND(SP, 12); XST_mPV(count++, "-window"); if(ti.uFlags & TTF_IDISHWND) { XST_mIV(count++, (IV) ti.uId); } else { XST_mIV(count++, PTR2IV(ti.hwnd)); XST_mPV(count++, "-id"); XST_mIV(count++, ti.uId); XST_mPV(count++, "-rect"); rect = newAV(); av_push(rect,newSViv(ti.rect.left)); av_push(rect,newSViv(ti.rect.top)); av_push(rect,newSViv(ti.rect.right)); av_push(rect,newSViv(ti.rect.bottom)); ST(count++) = sv_2mortal(newRV_noinc((SV*)rect)); } if (ti.lpszText != NULL) { if (ti.lpszText == LPSTR_TEXTCALLBACK) { XST_mPV(count++, "-needtext"); XST_mIV(count++, 1); } else if (IS_INTRESOURCE(ti.lpszText)) { XST_mPV(count++, "-text"); XST_mIV(count++, PTR2IV(ti.lpszText)); XST_mPV(count++, "-hinst"); XST_mIV(count++, PTR2IV(ti.hinst)); } else { XST_mPV(count++, "-text"); XST_mPV(count++, ti.lpszText); } } XST_mPV(count++, "-flag"); /* TODO: Decode flags? */ XST_mIV(count++, ti.uFlags); } if(tip) Safefree(tip); XSRETURN(count); ########################################################################### # (@)METHOD:GetBubbleSize(TOOL) # Retrieves the width and height of a tooltip control for a given tool. # # C identifies the tool to use to calculate the window size. # C may be one of the following: # # ID - only for backwards compatibility with Win32::GUI v1.03 # and earlier. A tool id identifying a tool that occupies # part of a window. The associated window defaults to the # owner window of the tooltip control, as for the default # for the -window option of the AddTool() method. # See AddTool(). # WINDOW - a window object or window handle, identifying a tool # that occupies the whole window. # [WINDOW] - an array reference containing a window object or window # handle, identifying a tool that occupies the whole # window. # [WINDOW, ID] - an array reference containing a window object or window # handle and a tool id, identifying a tool that occupies # part of a window. # # C and/or C are the values used for the C<-window> and/or <-id> # options used with the AddTool() method. See AddTool(). # # Returns a 2-element list containing the width and height of the tooltip # window on success, or an empty list on failure. void GetBubbleSize(handle, tool) HWND handle SV* tool PREINIT: TOOLINFO ti; LRESULT r; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ToolInfoFromTool(NOTXSCALL handle, tool, &ti); if(SendMessage(handle,TTM_GETTOOLINFO,0,(LPARAM)&ti)) { if(r = SendMessage(handle,TTM_GETBUBBLESIZE,0,(LPARAM)&ti)) { /* TODO: why crash? */ EXTEND(SP, 2); XST_mIV(0, LOWORD(r)); /* width */ XST_mIV(1, HIWORD(r)); /* height */ XSRETURN(2); } } XSRETURN_EMPTY; ########################################################################### # (@)METHOD:GetCurrentTool([BUFSIZE=0]) # Retrieves the information for the current tool (the one being displayed) # in a tooltip control. # # Returns a list of options and values on success, or an empty list on # failure (if there is no current tool). For details of the possible # options see AddTool(). # # B sets the size of the buffer for retrieving the text associated # with the tool. By default this is zero, and the text is not retrieved. # As there is no way to automatically determine the size of the buffer # required, this is a potential security hole, as the text may overrun # the size of the buffer provided. B. void GetCurrentTool(handle, bufsize=0) HWND handle int bufsize PREINIT: TOOLINFO ti; int count = 0; LPSTR tip = NULL; AV* rect; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); if (bufsize > 0) { Newz(0, tip, bufsize, CHAR); ti.lpszText = tip; } if (SendMessage(handle, TTM_GETCURRENTTOOL, (WPARAM) 0, (LPARAM) &ti)) { if(tip) { /* ensure tip is NULL terminated, even if we overran the buffer * to minimise damage - of course it may already be too late */ tip[bufsize-1] = 0; } EXTEND(SP, 12); XST_mPV(count++, "-window"); if(ti.uFlags & TTF_IDISHWND) { XST_mIV(count++, (IV) ti.uId); } else { XST_mIV(count++, PTR2IV(ti.hwnd)); XST_mPV(count++, "-id"); XST_mIV(count++, ti.uId); XST_mPV(count++, "-rect"); rect = newAV(); av_push(rect,newSViv(ti.rect.left)); av_push(rect,newSViv(ti.rect.top)); av_push(rect,newSViv(ti.rect.right)); av_push(rect,newSViv(ti.rect.bottom)); ST(count++) = sv_2mortal(newRV_noinc((SV*)rect)); } if (ti.lpszText != NULL) { if (ti.lpszText == LPSTR_TEXTCALLBACK) { XST_mPV(count++, "-needtext"); XST_mIV(count++, 1); } else if (IS_INTRESOURCE(ti.lpszText)) { XST_mPV(count++, "-text"); XST_mIV(count++, PTR2IV(ti.lpszText)); XST_mPV(count++, "-hinst"); XST_mIV(count++, PTR2IV(ti.hinst)); } else { XST_mPV(count++, "-text"); XST_mPV(count++, ti.lpszText); } } XST_mPV(count++, "-flag"); /* TODO: Decode flags? */ XST_mIV(count++, ti.uFlags); } if(tip) Safefree(tip); XSRETURN(count); ########################################################################### # (@)METHOD:GetDelayTime([FLAG=TTDT_INITIAL]) # Retrieves the initial, pop-up, and reshow durations currently set for a # tooltip control. # # B : Which duration value to retrieve. # # TTDT_RESHOW = 1 : Length of time it takes for subsequent tooltip # windows to appear as the pointer moves from one # tool to another. # TTDT_AUTOPOP = 2 : Length of time the tooltip window remains visible # if the pointer is stationary within a tool's # bounding rectangle. # TTDT_INITIAL = 3 : Length of time the pointer must remain stationary # within a tool's bounding rectangle before the # tooltip window appears. # # Return value is the requested duration in milliseconds. LRESULT GetDelayTime(handle,flag=TTDT_INITIAL) HWND handle WPARAM flag CODE: RETVAL = SendMessage(handle, TTM_GETDELAYTIME, flag, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:GetMargin() # Retrieves the top, left, bottom, and right margins set for a tooltip # window. A margin is the distance, in pixels, between the tooltip window # border and the text contained within the tooltip window. # # Returns a 4-element list containing the left, top, right and bottom # marign values in pixels. void GetMargin(handle) HWND handle PREINIT: RECT rect; CODE: SendMessage(handle, TTM_GETMARGIN, 0, (LPARAM) &rect); EXTEND(SP, 4); XST_mIV(0, rect.left); XST_mIV(1, rect.top); XST_mIV(2, rect.right); XST_mIV(3, rect.bottom); XSRETURN(4); ########################################################################### # (@)METHOD:GetMaxTipWidth() # Retrieves the maximum width for a tooltip window. # # Returns the maximum width in pixels, or -1 if no maximum width has been # set. INT GetMaxTipWidth(handle) HWND handle CODE: RETVAL = (INT)SendMessage(handle, TTM_GETMAXTIPWIDTH, 0, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:GetText(TOOL, [BUFSIZE=0]) # Retrieves the text associated with a tool. # # C identifies the tool whose text is retrieved. # C may be one of the following: # # ID - only for backwards compatibility with Win32::GUI v1.03 # and earlier. A tool id identifying a tool that occupies # part of a window. The associated window defaults to the # owner window of the tooltip control, as for the default # for the -window option of the AddTool() method. # See AddTool(). # WINDOW - a window object or window handle, identifying a tool # that occupies the whole window. # [WINDOW] - an array reference containing a window object or window # handle, identifying a tool that occupies the whole # window. # [WINDOW, ID] - an array reference containing a window object or window # handle and a tool id, identifying a tool that occupies # part of a window. # # C and/or C are the values used for the C<-window> and/or <-id> # options used with the AddTool() method. See AddTool(). # # B sets the size of the buffer for retrieving the text associated # with the tool. By default this is zero, and the text is not retrieved. # As there is no way to automatically determine the size of the buffer # required, this is a potential security hole, as the text may overrun # the size of the buffer provided. B. # Returns the text associated with the tooltip (if any, and # C > 0), otherwise FALSE. void GetText(handle, tool, bufsize=0) HWND handle SV* tool int bufsize PREINIT: TOOLINFO ti; LPSTR tip = NULL; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ToolInfoFromTool(NOTXSCALL handle, tool, &ti); if (bufsize > 0) { Newz(0, tip, bufsize, CHAR); ti.lpszText = tip; } else { W32G_WARN("Calling GetText with a zero buffersize won't do anything useful"); } SendMessage(handle, TTM_GETTEXT, 0, (LPARAM) &ti); if(tip) { /* ensure tip is NULL terminated, even if we overran the buffer * to minimise damage - of course it may already be too late */ tip[bufsize-1] = 0; } EXTEND(SP, 1); if (ti.lpszText != NULL) { if (ti.lpszText == LPSTR_TEXTCALLBACK) { /* Don't get here: needtext is called and string returned */ } else if (IS_INTRESOURCE(ti.lpszText)) { /* TODO: handle resource id, if necessary */ W32G_WARN("Resource identifiers not handled - please report this"); } else { XST_mPV(0, ti.lpszText); } } else { XST_mNO(0); /* 0 in numeric context, empty string in string context */ } if(tip) Safefree(tip); XSRETURN(1); ########################################################################### # (@)METHOD:GetTipBkColor() # Retrieves the background color in a tooltip window. COLORREF GetTipBkColor(handle) HWND handle CODE: RETVAL = (COLORREF) SendMessage(handle, TTM_GETTIPBKCOLOR, 0, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:GetTipTextColor() # Retrieves the text color in a tooltip window. COLORREF GetTipTextColor(handle) HWND handle CODE: RETVAL = (COLORREF) SendMessage(handle, TTM_GETTIPTEXTCOLOR, 0, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:Count() # (@)METHOD:GetToolCount() # Returns the number of tools in the Tooltip. LRESULT GetToolCount(handle) HWND handle ALIAS: Win32::GUI::Tooltip::Count = 1 CODE: RETVAL = SendMessage(handle, TTM_GETTOOLCOUNT, 0, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:GetToolInfo(TOOL, [BUFSIZE=0]) # Retrieves the information that a tooltip control maintains about a tool. # # C identifies the tool whose info is retrieved. # C may be one of the following: # # ID - only for backwards compatibility with Win32::GUI v1.03 # and earlier. A tool id identifying a tool that occupies # part of a window. The associated window defaults to the # owner window of the tooltip control, as for the default # for the -window option of the AddTool() method. # See AddTool(). # WINDOW - a window object or window handle, identifying a tool # that occupies the whole window. # [WINDOW] - an array reference containing a window object or window # handle, identifying a tool that occupies the whole # window. # [WINDOW, ID] - an array reference containing a window object or window # handle and a tool id, identifying a tool that occupies # part of a window. # # C and/or C are the values used for the C<-window> and/or <-id> # options used with the AddTool() method. See AddTool(). # # B sets the size of the buffer for retrieving the text associated # with the tool. By default this is zero, and the text is not retrieved. # As there is no way to automatically determine the size of the buffer # required, this is a potential security hole, as the text may overrun # the size of the buffer provided. B. # # Returns a list of options and values on success, or an empty list on # failure. For details of the possible options see AddTool(). void GetToolInfo(handle,tool, bufsize=0) HWND handle SV* tool int bufsize PREINIT: TOOLINFO ti; int count = 0; LPSTR tip = NULL; AV* rect; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ToolInfoFromTool(NOTXSCALL handle, tool, &ti); if (bufsize > 0) { Newz(0, tip, bufsize, CHAR); ti.lpszText = tip; } if (SendMessage(handle, TTM_GETTOOLINFO, (WPARAM) 0, (LPARAM) &ti)) { if(tip) { /* ensure tip is NULL terminated, even if we overran the buffer * to minimise damage - of course it may already be too late */ tip[bufsize-1] = 0; } EXTEND(SP, 12); XST_mPV(count++, "-window"); if(ti.uFlags & TTF_IDISHWND) { XST_mIV(count++, (IV) ti.uId); } else { XST_mIV(count++, PTR2IV(ti.hwnd)); XST_mPV(count++, "-id"); XST_mIV(count++, ti.uId); XST_mPV(count++, "-rect"); rect = newAV(); av_push(rect,newSViv(ti.rect.left)); av_push(rect,newSViv(ti.rect.top)); av_push(rect,newSViv(ti.rect.right)); av_push(rect,newSViv(ti.rect.bottom)); ST(count++) = sv_2mortal(newRV_noinc((SV*)rect)); } if (ti.lpszText != NULL) { if (ti.lpszText == LPSTR_TEXTCALLBACK) { XST_mPV(count++, "-needtext"); XST_mIV(count++, 1); } else if (IS_INTRESOURCE(ti.lpszText)) { XST_mPV(count++, "-text"); XST_mIV(count++, PTR2IV(ti.lpszText)); XST_mPV(count++, "-hinst"); XST_mIV(count++, PTR2IV(ti.hinst)); } else { XST_mPV(count++, "-text"); XST_mPV(count++, ti.lpszText); } } XST_mPV(count++, "-flag"); /* TODO: Decode flags? */ XST_mIV(count++, ti.uFlags); } if(tip) Safefree(tip); XSRETURN(count); ########################################################################### # (@)METHOD:HitTest(WINDOW, X, Y, [BUFSIZE=0]) # Retrieves the information about the tool at C in window C # # C and C are in client co-ordinates of the C. # C is a window object or window handle # # B sets the size of the buffer for retrieving the text associated # with the tool. By default this is zero, and the text is not retrieved. # As there is no way to automatically determine the size of the buffer # required, this is a potential security hole, as the text may overrun # the size of the buffer provided. B. # # Returns a list of options and values on success, or an empty list on # failure (no tool at C). For details of the possible options see # AddTool(). void HitTest(handle,window,x,y,bufsize=0) HWND handle HWND window LONG x LONG y int bufsize PREINIT: TTHITTESTINFO hti; int count = 0; LPSTR tip = NULL; AV* rect; CODE: ZeroMemory(&hti, sizeof(TTHITTESTINFO)); hti.pt.x = x; hti.pt.y = y; hti.ti.cbSize = sizeof(TOOLINFO); hti.hwnd = window; if (bufsize > 0) { Newz(0, tip, bufsize, CHAR); hti.ti.lpszText = tip; } if (SendMessage(handle, TTM_HITTEST, (WPARAM) 0, (LPARAM) &hti)) { if(tip) { /* ensure tip is NULL terminated, even if we overran the buffer * to minimise damage - of course it may already be too late */ tip[bufsize-1] = 0; } EXTEND(SP, 12); XST_mPV(count++, "-window"); if(hti.ti.uFlags & TTF_IDISHWND) { XST_mIV(count++, (IV) hti.ti.uId); } else { XST_mIV(count++, PTR2IV(hti.ti.hwnd)); XST_mPV(count++, "-id"); XST_mIV(count++, hti.ti.uId); XST_mPV(count++, "-rect"); rect = newAV(); av_push(rect,newSViv(hti.ti.rect.left)); av_push(rect,newSViv(hti.ti.rect.top)); av_push(rect,newSViv(hti.ti.rect.right)); av_push(rect,newSViv(hti.ti.rect.bottom)); ST(count++) = sv_2mortal(newRV_noinc((SV*)rect)); } if (hti.ti.lpszText != NULL) { if (hti.ti.lpszText == LPSTR_TEXTCALLBACK) { XST_mPV(count++, "-needtext"); XST_mIV(count++, 1); } else if (IS_INTRESOURCE(hti.ti.lpszText)) { XST_mPV(count++, "-text"); XST_mIV(count++, PTR2IV(hti.ti.lpszText)); XST_mPV(count++, "-hinst"); XST_mIV(count++, PTR2IV(hti.ti.hinst)); } else { XST_mPV(count++, "-text"); XST_mPV(count++, hti.ti.lpszText); } } XST_mPV(count++, "-flag"); /* TODO: Decode flags? */ XST_mIV(count++, hti.ti.uFlags); } if(tip) Safefree(tip); XSRETURN(count); ########################################################################### # (@)METHOD:NewToolRect(TOOL, LEFT, TOP, RIGHT, BOTTOM) # Sets a new bounding rectangle for a tool. # # C identifies the tool to use to calculate the window size. # C may be one of the following: # # ID - only for backwards compatibility with Win32::GUI v1.03 # and earlier. A tool id identifying a tool that occupies # part of a window. The associated window defaults to the # owner window of the tooltip control, as for the default # for the -window option of the AddTool() method. # See AddTool(). # WINDOW - a window object or window handle, identifying a tool # that occupies the whole window. # [WINDOW] - an array reference containing a window object or window # handle, identifying a tool that occupies the whole # window. # [WINDOW, ID] - an array reference containing a window object or window # handle and a tool id, identifying a tool that occupies # part of a window. # # C and/or C are the values used for the C<-window> and/or <-id> # options used with the AddTool() method. See AddTool(). # # C identifies the new tool rect. LRESULT NewToolRect(handle,tool,left,top,right,bottom) HWND handle SV* tool LONG left LONG top LONG right LONG bottom PREINIT: TOOLINFO ti; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ToolInfoFromTool(NOTXSCALL handle, tool, &ti); ti.rect.left = left; ti.rect.top = top; ti.rect.right = right; ti.rect.bottom = bottom; RETVAL = SendMessage(handle, TTM_NEWTOOLRECT, (WPARAM) 0, (LPARAM) &ti); OUTPUT: RETVAL ########################################################################### # (@)METHOD:Pop() # Removes a displayed tooltip window from view. LRESULT Pop(handle) HWND handle CODE: RETVAL = SendMessage(handle, TTM_POP, 0, 0); OUTPUT: RETVAL # TODO : TTM_RELAYEVENT (???) ########################################################################### # (@)METHOD:SetDelayTime(TIME,[FLAG=TTDT_INITIAL]) # Sets the initial, pop-up, and reshow durations for a tooltip control. # # B : # TTDT_RESHOW = 1 : Length of time it takes for subsequent tooltip # windows to appear as the pointer moves from one # tool to another. To reset the reshow duration to # it's default value set TIME to -1. # TTDT_AUTOPOP = 2 : Length of time the tooltip window remains visible # if the pointer is stationary within a tool's # bounding rectangle. To reset the pop-up duration to # it's default value set TIME to -1. # TTDT_INITIAL = 3 : Length of time the pointer must remain stationary # within a tool's bounding rectangle before the # tooltip window appears. To reset the initial duration # to it's default value set TIME to -1. # TTDT_AUTOMATIC = 0 : Set all three delay times to default proportions. The # autopop time will be ten times the initial time and # the reshow time will be one fifth the initial time. If # this flag is set, use a positive value of TIME to # specify the initial time, in milliseconds. Set TIME to # a negative value to return all three delay times to # their default values. LRESULT SetDelayTime(handle,time,flag=TTDT_INITIAL) HWND handle WPARAM time WPARAM flag CODE: RETVAL = SendMessage(handle, TTM_SETDELAYTIME, flag, (LPARAM) MAKELONG(time,0)); OUTPUT: RETVAL ########################################################################### # (@)METHOD:SetMargin(LEFT, TOP, RIGHT, BOTTOM) # Sets the left, top, right, and bottom margins for a tooltip window. # A margin is the distance, in pixels, between the tooltip window border # and the text contained within the tooltip window. LRESULT SetMargin(handle,left,top,right,bottom) HWND handle int left int top int right int bottom PREINIT: RECT myRect; CODE: myRect.left = left; myRect.top = top; myRect.right = right; myRect.bottom = bottom; RETVAL = SendMessage(handle, TTM_SETMARGIN, (WPARAM) 0, (LPARAM) &myRect); OUTPUT: RETVAL ########################################################################### # (@)METHOD:SetMaxTipWidth(WIDTH) # Sets the maximum width for a tooltip window. # # The maximum ToolTip width value does not indicate a ToolTip window's # actual width. Rather, if a ToolTip string exceeds the maximum width, the # control breaks the text into multiple lines, using spaces to determine # line breaks. If the text cannot be segmented into multiple lines, it will # be displayed on a single line. The length of this line may exceed the # maximum ToolTip width. # # Returns the previous maximum width (-1 if no previous maximum width # has been set) INT SetMaxTipWidth(handle,width) HWND handle WPARAM width CODE: RETVAL = (INT)SendMessage(handle, TTM_SETMAXTIPWIDTH, 0, (LPARAM) width); OUTPUT: RETVAL ########################################################################### # (@)METHOD:SetTipBkColor(COLOR) # Sets the background color in a tooltip window. LRESULT SetTipBkColor(handle,color) HWND handle COLORREF color CODE: RETVAL = SendMessage(handle, TTM_SETTIPBKCOLOR, (WPARAM) color, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:SetTipTextColor(COLOR) # Sets the text color in a tooltip window. LRESULT SetTipTextColor(handle,color) HWND handle COLORREF color CODE: RETVAL = SendMessage(handle, TTM_SETTIPTEXTCOLOR, (WPARAM) color, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:SetTitle(TITLE, [ICON]) # Sets the title and icon for a balloon tooltip. # # Allowed values for ICON are: error, info, warning, none. # Defaults to 'none'. # # Returns a true value on success, a false value on failure LRESULT SetTitle(handle, title, icon="none") HWND handle LPCSTR title LPCSTR icon PREINIT: UINT i; CODE: if(strcmp(icon, "error") == 0) { i = 3; } else if(strcmp(icon, "info") == 0) { i = 2; } else if(strcmp(icon, "warning") == 0) { i = 1; } else if(strcmp(icon, "none") == 0) { i = 0; } else { W32G_WARN("Invalid icon specification (%s): using 'none'",icon); i = 0; } RETVAL = SendMessage(handle, TTM_SETTITLE, (WPARAM)i, (LPARAM)title); OUTPUT: RETVAL ########################################################################### # (@)METHOD:SetToolInfo(@OPTIONS) # Sets the information that a tooltip control maintains for a tool. # # B<@OPTIONS>: See Add(). # # Some internal properties of a tool are established when the tool is # created, and are not recomputed when the SetToolInfo() method is used. # If you simply using SetToolInfo(), setting the required values # these properties may be lost. Instead, your application should first # request the tool's current properties using the GetToolInfo() method, # then, modify the options as needed and pass them back to the ToolTip # control with SetToolInfo(). LRESULT SetToolInfo(handle,...) HWND handle PREINIT: TOOLINFO ti; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ti.hwnd = (HWND) GetWindowLong(handle, GWL_HWNDPARENT); ParseTooltipOptions(NOTXSCALL sp, mark, ax, items, 1, &ti); RETVAL = SendMessage(handle, TTM_SETTOOLINFO, 0, (LPARAM) &ti); OUTPUT: RETVAL ########################################################################### # (@)METHOD:TrackActivate(TOOL, [FLAG=1]) # Activates or deactivates a tracking tooltip. # See AddTool(), C<-track> option. # # C identifies the tool to use to calculate the window size. # C may be one of the following: # # ID - only for backwards compatibility with Win32::GUI v1.03 # and earlier. A tool id identifying a tool that occupies # part of a window. The associated window defaults to the # owner window of the tooltip control, as for the default # for the -window option of the AddTool() method. # See AddTool(). # WINDOW - a window object or window handle, identifying a tool # that occupies the whole window. # [WINDOW] - an array reference containing a window object or window # handle, identifying a tool that occupies the whole # window. # [WINDOW, ID] - an array reference containing a window object or window # handle and a tool id, identifying a tool that occupies # part of a window. # # C and/or C are the values used for the C<-window> and/or <-id> # options used with the AddTool() method. See AddTool(). # # C identifies whether tracking is activated (1) or deactivated (0) LRESULT TrackActivate(handle,tool,flag=1) HWND handle SV* tool BOOL flag PREINIT: TOOLINFO ti; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ToolInfoFromTool(NOTXSCALL handle, tool, &ti); RETVAL = SendMessage(handle, TTM_TRACKACTIVATE, (WPARAM) flag, (LPARAM) &ti); OUTPUT: RETVAL ########################################################################### # (@)METHOD:TrackPosition(X,Y) # Sets the position of a tracking tooltip. # C and C are in screen co-ordinates. # See AddTool(), C<-track> and C<-absolute> options. LRESULT TrackPosition(handle,x,y) HWND handle UINT x UINT y CODE: RETVAL = SendMessage(handle, TTM_TRACKPOSITION, 0, (LPARAM) MAKELONG(x, y)); OUTPUT: RETVAL ########################################################################### # (@)METHOD:Update() # Forces the current tool to be redrawn. LRESULT Update(handle) HWND handle CODE: RETVAL = SendMessage(handle, TTM_UPDATE, 0, 0); OUTPUT: RETVAL ########################################################################### # (@)METHOD:UpdateTipText(TOOL, STRING_OR_RESID, [HINSTANCE=NULL]) # Sets the tooltip text for a tool. # # C identifies the tool whose text is set. # C may be one of the following: # # ID - only for backwards compatibility with Win32::GUI v1.03 # and earlier. A tool id identifying a tool that occupies # part of a window. The associated window defaults to the # owner window of the tooltip control, as for the default # for the -window option of the AddTool() method. # See AddTool(). # WINDOW - a window object or window handle, identifying a tool # that occupies the whole window. # [WINDOW] - an array reference containing a window object or window # handle, identifying a tool that occupies the whole # window. # [WINDOW, ID] - an array reference containing a window object or window # handle and a tool id, identifying a tool that occupies # part of a window. # # C and/or C are the values used for the C<-window> and/or <-id> # options used with the AddTool() method. See AddTool(). LRESULT UpdateTipText(handle, tool, string_or_resid, instance=NULL) HWND handle SV* tool SV* string_or_resid HINSTANCE instance PREINIT: TOOLINFO ti; CODE: ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ToolInfoFromTool(NOTXSCALL handle, tool, &ti); ti.lpszText = SvIOK(string_or_resid) ? MAKEINTRESOURCE(SvIV(string_or_resid)) : SvPV_nolen(string_or_resid); ti.hinst = instance; RETVAL = SendMessage(handle, TTM_UPDATETIPTEXT, 0, (LPARAM) &ti); OUTPUT: RETVAL ########################################################################### # (@)INTERNAL:WindowFromPoint(X, Y) # Allows a subclass procedure to cause a tooltip to display text for a window # other than the one beneath the mouse cursor. # # TTM_WINDOWFROMPOINT is supposed to be processed by a sub-class, not ever # sent: The tooltip class sends this to itself to determine the window under # the mouse (default implementation is simly WindowFromPoint(). A subclass # might (for example) want to use ChildWindowFromPoint(), so that disabled # windows aren't ignored, or something more complex so that a tool # belonging to another region is used. # # This documentation left here, to record that this message is purposely # not implemented as a mechanism to send this message.