Skip to content

Commit 18da1d6

Browse files
committed
Fit Table Tooltip in a single monitor for Win32
This commit contributes to the fitting of the table tooltip inside a single monitor if it spans over multiple monitor to avoid any infinite loop because of rescaling triggered by any DPI_CHANGED events. contributes to #62 and #128
1 parent 649bb49 commit 18da1d6

File tree

1 file changed

+66
-71
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets

1 file changed

+66
-71
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java

Lines changed: 66 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -7158,82 +7158,77 @@ LRESULT wmNotifyToolTip (NMHDR hdr, long wParam, long lParam) {
71587158
case OS.TTN_SHOW: {
71597159
LRESULT result = super.wmNotify (hdr, wParam, lParam);
71607160
if (result != null) return result;
7161-
if (hdr.code != OS.TTN_SHOW) tipRequested = true;
7162-
long code = callWindowProc (handle, OS.WM_NOTIFY, wParam, lParam);
7163-
if (hdr.code != OS.TTN_SHOW) tipRequested = false;
71647161
if (toolTipText != null) break;
7165-
if (isCustomToolTip ()) {
7166-
LVHITTESTINFO pinfo = new LVHITTESTINFO ();
7167-
int pos = OS.GetMessagePos ();
7168-
POINT pt = new POINT();
7169-
OS.POINTSTOPOINT (pt, pos);
7170-
OS.ScreenToClient (handle, pt);
7171-
pinfo.x = pt.x;
7172-
pinfo.y = pt.y;
7173-
/*
7174-
* Bug in Windows. When LVM_SUBITEMHITTEST is used to hittest
7175-
* a point that is above the table, instead of returning -1 to
7176-
* indicate that the hittest failed, a negative index is returned.
7177-
* The fix is to consider any value that is negative a failure.
7178-
*/
7179-
if (OS.SendMessage (handle, OS.LVM_SUBITEMHITTEST, 0, pinfo) >= 0) {
7180-
TableItem item = _getItem (pinfo.iItem);
7181-
long hDC = OS.GetDC (handle);
7182-
long oldFont = 0, newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
7183-
if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont);
7184-
long hFont = item.fontHandle (pinfo.iSubItem);
7185-
if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
7186-
Event event = sendMeasureItemEvent (item, pinfo.iItem, pinfo.iSubItem, hDC);
7187-
if (!isDisposed () && !item.isDisposed ()) {
7188-
RECT itemRect = new RECT ();
7189-
Rectangle boundsInPixels = DPIUtil.scaleUp(event.getBounds(), getZoom());
7190-
OS.SetRect (itemRect, boundsInPixels.x, boundsInPixels.y, boundsInPixels.x + boundsInPixels.width, boundsInPixels.y + boundsInPixels.height);
7191-
if (hdr.code == OS.TTN_SHOW) {
7192-
RECT toolRect = toolTipRect (itemRect);
7193-
OS.MapWindowPoints (handle, 0, toolRect, 2);
7194-
long hwndToolTip = OS.SendMessage (handle, OS.LVM_GETTOOLTIPS, 0, 0);
7195-
int flags = OS.SWP_NOACTIVATE | OS.SWP_NOZORDER;
7196-
int width = toolRect.right - toolRect.left, height = toolRect.bottom - toolRect.top;
7197-
OS.SetWindowPos (hwndToolTip, 0, toolRect.left , toolRect.top, width, height, flags);
7198-
} else {
7199-
NMTTDISPINFO lpnmtdi = new NMTTDISPINFO ();
7200-
OS.MoveMemory (lpnmtdi, lParam, NMTTDISPINFO.sizeof);
7201-
if (lpnmtdi.lpszText != 0) {
7202-
OS.MoveMemory (lpnmtdi.lpszText, new char [1], 2);
7203-
OS.MoveMemory (lParam, lpnmtdi, NMTTDISPINFO.sizeof);
7204-
}
7205-
RECT cellRect = item.getBounds (pinfo.iItem, pinfo.iSubItem, true, true, true, true, hDC);
7206-
RECT clientRect = new RECT ();
7207-
OS.GetClientRect (handle, clientRect);
7208-
if (itemRect.right > cellRect.right || itemRect.right > clientRect.right) {
7209-
//TEMPORARY CODE
7210-
String string = " ";
7211-
// String string = null;
7212-
// if (pinfo.iSubItem == 0) {
7213-
// string = item.text;
7214-
// } else {
7215-
// String [] strings = item.strings;
7216-
// if (strings != null) string = strings [pinfo.iSubItem];
7217-
// }
7218-
if (string != null) {
7219-
Shell shell = getShell ();
7220-
char [] chars = new char [string.length () + 1];
7221-
string.getChars (0, string.length (), chars, 0);
7222-
shell.setToolTipText (lpnmtdi, chars);
7223-
OS.MoveMemory (lParam, lpnmtdi, NMTTDISPINFO.sizeof);
7224-
}
7225-
}
7226-
}
7227-
}
7228-
if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
7229-
if (newFont != 0) OS.SelectObject (hDC, oldFont);
7230-
OS.ReleaseDC (handle, hDC);
7162+
result = positionTooltip(hdr, lParam);
7163+
return result;
7164+
}
7165+
}
7166+
return null;
7167+
}
7168+
7169+
private LRESULT positionTooltip(NMHDR hdr, long lParam) {
7170+
LRESULT result = null;
7171+
LVHITTESTINFO pinfo = new LVHITTESTINFO ();
7172+
int pos = OS.GetMessagePos ();
7173+
POINT pt = new POINT();
7174+
OS.POINTSTOPOINT (pt, pos);
7175+
OS.ScreenToClient (handle, pt);
7176+
pinfo.x = pt.x;
7177+
pinfo.y = pt.y;
7178+
/*
7179+
* Bug in Windows. When LVM_SUBITEMHITTEST is used to hittest
7180+
* a point that is above the table, instead of returning -1 to
7181+
* indicate that the hittest failed, a negative index is returned.
7182+
* The fix is to consider any value that is negative a failure.
7183+
*/
7184+
if (OS.SendMessage (handle, OS.LVM_SUBITEMHITTEST, 0, pinfo) >= 0) {
7185+
TableItem item = _getItem (pinfo.iItem);
7186+
long hDC = OS.GetDC (handle);
7187+
long oldFont = 0, newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
7188+
if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont);
7189+
long hFont = item.fontHandle (pinfo.iSubItem);
7190+
if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
7191+
Event event = sendMeasureItemEvent (item, pinfo.iItem, pinfo.iSubItem, hDC);
7192+
if (!isDisposed () && !item.isDisposed ()) {
7193+
RECT itemRect = new RECT ();
7194+
Rectangle boundsInPixels = DPIUtil.scaleUp(event.getBounds(), getZoom());
7195+
OS.SetRect (itemRect, boundsInPixels.x, boundsInPixels.y, boundsInPixels.x + boundsInPixels.width, boundsInPixels.y + boundsInPixels.height);
7196+
if (hdr.code == OS.TTN_SHOW) {
7197+
RECT toolRect = isCustomToolTip() ? toolTipRect (itemRect) : itemRect;
7198+
OS.MapWindowPoints (handle, 0, toolRect, 2);
7199+
long hwndToolTip = OS.SendMessage (handle, OS.LVM_GETTOOLTIPS, 0, 0);
7200+
int flags = OS.SWP_NOACTIVATE | OS.SWP_NOZORDER;
7201+
Rectangle adjustedTooltipBounds = getDisplay().fitRectangleBoundsIntoMonitorWithCursor(toolRect);
7202+
OS.SetWindowPos(hwndToolTip, 0, adjustedTooltipBounds.x, adjustedTooltipBounds.y,
7203+
adjustedTooltipBounds.width, adjustedTooltipBounds.height, flags);
7204+
result = LRESULT.ONE;
7205+
} else {
7206+
NMTTDISPINFO lpnmtdi = new NMTTDISPINFO ();
7207+
OS.MoveMemory (lpnmtdi, lParam, NMTTDISPINFO.sizeof);
7208+
if (lpnmtdi.lpszText != 0) {
7209+
OS.MoveMemory (lpnmtdi.lpszText, new char [1], 2);
7210+
OS.MoveMemory (lParam, lpnmtdi, NMTTDISPINFO.sizeof);
7211+
}
7212+
RECT cellRect = item.getBounds (pinfo.iItem, pinfo.iSubItem, true, true, true, true, hDC);
7213+
RECT clientRect = new RECT ();
7214+
OS.GetClientRect (handle, clientRect);
7215+
if (itemRect.right > cellRect.right || itemRect.right > clientRect.right) {
7216+
//TEMPORARY CODE
7217+
String string = " ";
7218+
Shell shell = getShell ();
7219+
char [] chars = new char [string.length () + 1];
7220+
string.getChars (0, string.length (), chars, 0);
7221+
shell.setToolTipText (lpnmtdi, chars);
7222+
OS.MoveMemory (lParam, lpnmtdi, NMTTDISPINFO.sizeof);
7223+
result = LRESULT.ONE;
72317224
}
72327225
}
7233-
return new LRESULT (code);
72347226
}
7227+
if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
7228+
if (newFont != 0) OS.SelectObject (hDC, oldFont);
7229+
OS.ReleaseDC (handle, hDC);
72357230
}
7236-
return null;
7231+
return result;
72377232
}
72387233

72397234
LRESULT wmNotifyToolTip (NMTTCUSTOMDRAW nmcd, long lParam) {

0 commit comments

Comments
 (0)