📄 coolbar.java
字号:
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if item order or sizes is null</li> * <li>ERROR_INVALID_ARGUMENT - if item order or sizes is not the same length as the number of items</li> * </ul> * @exception SWTError <ul> * <li>ERROR_CANNOT_GET_ITEM - if the operation fails because of an operating system failure</li> * </ul> */public void setItemLayout (int [] itemOrder, int [] wrapIndices, Point [] sizes) { checkWidget (); setRedraw (false); setItemOrder (itemOrder); setWrapIndices (wrapIndices); setItemSizes (sizes); setRedraw (true);}/* * Sets the order that the items in the receiver should * be displayed in to the given argument which is described * in terms of the zero-relative ordering of when the items * were added. * * @param itemOrder the new order to display the items in * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the item order is null</li> * <li>ERROR_INVALID_ARGUMENT - if the item order is not the same length as the number of items</li> * </ul> * @exception SWTError <ul> * <li>ERROR_CANNOT_GET_ITEM - if the operation fails because of an operating system failure</li> * </ul> */void setItemOrder (int [] itemOrder) { if (itemOrder == null) error (SWT.ERROR_NULL_ARGUMENT); int itemCount = OS.SendMessage (handle, OS.RB_GETBANDCOUNT, 0, 0); if (itemOrder.length != itemCount) error (SWT.ERROR_INVALID_ARGUMENT); /* Ensure that itemOrder does not contain any duplicates. */ boolean [] set = new boolean [itemCount]; for (int i=0; i<itemOrder.length; i++) { int index = itemOrder [i]; if (index < 0 || index >= itemCount) error (SWT.ERROR_INVALID_RANGE); if (set [index]) error (SWT.ERROR_INVALID_ARGUMENT); set [index] = true; } REBARBANDINFO rbBand = new REBARBANDINFO (); rbBand.cbSize = REBARBANDINFO.sizeof; for (int i=0; i<itemOrder.length; i++) { int id = originalItems [itemOrder [i]].id; int index = OS.SendMessage (handle, OS.RB_IDTOINDEX, id, 0); if (index != i) { int lastItemSrcRow = getLastIndexOfRow (index); int lastItemDstRow = getLastIndexOfRow (i); if (index == lastItemSrcRow) { resizeToPreferredWidth (index); } if (i == lastItemDstRow) { resizeToPreferredWidth (i); } /* Move the item */ OS.SendMessage (handle, OS.RB_MOVEBAND, index, i); if (index == lastItemSrcRow && index - 1 >= 0) { resizeToMaximumWidth (index - 1); } if (i == lastItemDstRow) { resizeToMaximumWidth (i); } } }}/* * Sets the width and height of the receiver's items to the ones * specified by the argument, which is an array of points whose x * and y coordinates describe the widths and heights (respectively) * in the order in which the items are currently being displayed. * * @param sizes an array containing the new sizes for each of the receiver's items in visual order * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the array of sizes is null</li> * <li>ERROR_INVALID_ARGUMENT - if the array of sizes is not the same length as the number of items</li> * </ul> * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */void setItemSizes (Point [] sizes) { if (sizes == null) error (SWT.ERROR_NULL_ARGUMENT); int count = OS.SendMessage (handle, OS.RB_GETBANDCOUNT, 0, 0); if (sizes.length != count) error (SWT.ERROR_INVALID_ARGUMENT); REBARBANDINFO rbBand = new REBARBANDINFO (); rbBand.cbSize = REBARBANDINFO.sizeof; rbBand.fMask = OS.RBBIM_ID; for (int i=0; i<count; i++) { OS.SendMessage (handle, OS.RB_GETBANDINFO, i, rbBand); items [rbBand.wID].setSize (sizes [i].x, sizes [i].y); }}/** * Sets whether or not the receiver is 'locked'. When a coolbar * is locked, its items cannot be repositioned. * * @param locked lock the coolbar if true, otherwise unlock the coolbar * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> * * @since 2.0 */public void setLocked (boolean locked) { checkWidget (); this.locked = locked; int count = OS.SendMessage (handle, OS.RB_GETBANDCOUNT, 0, 0); REBARBANDINFO rbBand = new REBARBANDINFO (); rbBand.cbSize = REBARBANDINFO.sizeof; rbBand.fMask = OS.RBBIM_STYLE; for (int i=0; i<count; i++) { OS.SendMessage (handle, OS.RB_GETBANDINFO, i, rbBand); if (locked) { rbBand.fStyle |= OS.RBBS_NOGRIPPER; } else { rbBand.fStyle &= ~OS.RBBS_NOGRIPPER; } OS.SendMessage (handle, OS.RB_SETBANDINFO, i, rbBand); }}/** * Sets the indices of all item(s) in the receiver that will * begin on a new row. The indices are given in the order in * which they are currently being displayed. The 0th item * always begins the first row, therefore it does not count * as a wrap index. If indices is null or empty, the items * will be placed on one line. * * @param indices an array of wrap indices, or null * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */public void setWrapIndices (int [] indices) { checkWidget (); if (indices == null) indices = new int [0]; int count = getItemCount (); for (int i=0; i<indices.length; i++) { if (indices [i] < 0 || indices [i] >= count) { error (SWT.ERROR_INVALID_RANGE); } } setRedraw (false); CoolItem [] items = getItems (); for (int i=0; i<items.length; i++) { CoolItem item = items [i]; if (item.getWrap ()) { resizeToPreferredWidth (i - 1); item.setWrap (false); } } resizeToMaximumWidth (count - 1); for (int i=0; i<indices.length; i++) { int index = indices [i]; if (0 <= index && index < items.length) { CoolItem item = items [index]; item.setWrap (true); resizeToMaximumWidth (index - 1); } } setRedraw (true);}int widgetStyle () { int bits = super.widgetStyle () | OS.CCS_NODIVIDER | OS.CCS_NORESIZE; bits |= OS.RBS_VARHEIGHT | OS.RBS_DBLCLKTOGGLE; if ((style & SWT.FLAT) == 0) bits |= OS.RBS_BANDBORDERS; return bits;}TCHAR windowClass () { return ReBarClass;}int windowProc () { return ReBarProc;}LRESULT WM_COMMAND (int wParam, int lParam) { /* * Feature in Windows. When the coolbar window * proc processes WM_COMMAND, it forwards this * message to its parent. This is done so that * children of this control that send this message * type to their parent will notify not only * this control but also the parent of this control, * which is typically the application window and * the window that is looking for the message. * If the control did not forward the message, * applications would have to subclass the control * window to see the message. Because the control * window is subclassed by SWT, the message * is delivered twice, once by SWT and once when * the message is forwarded by the window proc. * The fix is to avoid calling the window proc * for this control. */ LRESULT result = super.WM_COMMAND (wParam, lParam); if (result != null) return result; return LRESULT.ZERO;}LRESULT WM_ERASEBKGND (int wParam, int lParam) { LRESULT result = super.WM_ERASEBKGND (wParam, lParam); if (result != null) return result; /* * Feature in Windows. For some reason, Windows * does not fully erase the area that the cool bar * occupies when the size of the cool bar is larger * than the space occupied by the cool bar items. * The fix is to erase the cool bar background. * * NOTE: On versions of Windows prior to XP, for * some reason, the cool bar draws separators in * WM_ERASEBKGND. Therefore it is essential to run * the cool bar window proc after the background has * been erased. * * On XP, this work around is unnecessary because * the background is drawn using NM_CUSTOMDRAW. */ if (OS.COMCTL32_MAJOR < 6) drawBackground (wParam); return null;}LRESULT WM_NOTIFY (int wParam, int lParam) { /* * Feature in Windows. When the cool bar window * proc processes WM_NOTIFY, it forwards this * message to its parent. This is done so that * children of this control that send this message * type to their parent will notify not only * this control but also the parent of this control, * which is typically the application window and * the window that is looking for the message. * If the control did not forward the message, * applications would have to subclass the control * window to see the message. Because the control * window is subclassed by SWT, the message * is delivered twice, once by SWT and once when * the message is forwarded by the window proc. * The fix is to avoid calling the window proc * for this control. */ LRESULT result = super.WM_NOTIFY (wParam, lParam); if (result != null) return result; return LRESULT.ZERO;}LRESULT WM_SETREDRAW (int wParam, int lParam) { LRESULT result = super.WM_SETREDRAW (wParam, lParam); if (result != null) return result; /* * Feature in Windows. When redraw is turned off, the rebar * control does not call the default window proc. This means * that the rebar will redraw and children of the rebar will * also redraw. The fix is to call both the rebar window proc * and the default window proc. * * NOTE: The rebar control can resize itself in WM_SETREDRAW. * When redraw is turned off by the default window proc, this * can leave pixel corruption in the parent. The fix is to * detect the size change and damage the previous area in the * parent. * * NOTE: In version 6.00 of COMCTL32.DLL, when WM_SETREDRAW * is off, we cannot detect that the size has changed causing * pixel corruption. The fix is to disallow WM_SETREDRAW by * not running the default window proc or the rebar window * proc. */ if (OS.COMCTL32_MAJOR >= 6) return LRESULT.ZERO; Rectangle rect = getBounds (); int code = callWindowProc (OS.WM_SETREDRAW, wParam, lParam); OS.DefWindowProc (handle, OS.WM_SETREDRAW, wParam, lParam); if (!rect.equals (getBounds ())) { parent.redraw (rect.x, rect.y, rect.width, rect.height, true); } return new LRESULT (code);}LRESULT WM_SIZE(int wParam, int lParam) { if (ignoreResize) { int code = callWindowProc (OS.WM_SIZE, wParam, lParam); if (code == 0) return LRESULT.ZERO; return new LRESULT (code); } return super.WM_SIZE(wParam, lParam);}LRESULT wmNotifyChild (int wParam, int lParam) { NMHDR hdr = new NMHDR (); OS.MoveMemory (hdr, lParam, NMHDR.sizeof); switch (hdr.code) { case OS.RBN_HEIGHTCHANGE: if (!ignoreResize) { Point size = getSize (); int border = getBorderWidth (); int height = OS.SendMessage (handle, OS.RB_GETBARHEIGHT, 0, 0); setSize (size.x, height + (border * 2)); } break; case OS.RBN_CHEVRONPUSHED: NMREBARCHEVRON lpnm = new NMREBARCHEVRON (); OS.MoveMemory (lpnm, lParam, NMREBARCHEVRON.sizeof); CoolItem child = items [lpnm.wID]; if (child != null) { Event event = new Event(); event.detail = SWT.ARROW; event.x = lpnm.left; event.y = lpnm.bottom; child.postEvent (SWT.Selection, event); } break; case OS.NM_CUSTOMDRAW: /* * Bug in Windows. On versions of Windows prior to XP, * drawing the background color in NM_CUSTOMDRAW erases * the separators. The fix is to draw the background * in WM_ERASEBKGND. */ if (OS.COMCTL32_MAJOR < 6) break; if (background != -1 || (style & SWT.FLAT) != 0) { NMCUSTOMDRAW nmcd = new NMCUSTOMDRAW (); OS.MoveMemory (nmcd, lParam, NMCUSTOMDRAW.sizeof); switch (nmcd.dwDrawStage) { case OS.CDDS_PREERASE: return new LRESULT (OS.CDRF_NOTIFYPOSTERASE); case OS.CDDS_POSTERASE: drawBackground (nmcd.hdc); break; } } break; } return super.wmNotifyChild (wParam, lParam);}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -