Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java156
1 files changed, 133 insertions, 23 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java
index caa5188848..09485077ec 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java
@@ -154,7 +154,7 @@ public void addSelectionListener (SelectionListener listener) {
int /*long*/ callWindowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) {
if (handle == 0) return 0;
- if (LinkProc != 0) {
+ if (LinkProc != 0 && !getBufferredPaint()) {
/*
* Feature in Windows. By convention, native Windows controls
* check for a non-NULL wParam, assume that it is an HDC and
@@ -179,7 +179,7 @@ public Point computeSize (int wHint, int hHint, boolean changed) {
if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
int width, height;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
int /*long*/ hDC = OS.GetDC (handle);
int /*long*/ newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
int /*long*/ oldFont = OS.SelectObject (hDC, newFont);
@@ -229,7 +229,7 @@ public Point computeSize (int wHint, int hHint, boolean changed) {
void createHandle () {
super.createHandle ();
state |= THEME_BACKGROUND;
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
layout = new TextLayout (display);
if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (4, 10)) {
linkColor = Color.win32_new (display, OS.GetSysColor (OS.COLOR_HOTLIGHT));
@@ -248,7 +248,7 @@ void createHandle () {
void createWidget () {
super.createWidget ();
text = "";
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
if ((style & SWT.MIRRORED) != 0) {
layout.setOrientation (SWT.RIGHT_TO_LEFT);
}
@@ -256,6 +256,39 @@ void createWidget () {
}
}
+void drawBufferredTextRun(int /*long*/ targetDC, String parsedText, int runStart, int runEnd, int /*long*/ hFont) {
+ if (runStart >= runEnd)
+ return;
+
+ int color = 0x000000;
+ boolean underline = false;
+ TextStyle style = layout.getStyle(runStart);
+ if (style != null) {
+ color = (style.foreground.getBlue() << 16) + (style.foreground.getGreen() << 8) + style.foreground.getRed();
+ underline = style.underline;
+ }
+
+ Rectangle bounds = layout.getBounds(runStart, runEnd-1);
+ String runText = parsedText.substring(runStart, runEnd);
+ TCHAR runBuffer = new TCHAR (getCodePage (), runText, true);
+
+ RECT drawRect = new RECT();
+ drawRect.left = bounds.x;
+ drawRect.top = bounds.y;
+ drawRect.right = bounds.x + bounds.width;
+ drawRect.bottom = bounds.y + bounds.height;
+ drawBufferredText(targetDC, runBuffer, drawRect, hFont, color, 0);
+
+ if (underline) {
+ TEXTMETRIC tm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA();
+ OS.GetTextMetrics(targetDC, tm);
+ int underlineY = drawRect.bottom - tm.tmDescent;
+
+ OS.MoveToEx(targetDC, drawRect.left, underlineY, 0);
+ OS.LineTo(targetDC, drawRect.right, underlineY);
+ }
+}
+
void drawWidget (GC gc, RECT rect) {
drawBackground (gc.handle, rect);
int selStart = selection.x;
@@ -288,7 +321,7 @@ void drawWidget (GC gc, RECT rect) {
}
void enableWidget (boolean enabled) {
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
LITEM item = new LITEM ();
item.mask = OS.LIF_ITEMINDEX | OS.LIF_STATE;
item.stateMask = OS.LIS_ENABLED;
@@ -363,6 +396,14 @@ void initAccessible () {
});
}
+boolean getBufferredPaint() {
+ Shell shell = getShell ();
+ if ((shell.style & SWT.TRIM_FILL) != 0 && (style & SWT.TRIM_FILL) != 0) {
+ return true;
+ }
+ return false;
+}
+
String getNameText () {
return getText ();
}
@@ -421,7 +462,7 @@ boolean mnemonicHit (char key) {
char mnemonic = parsedText.charAt(mnemonics[i]);
if (uckey == Character.toUpperCase (mnemonic)) {
if (!setFocus ()) return false;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
LITEM item = new LITEM ();
item.mask = OS.LIF_ITEMINDEX | OS.LIF_STATE;
@@ -695,7 +736,7 @@ public void setText (String string) {
if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
if (string.equals (text)) return;
text = string;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
boolean enabled = OS.IsWindowEnabled (handle);
/*
* Bug in Windows. For some reason, when SetWindowText()
@@ -744,17 +785,17 @@ int widgetStyle () {
}
TCHAR windowClass () {
- return OS.COMCTL32_MAJOR >= 6 ? LinkClass : display.windowClass;
+ return OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint() ? LinkClass : display.windowClass;
}
int /*long*/ windowProc () {
- return LinkProc != 0 ? LinkProc : display.windowProc;
+ return LinkProc != 0 && !getBufferredPaint() ? LinkProc : display.windowProc;
}
LRESULT WM_CHAR (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_CHAR (wParam, lParam);
if (result != null) return result;
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
if (focusIndex == -1) return result;
switch ((int)/*64*/wParam) {
case ' ':
@@ -802,7 +843,7 @@ LRESULT WM_GETDLGCODE (int /*long*/ wParam, int /*long*/ lParam) {
if (result != null) return result;
int index, count;
int /*long*/ code = 0;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
LITEM item = new LITEM ();
item.mask = OS.LIF_ITEMINDEX | OS.LIF_STATE;
item.stateMask = OS.LIS_FOCUSED;
@@ -844,7 +885,7 @@ LRESULT WM_GETFONT (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT WM_KEYDOWN (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_KEYDOWN (wParam, lParam);
if (result != null) return result;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
switch ((int)/*64*/wParam) {
case OS.VK_SPACE:
case OS.VK_RETURN:
@@ -863,14 +904,14 @@ LRESULT WM_KEYDOWN (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT WM_KILLFOCUS (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_KILLFOCUS (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) redraw ();
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) redraw ();
return result;
}
LRESULT WM_LBUTTONDOWN (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_LBUTTONDOWN (wParam, lParam);
if (result == LRESULT.ZERO) return result;
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
if (focusIndex != -1) setFocus ();
int x = OS.GET_X_LPARAM (lParam);
int y = OS.GET_Y_LPARAM (lParam);
@@ -908,7 +949,7 @@ LRESULT WM_LBUTTONDOWN (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT WM_LBUTTONUP (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_LBUTTONUP (wParam, lParam);
if (result == LRESULT.ZERO) return result;
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
if (mouseDownIndex == -1) return result;
int x = OS.GET_X_LPARAM (lParam);
int y = OS.GET_Y_LPARAM (lParam);
@@ -936,14 +977,14 @@ LRESULT WM_NCHITTEST (int /*long*/ wParam, int /*long*/ lParam) {
* returns HTTRANSPARENT when mouse is over plain text. The fix is
* to always return HTCLIENT.
*/
- if (OS.COMCTL32_MAJOR >= 6) return new LRESULT (OS.HTCLIENT);
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) return new LRESULT (OS.HTCLIENT);
return result;
}
LRESULT WM_MOUSEMOVE (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_MOUSEMOVE (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
int x = OS.GET_X_LPARAM (lParam);
int y = OS.GET_Y_LPARAM (lParam);
if (OS.GetKeyState (OS.VK_LBUTTON) < 0) {
@@ -1000,7 +1041,7 @@ LRESULT WM_PAINT (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT WM_PRINTCLIENT (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_PRINTCLIENT (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
RECT rect = new RECT ();
OS.GetClientRect (handle, rect);
GCData data = new GCData ();
@@ -1015,12 +1056,12 @@ LRESULT WM_PRINTCLIENT (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT WM_SETFOCUS (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_SETFOCUS (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) redraw ();
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) redraw ();
return result;
}
LRESULT WM_SETFONT (int /*long*/ wParam, int /*long*/ lParam) {
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
layout.setFont (Font.win32_new (display, wParam));
}
if (lParam != 0) OS.InvalidateRect (handle, null, true);
@@ -1029,7 +1070,7 @@ LRESULT WM_SETFONT (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT WM_SIZE (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_SIZE (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
RECT rect = new RECT ();
OS.GetClientRect (handle, rect);
layout.setWidth (rect.right > 0 ? rect.right : -1);
@@ -1038,6 +1079,75 @@ LRESULT WM_SIZE (int /*long*/ wParam, int /*long*/ lParam) {
return result;
}
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ PAINTSTRUCT ps = new PAINTSTRUCT ();
+ int /*long*/ paintDC = OS.BeginPaint (hWnd, ps);
+
+ RECT rect = new RECT();
+ OS.GetClientRect(hWnd, rect);
+
+ BP_PAINTPARAMS params = new BP_PAINTPARAMS();
+ params.cbSize = BP_PAINTPARAMS.sizeof;
+ params.dwFlags = OS.BPPF_ERASE;
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint(paintDC, rect, OS.BPBF_TOPDOWNDIB, params, hdcBuffered);
+
+ if (hdcBuffered[0] != 0) {
+ String parsedText = parse (text);
+ int /*long*/ hFont = OS.SendMessage(this.handle, OS.WM_GETFONT, 0, 0);
+ int /*long*/ prevFont = OS.SelectObject(hdcBuffered[0], hFont);
+
+ int [] styleOffsets = layout.getRanges();
+ int [] lineOffsets = layout.getLineOffsets();
+ for (int i=1; i<styleOffsets.length; i+=2) {
+ styleOffsets[i]++; // every other offset in incremented by 1
+ }
+
+ int nextLine = 1;
+ for (int i=0; i<=styleOffsets.length; i++) {
+ int runStart = (i > 0) ? styleOffsets [i-1] : 0;
+ int runEnd = (i < styleOffsets.length) ? styleOffsets[i] : parsedText.length();
+
+ // skip leading whitespace characters since the lineOffsets from TextLayout have already done likewise
+ while(Character.isWhitespace(parsedText.charAt(runStart)) && runStart < runEnd) {
+ runStart++;
+ }
+
+ // see if we have exceeeded the extents of the current line, and if so draw the truncated text run
+ if (nextLine < lineOffsets.length && lineOffsets[nextLine] < runEnd) {
+ int truncated = lineOffsets[nextLine];
+ drawBufferredTextRun(hdcBuffered[0], parsedText, runStart, truncated, hFont);
+
+ // move to the beginning of the next line
+ runStart = lineOffsets[nextLine];
+ nextLine++;
+ }
+
+ drawBufferredTextRun(hdcBuffered[0], parsedText, runStart, runEnd, hFont);
+ }
+
+ if (hasFocus () && focusIndex != -1) {
+ Rectangle [] rects = getRectangles (focusIndex);
+ for (int i = 0; i < rects.length; i++) {
+ Rectangle rectangle = rects [i];
+ RECT focusRect = new RECT();
+ focusRect.left = rectangle.x;
+ focusRect.top = rectangle.y;
+ focusRect.right = rectangle.x + rectangle.width;
+ focusRect.bottom = rectangle.y + rectangle.height;
+
+ OS.DrawFocusRect (hdcBuffered[0], focusRect);
+ }
+ }
+
+ OS.SelectObject(hdcBuffered[0], prevFont);
+ OS.EndBufferedPaint(hBufferedPaint, true);
+ }
+
+ OS.EndPaint (handle, ps);
+ return LRESULT.ZERO;
+}
+
LRESULT wmColorChild (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.wmColorChild (wParam, lParam);
/*
@@ -1045,7 +1155,7 @@ LRESULT wmColorChild (int /*long*/ wParam, int /*long*/ lParam) {
* not gray out the non-link portion of the text. The fix
* is to set the text color to the system gray color.
*/
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
if (!OS.IsWindowEnabled (handle)) {
OS.SetTextColor (wParam, OS.GetSysColor (OS.COLOR_GRAYTEXT));
if (result == null) {
@@ -1060,7 +1170,7 @@ LRESULT wmColorChild (int /*long*/ wParam, int /*long*/ lParam) {
}
LRESULT wmNotifyChild (NMHDR hdr, int /*long*/ wParam, int /*long*/ lParam) {
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
switch (hdr.code) {
case OS.NM_RETURN:
case OS.NM_CLICK:

Back to the top