Dear TSVN team,
I could not find anything relating to this in the mailing list, so here is
my bug report (and fix).
P.S.: Please reply to me directly, as I'm not subscribed to the mailing
This problem occurs with TSVN 1.1.1 Build 1857 (and lower).
On a computer with two monitors, place the secondary monitor to the left of
the primary monitor in the display settings. Open the TSVN settings dialog
and point at a control that has a Balloonhelp tooltip. The tooltip will be
displayed on the primary monitor.
The same thing happens if the secondary monitor is above the primary
The code for the balloon help is somewhat aware of multiple monitors by
calling GetSystemMetrics(SM_CXVIRTUALSCREEN) and related functions. However,
the code is not aware of the fact that display coordinates can be negative
if the secondary monitor is to the left or above the primary monitor. Hence
clipping the windowrect of the Balloonhelp window to positive coordinates
can cause it to appear on the wrong monitor.
This requires changes to the methods CalculateInfoBoxRect,
TestHorizDirection, and TestVertDirection. I also added a new helper method
called GetMonitorWorkArea which retrieves the work area of the monitor that
contains a given point.
As a side effect, using the work area instead of the monitor rect causes the
Balloon window not be be behind the taskbar.
According to MSDN, this will not work on Windows 95 or NT. If those systems
ought to be supported, some other code needs to be in place.
Here are the modified methods as they appear in Balloon.cpp:
void CBalloon::GetMonitorWorkArea(const CPoint& sourcePoint, CRect&
// identify the monitor that contains the sourcePoint
// and return the work area (the portion of the screen
// not obscured by the system taskbar or by application
// desktop toolbars) of that monitor
hMonitor = MonitorFromPoint(sourcePoint, MONITOR_DEFAULTTONEAREST);
// get the work area
mi.cbSize = sizeof(mi);
monitorRect = mi.rcWork;
void CBalloon::CalculateInfoBoxRect(CPoint * pt, CRect * rect)
m_nLastDirection = m_pToolInfo.nDirection;
if (!TestHorizDirection(pt->x, rect->Width(), monitorRect,
m_nLastDirection = GetNextHorizDirection(m_nLastDirection);
TestHorizDirection(pt->x, rect->Width(), monitorRect,
if (!TestVertDirection(pt->y, rect->Height(), monitorRect,
m_nLastDirection = GetNextVertDirection(m_nLastDirection);
TestVertDirection(pt->y, rect->Height(), monitorRect,
if ((m_pToolInfo.nStyles & BALLOON_SHADOW) &&
((m_nLastDirection == BALLOON_LEFT_TOP) || (m_nLastDirection
BOOL CBalloon::TestHorizDirection(int x, int cx, const CRect& monitorRect,
int nDirection, LPRECT rect)
int left = 0;
int right = 0;
int anchorMarginSize = (int)m_nSizes[XBLSZ_MARGIN_ANCHOR];
right = ((x + anchorMarginSize) > monitorRect.right) ?
monitorRect.right : (x + anchorMarginSize);
left = right - cx;
left = (x - anchorMarginSize)<monitorRect.left ?
monitorRect.left : (x - anchorMarginSize);
right = left + cx;
BOOL bTestOk = ((left >= monitorRect.left) && (right <=
monitorRect.right)) ? TRUE : FALSE;
rect->left = left;
rect->right = right;
BOOL CBalloon::TestVertDirection(int y, int cy, const CRect& monitorRect,
int nDirection, LPRECT rect)
int top = 0;
int bottom = 0;
bottom = y;
top = bottom - cy;
top = y;
bottom = top + cy;
BOOL bTestOk = ((top >= monitorRect.top) && (bottom <=
monitorRect.bottom)) ? TRUE : FALSE;
rect->top = top;
rect->bottom = bottom;
To unsubscribe, e-mail: email@example.com
For additional commands, e-mail: firstname.lastname@example.org
Received on Thu Dec 16 19:47:59 2004