?? toolbar.java
字號:
* style BTNS_SEP and TB_SETROWS is used to set the number of rows * in the tool bar, depending on the number of buttons, the toolbar * will wrap items with the style BTNS_CHECK, even when the fLarger * flags is used to force the number of rows to be larger than the * number of items. The fix is to set the number of rows to be two * larger than the actual number of rows in the tool bar. When items * are being added, as long as the number of rows is at least one * item larger than the count, the tool bar is layed out properly. * When items are being removed, setting the number of rows to be * one more than the item count has no effect. The number of rows * is already one more causing TB_SETROWS to do nothing. Therefore, * choosing two instead of one as the row increment fixes both cases. */ count += 2; OS.SendMessage (handle, OS.TB_SETROWS, (1 << 16) | count, 0); int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOZORDER; SetWindowPos (handle, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, flags); ignoreResize = false; }}boolean setTabItemFocus () { int index = 0; while (index < items.length) { ToolItem item = items [index]; if (item != null && (item.style & SWT.SEPARATOR) == 0) { if (item.getEnabled ()) break; } index++; } if (index == items.length) return false; return super.setTabItemFocus ();}String toolTipText (NMTTDISPINFO hdr) { if ((hdr.uFlags & OS.TTF_IDISHWND) != 0) { return null; } /* * Bug in Windows. On Windows XP, when TB_SETHOTITEM is * used to set the hot item, the tool bar control attempts * to display the tool tip, even when the cursor is not in * the hot item. The fix is to detect this case and fail to * provide the string, causing no tool tip to be displayed. */ if (!hasCursor ()) return ""; //$NON-NLS-1$ int index = hdr.idFrom; int hwndToolTip = OS.SendMessage (handle, OS.TB_GETTOOLTIPS, 0, 0); if (hwndToolTip == hdr.hwndFrom) { if (toolTipText != null) return ""; //$NON-NLS-1$ if (0 <= index && index < items.length) { ToolItem item = items [index]; if (item != null) return item.toolTipText; } } return super.toolTipText (hdr);}int widgetStyle () { int bits = super.widgetStyle () | OS.CCS_NORESIZE | OS.TBSTYLE_TOOLTIPS | OS.TBSTYLE_CUSTOMERASE; if ((style & SWT.SHADOW_OUT) == 0) bits |= OS.CCS_NODIVIDER; if ((style & SWT.WRAP) != 0) bits |= OS.TBSTYLE_WRAPABLE; if ((style & SWT.FLAT) != 0) bits |= OS.TBSTYLE_FLAT; if ((style & SWT.RIGHT) != 0) bits |= OS.TBSTYLE_LIST; return bits;}TCHAR windowClass () { return ToolBarClass;}int windowProc () { return ToolBarProc;}LRESULT WM_COMMAND (int wParam, int lParam) { /* * Feature in Windows. When the toolbar 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_GETDLGCODE (int wParam, int lParam) { LRESULT result = super.WM_GETDLGCODE (wParam, lParam); /* * Return DLGC_BUTTON so that mnemonics will be * processed without needing to press the ALT key * when the widget has focus. */ if (result != null) return result; return new LRESULT (OS.DLGC_BUTTON);}LRESULT WM_KEYDOWN (int wParam, int lParam) { LRESULT result = super.WM_KEYDOWN (wParam, lParam); if (result != null) return result; switch (wParam) { case OS.VK_SPACE: int index = OS.SendMessage (handle, OS.TB_GETHOTITEM, 0, 0); if (index != -1) { TBBUTTON lpButton = new TBBUTTON (); int code = OS.SendMessage (handle, OS.TB_GETBUTTON, index, lpButton); if (code != 0) { items [lpButton.idCommand].click (false); return LRESULT.ZERO; } } } return result;}LRESULT WM_KILLFOCUS (int wParam, int lParam) { int index = OS.SendMessage (handle, OS.TB_GETHOTITEM, 0, 0); TBBUTTON lpButton = new TBBUTTON (); int code = OS.SendMessage (handle, OS.TB_GETBUTTON, index, lpButton); if (code != 0) lastFocusId = lpButton.idCommand; return super.WM_KILLFOCUS (wParam, lParam);}LRESULT WM_NOTIFY (int wParam, int lParam) { /* * Feature in Windows. When the toolbar 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_SETFOCUS (int wParam, int lParam) { LRESULT result = super.WM_SETFOCUS (wParam, lParam); if (lastFocusId != -1 && handle == OS.GetFocus ()) { int index = OS.SendMessage (handle, OS.TB_COMMANDTOINDEX, lastFocusId, 0); OS.SendMessage (handle, OS.TB_SETHOTITEM, index, 0); } return result;}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); } /* * Feature in Windows. When a tool bar that contains * separators is wrapped, under certain circumstances, * Windows redraws the entire tool bar unnecessarily * when resized and no item moves. Whether the entire * toolbar is damaged or not seems to depend on the size * of the tool bar and the position of the separators. * The fix is to ensure that the newly exposed areas are * always damaged, and avoid the redraw when no tool item * moves. */ RECT [] rects = null; int rgn = 0, oldCount = 0; boolean fixRedraw = drawCount == 0 && (style & SWT.WRAP) != 0 && OS.IsWindowVisible (handle) && OS.SendMessage (handle, OS.TB_GETROWS, 0, 0) != 1; if (fixRedraw) { rgn = OS.CreateRectRgn (0, 0, 0, 0); OS.GetUpdateRgn (handle, rgn, false); oldCount = OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0); rects = new RECT [oldCount]; for (int i=0; i<oldCount; i++) { rects [i] = new RECT (); OS.SendMessage (handle, OS.TB_GETITEMRECT, i, rects [i]); } } LRESULT result = super.WM_SIZE (wParam, lParam); /* * It is possible (but unlikely), that application * code could have disposed the widget in the resize * event. If this happens, end the processing of the * Windows message by returning the result of the * WM_SIZE message. */ if (isDisposed ()) return result; if (fixRedraw) { int newCount = OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0); if (newCount == oldCount) { int index = 0; RECT rect = new RECT (); while (index < newCount) { OS.SendMessage (handle, OS.TB_GETITEMRECT, index, rect); if (!OS.EqualRect (rects [index], rect)) break; index++; } if (index == newCount) { OS.ValidateRect (handle, null); OS.InvalidateRgn (handle, rgn, false); } } OS.DeleteObject (rgn); } layoutItems (); return result;}LRESULT WM_WINDOWPOSCHANGING (int wParam, int lParam) { LRESULT result = super.WM_WINDOWPOSCHANGING (wParam, lParam); if (result != null) return result; /* * Feature in Windows. When a tool bar that contains * separators is wrapped, under certain circumstances, * Windows redraws the entire tool bar unnecessarily * when resized no item is moves. Whether the entire * toolbar is damaged or not seems to depend on the * size of the tool bar and the position of the separators. * The fix is to ensure that the newly exposed areas are * always damaged, and avoid the redraw when no tool item * moves. */ if (drawCount != 0) return result; if ((style & SWT.WRAP) == 0) return result; if (!OS.IsWindowVisible (handle)) return result; if (OS.SendMessage (handle, OS.TB_GETROWS, 0, 0) == 1) { return result; } WINDOWPOS lpwp = new WINDOWPOS (); OS.MoveMemory (lpwp, lParam, WINDOWPOS.sizeof); if ((lpwp.flags & (OS.SWP_NOSIZE | OS.SWP_NOREDRAW)) != 0) { return result; } RECT oldRect = new RECT (); OS.GetClientRect (handle, oldRect); RECT newRect = new RECT (); OS.SetRect (newRect, 0, 0, lpwp.cx, lpwp.cy); OS.SendMessage (handle, OS.WM_NCCALCSIZE, 0, newRect); int oldWidth = oldRect.right - oldRect.left; int oldHeight = oldRect.bottom - oldRect.top; int newWidth = newRect.right - newRect.left; int newHeight = newRect.bottom - newRect.top; if (newWidth > oldWidth) { /* * Bug in Windows. When a flat tool bar is wrapped, * Windows draws a horizontal separator between the * rows. The tool bar does not draw the first or * the last two pixels of this separator. When the * toolbar is resized to be bigger, only the new * area is drawn and the last two pixels, which are * blank are drawn over by separator. This leaves * garbage on the screen. The fix is to damage the * pixels. */ RECT rect = new RECT (); OS.SetRect (rect, oldWidth - 2, 0, oldWidth, newHeight); OS.InvalidateRect (handle, rect, false); OS.SetRect (rect, oldRect.right, newRect.top, newRect.right, newRect.bottom); OS.InvalidateRect (handle, rect, true); } if (newHeight > oldHeight) { RECT rect = new RECT (); OS.SetRect (rect, newRect.left, oldRect.bottom, newRect.right, newRect.bottom); OS.InvalidateRect (handle, rect, true); } return result;}LRESULT wmCommandChild (int wParam, int lParam) { ToolItem child = items [wParam & 0xFFFF]; if (child == null) return null; return child.wmCommandChild (wParam, lParam);}LRESULT wmNotifyChild (int wParam, int lParam) { NMHDR hdr = new NMHDR (); OS.MoveMemory (hdr, lParam, NMHDR.sizeof); switch (hdr.code) { case OS.TBN_DROPDOWN: NMTOOLBAR lpnmtb = new NMTOOLBAR (); OS.MoveMemory (lpnmtb, lParam, NMTOOLBAR.sizeof); ToolItem child = items [lpnmtb.iItem]; if (child != null) { Event event = new Event (); event.detail = SWT.ARROW; int index = OS.SendMessage (handle, OS.TB_COMMANDTOINDEX, lpnmtb.iItem, 0); RECT rect = new RECT (); OS.SendMessage (handle, OS.TB_GETITEMRECT, index, rect); event.x = rect.left; event.y = rect.bottom; child.postEvent (SWT.Selection, event); } break; case OS.NM_CUSTOMDRAW: if (background == -1) break; 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); return null; } break; } return super.wmNotifyChild (wParam, lParam);}}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -