?? tree.java
字號:
return new LRESULT (code); } } if (OS.GetKeyState (OS.VK_CONTROL) < 0) { int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); if (hItem != 0) { TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_STATE; tvItem.stateMask = OS.TVIS_SELECTED; tvItem.hItem = hItem; OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); boolean oldSelected = (tvItem.state & OS.TVIS_SELECTED) != 0; int hNewItem = 0; switch (wParam) { case OS.VK_UP: hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PREVIOUSVISIBLE, hItem); break; case OS.VK_DOWN: hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hItem); break; case OS.VK_HOME: hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); break; case OS.VK_PRIOR: hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); if (hNewItem == hItem) { OS.SendMessage (handle, OS.WM_VSCROLL, OS.SB_PAGEUP, 0); hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); } break; case OS.VK_NEXT: RECT rect = new RECT (), clientRect = new RECT (); OS.GetClientRect (handle, clientRect); hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); do { int hVisible = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hNewItem); if (hVisible == 0) break; rect.left = hVisible; OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect); if (rect.bottom > clientRect.bottom) break; if ((hNewItem = hVisible) == hItem) { OS.SendMessage (handle, OS.WM_VSCROLL, OS.SB_PAGEDOWN, 0); } } while (hNewItem != 0); break; case OS.VK_END: hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); break; } if (hNewItem != 0) { OS.SendMessage (handle, OS.TVM_ENSUREVISIBLE, 0, hNewItem); tvItem.hItem = hNewItem; OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); boolean newSelected = (tvItem.state & OS.TVIS_SELECTED) != 0; if (!newSelected && drawCount == 0) { OS.UpdateWindow (handle); OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); /* * This code is intentionally commented. */// OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); } ignoreSelect = true; OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, hNewItem); ignoreSelect = false; if (oldSelected) { tvItem.state = OS.TVIS_SELECTED; tvItem.hItem = hItem; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); } if (!newSelected) { tvItem.state = 0; tvItem.hItem = hNewItem; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); } if (!newSelected && drawCount == 0) { RECT rect1 = new RECT (), rect2 = new RECT (); rect1.left = hItem; rect2.left = hNewItem; OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect1); OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect2); /* * This code is intentionally commented. */// OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0); OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); if (OS.IsWinCE) { OS.InvalidateRect (handle, rect1, false); OS.InvalidateRect (handle, rect2, false); OS.UpdateWindow (handle); } else { int flags = OS.RDW_UPDATENOW | OS.RDW_INVALIDATE; OS.RedrawWindow (handle, rect1, 0, flags); OS.RedrawWindow (handle, rect2, 0, flags); } } return LRESULT.ZERO; } } } int code = callWindowProc (OS.WM_KEYDOWN, wParam, lParam); hAnchor = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); return new LRESULT (code); } } return result;}LRESULT WM_KILLFOCUS (int wParam, int lParam) { LRESULT result = super.WM_KILLFOCUS (wParam, lParam); if ((style & SWT.SINGLE) != 0) return result; /* * Feature in Windows. When multiple item have * the TVIS_SELECTED state, Windows redraws only * the focused item in the color used to show the * selection when the tree loses or gains focus. * The fix is to force Windows to redraw all the * visible items when focus is gained or lost. */ OS.InvalidateRect (handle, null, false); return result;}LRESULT WM_LBUTTONDOWN (int wParam, int lParam) { /* * Feature in Windows. When a tree item is * reselected, Windows does not issue a WM_NOTIFY. * This is inconsistent with the list widget and * other widgets in Windows. The fix is to detect * the case when an item is reselected and issue * the notification. The first part of this work * around is to ensure that the user has selected * an item. */ TVHITTESTINFO lpht = new TVHITTESTINFO (); lpht.x = (short) (lParam & 0xFFFF); lpht.y = (short) (lParam >> 16); OS.SendMessage (handle, OS.TVM_HITTEST, 0, lpht); if (lpht.hItem == 0 || (lpht.flags & OS.TVHT_ONITEM) == 0) { sendMouseEvent (SWT.MouseDown, 1, OS.WM_LBUTTONDOWN, wParam, lParam); int code = callWindowProc (OS.WM_LBUTTONDOWN, wParam, lParam); if (OS.GetCapture () != handle) OS.SetCapture (handle); return new LRESULT (code); } /* Look for check/uncheck */ if ((style & SWT.CHECK) != 0) { if ((lpht.flags & OS.TVHT_ONITEMSTATEICON) != 0) { TVITEM tvItem = new TVITEM (); tvItem.hItem = lpht.hItem; tvItem.mask = OS.TVIF_PARAM | OS.TVIF_STATE; tvItem.stateMask = OS.TVIS_STATEIMAGEMASK; OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); int state = tvItem.state >> 12; if ((state & 0x1) != 0) { state++; } else { --state; } tvItem.state = state << 12; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); if (!OS.IsWinCE) { int id = tvItem.hItem; if (OS.COMCTL32_MAJOR >= 6) { id = OS.SendMessage (handle, OS.TVM_MAPHTREEITEMTOACCID, tvItem.hItem, 0); } OS.NotifyWinEvent (OS.EVENT_OBJECT_FOCUS, handle, OS.OBJID_CLIENT, id); } Event event = new Event (); event.item = items [tvItem.lParam]; event.detail = SWT.CHECK; postEvent (SWT.Selection, event); sendMouseEvent (SWT.MouseDown, 1, OS.WM_LBUTTONDOWN, wParam, lParam); if (OS.GetCapture () != handle) OS.SetCapture (handle); return LRESULT.ZERO; } } /* Get the selected state of the item under the mouse */ TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_STATE; tvItem.stateMask = OS.TVIS_SELECTED; boolean hittestSelected = false; if ((style & SWT.MULTI) != 0) { tvItem.hItem = lpht.hItem; OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); hittestSelected = (tvItem.state & OS.TVIS_SELECTED) != 0; } /* Get the selected state of the last selected item */ int hOldItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); if ((style & SWT.MULTI) != 0) { tvItem.hItem = hOldItem; OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); /* Check for CONTROL or drag selection */ if (hittestSelected || (wParam & OS.MK_CONTROL) != 0) { if (drawCount == 0) { OS.UpdateWindow (handle); OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); /* * This code is intentionally commented. */// OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); } } else { deselectAll (); } } /* Do the selection */ sendMouseEvent (SWT.MouseDown, 1, OS.WM_LBUTTONDOWN, wParam, lParam); dragStarted = gestureCompleted = false; ignoreDeselect = ignoreSelect = true; int code = callWindowProc (OS.WM_LBUTTONDOWN, wParam, lParam); ignoreDeselect = ignoreSelect = false; if (dragStarted && OS.GetCapture () != handle) OS.SetCapture (handle); int hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); /* * Feature in Windows. When the old and new focused item * are the same, Windows does not check to make sure that * the item is actually selected, not just focused. The * fix is to force the item to draw selected by setting * the state mask. This is only necessary when the tree * is single select. */ if ((style & SWT.SINGLE) != 0) { if (hOldItem == hNewItem) { tvItem.mask = OS.TVIF_STATE; tvItem.state = OS.TVIS_SELECTED; tvItem.stateMask = OS.TVIS_SELECTED; tvItem.hItem = hNewItem; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); } } /* Reselect the last item that was unselected */ if ((style & SWT.MULTI) != 0) { /* Check for CONTROL and reselect the last item */ if (hittestSelected || (wParam & OS.MK_CONTROL) != 0) { if (hOldItem == hNewItem && hOldItem == lpht.hItem) { if ((wParam & OS.MK_CONTROL) != 0) { tvItem.state ^= OS.TVIS_SELECTED; if (dragStarted) tvItem.state = OS.TVIS_SELECTED; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); } } else { if ((tvItem.state & OS.TVIS_SELECTED) != 0) { tvItem.state = OS.TVIS_SELECTED; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); } if ((wParam & OS.MK_CONTROL) != 0 && !dragStarted) { if (hittestSelected) { tvItem.state = 0; tvItem.hItem = lpht.hItem; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); } } } if (drawCount == 0) { RECT rect1 = new RECT (), rect2 = new RECT (); rect1.left = hOldItem; rect2.left = hNewItem; OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect1); OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect2); /* * This code is intentionally commented. */// OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0); OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); if (OS.IsWinCE) { OS.InvalidateRect (handle, rect1, false); OS.InvalidateRect (handle, rect2, false); OS.UpdateWindow (handle); } else { int flags = OS.RDW_UPDATENOW | OS.RDW_INVALIDATE; OS.RedrawWindow (handle, rect1, 0, flags); OS.RedrawWindow (handle, rect2, 0, flags); } } } /* Check for SHIFT or normal select and delect/reselect items */ if ((wParam & OS.MK_CONTROL) == 0) { if (!hittestSelected || !dragStarted) { tvItem.state = 0; int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); OS.SetWindowLong (handle, OS.GWL_WNDPROC, TreeProc); for (int i=0; i<items.length; i++) { TreeItem item = items [i]; if (item != null && item.handle != hNewItem) { tvItem.hItem = item.handle; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); } } tvItem.hItem = hNewItem; tvItem.state = OS.TVIS_SELECTED; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); if ((wParam & OS.MK_SHIFT) != 0) { RECT rect1 = new RECT (); if (hAnchor == 0) hAnchor = hNewItem; rect1.left = hAnchor; if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect1) != 0) { RECT rect2 = rect2 = new RECT (); rect2.left = hNewItem; OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect2); int flags = rect1.top < rect2.top ? OS.TVGN_NEXTVISIBLE : OS.TVGN_PREVIOUSVISIBLE; tvItem.state = OS.TVIS_SELECTED; int hItem = tvItem.hItem = hAnchor; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); while (hItem != hNewItem) { tvItem.hItem = hItem; OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, flags, hItem); } } } } } } if ((wParam & OS.MK_SHIFT) == 0) hAnchor = hNewItem; /* Issue notification */ if (!gestureCompleted) { tvItem.hItem = hNewItem; tvItem.mask = OS.TVIF_PARAM; OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); Event event = new Event (); event.item = items [tvItem.lParam]; postEvent (SWT.Selection, event); } gestureCompleted = false; /* * Feature in Windows. Inside WM_LBUTTONDOWN and WM_RBUTTONDOWN, * the widget starts a modal loop to determine if the user wants * to begin a drag/drop operation or marque select. Unfortunately, * this modal loop eats the corresponding mouse up. The fix is to * detect the cases when the modal loop has eaten the mouse up and * issue a fake mouse up. */ if (dragStarted) { Event event = new Event (); event.x = (short) (lParam & 0xFFFF); event.y = (short) (lParam >> 16); postEvent (SWT.DragDetect, event); } else { sendMouseEvent (SWT.MouseUp, 1, OS.WM_LBUTTONUP, wParam, lParam); } dragStarted = false; return new LRESULT (code);}LRESULT WM_RBUTTONDOWN (int wParam, int lParam) { /* * Feature in Windows. The receiver uses WM_RBUTTONDOWN * to initiate a drag/drop operation depending on how the * user moves the mouse. If the user clicks the right button, * without moving the mouse, the tree consumes the corresponding * WM_RBUTTONUP. The fix is to avoid calling the window proc for * the tree. */ sendMouseEvent (SWT.MouseDown, 3, OS.WM_RBUTTONDOWN, wParam, lParam); /* * This code is intentionally commented. */// if (OS.GetCapture () != handle) OS.SetCapture (handle); setFocus (); /* * Feature in Windows. When the user selects a tree item * with the right mouse button, the item remains selected * only as long as the user does not release or move the * mouse. As soon as this happens, the selection snaps * back to the previous selection. This behavior can be * observed in the Explorer but is not instantly apparent * because
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -