Пример #1
0
 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();
 }
Пример #2
0
  private void drag(Event dragEvent) {
    DNDEvent event = new DNDEvent();
    event.widget = this;
    event.x = dragEvent.x;
    event.y = dragEvent.y;
    event.time = OS.GetMessageTime();
    event.doit = true;
    notifyListeners(DND.DragStart, event);
    if (!event.doit || transferAgents == null || transferAgents.length == 0) return;

    int[] pdwEffect = new int[1];
    int operations = opToOs(getStyle());
    Display display = control.getDisplay();
    String key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; // $NON-NLS-1$
    Object oldValue = display.getData(key);
    display.setData(key, Boolean.TRUE);
    ImageList imagelist = null;
    Image image = event.image;
    hwndDrag = 0;
    topControl = null;
    if (image != null) {
      imagelist = new ImageList(SWT.NONE);
      imagelist.add(image);
      topControl = control.getShell();
      /*
       * Bug in Windows. The image is inverted if the shell is RIGHT_TO_LEFT.
       * The fix is to create a transparent window that covers the shell client
       * area and use it during the drag to prevent the image from being inverted.
       * On XP if the shell is RTL, the image is not displayed.
       */
      int offsetX = event.offsetX;
      hwndDrag = topControl.handle;
      if ((topControl.getStyle() & SWT.RIGHT_TO_LEFT) != 0) {
        offsetX = image.getBounds().width - offsetX;
        RECT rect = new RECT();
        OS.GetClientRect(topControl.handle, rect);
        hwndDrag =
            OS.CreateWindowEx(
                OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT,
                WindowClass,
                null,
                OS.WS_CHILD | OS.WS_CLIPSIBLINGS,
                0,
                0,
                rect.right - rect.left,
                rect.bottom - rect.top,
                topControl.handle,
                0,
                OS.GetModuleHandle(null),
                null);
        OS.ShowWindow(hwndDrag, OS.SW_SHOW);
      }
      OS.ImageList_BeginDrag(imagelist.getHandle(), 0, offsetX, event.offsetY);
      /*
       * Feature in Windows. When ImageList_DragEnter() is called,
       * it takes a snapshot of the screen  If a drag is started
       * when another window is in front, then the snapshot will
       * contain part of the other window, causing pixel corruption.
       * The fix is to force all paints to be delivered before
       * calling ImageList_DragEnter().
       */
      if (OS.IsWinCE) {
        OS.UpdateWindow(topControl.handle);
      } else {
        int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
        OS.RedrawWindow(topControl.handle, null, 0, flags);
      }
      POINT pt = new POINT();
      pt.x = dragEvent.x;
      pt.y = dragEvent.y;
      OS.MapWindowPoints(control.handle, 0, pt, 1);
      RECT rect = new RECT();
      OS.GetWindowRect(hwndDrag, rect);
      OS.ImageList_DragEnter(hwndDrag, pt.x - rect.left, pt.y - rect.top);
    }
    int result = COM.DRAGDROP_S_CANCEL;
    try {
      result =
          COM.DoDragDrop(iDataObject.getAddress(), iDropSource.getAddress(), operations, pdwEffect);
    } finally {
      // ensure that we don't leave transparent window around
      if (hwndDrag != 0) {
        OS.ImageList_DragLeave(hwndDrag);
        OS.ImageList_EndDrag();
        imagelist.dispose();
        if (hwndDrag != topControl.handle) OS.DestroyWindow(hwndDrag);
        hwndDrag = 0;
        topControl = null;
      }
      display.setData(key, oldValue);
    }
    int operation = osToOp(pdwEffect[0]);
    if (dataEffect == DND.DROP_MOVE) {
      operation =
          (operation == DND.DROP_NONE || operation == DND.DROP_COPY)
              ? DND.DROP_TARGET_MOVE
              : DND.DROP_MOVE;
    } else {
      if (dataEffect != DND.DROP_NONE) {
        operation = dataEffect;
      }
    }
    event = new DNDEvent();
    event.widget = this;
    event.time = OS.GetMessageTime();
    event.doit = (result == COM.DRAGDROP_S_DROP);
    event.detail = operation;
    notifyListeners(DND.DragEnd, event);
    dataEffect = DND.DROP_NONE;
  }