Skip to content

Commit 5a97f16

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 ce55334 commit 5a97f16

File tree

1 file changed

+68
-63
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets

1 file changed

+68
-63
lines changed

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

Lines changed: 68 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7158,82 +7158,87 @@ 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 = " ";
7162+
if (isCustomToolTip () || hdr.code == OS.TTN_SHOW) {
7163+
result = positionTooltip(hdr, lParam);
7164+
}
7165+
return result;
7166+
}
7167+
}
7168+
return null;
7169+
}
7170+
7171+
private LRESULT positionTooltip(NMHDR hdr, long lParam) {
7172+
LRESULT result = null;
7173+
LVHITTESTINFO pinfo = new LVHITTESTINFO ();
7174+
int pos = OS.GetMessagePos ();
7175+
POINT pt = new POINT();
7176+
OS.POINTSTOPOINT (pt, pos);
7177+
OS.ScreenToClient (handle, pt);
7178+
pinfo.x = pt.x;
7179+
pinfo.y = pt.y;
7180+
/*
7181+
* Bug in Windows. When LVM_SUBITEMHITTEST is used to hittest
7182+
* a point that is above the table, instead of returning -1 to
7183+
* indicate that the hittest failed, a negative index is returned.
7184+
* The fix is to consider any value that is negative a failure.
7185+
*/
7186+
if (OS.SendMessage (handle, OS.LVM_SUBITEMHITTEST, 0, pinfo) >= 0) {
7187+
TableItem item = _getItem (pinfo.iItem);
7188+
long hDC = OS.GetDC (handle);
7189+
long oldFont = 0, newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
7190+
if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont);
7191+
long hFont = item.fontHandle (pinfo.iSubItem);
7192+
if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
7193+
Event event = sendMeasureItemEvent (item, pinfo.iItem, pinfo.iSubItem, hDC);
7194+
if (!isDisposed () && !item.isDisposed ()) {
7195+
RECT itemRect = new RECT ();
7196+
Rectangle boundsInPixels = DPIUtil.scaleUp(event.getBounds(), getZoom());
7197+
OS.SetRect (itemRect, boundsInPixels.x, boundsInPixels.y, boundsInPixels.x + boundsInPixels.width, boundsInPixels.y + boundsInPixels.height);
7198+
if (hdr.code == OS.TTN_SHOW) {
7199+
RECT toolRect = isCustomToolTip() ? toolTipRect (itemRect) : itemRect;
7200+
OS.MapWindowPoints (handle, 0, toolRect, 2);
7201+
long hwndToolTip = OS.SendMessage (handle, OS.LVM_GETTOOLTIPS, 0, 0);
7202+
int flags = OS.SWP_NOACTIVATE | OS.SWP_NOZORDER;
7203+
Rectangle adjustedTooltipBounds = getDisplay().fitRectangleBoundsIntoMonitorWithCursor(toolRect);
7204+
OS.SetWindowPos(hwndToolTip, 0, adjustedTooltipBounds.x, adjustedTooltipBounds.y,
7205+
adjustedTooltipBounds.width, adjustedTooltipBounds.height, flags);
7206+
result = LRESULT.ONE;
7207+
} else {
7208+
NMTTDISPINFO lpnmtdi = new NMTTDISPINFO ();
7209+
OS.MoveMemory (lpnmtdi, lParam, NMTTDISPINFO.sizeof);
7210+
if (lpnmtdi.lpszText != 0) {
7211+
OS.MoveMemory (lpnmtdi.lpszText, new char [1], 2);
7212+
OS.MoveMemory (lParam, lpnmtdi, NMTTDISPINFO.sizeof);
7213+
}
7214+
RECT cellRect = item.getBounds (pinfo.iItem, pinfo.iSubItem, true, true, true, true, hDC);
7215+
RECT clientRect = new RECT ();
7216+
OS.GetClientRect (handle, clientRect);
7217+
if (itemRect.right > cellRect.right || itemRect.right > clientRect.right) {
7218+
//TEMPORARY CODE
7219+
String string = " ";
72117220
// String string = null;
72127221
// if (pinfo.iSubItem == 0) {
72137222
// string = item.text;
72147223
// } else {
72157224
// String [] strings = item.strings;
72167225
// if (strings != null) string = strings [pinfo.iSubItem];
72177226
// }
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+
if (string != null) {
7228+
Shell shell = getShell ();
7229+
char [] chars = new char [string.length () + 1];
7230+
string.getChars (0, string.length (), chars, 0);
7231+
shell.setToolTipText (lpnmtdi, chars);
7232+
OS.MoveMemory (lParam, lpnmtdi, NMTTDISPINFO.sizeof);
72277233
}
7228-
if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
7229-
if (newFont != 0) OS.SelectObject (hDC, oldFont);
7230-
OS.ReleaseDC (handle, hDC);
72317234
}
72327235
}
7233-
return new LRESULT (code);
72347236
}
7237+
if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
7238+
if (newFont != 0) OS.SelectObject (hDC, oldFont);
7239+
OS.ReleaseDC (handle, hDC);
72357240
}
7236-
return null;
7241+
return result;
72377242
}
72387243

72397244
LRESULT wmNotifyToolTip (NMTTCUSTOMDRAW nmcd, long lParam) {

0 commit comments

Comments
 (0)