public void show(int effect, int x, int y) { effect = checkEffect(effect); int handle = table.handle; Point coordinates = new Point(x, y); coordinates = table.toControl(coordinates); LVHITTESTINFO pinfo = new LVHITTESTINFO(); pinfo.x = coordinates.x; pinfo.y = coordinates.y; OS.SendMessage(handle, OS.LVM_HITTEST, 0, pinfo); if ((effect & DND.FEEDBACK_SCROLL) == 0) { scrollBeginTime = 0; scrollIndex = -1; } else { if (pinfo.iItem != -1 && scrollIndex == pinfo.iItem && scrollBeginTime != 0) { if (System.currentTimeMillis() >= scrollBeginTime) { int top = Math.max(0, OS.SendMessage(handle, OS.LVM_GETTOPINDEX, 0, 0)); int count = OS.SendMessage(handle, OS.LVM_GETITEMCOUNT, 0, 0); int index = (scrollIndex - 1 < top) ? Math.max(0, scrollIndex - 1) : Math.min(count - 1, scrollIndex + 1); OS.SendMessage(handle, OS.LVM_ENSUREVISIBLE, index, 0); scrollBeginTime = 0; scrollIndex = -1; } } else { scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS; scrollIndex = pinfo.iItem; } } LVITEM lvItem = new LVITEM(); lvItem.stateMask = OS.LVIS_DROPHILITED; OS.SendMessage(handle, OS.LVM_SETITEMSTATE, -1, lvItem); if (pinfo.iItem != -1 && (effect & DND.FEEDBACK_SELECT) != 0) { lvItem.state = OS.LVIS_DROPHILITED; OS.SendMessage(handle, OS.LVM_SETITEMSTATE, pinfo.iItem, lvItem); } // Insert mark only supported on Windows XP with manifest // if (OS.COMCTL32_MAJOR >= 6) { // if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0 || (effect & DND.FEEDBACK_INSERT_AFTER) != 0) // { // LVINSERTMARK lvinsertmark = new LVINSERTMARK(); // lvinsertmark.cbSize = LVINSERTMARK.sizeof; // lvinsertmark.dwFlags = (effect & DND.FEEDBACK_INSERT_BEFORE) != 0 ? 0 : OS.LVIM_AFTER; // lvinsertmark.iItem = pinfo.iItem == -1 ? 0 : pinfo.iItem; // int hItem = pinfo.iItem; // OS.SendMessage (handle, OS.LVM_SETINSERTMARK, 0, lvinsertmark); // } else { // OS.SendMessage (handle, OS.LVM_SETINSERTMARK, 0, 0); // } // } return; }
LRESULT wmMeasureChild(long /*int*/ wParam, long /*int*/ lParam) { MEASUREITEMSTRUCT struct = new MEASUREITEMSTRUCT(); OS.MoveMemory(struct, lParam, MEASUREITEMSTRUCT.sizeof); int width = 0, height = 0; if (image != null) { Rectangle rect = image.getBounds(); width = rect.width; height = rect.height; } else { /* * Bug in Windows. If a menu contains items that have * images and can be checked, Windows does not include * the width of the image and the width of the check when * computing the width of the menu. When the longest item * does not have an image, the label and the accelerator * text can overlap. The fix is to use SetMenuItemInfo() * to indicate that all items have a bitmap and then include * the width of the widest bitmap in WM_MEASURECHILD. */ MENUINFO lpcmi = new MENUINFO(); lpcmi.cbSize = MENUINFO.sizeof; lpcmi.fMask = OS.MIM_STYLE; long /*int*/ hMenu = parent.handle; OS.GetMenuInfo(hMenu, lpcmi); if ((lpcmi.dwStyle & OS.MNS_CHECKORBMP) == 0) { MenuItem[] items = parent.getItems(); for (int i = 0; i < items.length; i++) { MenuItem item = items[i]; if (item.image != null) { Rectangle rect = item.image.getBounds(); width = Math.max(width, rect.width); } } } } if (width != 0 || height != 0) { struct.itemWidth = width + MARGIN_WIDTH * 2; struct.itemHeight = height + MARGIN_HEIGHT * 2; OS.MoveMemory(lParam, struct, MEASUREITEMSTRUCT.sizeof); } return null; }
String parse(String string) { int length = string.length(); offsets = new Point[length / 4]; ids = new String[length / 4]; mnemonics = new int[length / 4 + 1]; StringBuffer result = new StringBuffer(); char[] buffer = new char[length]; string.getChars(0, string.length(), buffer, 0); int index = 0, state = 0, linkIndex = 0; int start = 0, tagStart = 0, linkStart = 0, endtagStart = 0, refStart = 0; while (index < length) { char c = Character.toLowerCase(buffer[index]); switch (state) { case 0: if (c == '<') { tagStart = index; state++; } break; case 1: if (c == 'a') state++; break; case 2: switch (c) { case 'h': state = 7; break; case '>': linkStart = index + 1; state++; break; default: if (Character.isWhitespace(c)) break; else state = 13; } break; case 3: if (c == '<') { endtagStart = index; state++; } break; case 4: state = c == '/' ? state + 1 : 3; break; case 5: state = c == 'a' ? state + 1 : 3; break; case 6: if (c == '>') { mnemonics[linkIndex] = parseMnemonics(buffer, start, tagStart, result); int offset = result.length(); parseMnemonics(buffer, linkStart, endtagStart, result); offsets[linkIndex] = new Point(offset, result.length() - 1); if (ids[linkIndex] == null) { ids[linkIndex] = new String(buffer, linkStart, endtagStart - linkStart); } linkIndex++; start = tagStart = linkStart = endtagStart = refStart = index + 1; state = 0; } else { state = 3; } break; case 7: state = c == 'r' ? state + 1 : 0; break; case 8: state = c == 'e' ? state + 1 : 0; break; case 9: state = c == 'f' ? state + 1 : 0; break; case 10: state = c == '=' ? state + 1 : 0; break; case 11: if (c == '"') { state++; refStart = index + 1; } else { state = 0; } break; case 12: if (c == '"') { ids[linkIndex] = new String(buffer, refStart, index - refStart); state = 2; } break; case 13: if (Character.isWhitespace(c)) { state = 0; } else if (c == '=') { state++; } break; case 14: state = c == '"' ? state + 1 : 0; break; case 15: if (c == '"') state = 2; break; default: state = 0; break; } index++; } if (start < length) { int tmp = parseMnemonics(buffer, start, tagStart, result); int mnemonic = parseMnemonics(buffer, Math.max(tagStart, linkStart), length, result); if (mnemonic == -1) mnemonic = tmp; mnemonics[linkIndex] = mnemonic; } else { mnemonics[linkIndex] = -1; } if (offsets.length != linkIndex) { Point[] newOffsets = new Point[linkIndex]; System.arraycopy(offsets, 0, newOffsets, 0, linkIndex); offsets = newOffsets; String[] newIDs = new String[linkIndex]; System.arraycopy(ids, 0, newIDs, 0, linkIndex); ids = newIDs; int[] newMnemonics = new int[linkIndex + 1]; System.arraycopy(mnemonics, 0, newMnemonics, 0, linkIndex + 1); mnemonics = newMnemonics; } return result.toString(); }
void scrollInPixels(int destX, int destY, int x, int y, int width, int height, boolean all) { forceResize(); boolean isFocus = caret != null && caret.isFocusCaret(); if (isFocus) caret.killFocus(); RECT sourceRect = new RECT(); OS.SetRect(sourceRect, x, y, x + width, y + height); RECT clientRect = new RECT(); OS.GetClientRect(handle, clientRect); if (OS.IntersectRect(clientRect, sourceRect, clientRect)) { if (OS.IsWinCE) { OS.UpdateWindow(handle); } else { int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; OS.RedrawWindow(handle, null, 0, flags); } } int deltaX = destX - x, deltaY = destY - y; if (findImageControl() != null) { if (OS.IsWinCE) { OS.InvalidateRect(handle, sourceRect, true); } else { int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE; if (all) flags |= OS.RDW_ALLCHILDREN; OS.RedrawWindow(handle, sourceRect, 0, flags); } OS.OffsetRect(sourceRect, deltaX, deltaY); if (OS.IsWinCE) { OS.InvalidateRect(handle, sourceRect, true); } else { int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE; if (all) flags |= OS.RDW_ALLCHILDREN; OS.RedrawWindow(handle, sourceRect, 0, flags); } } else { int flags = OS.SW_INVALIDATE | OS.SW_ERASE; /* * Feature in Windows. If any child in the widget tree partially * intersects the scrolling rectangle, Windows moves the child * and copies the bits that intersect the scrolling rectangle but * does not redraw the child. * * Feature in Windows. When any child in the widget tree does not * intersect the scrolling rectangle but the parent does intersect, * Windows does not move the child. This is the documented (but * strange) Windows behavior. * * The fix is to not use SW_SCROLLCHILDREN and move the children * explicitly after scrolling. */ // if (all) flags |= OS.SW_SCROLLCHILDREN; OS.ScrollWindowEx(handle, deltaX, deltaY, sourceRect, null, 0, null, flags); } if (all) { Control[] children = _getChildren(); for (int i = 0; i < children.length; i++) { Control child = children[i]; Rectangle rect = child.getBoundsInPixels(); if (Math.min(x + width, rect.x + rect.width) >= Math.max(x, rect.x) && Math.min(y + height, rect.y + rect.height) >= Math.max(y, rect.y)) { child.setLocationInPixels(rect.x + deltaX, rect.y + deltaY); } } } if (isFocus) caret.setFocus(); }
@Override void draw(Theme theme, GC gc, Rectangle bounds) { if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed()) { // TODO - drawScale not done int style = this.style; int minimum = this.minimum; int maximum = this.maximum; int selection = this.selection; int pageIncrement = this.pageIncrement; long /*int*/ hTheme = OS.OpenThemeData(0, getClassId()); RECT rect = new RECT(); rect.left = bounds.x; rect.right = rect.left + bounds.width; rect.top = bounds.y; rect.bottom = rect.top + bounds.height; SIZE size = new SIZE(); if ((style & SWT.VERTICAL) != 0) { OS.GetThemePartSize(hTheme, gc.handle, OS.TKP_TRACKVERT, 0, null, OS.TS_TRUE, size); int trackWidth = size.cx - 1; OS.GetThemePartSize(hTheme, gc.handle, OS.TKP_THUMBVERT, 0, null, OS.TS_TRUE, size); int thumbWidth = size.cx, thumbHeight = size.cy; OS.GetThemePartSize(hTheme, gc.handle, OS.TKP_TICS, 0, rect, OS.TS_TRUE, size); int ticWidth = size.cx; int marginX = (thumbWidth - trackWidth) / 2; int marginY = marginX; marginX += TICS_MARGIN; rect.left += marginX; rect.top += marginY; rect.right = rect.left + trackWidth; rect.bottom -= marginY; int trackHeight = rect.bottom - rect.top; OS.DrawThemeBackground(hTheme, gc.handle, OS.TKP_TRACKVERT, 0, rect, null); rect.top += ((trackHeight - thumbHeight) * (selection - minimum)) / Math.max(1, maximum - minimum); rect.left -= (thumbWidth - trackWidth) / 2; rect.right = rect.left + thumbWidth; rect.bottom = rect.top + thumbHeight; OS.DrawThemeBackground(hTheme, gc.handle, OS.TKP_THUMBVERT, 0, rect, null); rect.top = bounds.y + marginY + thumbHeight / 2; rect.bottom = rect.top + 1; for (int sel = minimum; sel <= maximum; sel += pageIncrement) { rect.left = bounds.x + TICS_MARGIN / 2; rect.right = rect.left + ticWidth; if (sel != minimum && sel != maximum) rect.left++; rect.top = bounds.y + marginY + thumbHeight / 2; rect.top += ((trackHeight - thumbHeight) * (sel - minimum)) / Math.max(1, maximum - minimum); rect.bottom = rect.top + 1; // TODO - why tics are ot drawn OS.DrawThemeBackground(hTheme, gc.handle, OS.TKP_TICSVERT, 1, rect, null); gc.drawLine(rect.left, rect.top, rect.right, rect.top); rect.left = bounds.x + TICS_MARGIN + thumbWidth + 1; rect.right = rect.left + ticWidth; if (sel != minimum && sel != maximum) rect.right--; // TODO - why tics are ot drawn OS.DrawThemeBackground(hTheme, gc.handle, OS.TKP_TICSVERT, 1, rect, null); gc.drawLine(rect.left, rect.top, rect.right, rect.top); } } else { } OS.CloseThemeData(hTheme); } }