]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/widgets/Control.java
Remove invalid SHA-256-Digests
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / widgets / Control.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2019 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     Stefan Xenos (Google) - bug 468854 - Add a requestLayout method to Control
14  *******************************************************************************/
15 package org.eclipse.swt.widgets;
16
17
18 import org.eclipse.swt.*;
19 import org.eclipse.swt.accessibility.*;
20 import org.eclipse.swt.events.*;
21 import org.eclipse.swt.graphics.*;
22 import org.eclipse.swt.internal.*;
23 import org.eclipse.swt.internal.gdip.*;
24 import org.eclipse.swt.internal.win32.*;
25
26 /**
27  * Control is the abstract superclass of all windowed user interface classes.
28  * <dl>
29  * <dt><b>Styles:</b>
30  * <dd>BORDER</dd>
31  * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT, FLIP_TEXT_DIRECTION</dd>
32  * <dt><b>Events:</b>
33  * <dd>DragDetect, FocusIn, FocusOut, Help, KeyDown, KeyUp, MenuDetect, MouseDoubleClick, MouseDown, MouseEnter,
34  *     MouseExit, MouseHover, MouseUp, MouseMove, MouseWheel, MouseHorizontalWheel, MouseVerticalWheel, Move,
35  *     Paint, Resize, Traverse</dd>
36  * </dl>
37  * <p>
38  * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
39  * </p><p>
40  * IMPORTANT: This class is intended to be subclassed <em>only</em>
41  * within the SWT implementation.
42  * </p>
43  *
44  * @see <a href="http://www.eclipse.org/swt/snippets/#control">Control snippets</a>
45  * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
46  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
47  * @noextend This class is not intended to be subclassed by clients.
48  */
49 public abstract class Control extends Widget implements Drawable {
50
51         /**
52          * the handle to the OS resource
53          * (Warning: This field is platform dependent)
54          * <p>
55          * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
56          * public API. It is marked public only so that it can be shared
57          * within the packages provided by SWT. It is not available on all
58          * platforms and should never be accessed from application code.
59          * </p>
60          *
61          * @noreference This field is not intended to be referenced by clients.
62          */
63         public long handle;
64         Composite parent;
65         Cursor cursor;
66         Menu menu, activeMenu;
67         String toolTipText;
68         Object layoutData;
69         Accessible accessible;
70         Image backgroundImage;
71         Region region;
72         Font font;
73         int drawCount, foreground, background, backgroundAlpha = 255;
74
75 /**
76  * Prevents uninitialized instances from being created outside the package.
77  */
78 Control () {
79 }
80
81 /**
82  * Constructs a new instance of this class given its parent
83  * and a style value describing its behavior and appearance.
84  * <p>
85  * The style value is either one of the style constants defined in
86  * class <code>SWT</code> which is applicable to instances of this
87  * class, or must be built by <em>bitwise OR</em>'ing together
88  * (that is, using the <code>int</code> "|" operator) two or more
89  * of those <code>SWT</code> style constants. The class description
90  * lists the style constants that are applicable to the class.
91  * Style bits are also inherited from superclasses.
92  * </p>
93  *
94  * @param parent a composite control which will be the parent of the new instance (cannot be null)
95  * @param style the style of control to construct
96  *
97  * @exception IllegalArgumentException <ul>
98  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
99  * </ul>
100  * @exception SWTException <ul>
101  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
102  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
103  * </ul>
104  *
105  * @see SWT#BORDER
106  * @see SWT#LEFT_TO_RIGHT
107  * @see SWT#RIGHT_TO_LEFT
108  * @see Widget#checkSubclass
109  * @see Widget#getStyle
110  */
111 public Control (Composite parent, int style) {
112         super (parent, style);
113         this.parent = parent;
114         createWidget ();
115 }
116
117 /**
118  * Adds the listener to the collection of listeners who will
119  * be notified when the control is moved or resized, by sending
120  * it one of the messages defined in the <code>ControlListener</code>
121  * interface.
122  *
123  * @param listener the listener which should be notified
124  *
125  * @exception IllegalArgumentException <ul>
126  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
127  * </ul>
128  * @exception SWTException <ul>
129  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
130  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
131  * </ul>
132  *
133  * @see ControlListener
134  * @see #removeControlListener
135  */
136 public void addControlListener(ControlListener listener) {
137         checkWidget ();
138         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
139         TypedListener typedListener = new TypedListener (listener);
140         addListener (SWT.Resize,typedListener);
141         addListener (SWT.Move,typedListener);
142 }
143
144 /**
145  * Adds the listener to the collection of listeners who will
146  * be notified when a drag gesture occurs, by sending it
147  * one of the messages defined in the <code>DragDetectListener</code>
148  * interface.
149  *
150  * @param listener the listener which should be notified
151  *
152  * @exception IllegalArgumentException <ul>
153  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
154  * </ul>
155  * @exception SWTException <ul>
156  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
157  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
158  * </ul>
159  *
160  * @see DragDetectListener
161  * @see #removeDragDetectListener
162  *
163  * @since 3.3
164  */
165 public void addDragDetectListener (DragDetectListener listener) {
166         checkWidget ();
167         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
168         TypedListener typedListener = new TypedListener (listener);
169         addListener (SWT.DragDetect,typedListener);
170 }
171
172 /**
173  * Adds the listener to the collection of listeners who will
174  * be notified when the control gains or loses focus, by sending
175  * it one of the messages defined in the <code>FocusListener</code>
176  * interface.
177  *
178  * @param listener the listener which should be notified
179  *
180  * @exception IllegalArgumentException <ul>
181  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
182  * </ul>
183  * @exception SWTException <ul>
184  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
185  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
186  * </ul>
187  *
188  * @see FocusListener
189  * @see #removeFocusListener
190  */
191 public void addFocusListener (FocusListener listener) {
192         checkWidget ();
193         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
194         TypedListener typedListener = new TypedListener (listener);
195         addListener (SWT.FocusIn,typedListener);
196         addListener (SWT.FocusOut,typedListener);
197 }
198
199 /**
200  * Adds the listener to the collection of listeners who will
201  * be notified when gesture events are generated for the control,
202  * by sending it one of the messages defined in the
203  * <code>GestureListener</code> interface.
204  * <p>
205  * NOTE: If <code>setTouchEnabled(true)</code> has previously been
206  * invoked on the receiver then <code>setTouchEnabled(false)</code>
207  * must be invoked on it to specify that gesture events should be
208  * sent instead of touch events.
209  * </p>
210  * <p>
211  * <b>Warning</b>: This API is currently only implemented on Windows and Cocoa.
212  * SWT doesn't send Gesture or Touch events on GTK.
213  * </p>
214  *
215  * @param listener the listener which should be notified
216  *
217  * @exception IllegalArgumentException <ul>
218  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
219  * </ul>
220  * @exception SWTException <ul>
221  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
222  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
223  * </ul>
224  *
225  * @see GestureListener
226  * @see #removeGestureListener
227  * @see #setTouchEnabled
228  *
229  * @since 3.7
230  */
231 public void addGestureListener (GestureListener listener) {
232         checkWidget();
233         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
234         TypedListener typedListener = new TypedListener (listener);
235         addListener (SWT.Gesture, typedListener);
236 }
237
238 /**
239  * Adds the listener to the collection of listeners who will
240  * be notified when help events are generated for the control,
241  * by sending it one of the messages defined in the
242  * <code>HelpListener</code> interface.
243  *
244  * @param listener the listener which should be notified
245  *
246  * @exception IllegalArgumentException <ul>
247  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
248  * </ul>
249  * @exception SWTException <ul>
250  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
251  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
252  * </ul>
253  *
254  * @see HelpListener
255  * @see #removeHelpListener
256  */
257 public void addHelpListener (HelpListener listener) {
258         checkWidget ();
259         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
260         TypedListener typedListener = new TypedListener (listener);
261         addListener (SWT.Help, typedListener);
262 }
263
264 /**
265  * Adds the listener to the collection of listeners who will
266  * be notified when keys are pressed and released on the system keyboard, by sending
267  * it one of the messages defined in the <code>KeyListener</code>
268  * interface.
269  * <p>
270  * When a key listener is added to a control, the control
271  * will take part in widget traversal.  By default, all
272  * traversal keys (such as the tab key and so on) are
273  * delivered to the control.  In order for a control to take
274  * part in traversal, it should listen for traversal events.
275  * Otherwise, the user can traverse into a control but not
276  * out.  Note that native controls such as table and tree
277  * implement key traversal in the operating system.  It is
278  * not necessary to add traversal listeners for these controls,
279  * unless you want to override the default traversal.
280  * </p>
281  * @param listener the listener which should be notified
282  *
283  * @exception IllegalArgumentException <ul>
284  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
285  * </ul>
286  * @exception SWTException <ul>
287  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
288  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
289  * </ul>
290  *
291  * @see KeyListener
292  * @see #removeKeyListener
293  */
294 public void addKeyListener (KeyListener listener) {
295         checkWidget ();
296         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
297         TypedListener typedListener = new TypedListener (listener);
298         addListener (SWT.KeyUp,typedListener);
299         addListener (SWT.KeyDown,typedListener);
300 }
301
302 /**
303  * Adds the listener to the collection of listeners who will
304  * be notified when the platform-specific context menu trigger
305  * has occurred, by sending it one of the messages defined in
306  * the <code>MenuDetectListener</code> interface.
307  *
308  * @param listener the listener which should be notified
309  *
310  * @exception IllegalArgumentException <ul>
311  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
312  * </ul>
313  * @exception SWTException <ul>
314  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
315  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
316  * </ul>
317  *
318  * @see MenuDetectListener
319  * @see #removeMenuDetectListener
320  *
321  * @since 3.3
322  */
323 public void addMenuDetectListener (MenuDetectListener listener) {
324         checkWidget ();
325         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
326         TypedListener typedListener = new TypedListener (listener);
327         addListener (SWT.MenuDetect, typedListener);
328 }
329
330 /**
331  * Adds the listener to the collection of listeners who will
332  * be notified when mouse buttons are pressed and released, by sending
333  * it one of the messages defined in the <code>MouseListener</code>
334  * interface.
335  *
336  * @param listener the listener which should be notified
337  *
338  * @exception IllegalArgumentException <ul>
339  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
340  * </ul>
341  * @exception SWTException <ul>
342  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
343  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
344  * </ul>
345  *
346  * @see MouseListener
347  * @see #removeMouseListener
348  */
349 public void addMouseListener (MouseListener listener) {
350         checkWidget ();
351         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
352         TypedListener typedListener = new TypedListener (listener);
353         addListener (SWT.MouseDown,typedListener);
354         addListener (SWT.MouseUp,typedListener);
355         addListener (SWT.MouseDoubleClick,typedListener);
356 }
357
358 /**
359  * Adds the listener to the collection of listeners who will
360  * be notified when the mouse passes or hovers over controls, by sending
361  * it one of the messages defined in the <code>MouseTrackListener</code>
362  * interface.
363  *
364  * @param listener the listener which should be notified
365  *
366  * @exception IllegalArgumentException <ul>
367  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
368  * </ul>
369  * @exception SWTException <ul>
370  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
371  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
372  * </ul>
373  *
374  * @see MouseTrackListener
375  * @see #removeMouseTrackListener
376  */
377 public void addMouseTrackListener (MouseTrackListener listener) {
378         checkWidget ();
379         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
380         TypedListener typedListener = new TypedListener (listener);
381         addListener (SWT.MouseEnter,typedListener);
382         addListener (SWT.MouseExit,typedListener);
383         addListener (SWT.MouseHover,typedListener);
384 }
385
386 /**
387  * Adds the listener to the collection of listeners who will
388  * be notified when the mouse moves, by sending it one of the
389  * messages defined in the <code>MouseMoveListener</code>
390  * interface.
391  *
392  * @param listener the listener which should be notified
393  *
394  * @exception IllegalArgumentException <ul>
395  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
396  * </ul>
397  * @exception SWTException <ul>
398  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
399  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
400  * </ul>
401  *
402  * @see MouseMoveListener
403  * @see #removeMouseMoveListener
404  */
405 public void addMouseMoveListener (MouseMoveListener listener) {
406         checkWidget ();
407         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
408         TypedListener typedListener = new TypedListener (listener);
409         addListener (SWT.MouseMove,typedListener);
410 }
411
412 /**
413  * Adds the listener to the collection of listeners who will
414  * be notified when the mouse wheel is scrolled, by sending
415  * it one of the messages defined in the
416  * <code>MouseWheelListener</code> interface.
417  *
418  * @param listener the listener which should be notified
419  *
420  * @exception IllegalArgumentException <ul>
421  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
422  * </ul>
423  * @exception SWTException <ul>
424  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
425  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
426  * </ul>
427  *
428  * @see MouseWheelListener
429  * @see #removeMouseWheelListener
430  *
431  * @since 3.3
432  */
433 public void addMouseWheelListener (MouseWheelListener listener) {
434         checkWidget ();
435         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
436         TypedListener typedListener = new TypedListener (listener);
437         addListener (SWT.MouseWheel, typedListener);
438 }
439
440 /**
441  * Adds the listener to the collection of listeners who will
442  * be notified when the receiver needs to be painted, by sending it
443  * one of the messages defined in the <code>PaintListener</code>
444  * interface.
445  *
446  * @param listener the listener which should be notified
447  *
448  * @exception IllegalArgumentException <ul>
449  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
450  * </ul>
451  * @exception SWTException <ul>
452  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
453  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
454  * </ul>
455  *
456  * @see PaintListener
457  * @see #removePaintListener
458  */
459 public void addPaintListener (PaintListener listener) {
460         checkWidget ();
461         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
462         TypedListener typedListener = new TypedListener (listener);
463         addListener (SWT.Paint,typedListener);
464 }
465
466 /**
467  * Adds the listener to the collection of listeners who will
468  * be notified when touch events occur, by sending it
469  * one of the messages defined in the <code>TouchListener</code>
470  * interface.
471  * <p>
472  * NOTE: You must also call <code>setTouchEnabled(true)</code> to
473  * specify that touch events should be sent, which will cause gesture
474  * events to not be sent.
475  * </p>
476  * <p>
477  * <b>Warning</b>: This API is currently only implemented on Windows and Cocoa.
478  * SWT doesn't send Gesture or Touch events on GTK.
479  * </p>
480  *
481  * @param listener the listener which should be notified
482  *
483  * @exception IllegalArgumentException <ul>
484  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
485  * </ul>
486  * @exception SWTException <ul>
487  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
488  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
489  * </ul>
490  *
491  * @see TouchListener
492  * @see #removeTouchListener
493  * @see #setTouchEnabled
494  *
495  * @since 3.7
496  */
497 public void addTouchListener (TouchListener listener) {
498         checkWidget();
499         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
500         TypedListener typedListener = new TypedListener (listener);
501         addListener (SWT.Touch,typedListener);
502 }
503
504 /**
505  * Adds the listener to the collection of listeners who will
506  * be notified when traversal events occur, by sending it
507  * one of the messages defined in the <code>TraverseListener</code>
508  * interface.
509  *
510  * @param listener the listener which should be notified
511  *
512  * @exception IllegalArgumentException <ul>
513  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
514  * </ul>
515  * @exception SWTException <ul>
516  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
517  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
518  * </ul>
519  *
520  * @see TraverseListener
521  * @see #removeTraverseListener
522  */
523 public void addTraverseListener (TraverseListener listener) {
524         checkWidget ();
525         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
526         TypedListener typedListener = new TypedListener (listener);
527         addListener (SWT.Traverse,typedListener);
528 }
529
530 int binarySearch (int [] indices, int start, int end, int index) {
531         int low = start, high = end - 1;
532         while (low <= high) {
533                 int mid = (low + high) >>> 1;
534                 if (indices [mid] == index) return mid;
535                 if (indices [mid] < index) {
536                         low = mid + 1;
537                 } else {
538                         high = mid - 1;
539                 }
540         }
541         return -low - 1;
542 }
543
544 long borderHandle () {
545         return handle;
546 }
547
548 void checkBackground () {
549         Shell shell = getShell ();
550         if (this == shell) return;
551         state &= ~PARENT_BACKGROUND;
552         Composite composite = parent;
553         do {
554                 int mode = composite.backgroundMode;
555                 if (mode != 0 || backgroundAlpha == 0) {
556                         if (mode == SWT.INHERIT_DEFAULT || backgroundAlpha == 0) {
557                                 Control control = this;
558                                 do {
559                                         if ((control.state & THEME_BACKGROUND) == 0) {
560                                                 return;
561                                         }
562                                         control = control.parent;
563                                 } while (control != composite);
564                         }
565                         state |= PARENT_BACKGROUND;
566                         return;
567                 }
568                 if (composite == shell) break;
569                 composite = composite.parent;
570         } while (true);
571 }
572
573 void checkBorder () {
574         if (getBorderWidthInPixels () == 0) style &= ~SWT.BORDER;
575 }
576
577 void checkBuffered () {
578         style &= ~SWT.DOUBLE_BUFFERED;
579 }
580
581 void checkComposited () {
582         /* Do nothing */
583 }
584
585 boolean checkHandle (long hwnd) {
586         return hwnd == handle;
587 }
588
589 void checkMirrored () {
590         if ((style & SWT.RIGHT_TO_LEFT) != 0) {
591                 int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
592                 if ((bits & OS.WS_EX_LAYOUTRTL) != 0) style |= SWT.MIRRORED;
593         }
594 }
595
596 /**
597  * Returns the preferred size (in points) of the receiver.
598  * <p>
599  * The <em>preferred size</em> of a control is the size that it would
600  * best be displayed at. The width hint and height hint arguments
601  * allow the caller to ask a control questions such as "Given a particular
602  * width, how high does the control need to be to show all of the contents?"
603  * To indicate that the caller does not wish to constrain a particular
604  * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint.
605  * </p>
606  *
607  * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
608  * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
609  * @return the preferred size of the control
610  *
611  * @exception SWTException <ul>
612  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
613  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
614  * </ul>
615  *
616  * @see Layout
617  * @see #getBorderWidth
618  * @see #getBounds
619  * @see #getSize
620  * @see #pack(boolean)
621  * @see "computeTrim, getClientArea for controls that implement them"
622  */
623 public Point computeSize (int wHint, int hHint) {
624         return computeSize(wHint, hHint, true);
625 }
626
627 /**
628  * Returns the preferred size (in points) of the receiver.
629  * <p>
630  * The <em>preferred size</em> of a control is the size that it would
631  * best be displayed at. The width hint and height hint arguments
632  * allow the caller to ask a control questions such as "Given a particular
633  * width, how high does the control need to be to show all of the contents?"
634  * To indicate that the caller does not wish to constrain a particular
635  * dimension, the constant <code>SWT.DEFAULT</code> is passed for the hint.
636  * </p><p>
637  * If the changed flag is <code>true</code>, it indicates that the receiver's
638  * <em>contents</em> have changed, therefore any caches that a layout manager
639  * containing the control may have been keeping need to be flushed. When the
640  * control is resized, the changed flag will be <code>false</code>, so layout
641  * manager caches can be retained.
642  * </p>
643  *
644  * @param wHint the width hint (can be <code>SWT.DEFAULT</code>)
645  * @param hHint the height hint (can be <code>SWT.DEFAULT</code>)
646  * @param changed <code>true</code> if the control's contents have changed, and <code>false</code> otherwise
647  * @return the preferred size of the control.
648  *
649  * @exception SWTException <ul>
650  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
651  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
652  * </ul>
653  *
654  * @see Layout
655  * @see #getBorderWidth
656  * @see #getBounds
657  * @see #getSize
658  * @see #pack(boolean)
659  * @see "computeTrim, getClientArea for controls that implement them"
660  */
661 public Point computeSize (int wHint, int hHint, boolean changed){
662         checkWidget ();
663         wHint = (wHint != SWT.DEFAULT ? DPIUtil.autoScaleUp(wHint) : wHint);
664         hHint = (hHint != SWT.DEFAULT ? DPIUtil.autoScaleUp(hHint) : hHint);
665         return DPIUtil.autoScaleDown(computeSizeInPixels(wHint, hHint, changed));
666 }
667
668 Point computeSizeInPixels (int wHint, int hHint, boolean changed) {
669         int width = DEFAULT_WIDTH;
670         int height = DEFAULT_HEIGHT;
671         if (wHint != SWT.DEFAULT) width = wHint;
672         if (hHint != SWT.DEFAULT) height = hHint;
673         int border = getBorderWidthInPixels ();
674         width += border * 2;
675         height += border * 2;
676         return new Point (width, height);
677 }
678
679 Widget computeTabGroup () {
680         if (isTabGroup ()) return this;
681         return parent.computeTabGroup ();
682 }
683
684 Control computeTabRoot () {
685         Control [] tabList = parent._getTabList ();
686         if (tabList != null) {
687                 int index = 0;
688                 while (index < tabList.length) {
689                         if (tabList [index] == this) break;
690                         index++;
691                 }
692                 if (index == tabList.length) {
693                         if (isTabGroup ()) return this;
694                 }
695         }
696         return parent.computeTabRoot ();
697 }
698
699 Widget [] computeTabList () {
700         if (isTabGroup ()) {
701                 if (getVisible () && getEnabled ()) {
702                         return new Widget [] {this};
703                 }
704         }
705         return new Widget [0];
706 }
707
708 void createHandle () {
709         long hwndParent = widgetParent ();
710         handle = OS.CreateWindowEx (
711                 widgetExtStyle (),
712                 windowClass (),
713                 null,
714                 widgetStyle (),
715                 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0,
716                 hwndParent,
717                 0,
718                 OS.GetModuleHandle (null),
719                 widgetCreateStruct ());
720         if (handle == 0) error (SWT.ERROR_NO_HANDLES);
721         int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
722         if ((bits & OS.WS_CHILD) != 0) {
723                 OS.SetWindowLongPtr (handle, OS.GWLP_ID, handle);
724         }
725         if (OS.IsDBLocale && hwndParent != 0) {
726                 long hIMC = OS.ImmGetContext (hwndParent);
727                 OS.ImmAssociateContext (handle, hIMC);
728                 OS.ImmReleaseContext (hwndParent, hIMC);
729         }
730
731 }
732
733 void checkGesture () {
734         if (OS.WIN32_VERSION >= OS.VERSION (6, 1)) {
735                 int value = OS.GetSystemMetrics (OS.SM_DIGITIZER);
736                 if ((value & (OS.NID_READY | OS.NID_MULTI_INPUT)) != 0) {
737                         /*
738                          * Feature in Windows 7: All gestures are enabled by default except GID_ROTATE.
739                          * Enable it explicitly by calling SetGestureConfig.
740                          */
741                         long hHeap = OS.GetProcessHeap ();
742                         long pConfigs = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY,  GESTURECONFIG.sizeof);
743                         if (pConfigs != 0) {
744                                 GESTURECONFIG config = new GESTURECONFIG();
745                                 config.dwID = OS.GID_ROTATE;
746                                 config.dwWant = 1;
747                                 config.dwBlock = 0;
748                                 OS.MoveMemory (pConfigs, config, GESTURECONFIG.sizeof);
749                                 OS.SetGestureConfig (handle, 0, 1, pConfigs, GESTURECONFIG.sizeof);
750                                 OS.HeapFree (hHeap, 0, pConfigs);
751                         }
752                 }
753         }
754 }
755
756 void createWidget () {
757         state |= DRAG_DETECT;
758         foreground = background = -1;
759         checkOrientation (parent);
760         createHandle ();
761         checkBackground ();
762         checkBuffered ();
763         checkComposited ();
764         register ();
765         subclass ();
766         setDefaultFont ();
767         checkMirrored ();
768         checkBorder ();
769         checkGesture ();
770         if ((state & PARENT_BACKGROUND) != 0) {
771                 setBackground ();
772         }
773 }
774
775 int defaultBackground () {
776         return OS.GetSysColor (OS.COLOR_BTNFACE);
777 }
778
779 long defaultFont () {
780         return display.getSystemFont ().handle;
781 }
782
783 int defaultForeground () {
784         return OS.GetSysColor (OS.COLOR_WINDOWTEXT);
785 }
786
787 void deregister () {
788         display.removeControl (handle);
789 }
790
791 @Override
792 void destroyWidget () {
793         long hwnd = topHandle ();
794         releaseHandle ();
795         if (hwnd != 0) {
796                 OS.DestroyWindow (hwnd);
797         }
798 }
799
800 /**
801  * Detects a drag and drop gesture.  This method is used
802  * to detect a drag gesture when called from within a mouse
803  * down listener.
804  *
805  * <p>By default, a drag is detected when the gesture
806  * occurs anywhere within the client area of a control.
807  * Some controls, such as tables and trees, override this
808  * behavior.  In addition to the operating system specific
809  * drag gesture, they require the mouse to be inside an
810  * item.  Custom widget writers can use <code>setDragDetect</code>
811  * to disable the default detection, listen for mouse down,
812  * and then call <code>dragDetect()</code> from within the
813  * listener to conditionally detect a drag.
814  * </p>
815  *
816  * @param event the mouse down event
817  *
818  * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise.
819  *
820  * @exception IllegalArgumentException <ul>
821  *   <li>ERROR_NULL_ARGUMENT if the event is null</li>
822  * </ul>
823  * @exception SWTException <ul>
824  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
825  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
826  * </ul>
827  *
828  * @see DragDetectListener
829  * @see #addDragDetectListener
830  *
831  * @see #getDragDetect
832  * @see #setDragDetect
833  *
834  * @since 3.3
835  */
836 public boolean dragDetect (Event event) {
837         checkWidget ();
838         if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
839         Point loc = event.getLocationInPixels();
840         return dragDetect (event.button, event.count, event.stateMask, loc.x, loc.y);
841 }
842
843 /**
844  * Detects a drag and drop gesture.  This method is used
845  * to detect a drag gesture when called from within a mouse
846  * down listener.
847  *
848  * <p>By default, a drag is detected when the gesture
849  * occurs anywhere within the client area of a control.
850  * Some controls, such as tables and trees, override this
851  * behavior.  In addition to the operating system specific
852  * drag gesture, they require the mouse to be inside an
853  * item.  Custom widget writers can use <code>setDragDetect</code>
854  * to disable the default detection, listen for mouse down,
855  * and then call <code>dragDetect()</code> from within the
856  * listener to conditionally detect a drag.
857  * </p>
858  *
859  * @param event the mouse down event
860  *
861  * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise.
862  *
863  * @exception IllegalArgumentException <ul>
864  *   <li>ERROR_NULL_ARGUMENT if the event is null</li>
865  * </ul>
866  * @exception SWTException <ul>
867  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
868  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
869  * </ul>
870  *
871  * @see DragDetectListener
872  * @see #addDragDetectListener
873  *
874  * @see #getDragDetect
875  * @see #setDragDetect
876  *
877  * @since 3.3
878  */
879 public boolean dragDetect (MouseEvent event) {
880         checkWidget ();
881         if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
882         return dragDetect (event.button, event.count, event.stateMask, DPIUtil.autoScaleUp(event.x), DPIUtil.autoScaleUp(event.y)); // To Pixels
883 }
884
885 boolean dragDetect (int button, int count, int stateMask, int x, int y) {
886         if (button != 1 || count != 1) return false;
887         boolean dragging = dragDetect (handle, x, y, false, null, null);
888         if (OS.GetKeyState (OS.VK_LBUTTON) < 0) {
889                 if (OS.GetCapture () != handle) OS.SetCapture (handle);
890         }
891         if (!dragging) {
892                 /*
893                 * Feature in Windows.  DragDetect() captures the mouse
894                 * and tracks its movement until the user releases the
895                 * left mouse button, presses the ESC key, or moves the
896                 * mouse outside the drag rectangle.  If the user moves
897                 * the mouse outside of the drag rectangle, DragDetect()
898                 * returns true and a drag and drop operation can be
899                 * started.  When the left mouse button is released or
900                 * the ESC key is pressed, these events are consumed by
901                 * DragDetect() so that application code that matches
902                 * mouse down/up pairs or looks for the ESC key will not
903                 * function properly.  The fix is to send the missing
904                 * events when the drag has not started.
905                 *
906                 * NOTE: For now, don't send a fake WM_KEYDOWN/WM_KEYUP
907                 * events for the ESC key.  This would require computing
908                 * wParam (the key) and lParam (the repeat count, scan code,
909                 * extended-key flag, context code, previous key-state flag,
910                 * and transition-state flag) which is non-trivial.
911                 */
912                 if (button == 1 && OS.GetKeyState (OS.VK_ESCAPE) >= 0) {
913                         int wParam = 0;
914                         if ((stateMask & SWT.CTRL) != 0) wParam |= OS.MK_CONTROL;
915                         if ((stateMask & SWT.SHIFT) != 0) wParam |= OS.MK_SHIFT;
916                         if ((stateMask & SWT.ALT) != 0) wParam |= OS.MK_ALT;
917                         if ((stateMask & SWT.BUTTON1) != 0) wParam |= OS.MK_LBUTTON;
918                         if ((stateMask & SWT.BUTTON2) != 0) wParam |= OS.MK_MBUTTON;
919                         if ((stateMask & SWT.BUTTON3) != 0) wParam |= OS.MK_RBUTTON;
920                         if ((stateMask & SWT.BUTTON4) != 0) wParam |= OS.MK_XBUTTON1;
921                         if ((stateMask & SWT.BUTTON5) != 0) wParam |= OS.MK_XBUTTON2;
922                         long lParam = OS.MAKELPARAM (x, y);
923                         OS.SendMessage (handle, OS.WM_LBUTTONUP, wParam, lParam);
924                 }
925                 return false;
926         }
927         return sendDragEvent (button, stateMask, x, y);
928 }
929
930 void drawBackground (long hDC) {
931         RECT rect = new RECT ();
932         OS.GetClientRect (handle, rect);
933         drawBackground (hDC, rect);
934 }
935
936 void drawBackground (long hDC, RECT rect) {
937         drawBackground (hDC, rect, -1, 0, 0);
938 }
939
940 void drawBackground (long hDC, RECT rect, int pixel, int tx, int ty) {
941         Control control = findBackgroundControl ();
942         if (control != null) {
943                 if (control.backgroundImage != null) {
944                         fillImageBackground (hDC, control, rect, tx, ty);
945                         return;
946                 }
947                 pixel = control.getBackgroundPixel ();
948         }
949         if (pixel == -1) {
950                 if ((state & THEME_BACKGROUND) != 0) {
951                         if (OS.IsAppThemed ()) {
952                                 control = findThemeControl ();
953                                 if (control != null) {
954                                         fillThemeBackground (hDC, control, rect);
955                                         return;
956                                 }
957                         }
958                 }
959         }
960         if (pixel == -1) pixel = getBackgroundPixel ();
961         fillBackground (hDC, pixel, rect);
962 }
963
964 void drawImageBackground (long hDC, long hwnd, long hBitmap, RECT rect, int tx, int ty) {
965         RECT rect2 = new RECT ();
966         OS.GetClientRect (hwnd, rect2);
967         OS.MapWindowPoints (hwnd, handle, rect2, 2);
968         long hBrush = findBrush (hBitmap, OS.BS_PATTERN);
969         POINT lpPoint = new POINT ();
970         OS.GetWindowOrgEx (hDC, lpPoint);
971         OS.SetBrushOrgEx (hDC, -rect2.left - lpPoint.x - tx, -rect2.top - lpPoint.y - ty, lpPoint);
972         long hOldBrush = OS.SelectObject (hDC, hBrush);
973         OS.PatBlt (hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY);
974         OS.SetBrushOrgEx (hDC, lpPoint.x, lpPoint.y, null);
975         OS.SelectObject (hDC, hOldBrush);
976 }
977
978 void drawThemeBackground (long hDC, long hwnd, RECT rect) {
979         /* Do nothing */
980 }
981
982 void enableDrag (boolean enabled) {
983         /* Do nothing */
984 }
985
986 void enableWidget (boolean enabled) {
987         OS.EnableWindow (handle, enabled);
988 }
989
990 void fillBackground (long hDC, int pixel, RECT rect) {
991         if (rect.left > rect.right || rect.top > rect.bottom) return;
992         OS.FillRect (hDC, rect, findBrush (pixel, OS.BS_SOLID));
993 }
994
995 void fillImageBackground (long hDC, Control control, RECT rect, int tx, int ty) {
996         if (rect.left > rect.right || rect.top > rect.bottom) return;
997         if (control != null) {
998                 Image image = control.backgroundImage;
999                 if (image != null) {
1000                         control.drawImageBackground (hDC, handle, image.handle, rect, tx, ty);
1001                 }
1002         }
1003 }
1004
1005 void fillThemeBackground (long hDC, Control control, RECT rect) {
1006         if (rect.left > rect.right || rect.top > rect.bottom) return;
1007         if (control != null) {
1008                 control.drawThemeBackground (hDC, handle, rect);
1009         }
1010 }
1011
1012 Control findBackgroundControl () {
1013         if ((background != -1 || backgroundImage != null) && backgroundAlpha > 0) return this;
1014         return (parent != null && (state & PARENT_BACKGROUND) != 0) ? parent.findBackgroundControl () : null;
1015 }
1016
1017 long findBrush (long value, int lbStyle) {
1018         return parent.findBrush (value, lbStyle);
1019 }
1020
1021 Cursor findCursor () {
1022         if (cursor != null) return cursor;
1023         return parent.findCursor ();
1024 }
1025
1026 Control findImageControl () {
1027         Control control = findBackgroundControl ();
1028         return control != null && control.backgroundImage != null ? control : null;
1029 }
1030
1031 Control findThemeControl () {
1032         return background == -1 && backgroundImage == null ? parent.findThemeControl () : null;
1033 }
1034
1035 Menu [] findMenus (Control control) {
1036         if (menu != null && this != control) return new Menu [] {menu};
1037         return new Menu [0];
1038 }
1039
1040 char findMnemonic (String string) {
1041         int index = 0;
1042         int length = string.length ();
1043         do {
1044                 while (index < length && string.charAt (index) != '&') index++;
1045                 if (++index >= length) return '\0';
1046                 if (string.charAt (index) != '&') return string.charAt (index);
1047                 index++;
1048         } while (index < length);
1049         return '\0';
1050 }
1051
1052 void fixChildren (Shell newShell, Shell oldShell, Decorations newDecorations, Decorations oldDecorations, Menu [] menus) {
1053         oldShell.fixShell (newShell, this);
1054         oldDecorations.fixDecorations (newDecorations, this, menus);
1055 }
1056
1057 void fixFocus (Control focusControl) {
1058         Shell shell = getShell ();
1059         Control control = this;
1060         Display display = this.display;
1061         boolean oldFixFocus = display.fixFocus;
1062         display.fixFocus = true;
1063         try {
1064                 while (control != shell && (control = control.parent) != null) {
1065                                 if (control.setFocus ()) return;
1066                 }
1067         } finally {
1068                 display.fixFocus = oldFixFocus;
1069         }
1070         shell.setSavedFocus (focusControl);
1071         OS.SetFocus (0);
1072 }
1073
1074 /**
1075  * Forces the receiver to have the <em>keyboard focus</em>, causing
1076  * all keyboard events to be delivered to it.
1077  *
1078  * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.
1079  *
1080  * @exception SWTException <ul>
1081  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1082  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1083  * </ul>
1084  *
1085  * @see #setFocus
1086  */
1087 public boolean forceFocus () {
1088         checkWidget ();
1089         if (display.focusEvent == SWT.FocusOut) return false;
1090         Decorations shell = menuShell ();
1091         shell.setSavedFocus (this);
1092         if (!isEnabled () || !isVisible () || !isActive ()) return false;
1093         if (isFocusControl ()) return true;
1094         shell.setSavedFocus (null);
1095         /*
1096         * This code is intentionally commented.
1097         *
1098         * When setting focus to a control, it is
1099         * possible that application code can set
1100         * the focus to another control inside of
1101         * WM_SETFOCUS.  In this case, the original
1102         * control will no longer have the focus
1103         * and the call to setFocus() will return
1104         * false indicating failure.
1105         *
1106         * We are still working on a solution at
1107         * this time.
1108         */
1109 //      if (OS.GetFocus () != OS.SetFocus (handle)) return false;
1110         OS.SetFocus (handle);
1111         if (isDisposed ()) return false;
1112         shell.setSavedFocus (this);
1113         return isFocusControl ();
1114 }
1115
1116 void forceResize () {
1117         if (parent == null) return;
1118         WINDOWPOS [] lpwp = parent.lpwp;
1119         if (lpwp == null) return;
1120         for (int i=0; i<lpwp.length; i++) {
1121                 WINDOWPOS wp = lpwp [i];
1122                 if (wp != null && wp.hwnd == handle) {
1123                         /*
1124                         * This code is intentionally commented.  All widgets that
1125                         * are created by SWT have WS_CLIPSIBLINGS to ensure that
1126                         * application code does not draw outside of the control.
1127                         */
1128 //                      int count = parent.getChildrenCount ();
1129 //                      if (count > 1) {
1130 //                              int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
1131 //                              if ((bits & OS.WS_CLIPSIBLINGS) == 0) wp.flags |= OS.SWP_NOCOPYBITS;
1132 //                      }
1133                         OS.SetWindowPos (wp.hwnd, 0, wp.x, wp.y, wp.cx, wp.cy, wp.flags);
1134                         lpwp [i] = null;
1135                         return;
1136                 }
1137         }
1138 }
1139
1140 /**
1141  * Returns the accessible object for the receiver.
1142  * <p>
1143  * If this is the first time this object is requested,
1144  * then the object is created and returned. The object
1145  * returned by getAccessible() does not need to be disposed.
1146  * </p>
1147  *
1148  * @return the accessible object
1149  *
1150  * @exception SWTException <ul>
1151  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1152  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1153  * </ul>
1154  *
1155  * @see Accessible#addAccessibleListener
1156  * @see Accessible#addAccessibleControlListener
1157  *
1158  * @since 2.0
1159  */
1160 public Accessible getAccessible () {
1161         checkWidget ();
1162         if (accessible == null) accessible = new_Accessible (this);
1163         return accessible;
1164 }
1165
1166 /**
1167  * Returns the receiver's background color.
1168  * <p>
1169  * Note: This operation is a hint and may be overridden by the platform.
1170  * For example, on some versions of Windows the background of a TabFolder,
1171  * is a gradient rather than a solid color.
1172  * </p>
1173  * @return the background color
1174  *
1175  * @exception SWTException <ul>
1176  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1177  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1178  * </ul>
1179  */
1180 public Color getBackground () {
1181         checkWidget ();
1182         if (backgroundAlpha == 0) {
1183                 Color color =  Color.win32_new (display, background, 0);
1184                 return color;
1185         }
1186         else {
1187                 Control control = findBackgroundControl ();
1188                 if (control == null) control = this;
1189                 return Color.win32_new (display, control.getBackgroundPixel (), backgroundAlpha);
1190         }
1191 }
1192
1193 /**
1194  * Returns the receiver's background image.
1195  *
1196  * @return the background image
1197  *
1198  * @exception SWTException <ul>
1199  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1200  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1201  * </ul>
1202  *
1203  * @since 3.2
1204  */
1205 public Image getBackgroundImage () {
1206         checkWidget ();
1207         Control control = findBackgroundControl ();
1208         if (control == null) control = this;
1209         return control.backgroundImage;
1210 }
1211
1212 int getBackgroundPixel () {
1213         return background != -1 ? background :  defaultBackground ();
1214 }
1215
1216 /**
1217  * Returns the receiver's border width in points.
1218  *
1219  * @return the border width
1220  *
1221  * @exception SWTException <ul>
1222  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1223  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1224  * </ul>
1225  */
1226 public int getBorderWidth () {
1227         checkWidget ();
1228         return DPIUtil.autoScaleDown(getBorderWidthInPixels ());
1229 }
1230
1231 int getBorderWidthInPixels () {
1232         long borderHandle = borderHandle ();
1233         int bits1 = OS.GetWindowLong (borderHandle, OS.GWL_EXSTYLE);
1234         if ((bits1 & OS.WS_EX_CLIENTEDGE) != 0) return OS.GetSystemMetrics (OS.SM_CXEDGE);
1235         if ((bits1 & OS.WS_EX_STATICEDGE) != 0) return OS.GetSystemMetrics (OS.SM_CXBORDER);
1236         int bits2 = OS.GetWindowLong (borderHandle, OS.GWL_STYLE);
1237         if ((bits2 & OS.WS_BORDER) != 0) return OS.GetSystemMetrics (OS.SM_CXBORDER);
1238         return 0;
1239 }
1240
1241 /**
1242  * Returns a rectangle describing the receiver's size and location in points
1243  * relative to its parent (or its display if its parent is null),
1244  * unless the receiver is a shell. In this case, the location is
1245  * relative to the display.
1246  *
1247  * @return the receiver's bounding rectangle
1248  *
1249  * @exception SWTException <ul>
1250  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1251  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1252  * </ul>
1253  */
1254 public Rectangle getBounds (){
1255         checkWidget ();
1256         return DPIUtil.autoScaleDown(getBoundsInPixels ());
1257 }
1258
1259 Rectangle getBoundsInPixels () {
1260         forceResize ();
1261         RECT rect = new RECT ();
1262         OS.GetWindowRect (topHandle (), rect);
1263         long hwndParent = parent == null ? 0 : parent.handle;
1264         OS.MapWindowPoints (0, hwndParent, rect, 2);
1265         int width = rect.right - rect.left;
1266         int height =  rect.bottom - rect.top;
1267         return new Rectangle (rect.left, rect.top, width, height);
1268 }
1269
1270 int getCodePage () {
1271         return OS.CP_ACP;
1272 }
1273
1274 String getClipboardText () {
1275         String string = "";
1276         if (OS.OpenClipboard (0)) {
1277                 long hMem = OS.GetClipboardData (OS.CF_UNICODETEXT);
1278                 if (hMem != 0) {
1279                         /* Ensure byteCount is a multiple of 2 bytes on UNICODE platforms */
1280                         int byteCount = OS.GlobalSize (hMem) / TCHAR.sizeof * TCHAR.sizeof;
1281                         long ptr = OS.GlobalLock (hMem);
1282                         if (ptr != 0) {
1283                                 /* Use the character encoding for the default locale */
1284                                 TCHAR buffer = new TCHAR (0, byteCount / TCHAR.sizeof);
1285                                 OS.MoveMemory (buffer, ptr, byteCount);
1286                                 string = buffer.toString (0, buffer.strlen ());
1287                                 OS.GlobalUnlock (hMem);
1288                         }
1289                 }
1290                 OS.CloseClipboard ();
1291         }
1292         return string;
1293 }
1294
1295 /**
1296  * Returns the receiver's cursor, or null if it has not been set.
1297  * <p>
1298  * When the mouse pointer passes over a control its appearance
1299  * is changed to match the control's cursor.
1300  * </p>
1301  *
1302  * @return the receiver's cursor or <code>null</code>
1303  *
1304  * @exception SWTException <ul>
1305  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1306  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1307  * </ul>
1308  *
1309  * @since 3.3
1310  */
1311 public Cursor getCursor () {
1312         checkWidget ();
1313         return cursor;
1314 }
1315
1316 /**
1317  * Returns <code>true</code> if the receiver is detecting
1318  * drag gestures, and  <code>false</code> otherwise.
1319  *
1320  * @return the receiver's drag detect state
1321  *
1322  * @exception SWTException <ul>
1323  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1324  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1325  * </ul>
1326  *
1327  * @since 3.3
1328  */
1329 public boolean getDragDetect () {
1330         checkWidget ();
1331         return (state & DRAG_DETECT) != 0;
1332 }
1333
1334 boolean getDrawing () {
1335         return drawCount <= 0;
1336 }
1337
1338 /**
1339  * Returns <code>true</code> if the receiver is enabled, and
1340  * <code>false</code> otherwise. A disabled control is typically
1341  * not selectable from the user interface and draws with an
1342  * inactive or "grayed" look.
1343  *
1344  * @return the receiver's enabled state
1345  *
1346  * @exception SWTException <ul>
1347  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1348  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1349  * </ul>
1350  *
1351  * @see #isEnabled
1352  */
1353 public boolean getEnabled () {
1354         checkWidget ();
1355         return OS.IsWindowEnabled (handle);
1356 }
1357
1358 /**
1359  * Returns the font that the receiver will use to paint textual information.
1360  *
1361  * @return the receiver's font
1362  *
1363  * @exception SWTException <ul>
1364  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1365  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1366  * </ul>
1367  */
1368 public Font getFont () {
1369         checkWidget ();
1370         if (font != null) return font;
1371         long hFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
1372         if (hFont == 0) hFont = defaultFont ();
1373         return Font.win32_new (display, hFont);
1374 }
1375
1376 /**
1377  * Returns the foreground color that the receiver will use to draw.
1378  *
1379  * @return the receiver's foreground color
1380  *
1381  * @exception SWTException <ul>
1382  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1383  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1384  * </ul>
1385  */
1386 public Color getForeground () {
1387         checkWidget ();
1388         return Color.win32_new (display, getForegroundPixel ());
1389 }
1390
1391 int getForegroundPixel () {
1392         return foreground != -1 ? foreground : defaultForeground ();
1393 }
1394
1395 /**
1396  * Returns layout data which is associated with the receiver.
1397  *
1398  * @return the receiver's layout data
1399  *
1400  * @exception SWTException <ul>
1401  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1402  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1403  * </ul>
1404  */
1405 public Object getLayoutData () {
1406         checkWidget ();
1407         return layoutData;
1408 }
1409
1410 /**
1411  * Returns a point describing the receiver's location relative
1412  * to its parent in points (or its display if its parent is null), unless
1413  * the receiver is a shell. In this case, the point is
1414  * relative to the display.
1415  *
1416  * @return the receiver's location
1417  *
1418  * @exception SWTException <ul>
1419  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1420  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1421  * </ul>
1422  */
1423 public Point getLocation () {
1424         checkWidget ();
1425         return DPIUtil.autoScaleDown(getLocationInPixels());
1426 }
1427
1428 Point getLocationInPixels () {
1429         forceResize ();
1430         RECT rect = new RECT ();
1431         OS.GetWindowRect (topHandle (), rect);
1432         long hwndParent = parent == null ? 0 : parent.handle;
1433         OS.MapWindowPoints (0, hwndParent, rect, 2);
1434         return new Point (rect.left, rect.top);
1435 }
1436
1437 /**
1438  * Returns the receiver's pop up menu if it has one, or null
1439  * if it does not. All controls may optionally have a pop up
1440  * menu that is displayed when the user requests one for
1441  * the control. The sequence of key strokes, button presses
1442  * and/or button releases that are used to request a pop up
1443  * menu is platform specific.
1444  *
1445  * @return the receiver's menu
1446  *
1447  * @exception SWTException <ul>
1448  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1449  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1450  * </ul>
1451  */
1452 @Override
1453 public Menu getMenu () {
1454         checkWidget ();
1455         return menu;
1456 }
1457
1458 /**
1459  * Returns the receiver's monitor.
1460  *
1461  * @return the receiver's monitor
1462  *
1463  * @exception SWTException <ul>
1464  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1465  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1466  * </ul>
1467  *
1468  * @since 3.0
1469  */
1470 public Monitor getMonitor () {
1471         checkWidget ();
1472         long hmonitor = OS.MonitorFromWindow (handle, OS.MONITOR_DEFAULTTONEAREST);
1473         return display.getMonitor (hmonitor);
1474 }
1475
1476 /**
1477  * Returns the orientation of the receiver, which will be one of the
1478  * constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
1479  *
1480  * @return the orientation style
1481  *
1482  * @exception SWTException <ul>
1483  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1484  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1485  * </ul>
1486  *
1487  * @since 3.7
1488  */
1489 public int getOrientation () {
1490         checkWidget ();
1491         return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
1492 }
1493
1494 /**
1495  * Returns the receiver's parent, which must be a <code>Composite</code>
1496  * or null when the receiver is a shell that was created with null or
1497  * a display for a parent.
1498  *
1499  * @return the receiver's parent
1500  *
1501  * @exception SWTException <ul>
1502  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1503  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1504  * </ul>
1505  */
1506 public Composite getParent () {
1507         checkWidget ();
1508         return parent;
1509 }
1510
1511 Control [] getPath () {
1512         int count = 0;
1513         Shell shell = getShell ();
1514         Control control = this;
1515         while (control != shell) {
1516                 count++;
1517                 control = control.parent;
1518         }
1519         control = this;
1520         Control [] result = new Control [count];
1521         while (control != shell) {
1522                 result [--count] = control;
1523                 control = control.parent;
1524         }
1525         return result;
1526 }
1527
1528 /**
1529  * Returns the region that defines the shape of the control,
1530  * or null if the control has the default shape.
1531  *
1532  * @return the region that defines the shape of the shell (or null)
1533  *
1534  * @exception SWTException <ul>
1535  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1536  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1537  * </ul>
1538  *
1539  * @since 3.4
1540  */
1541 public Region getRegion () {
1542         checkWidget ();
1543         return region;
1544 }
1545
1546 /**
1547  * Returns the receiver's shell. For all controls other than
1548  * shells, this simply returns the control's nearest ancestor
1549  * shell. Shells return themselves, even if they are children
1550  * of other shells.
1551  *
1552  * @return the receiver's shell
1553  *
1554  * @exception SWTException <ul>
1555  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1556  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1557  * </ul>
1558  *
1559  * @see #getParent
1560  */
1561 public Shell getShell () {
1562         checkWidget ();
1563         return parent.getShell ();
1564 }
1565
1566 /**
1567  * Returns a point describing the receiver's size in points. The
1568  * x coordinate of the result is the width of the receiver.
1569  * The y coordinate of the result is the height of the
1570  * receiver.
1571  *
1572  * @return the receiver's size
1573  *
1574  * @exception SWTException <ul>
1575  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1576  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1577  * </ul>
1578  */
1579 public Point getSize (){
1580         checkWidget ();
1581         return DPIUtil.autoScaleDown(getSizeInPixels ());
1582 }
1583
1584 Point getSizeInPixels () {
1585         forceResize ();
1586         RECT rect = new RECT ();
1587         OS.GetWindowRect (topHandle (), rect);
1588         int width = rect.right - rect.left;
1589         int height = rect.bottom - rect.top;
1590         return new Point (width, height);
1591 }
1592
1593 /**
1594  * Calculates a slightly different color, e.g. for the hot state of a button.
1595  * @param pixel the color to start with
1596  */
1597 int getSlightlyDifferentColor(int pixel) {
1598         return getDifferentColor(pixel, 0.1);
1599 }
1600
1601 /**
1602  * Calculates a different color, e.g. for the checked state of a toggle button
1603  * or to highlight a selected button.
1604  * @param pixel the color to start with
1605  */
1606 int getDifferentColor(int pixel) {
1607         return getDifferentColor(pixel, 0.2);
1608 }
1609
1610 /**
1611  * @param factor must be between [0..1]. The bounds are not checked
1612  */
1613 int getDifferentColor(int pixel, double factor) {
1614         int red = pixel & 0xFF;
1615         int green = (pixel & 0xFF00) >> 8;
1616         int blue = (pixel & 0xFF0000) >> 16;
1617         red += calcDiff(red, factor);
1618         green += calcDiff(green, factor);
1619         blue += calcDiff(blue, factor);
1620         return (red & 0xFF) | ((green & 0xFF) << 8) | ((blue & 0xFF) << 16);
1621 }
1622
1623 long /* int */ calcDiff(int component, double factor) {
1624         if (component > 127) {
1625                 return Math.round(component * -1 * factor);
1626         } else {
1627                 return Math.round((255 - component) * factor);
1628         }
1629 }
1630
1631 /**
1632  * Calculates a slightly different background color, e.g. for highlighting the sort column
1633  * in a table or tree. This method produces less contrast that {@link #getSlightlyDifferentColor(int)}.
1634  * @param pixel the color to start with
1635  */
1636 int getSlightlyDifferentBackgroundColor(int pixel) {
1637         int offset = 8;
1638         int red = pixel & 0xFF;
1639         int green = (pixel & 0xFF00) >> 8;
1640         int blue = (pixel & 0xFF0000) >> 16;
1641         red = red > 127 ? red-offset : red+offset;
1642         green = green > 127 ? green-offset : green+offset;
1643         blue = blue > 127 ? blue-offset : blue+offset;
1644         return (red & 0xFF) | ((green & 0xFF) << 8) | ((blue & 0xFF) << 16);
1645 }
1646
1647 /**
1648  * Returns the text direction of the receiver, which will be one of the
1649  * constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
1650  *
1651  * @return the text direction style
1652  *
1653  * @exception SWTException <ul>
1654  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1655  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1656  * </ul>
1657  *
1658  * @since 3.102
1659  */
1660 public int getTextDirection() {
1661         checkWidget ();
1662         int flags = OS.WS_EX_LAYOUTRTL | OS.WS_EX_RTLREADING;
1663         int bits  = OS.GetWindowLong (handle, OS.GWL_EXSTYLE) & flags;
1664         return bits == 0 || bits == flags ? SWT.LEFT_TO_RIGHT : SWT.RIGHT_TO_LEFT;
1665 }
1666
1667 /**
1668  * Returns the receiver's tool tip text, or null if it has
1669  * not been set.
1670  *
1671  * @return the receiver's tool tip text
1672  *
1673  * @exception SWTException <ul>
1674  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1675  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1676  * </ul>
1677  */
1678 public String getToolTipText () {
1679         checkWidget ();
1680         return toolTipText;
1681 }
1682
1683 /**
1684  * Returns <code>true</code> if this control is set to send touch events, or
1685  * <code>false</code> if it is set to send gesture events instead.  This method
1686  * also returns <code>false</code> if a touch-based input device is not detected
1687  * (this can be determined with <code>Display#getTouchEnabled()</code>).  Use
1688  * {@link #setTouchEnabled(boolean)} to switch the events that a control sends
1689  * between touch events and gesture events.
1690  *
1691  * @return <code>true</code> if the control is set to send touch events, or <code>false</code> otherwise
1692  *
1693  * @exception SWTException <ul>
1694  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1695  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1696  * </ul>
1697  *
1698  * @see #setTouchEnabled
1699  * @see Display#getTouchEnabled
1700  *
1701  * @since 3.7
1702  */
1703 public boolean getTouchEnabled () {
1704         checkWidget ();
1705         return OS.IsTouchWindow (handle, null);
1706 }
1707
1708 /**
1709  * Returns <code>true</code> if the receiver is visible, and
1710  * <code>false</code> otherwise.
1711  * <p>
1712  * If one of the receiver's ancestors is not visible or some
1713  * other condition makes the receiver not visible, this method
1714  * may still indicate that it is considered visible even though
1715  * it may not actually be showing.
1716  * </p>
1717  *
1718  * @return the receiver's visibility state
1719  *
1720  * @exception SWTException <ul>
1721  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1722  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1723  * </ul>
1724  */
1725 public boolean getVisible () {
1726         checkWidget ();
1727         if (!getDrawing()) return (state & HIDDEN) == 0;
1728         int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
1729         return (bits & OS.WS_VISIBLE) != 0;
1730 }
1731
1732 boolean hasCursor () {
1733         RECT rect = new RECT ();
1734         if (!OS.GetClientRect (handle, rect)) return false;
1735         OS.MapWindowPoints (handle, 0, rect, 2);
1736         POINT pt = new POINT ();
1737         return OS.GetCursorPos (pt) && OS.PtInRect (rect, pt);
1738 }
1739
1740 boolean hasCustomBackground() {
1741         return background != -1;
1742 }
1743
1744 boolean hasCustomForeground() {
1745         return foreground != -1;
1746 }
1747
1748 boolean hasFocus () {
1749         /*
1750         * If a non-SWT child of the control has focus,
1751         * then this control is considered to have focus
1752         * even though it does not have focus in Windows.
1753         */
1754         long hwndFocus = OS.GetFocus ();
1755         while (hwndFocus != 0) {
1756                 if (hwndFocus == handle) return true;
1757                 if (display.getControl (hwndFocus) != null) {
1758                         return false;
1759                 }
1760                 hwndFocus = OS.GetParent (hwndFocus);
1761         }
1762         return false;
1763 }
1764
1765 /**
1766  * Invokes platform specific functionality to allocate a new GC handle.
1767  * <p>
1768  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
1769  * API for <code>Control</code>. It is marked public only so that it
1770  * can be shared within the packages provided by SWT. It is not
1771  * available on all platforms, and should never be called from
1772  * application code.
1773  * </p>
1774  *
1775  * @param data the platform specific GC data
1776  * @return the platform specific GC handle
1777  *
1778  * @noreference This method is not intended to be referenced by clients.
1779  */
1780 @Override
1781 public long internal_new_GC (GCData data) {
1782         checkWidget();
1783         long hwnd = handle;
1784         if (data != null && data.hwnd != 0) hwnd = data.hwnd;
1785         if (data != null) data.hwnd = hwnd;
1786         long hDC = 0;
1787         if (data == null || data.ps == null) {
1788                 hDC = OS.GetDC (hwnd);
1789         } else {
1790                 hDC = OS.BeginPaint (hwnd, data.ps);
1791         }
1792         if (hDC == 0) error(SWT.ERROR_NO_HANDLES);
1793         if (data != null) {
1794                 int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
1795                 if ((data.style & mask) != 0) {
1796                         data.layout = (data.style & SWT.RIGHT_TO_LEFT) != 0 ? OS.LAYOUT_RTL : 0;
1797                 } else {
1798                         int flags = OS.GetLayout (hDC);
1799                         if ((flags & OS.LAYOUT_RTL) != 0) {
1800                                 data.style |= SWT.RIGHT_TO_LEFT | SWT.MIRRORED;
1801                         } else {
1802                                 data.style |= SWT.LEFT_TO_RIGHT;
1803                         }
1804                 }
1805                 data.device = display;
1806                 int foreground = getForegroundPixel ();
1807                 if (foreground != OS.GetTextColor (hDC)) data.foreground = foreground;
1808                 Control control = findBackgroundControl ();
1809                 if (control == null) control = this;
1810                 int background = control.getBackgroundPixel ();
1811                 if (background != OS.GetBkColor (hDC)) data.background = background;
1812                 data.font = font != null ? font : Font.win32_new (display, OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0));
1813                 data.uiState = (int)OS.SendMessage (hwnd, OS.WM_QUERYUISTATE, 0, 0);
1814         }
1815         return hDC;
1816 }
1817
1818 /**
1819  * Invokes platform specific functionality to dispose a GC handle.
1820  * <p>
1821  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
1822  * API for <code>Control</code>. It is marked public only so that it
1823  * can be shared within the packages provided by SWT. It is not
1824  * available on all platforms, and should never be called from
1825  * application code.
1826  * </p>
1827  *
1828  * @param hDC the platform specific GC handle
1829  * @param data the platform specific GC data
1830  *
1831  * @noreference This method is not intended to be referenced by clients.
1832  */
1833 @Override
1834 public void internal_dispose_GC (long hDC, GCData data) {
1835         checkWidget ();
1836         long hwnd = handle;
1837         if (data != null && data.hwnd != 0) {
1838                 hwnd = data.hwnd;
1839         }
1840         if (data == null || data.ps == null) {
1841                 OS.ReleaseDC (hwnd, hDC);
1842         } else {
1843                 OS.EndPaint (hwnd, data.ps);
1844         }
1845 }
1846
1847 boolean isActive () {
1848         Dialog dialog = display.getModalDialog ();
1849         if (dialog != null) {
1850                 Shell dialogShell = dialog.parent;
1851                 if (dialogShell != null && !dialogShell.isDisposed ()) {
1852                         if (dialogShell != getShell ()) return false;
1853                 }
1854         }
1855         Shell shell = null;
1856         Shell [] modalShells = display.modalShells;
1857         if (modalShells != null) {
1858                 int bits = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
1859                 int index = modalShells.length;
1860                 while (--index >= 0) {
1861                         Shell modal = modalShells [index];
1862                         if (modal != null) {
1863                                 if ((modal.style & bits) != 0) {
1864                                         Control control = this;
1865                                         while (control != null) {
1866                                                 if (control == modal) break;
1867                                                 control = control.parent;
1868                                         }
1869                                         if (control != modal) return false;
1870                                         break;
1871                                 }
1872                                 if ((modal.style & SWT.PRIMARY_MODAL) != 0) {
1873                                         if (shell == null) shell = getShell ();
1874                                         if (modal.parent == shell) return false;
1875                                 }
1876                         }
1877                 }
1878         }
1879         if (shell == null) shell = getShell ();
1880         return shell.getEnabled ();
1881 }
1882
1883 /**
1884  * Returns <code>true</code> if the receiver is enabled and all
1885  * ancestors up to and including the receiver's nearest ancestor
1886  * shell are enabled.  Otherwise, <code>false</code> is returned.
1887  * A disabled control is typically not selectable from the user
1888  * interface and draws with an inactive or "grayed" look.
1889  *
1890  * @return the receiver's enabled state
1891  *
1892  * @exception SWTException <ul>
1893  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1894  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1895  * </ul>
1896  *
1897  * @see #getEnabled
1898  */
1899 public boolean isEnabled () {
1900         checkWidget ();
1901         return getEnabled () && parent.isEnabled ();
1902 }
1903
1904 /**
1905  * Returns <code>true</code> if the receiver has the user-interface
1906  * focus, and <code>false</code> otherwise.
1907  *
1908  * @return the receiver's focus state
1909  *
1910  * @exception SWTException <ul>
1911  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1912  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1913  * </ul>
1914  */
1915 public boolean isFocusControl () {
1916         checkWidget ();
1917         Control focusControl = display.focusControl;
1918         if (focusControl != null && !focusControl.isDisposed ()) {
1919                 return this == focusControl;
1920         }
1921         return hasFocus ();
1922 }
1923
1924 boolean isFocusAncestor (Control control) {
1925         while (control != null && control != this && !(control instanceof Shell)) {
1926                 control = control.parent;
1927         }
1928         return control == this;
1929 }
1930
1931 /**
1932  * Returns <code>true</code> if the underlying operating
1933  * system supports this reparenting, otherwise <code>false</code>
1934  *
1935  * @return <code>true</code> if the widget can be reparented, otherwise <code>false</code>
1936  *
1937  * @exception SWTException <ul>
1938  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1939  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1940  * </ul>
1941  */
1942 public boolean isReparentable () {
1943         checkWidget ();
1944         return true;
1945 }
1946
1947 boolean isShowing () {
1948         /*
1949         * This is not complete.  Need to check if the
1950         * widget is obscured by a parent or sibling.
1951         */
1952         if (!isVisible ()) return false;
1953         Control control = this;
1954         while (control != null) {
1955                 Point size = control.getSizeInPixels ();
1956                 if (size.x == 0 || size.y == 0) {
1957                         return false;
1958                 }
1959                 control = control.parent;
1960         }
1961         return true;
1962         /*
1963         * Check to see if current damage is included.
1964         */
1965 //      if (!OS.IsWindowVisible (handle)) return false;
1966 //      int flags = OS.DCX_CACHE | OS.DCX_CLIPCHILDREN | OS.DCX_CLIPSIBLINGS;
1967 //      long hDC = OS.GetDCEx (handle, 0, flags);
1968 //      int result = OS.GetClipBox (hDC, new RECT ());
1969 //      OS.ReleaseDC (handle, hDC);
1970 //      return result != OS.NULLREGION;
1971 }
1972
1973 boolean isTabGroup () {
1974         Control [] tabList = parent._getTabList ();
1975         if (tabList != null) {
1976                 for (int i=0; i<tabList.length; i++) {
1977                         if (tabList [i] == this) return true;
1978                 }
1979         }
1980         int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
1981         return (bits & OS.WS_TABSTOP) != 0;
1982 }
1983
1984 boolean isTabItem () {
1985         Control [] tabList = parent._getTabList ();
1986         if (tabList != null) {
1987                 for (int i=0; i<tabList.length; i++) {
1988                         if (tabList [i] == this) return false;
1989                 }
1990         }
1991         int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
1992         if ((bits & OS.WS_TABSTOP) != 0) return false;
1993         long code = OS.SendMessage (handle, OS.WM_GETDLGCODE, 0, 0);
1994         if ((code & OS.DLGC_STATIC) != 0) return false;
1995         if ((code & OS.DLGC_WANTALLKEYS) != 0) return false;
1996         if ((code & OS.DLGC_WANTARROWS) != 0) return false;
1997         if ((code & OS.DLGC_WANTTAB) != 0) return false;
1998         return true;
1999 }
2000
2001 /**
2002  * Returns <code>true</code> if the receiver is visible and all
2003  * ancestors up to and including the receiver's nearest ancestor
2004  * shell are visible. Otherwise, <code>false</code> is returned.
2005  *
2006  * @return the receiver's visibility state
2007  *
2008  * @exception SWTException <ul>
2009  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2010  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2011  * </ul>
2012  *
2013  * @see #getVisible
2014  */
2015 public boolean isVisible () {
2016         checkWidget ();
2017         if (OS.IsWindowVisible (handle)) return true;
2018         return getVisible () && parent.isVisible ();
2019 }
2020
2021 @Override
2022 void mapEvent (long hwnd, Event event) {
2023         if (hwnd != handle) {
2024                 POINT point = new POINT ();
2025                 Point loc = event.getLocationInPixels();
2026                 point.x = loc.x;
2027                 point.y = loc.y;
2028                 OS.MapWindowPoints (hwnd, handle, point, 1);
2029                 event.setLocationInPixels(point.x, point.y);
2030         }
2031 }
2032
2033 void markLayout (boolean changed, boolean all) {
2034         /* Do nothing */
2035 }
2036
2037 Decorations menuShell () {
2038         return parent.menuShell ();
2039 }
2040
2041 boolean mnemonicHit (char key) {
2042         return false;
2043 }
2044
2045 boolean mnemonicMatch (char key) {
2046         return false;
2047 }
2048
2049 /**
2050  * Moves the receiver above the specified control in the
2051  * drawing order. If the argument is null, then the receiver
2052  * is moved to the top of the drawing order. The control at
2053  * the top of the drawing order will not be covered by other
2054  * controls even if they occupy intersecting areas.
2055  *
2056  * @param control the sibling control (or null)
2057  *
2058  * @exception IllegalArgumentException <ul>
2059  *    <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
2060  * </ul>
2061  * @exception SWTException <ul>
2062  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2063  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2064  * </ul>
2065  *
2066  * @see Control#moveBelow
2067  * @see Composite#getChildren
2068  */
2069 public void moveAbove (Control control) {
2070         checkWidget ();
2071         long topHandle = topHandle (), hwndAbove = OS.HWND_TOP;
2072         if (control != null) {
2073                 if (control.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT);
2074                 if (parent != control.parent) return;
2075                 long hwnd = control.topHandle ();
2076                 if (hwnd == 0 || hwnd == topHandle) return;
2077                 hwndAbove = OS.GetWindow (hwnd, OS.GW_HWNDPREV);
2078                 /*
2079                 * Bug in Windows.  For some reason, when GetWindow ()
2080                 * with GW_HWNDPREV is used to query the previous window
2081                 * in the z-order with the first child, Windows returns
2082                 * the first child instead of NULL.  The fix is to detect
2083                 * this case and move the control to the top.
2084                 */
2085                 if (hwndAbove == 0 || hwndAbove == hwnd) {
2086                         hwndAbove = OS.HWND_TOP;
2087                 }
2088         }
2089         int flags = OS.SWP_NOSIZE | OS.SWP_NOMOVE | OS.SWP_NOACTIVATE;
2090         OS.SetWindowPos (topHandle, hwndAbove, 0, 0, 0, 0, flags);
2091 }
2092
2093 /**
2094  * Moves the receiver below the specified control in the
2095  * drawing order. If the argument is null, then the receiver
2096  * is moved to the bottom of the drawing order. The control at
2097  * the bottom of the drawing order will be covered by all other
2098  * controls which occupy intersecting areas.
2099  *
2100  * @param control the sibling control (or null)
2101  *
2102  * @exception IllegalArgumentException <ul>
2103  *    <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
2104  * </ul>
2105  * @exception SWTException <ul>
2106  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2107  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2108  * </ul>
2109  *
2110  * @see Control#moveAbove
2111  * @see Composite#getChildren
2112  */
2113 public void moveBelow (Control control) {
2114         checkWidget ();
2115         long topHandle = topHandle (), hwndAbove = OS.HWND_BOTTOM;
2116         if (control != null) {
2117                 if (control.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT);
2118                 if (parent != control.parent) return;
2119                 hwndAbove = control.topHandle ();
2120         } else {
2121                 /*
2122                 * Bug in Windows.  When SetWindowPos() is called
2123                 * with HWND_BOTTOM on a dialog shell, the dialog
2124                 * and the parent are moved to the bottom of the
2125                 * desktop stack.  The fix is to move the dialog
2126                 * to the bottom of the dialog window stack by
2127                 * moving behind the first dialog child.
2128                 */
2129                 Shell shell = getShell ();
2130                 if (this == shell && parent != null) {
2131                         /*
2132                         * Bug in Windows.  For some reason, when GetWindow ()
2133                         * with GW_HWNDPREV is used to query the previous window
2134                         * in the z-order with the first child, Windows returns
2135                         * the first child instead of NULL.  The fix is to detect
2136                         * this case and do nothing because the control is already
2137                         * at the bottom.
2138                         */
2139                         long hwndParent = parent.handle, hwnd = hwndParent;
2140                         hwndAbove = OS.GetWindow (hwnd, OS.GW_HWNDPREV);
2141                         while (hwndAbove != 0 && hwndAbove != hwnd) {
2142                                 if (OS.GetWindow (hwndAbove, OS.GW_OWNER) == hwndParent) break;
2143                                 hwndAbove = OS.GetWindow (hwnd = hwndAbove, OS.GW_HWNDPREV);
2144                         }
2145                         if (hwndAbove == hwnd) return;
2146                 }
2147         }
2148         if (hwndAbove == 0 || hwndAbove == topHandle) return;
2149         int flags = OS.SWP_NOSIZE | OS.SWP_NOMOVE | OS.SWP_NOACTIVATE;
2150         OS.SetWindowPos (topHandle, hwndAbove, 0, 0, 0, 0, flags);
2151 }
2152
2153 Accessible new_Accessible (Control control) {
2154         return Accessible.internal_new_Accessible (this);
2155 }
2156
2157 @Override
2158 GC new_GC (GCData data) {
2159         return GC.win32_new (this, data);
2160 }
2161
2162 /**
2163  * Causes the receiver to be resized to its preferred size.
2164  * For a composite, this involves computing the preferred size
2165  * from its layout, if there is one.
2166  *
2167  * @exception SWTException <ul>
2168  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2169  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2170  * </ul>
2171  *
2172  * @see #computeSize(int, int, boolean)
2173  */
2174 public void pack () {
2175         checkWidget ();
2176         pack (true);
2177 }
2178
2179 /**
2180  * Causes the receiver to be resized to its preferred size.
2181  * For a composite, this involves computing the preferred size
2182  * from its layout, if there is one.
2183  * <p>
2184  * If the changed flag is <code>true</code>, it indicates that the receiver's
2185  * <em>contents</em> have changed, therefore any caches that a layout manager
2186  * containing the control may have been keeping need to be flushed. When the
2187  * control is resized, the changed flag will be <code>false</code>, so layout
2188  * manager caches can be retained.
2189  * </p>
2190  *
2191  * @param changed whether or not the receiver's contents have changed
2192  *
2193  * @exception SWTException <ul>
2194  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2195  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2196  * </ul>
2197  *
2198  * @see #computeSize(int, int, boolean)
2199  */
2200 public void pack (boolean changed) {
2201         checkWidget ();
2202         /*
2203          * Since computeSize is overridden by Custom classes like CCombo
2204          * etc... hence we cannot call computeSizeInPixels directly.
2205          */
2206         setSize (computeSize (SWT.DEFAULT, SWT.DEFAULT, changed));
2207 }
2208
2209 /**
2210  * Prints the receiver and all children.
2211  *
2212  * @param gc the gc where the drawing occurs
2213  * @return <code>true</code> if the operation was successful and <code>false</code> otherwise
2214  *
2215  * @exception IllegalArgumentException <ul>
2216  *    <li>ERROR_NULL_ARGUMENT - if the gc is null</li>
2217  *    <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li>
2218  * </ul>
2219  * @exception SWTException <ul>
2220  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2221  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2222  * </ul>
2223  *
2224  * @since 3.4
2225  */
2226 public boolean print (GC gc) {
2227         checkWidget ();
2228         if (gc == null) error (SWT.ERROR_NULL_ARGUMENT);
2229         if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
2230         long topHandle = topHandle ();
2231         long hdc = gc.handle;
2232         int state = 0;
2233         long gdipGraphics = gc.getGCData().gdipGraphics;
2234         if (gdipGraphics != 0) {
2235                 long clipRgn = 0;
2236                 Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone);
2237                 long rgn = Gdip.Region_new();
2238                 if (rgn == 0) error(SWT.ERROR_NO_HANDLES);
2239                 Gdip.Graphics_GetClip(gdipGraphics, rgn);
2240                 if (!Gdip.Region_IsInfinite(rgn, gdipGraphics)) {
2241                         clipRgn = Gdip.Region_GetHRGN(rgn, gdipGraphics);
2242                 }
2243                 Gdip.Region_delete(rgn);
2244                 Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeHalf);
2245                 float[] lpXform = null;
2246                 long matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0);
2247                 if (matrix == 0) error(SWT.ERROR_NO_HANDLES);
2248                 Gdip.Graphics_GetTransform(gdipGraphics, matrix);
2249                 if (!Gdip.Matrix_IsIdentity(matrix)) {
2250                         lpXform = new float[6];
2251                         Gdip.Matrix_GetElements(matrix, lpXform);
2252                 }
2253                 Gdip.Matrix_delete(matrix);
2254                 hdc = Gdip.Graphics_GetHDC(gdipGraphics);
2255                 state = OS.SaveDC(hdc);
2256                 if (lpXform != null) {
2257                         OS.SetGraphicsMode(hdc, OS.GM_ADVANCED);
2258                         OS.SetWorldTransform(hdc, lpXform);
2259                 }
2260                 if (clipRgn != 0) {
2261                         OS.SelectClipRgn(hdc, clipRgn);
2262                         OS.DeleteObject(clipRgn);
2263                 }
2264         }
2265         int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
2266         OS.RedrawWindow (topHandle, null, 0, flags);
2267         printWidget (topHandle, hdc, gc);
2268         if (gdipGraphics != 0) {
2269                 OS.RestoreDC(hdc, state);
2270                 Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc);
2271         }
2272         return true;
2273 }
2274
2275 void printWidget (long hwnd, long hdc, GC gc) {
2276         /*
2277         * Bug in Windows.  For some reason, PrintWindow()
2278         * returns success but does nothing when it is called
2279         * on a printer.  The fix is to just go directly to
2280         * WM_PRINT in this case.
2281         */
2282         boolean success = false;
2283         if (!(OS.GetDeviceCaps(gc.handle, OS.TECHNOLOGY) == OS.DT_RASPRINTER)) {
2284                 /*
2285                 * Bug in Windows.  When PrintWindow() will only draw that
2286                 * portion of a control that is not obscured by the shell.
2287                 * The fix is temporarily reparent the window to the desktop,
2288                 * call PrintWindow() then reparent the window back.
2289                 */
2290                 long hwndParent = OS.GetParent (hwnd);
2291                 long hwndShell = hwndParent;
2292                 while (OS.GetParent (hwndShell) != 0) {
2293                         if (OS.GetWindow (hwndShell, OS.GW_OWNER) != 0) break;
2294                         hwndShell = OS.GetParent (hwndShell);
2295                 }
2296                 RECT rect1 = new RECT ();
2297                 OS.GetWindowRect (hwnd, rect1);
2298                 boolean fixPrintWindow = !OS.IsWindowVisible(hwnd);
2299                 if (!fixPrintWindow) {
2300                         RECT rect2 = new RECT ();
2301                         OS.GetWindowRect (hwndShell, rect2);
2302                         OS.IntersectRect (rect2, rect1, rect2);
2303                         fixPrintWindow = !OS.EqualRect (rect2, rect1);
2304                 }
2305                 /*
2306                 * Bug in Windows. PrintWindow() does not print portions
2307                 * of the receiver that are clipped out using SetWindowRgn()
2308                 * in a parent.  The fix is temporarily reparent the window
2309                 * to the desktop, call PrintWindow() then reparent the window
2310                 * back.
2311                 */
2312                 if (!fixPrintWindow) {
2313                         long rgn = OS.CreateRectRgn(0, 0, 0, 0);
2314                         long parent = OS.GetParent(hwnd);
2315                         while (parent != hwndShell && !fixPrintWindow) {
2316                                 if (OS.GetWindowRgn(parent, rgn) != 0) {
2317                                         fixPrintWindow = true;
2318                                 }
2319                                 parent = OS.GetParent(parent);
2320                         }
2321                         OS.DeleteObject(rgn);
2322                 }
2323                 int bits1 = OS.GetWindowLong (hwnd, OS.GWL_STYLE);
2324                 int bits2 = OS.GetWindowLong (hwnd, OS.GWL_EXSTYLE);
2325                 long hwndInsertAfter = OS.GetWindow (hwnd, OS.GW_HWNDPREV);
2326                 /*
2327                 * Bug in Windows.  For some reason, when GetWindow ()
2328                 * with GW_HWNDPREV is used to query the previous window
2329                 * in the z-order with the first child, Windows returns
2330                 * the first child instead of NULL.  The fix is to detect
2331                 * this case and move the control to the top.
2332                 */
2333                 if (hwndInsertAfter == 0 || hwndInsertAfter == hwnd) {
2334                         hwndInsertAfter = OS.HWND_TOP;
2335                 }
2336                 if (fixPrintWindow) {
2337                         int x = OS.GetSystemMetrics (OS.SM_XVIRTUALSCREEN);
2338                         int y = OS.GetSystemMetrics (OS.SM_YVIRTUALSCREEN);
2339                         int width = OS.GetSystemMetrics (OS.SM_CXVIRTUALSCREEN);
2340                         int height = OS.GetSystemMetrics (OS.SM_CYVIRTUALSCREEN);
2341                         int flags = OS.SWP_NOSIZE | OS.SWP_NOZORDER | OS.SWP_NOACTIVATE | OS.SWP_DRAWFRAME;
2342                         if ((bits1 & OS.WS_VISIBLE) != 0) {
2343                                 OS.DefWindowProc (hwnd, OS.WM_SETREDRAW, 0, 0);
2344                         }
2345                         OS.SetWindowPos (hwnd, 0, x + width, y + height, 0, 0, flags);
2346                         OS.SetWindowLong (hwnd, OS.GWL_STYLE, (bits1 & ~OS.WS_CHILD) | OS.WS_POPUP);
2347                         OS.SetWindowLong (hwnd, OS.GWL_EXSTYLE, bits2 | OS.WS_EX_TOOLWINDOW);
2348                         Shell shell = getShell ();
2349                         Control savedFocus = shell.savedFocus;
2350                         OS.SetParent (hwnd, 0);
2351                         shell.setSavedFocus (savedFocus);
2352                         if ((bits1 & OS.WS_VISIBLE) != 0) {
2353                                 OS.DefWindowProc (hwnd, OS.WM_SETREDRAW, 1, 0);
2354                         }
2355                 }
2356                 if ((bits1 & OS.WS_VISIBLE) == 0) {
2357                         OS.ShowWindow (hwnd, OS.SW_SHOW);
2358                 }
2359                 success = OS.PrintWindow (hwnd, hdc, 0);
2360                 if ((bits1 & OS.WS_VISIBLE) == 0) {
2361                         OS.ShowWindow (hwnd, OS.SW_HIDE);
2362                 }
2363                 if (fixPrintWindow) {
2364                         if ((bits1 & OS.WS_VISIBLE) != 0) {
2365                                 OS.DefWindowProc (hwnd, OS.WM_SETREDRAW, 0, 0);
2366                         }
2367                         OS.SetWindowLong (hwnd, OS.GWL_STYLE, bits1);
2368                         OS.SetWindowLong (hwnd, OS.GWL_EXSTYLE, bits2);
2369                         OS.SetParent (hwnd, hwndParent);
2370                         OS.MapWindowPoints (0, hwndParent, rect1, 2);
2371                         int flags = OS.SWP_NOSIZE | OS.SWP_NOACTIVATE | OS.SWP_DRAWFRAME;
2372                         OS.SetWindowPos (hwnd, hwndInsertAfter, rect1.left, rect1.top, rect1.right - rect1.left, rect1.bottom - rect1.top, flags);
2373                         if ((bits1 & OS.WS_VISIBLE) != 0) {
2374                                 OS.DefWindowProc (hwnd, OS.WM_SETREDRAW, 1, 0);
2375                         }
2376                 }
2377         }
2378
2379         /*
2380         * Bug in Windows.  For some reason, PrintWindow() fails
2381         * when it is called on a push button.  The fix is to
2382         * detect the failure and use WM_PRINT instead.  Note
2383         * that WM_PRINT cannot be used all the time because it
2384         * fails for browser controls when the browser has focus.
2385         */
2386         if (!success) {
2387                 int flags = OS.PRF_CLIENT | OS.PRF_NONCLIENT | OS.PRF_ERASEBKGND | OS.PRF_CHILDREN;
2388                 OS.SendMessage (hwnd, OS.WM_PRINT, hdc, flags);
2389         }
2390 }
2391
2392 /**
2393  * Requests that this control and all of its ancestors be repositioned by
2394  * their layouts at the earliest opportunity. This should be invoked after
2395  * modifying the control in order to inform any dependent layouts of
2396  * the change.
2397  * <p>
2398  * The control will not be repositioned synchronously. This method is
2399  * fast-running and only marks the control for future participation in
2400  * a deferred layout.
2401  * <p>
2402  * Invoking this method multiple times before the layout occurs is an
2403  * inexpensive no-op.
2404  *
2405  * @since 3.105
2406  */
2407 public void requestLayout () {
2408         getShell ().layout (new Control[] {this}, SWT.DEFER);
2409 }
2410
2411 /**
2412  * Causes the entire bounds of the receiver to be marked
2413  * as needing to be redrawn. The next time a paint request
2414  * is processed, the control will be completely painted,
2415  * including the background.
2416  * <p>
2417  * Schedules a paint request if the invalidated area is visible
2418  * or becomes visible later. It is not necessary for the caller
2419  * to explicitly call {@link #update()} after calling this method,
2420  * but depending on the platform, the automatic repaints may be
2421  * delayed considerably.
2422  * </p>
2423  *
2424  * @exception SWTException <ul>
2425  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2426  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2427  * </ul>
2428  *
2429  * @see #update()
2430  * @see PaintListener
2431  * @see SWT#Paint
2432  * @see SWT#NO_BACKGROUND
2433  * @see SWT#NO_REDRAW_RESIZE
2434  * @see SWT#NO_MERGE_PAINTS
2435  * @see SWT#DOUBLE_BUFFERED
2436  */
2437 public void redraw () {
2438         checkWidget ();
2439         redraw (false);
2440 }
2441
2442 void redraw (boolean all) {
2443 //      checkWidget ();
2444         if (!OS.IsWindowVisible (handle)) return;
2445         int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE;
2446         if (all) flags |= OS.RDW_ALLCHILDREN;
2447         OS.RedrawWindow (handle, null, 0, flags);
2448 }
2449 /**
2450  * Causes the rectangular area of the receiver specified by
2451  * the arguments to be marked as needing to be redrawn.
2452  * The next time a paint request is processed, that area of
2453  * the receiver will be painted, including the background.
2454  * If the <code>all</code> flag is <code>true</code>, any
2455  * children of the receiver which intersect with the specified
2456  * area will also paint their intersecting areas. If the
2457  * <code>all</code> flag is <code>false</code>, the children
2458  * will not be painted.
2459  * <p>
2460  * Schedules a paint request if the invalidated area is visible
2461  * or becomes visible later. It is not necessary for the caller
2462  * to explicitly call {@link #update()} after calling this method,
2463  * but depending on the platform, the automatic repaints may be
2464  * delayed considerably.
2465  * </p>
2466  *
2467  * @param x the x coordinate of the area to draw
2468  * @param y the y coordinate of the area to draw
2469  * @param width the width of the area to draw
2470  * @param height the height of the area to draw
2471  * @param all <code>true</code> if children should redraw, and <code>false</code> otherwise
2472  *
2473  * @exception SWTException <ul>
2474  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2475  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2476  * </ul>
2477  *
2478  * @see #update()
2479  * @see PaintListener
2480  * @see SWT#Paint
2481  * @see SWT#NO_BACKGROUND
2482  * @see SWT#NO_REDRAW_RESIZE
2483  * @see SWT#NO_MERGE_PAINTS
2484  * @see SWT#DOUBLE_BUFFERED
2485  */
2486 public void redraw (int x, int y, int width, int height, boolean all) {
2487         checkWidget ();
2488         x = DPIUtil.autoScaleUp(x);
2489         y = DPIUtil.autoScaleUp(y);
2490         width = DPIUtil.autoScaleUp(width);
2491         height = DPIUtil.autoScaleUp(height);
2492         redrawInPixels(x, y, width, height, all);
2493 }
2494
2495 void redrawInPixels (int x, int y, int width, int height, boolean all) {
2496         if (width <= 0 || height <= 0) return;
2497         if (!OS.IsWindowVisible (handle)) return;
2498         RECT rect = new RECT ();
2499         OS.SetRect (rect, x, y, x + width, y + height);
2500         int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE;
2501         if (all) flags |= OS.RDW_ALLCHILDREN;
2502         OS.RedrawWindow (handle, rect, 0, flags);
2503 }
2504
2505 boolean redrawChildren () {
2506         if (!OS.IsWindowVisible (handle)) return false;
2507         Control control = findBackgroundControl ();
2508         if (control == null) {
2509                 if ((state & THEME_BACKGROUND) != 0) {
2510                         if (OS.IsAppThemed ()) {
2511                                 OS.InvalidateRect (handle, null, true);
2512                                 return true;
2513                         }
2514                 }
2515         } else {
2516                 if (control.backgroundImage != null) {
2517                         OS.InvalidateRect (handle, null, true);
2518                         return true;
2519                 }
2520         }
2521         return false;
2522 }
2523
2524 void register () {
2525         display.addControl (handle, this);
2526 }
2527
2528 @Override
2529 void releaseHandle () {
2530         super.releaseHandle ();
2531         handle = 0;
2532         parent = null;
2533 }
2534
2535 @Override
2536 void releaseParent () {
2537         parent.removeControl (this);
2538 }
2539
2540 @Override
2541 void releaseWidget () {
2542         super.releaseWidget ();
2543         if (OS.IsDBLocale) {
2544                 OS.ImmAssociateContext (handle, 0);
2545         }
2546         if (toolTipText != null) {
2547                 setToolTipText (getShell (), null);
2548         }
2549         toolTipText = null;
2550         if (menu != null && !menu.isDisposed ()) {
2551                 menu.dispose ();
2552         }
2553         backgroundImage = null;
2554         menu = null;
2555         cursor = null;
2556         unsubclass ();
2557         deregister ();
2558         layoutData = null;
2559         if (accessible != null) {
2560                 accessible.internal_dispose_Accessible ();
2561         }
2562         accessible = null;
2563         region = null;
2564         font = null;
2565 }
2566
2567 /**
2568  * Removes the listener from the collection of listeners who will
2569  * be notified when the control is moved or resized.
2570  *
2571  * @param listener the listener which should no longer be notified
2572  *
2573  * @exception IllegalArgumentException <ul>
2574  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2575  * </ul>
2576  * @exception SWTException <ul>
2577  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2578  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2579  * </ul>
2580  *
2581  * @see ControlListener
2582  * @see #addControlListener
2583  */
2584 public void removeControlListener (ControlListener listener) {
2585         checkWidget ();
2586         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2587         if (eventTable == null) return;
2588         eventTable.unhook (SWT.Move, listener);
2589         eventTable.unhook (SWT.Resize, listener);
2590 }
2591
2592 /**
2593  * Removes the listener from the collection of listeners who will
2594  * be notified when a drag gesture occurs.
2595  *
2596  * @param listener the listener which should no longer be notified
2597  *
2598  * @exception IllegalArgumentException <ul>
2599  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2600  * </ul>
2601  * @exception SWTException <ul>
2602  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2603  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2604  * </ul>
2605  *
2606  * @see DragDetectListener
2607  * @see #addDragDetectListener
2608  *
2609  * @since 3.3
2610  */
2611 public void removeDragDetectListener(DragDetectListener listener) {
2612         checkWidget ();
2613         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2614         if (eventTable == null) return;
2615         eventTable.unhook (SWT.DragDetect, listener);
2616 }
2617
2618 /**
2619  * Removes the listener from the collection of listeners who will
2620  * be notified when the control gains or loses focus.
2621  *
2622  * @param listener the listener which should no longer be notified
2623  *
2624  * @exception IllegalArgumentException <ul>
2625  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2626  * </ul>
2627  * @exception SWTException <ul>
2628  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2629  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2630  * </ul>
2631  *
2632  * @see FocusListener
2633  * @see #addFocusListener
2634  */
2635 public void removeFocusListener(FocusListener listener) {
2636         checkWidget ();
2637         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2638         if (eventTable == null) return;
2639         eventTable.unhook (SWT.FocusIn, listener);
2640         eventTable.unhook (SWT.FocusOut, listener);
2641 }
2642
2643 /**
2644  * Removes the listener from the collection of listeners who will
2645  * be notified when gesture events are generated for the control.
2646  *
2647  * @param listener the listener which should no longer be notified
2648  *
2649  * @exception IllegalArgumentException <ul>
2650  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2651  * </ul>
2652  * @exception SWTException <ul>
2653  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2654  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2655  * </ul>
2656  *
2657  * @see GestureListener
2658  * @see #addGestureListener
2659  *
2660  * @since 3.7
2661  */
2662 public void removeGestureListener (GestureListener listener) {
2663         checkWidget();
2664         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2665         if (eventTable == null) return;
2666         eventTable.unhook (SWT.Gesture, listener);
2667 }
2668
2669 /**
2670  * Removes the listener from the collection of listeners who will
2671  * be notified when the help events are generated for the control.
2672  *
2673  * @param listener the listener which should no longer be notified
2674  *
2675  * @exception IllegalArgumentException <ul>
2676  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2677  * </ul>
2678  * @exception SWTException <ul>
2679  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2680  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2681  * </ul>
2682  *
2683  * @see HelpListener
2684  * @see #addHelpListener
2685  */
2686 public void removeHelpListener (HelpListener listener) {
2687         checkWidget ();
2688         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2689         if (eventTable == null) return;
2690         eventTable.unhook (SWT.Help, listener);
2691 }
2692
2693 /**
2694  * Removes the listener from the collection of listeners who will
2695  * be notified when keys are pressed and released on the system keyboard.
2696  *
2697  * @param listener the listener which should no longer be notified
2698  *
2699  * @exception IllegalArgumentException <ul>
2700  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2701  * </ul>
2702  * @exception SWTException <ul>
2703  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2704  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2705  * </ul>
2706  *
2707  * @see KeyListener
2708  * @see #addKeyListener
2709  */
2710 public void removeKeyListener(KeyListener listener) {
2711         checkWidget ();
2712         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2713         if (eventTable == null) return;
2714         eventTable.unhook (SWT.KeyUp, listener);
2715         eventTable.unhook (SWT.KeyDown, listener);
2716 }
2717
2718 /**
2719  * Removes the listener from the collection of listeners who will
2720  * be notified when the platform-specific context menu trigger has
2721  * occurred.
2722  *
2723  * @param listener the listener which should no longer be notified
2724  *
2725  * @exception IllegalArgumentException <ul>
2726  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2727  * </ul>
2728  * @exception SWTException <ul>
2729  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2730  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2731  * </ul>
2732  *
2733  * @see MenuDetectListener
2734  * @see #addMenuDetectListener
2735  *
2736  * @since 3.3
2737  */
2738 public void removeMenuDetectListener (MenuDetectListener listener) {
2739         checkWidget ();
2740         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2741         if (eventTable == null) return;
2742         eventTable.unhook (SWT.MenuDetect, listener);
2743 }
2744
2745 /**
2746  * Removes the listener from the collection of listeners who will
2747  * be notified when the mouse passes or hovers over controls.
2748  *
2749  * @param listener the listener which should no longer be notified
2750  *
2751  * @exception IllegalArgumentException <ul>
2752  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2753  * </ul>
2754  * @exception SWTException <ul>
2755  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2756  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2757  * </ul>
2758  *
2759  * @see MouseTrackListener
2760  * @see #addMouseTrackListener
2761  */
2762 public void removeMouseTrackListener(MouseTrackListener listener) {
2763         checkWidget ();
2764         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2765         if (eventTable == null) return;
2766         eventTable.unhook (SWT.MouseEnter, listener);
2767         eventTable.unhook (SWT.MouseExit, listener);
2768         eventTable.unhook (SWT.MouseHover, listener);
2769 }
2770
2771 /**
2772  * Removes the listener from the collection of listeners who will
2773  * be notified when mouse buttons are pressed and released.
2774  *
2775  * @param listener the listener which should no longer be notified
2776  *
2777  * @exception IllegalArgumentException <ul>
2778  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2779  * </ul>
2780  * @exception SWTException <ul>
2781  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2782  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2783  * </ul>
2784  *
2785  * @see MouseListener
2786  * @see #addMouseListener
2787  */
2788 public void removeMouseListener (MouseListener listener) {
2789         checkWidget ();
2790         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2791         if (eventTable == null) return;
2792         eventTable.unhook (SWT.MouseDown, listener);
2793         eventTable.unhook (SWT.MouseUp, listener);
2794         eventTable.unhook (SWT.MouseDoubleClick, listener);
2795 }
2796
2797 /**
2798  * Removes the listener from the collection of listeners who will
2799  * be notified when the mouse moves.
2800  *
2801  * @param listener the listener which should no longer be notified
2802  *
2803  * @exception IllegalArgumentException <ul>
2804  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2805  * </ul>
2806  * @exception SWTException <ul>
2807  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2808  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2809  * </ul>
2810  *
2811  * @see MouseMoveListener
2812  * @see #addMouseMoveListener
2813  */
2814 public void removeMouseMoveListener(MouseMoveListener listener) {
2815         checkWidget ();
2816         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2817         if (eventTable == null) return;
2818         eventTable.unhook (SWT.MouseMove, listener);
2819 }
2820
2821 /**
2822  * Removes the listener from the collection of listeners who will
2823  * be notified when the mouse wheel is scrolled.
2824  *
2825  * @param listener the listener which should no longer be notified
2826  *
2827  * @exception IllegalArgumentException <ul>
2828  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2829  * </ul>
2830  * @exception SWTException <ul>
2831  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2832  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2833  * </ul>
2834  *
2835  * @see MouseWheelListener
2836  * @see #addMouseWheelListener
2837  *
2838  * @since 3.3
2839  */
2840 public void removeMouseWheelListener (MouseWheelListener listener) {
2841         checkWidget ();
2842         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2843         if (eventTable == null) return;
2844         eventTable.unhook (SWT.MouseWheel, listener);
2845 }
2846
2847 /**
2848  * Removes the listener from the collection of listeners who will
2849  * be notified when the receiver needs to be painted.
2850  *
2851  * @param listener the listener which should no longer be notified
2852  *
2853  * @exception IllegalArgumentException <ul>
2854  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2855  * </ul>
2856  * @exception SWTException <ul>
2857  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2858  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2859  * </ul>
2860  *
2861  * @see PaintListener
2862  * @see #addPaintListener
2863  */
2864 public void removePaintListener(PaintListener listener) {
2865         checkWidget ();
2866         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2867         if (eventTable == null) return;
2868         eventTable.unhook(SWT.Paint, listener);
2869 }
2870
2871 /**
2872  * Removes the listener from the collection of listeners who will
2873  * be notified when touch events occur.
2874  *
2875  * @param listener the listener which should no longer be notified
2876  *
2877  * @exception IllegalArgumentException <ul>
2878  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2879  * </ul>
2880  * @exception SWTException <ul>
2881  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2882  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2883  * </ul>
2884  *
2885  * @see TouchListener
2886  * @see #addTouchListener
2887  *
2888  * @since 3.7
2889  */
2890 public void removeTouchListener(TouchListener listener) {
2891         checkWidget();
2892         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2893         if (eventTable == null) return;
2894         eventTable.unhook (SWT.Touch, listener);
2895 }
2896
2897 /**
2898  * Removes the listener from the collection of listeners who will
2899  * be notified when traversal events occur.
2900  *
2901  * @param listener the listener which should no longer be notified
2902  *
2903  * @exception IllegalArgumentException <ul>
2904  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
2905  * </ul>
2906  * @exception SWTException <ul>
2907  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2908  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2909  * </ul>
2910  *
2911  * @see TraverseListener
2912  * @see #addTraverseListener
2913  */
2914 public void removeTraverseListener(TraverseListener listener) {
2915         checkWidget ();
2916         if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
2917         if (eventTable == null) return;
2918         eventTable.unhook (SWT.Traverse, listener);
2919 }
2920
2921 int resolveTextDirection() {
2922         /*
2923          * For generic Controls do nothing here. Text-enabled Controls will resolve
2924          * AUTO text direction according to their text content.
2925          */
2926         return SWT.NONE;
2927 }
2928
2929 void showWidget (boolean visible) {
2930         long topHandle = topHandle ();
2931         OS.ShowWindow (topHandle, visible ? OS.SW_SHOW : OS.SW_HIDE);
2932         if (handle != topHandle) OS.ShowWindow (handle, visible ? OS.SW_SHOW : OS.SW_HIDE);
2933 }
2934
2935 @Override
2936 boolean sendFocusEvent (int type) {
2937         Shell shell = getShell ();
2938
2939         /*
2940         * Feature in Windows.  During the processing of WM_KILLFOCUS,
2941         * when the focus window is queried using GetFocus(), it has
2942         * already been assigned to the new window.  The fix is to
2943         * remember the control that is losing or gaining focus and
2944         * answer it during WM_KILLFOCUS.  If a WM_SETFOCUS occurs
2945         * during WM_KILLFOCUS, the focus control needs to be updated
2946         * to the current control.  At any other time, the focus
2947         * control matches Windows.
2948         */
2949         Display display = this.display;
2950         display.focusEvent = type;
2951         display.focusControl = this;
2952         sendEvent (type);
2953         // widget could be disposed at this point
2954         display.focusEvent = SWT.None;
2955         display.focusControl = null;
2956
2957         /*
2958         * It is possible that the shell may be
2959         * disposed at this point.  If this happens
2960         * don't send the activate and deactivate
2961         * events.
2962         */
2963         if (!shell.isDisposed ()) {
2964                 switch (type) {
2965                         case SWT.FocusIn:
2966                                 shell.setActiveControl (this);
2967                                 break;
2968                         case SWT.FocusOut:
2969                                 if (shell != display.getActiveShell ()) {
2970                                         shell.setActiveControl (null);
2971                                 }
2972                                 break;
2973                 }
2974         }
2975         return true;
2976 }
2977
2978 boolean sendGestureEvent (GESTUREINFO gi) {
2979         /**
2980          * Feature in Windows 7.  GID_BEGIN and GID_END events bubble up through the window
2981          * hierarchy for legacy support.  Ignore events not targeted for this control.
2982          */
2983         if (gi.hwndTarget != handle) return true;
2984         Event event = new Event ();
2985         int type = 0;
2986         Point globalPt = new Point(gi.x, gi.y);
2987         Point point = toControlInPixels(globalPt.x, globalPt.y);
2988         event.setLocationInPixels(point.x, point.y);
2989         switch (gi.dwID) {
2990                 case OS.GID_ZOOM:
2991                         type = SWT.Gesture;
2992                         event.detail = SWT.GESTURE_MAGNIFY;
2993                         int fingerDistance = OS.LODWORD (gi.ullArguments);
2994                         if ((gi.dwFlags & OS.GF_BEGIN) != 0) {
2995                                 event.detail = SWT.GESTURE_BEGIN;
2996                                 display.magStartDistance = display.lastDistance = fingerDistance;
2997                         } else if ((gi.dwFlags & OS.GF_END) != 0) {
2998                                 event.detail = SWT.GESTURE_END;
2999                         }
3000
3001                         /*
3002                         * The gi.ullArguments is the distance between the fingers.
3003                         * Scale factor is relative to that original value.
3004                         */
3005                         if (fingerDistance == display.lastDistance && event.detail == SWT.GESTURE_MAGNIFY) return true;
3006                         if (fingerDistance != 0) event.magnification = fingerDistance / display.magStartDistance;
3007                         display.lastDistance = fingerDistance;
3008                         break;
3009                 case OS.GID_PAN:
3010                         type = SWT.Gesture;
3011                         event.detail = SWT.GESTURE_PAN;
3012                         if ((gi.dwFlags & OS.GF_BEGIN) != 0) {
3013                                 event.detail = SWT.GESTURE_BEGIN;
3014                                 display.lastX = point.x;
3015                                 display.lastY = point.y;
3016                         } else if ((gi.dwFlags & OS.GF_END) != 0) {
3017                                 event.detail = SWT.GESTURE_END;
3018                         }
3019                         if (display.lastX == point.x && display.lastY == point.y && event.detail == SWT.GESTURE_PAN) return true;
3020                         event.xDirection = point.x - display.lastX;
3021                         event.yDirection = point.y - display.lastY;
3022                         display.lastX = point.x;
3023                         display.lastY = point.y;
3024                         break;
3025                 case OS.GID_ROTATE:
3026                         type = SWT.Gesture;
3027                         event.detail = SWT.GESTURE_ROTATE;
3028                         double rotationInRadians = OS.GID_ROTATE_ANGLE_FROM_ARGUMENT (OS.LODWORD (gi.ullArguments));
3029                         if ((gi.dwFlags & OS.GF_BEGIN) != 0) {
3030                                 event.detail = SWT.GESTURE_BEGIN;
3031                                 display.rotationAngle = rotationInRadians;
3032                         } else if ((gi.dwFlags & OS.GF_END) != 0) {
3033                                 event.detail = SWT.GESTURE_END;
3034                         }
3035
3036                         /*
3037                         * Feature in Win32. Rotation events are sent even when the fingers are at rest.
3038                         * If the current rotation is the same as the last one received don't send the event.
3039                         */
3040                         if (display.rotationAngle == rotationInRadians && event.detail == SWT.GESTURE_ROTATE) return true;
3041                         event.rotation = rotationInRadians * 180.0 / Math.PI;
3042                         display.rotationAngle = rotationInRadians;
3043                         break;
3044                 default:
3045                         // Unknown gesture -- ignore.
3046                         break;
3047         }
3048
3049         if (type == 0) return true;
3050         setInputState (event, type);
3051         sendEvent (type, event);
3052         return event.doit;
3053 }
3054
3055 void sendMove () {
3056         sendEvent (SWT.Move);
3057 }
3058
3059 void sendResize () {
3060         sendEvent (SWT.Resize);
3061 }
3062
3063 void sendTouchEvent (TOUCHINPUT touchInput []) {
3064         Event event = new Event ();
3065         POINT pt = new POINT ();
3066         OS.GetCursorPos (pt);
3067         OS.ScreenToClient (handle, pt);
3068         event.setLocationInPixels(pt.x, pt.y);
3069         Touch [] touches = new Touch [touchInput.length];
3070         Monitor monitor = getMonitor ();
3071         for (int i = 0; i < touchInput.length; i++) {
3072                 TOUCHINPUT ti = touchInput [i];
3073                 TouchSource inputSource = display.findTouchSource (ti.hSource, monitor);
3074                 int state = 0;
3075                 if ((ti.dwFlags & OS.TOUCHEVENTF_DOWN) != 0) state = SWT.TOUCHSTATE_DOWN;
3076                 if ((ti.dwFlags & OS.TOUCHEVENTF_UP) != 0) state = SWT.TOUCHSTATE_UP;
3077                 if ((ti.dwFlags & OS.TOUCHEVENTF_MOVE) != 0) state = SWT.TOUCHSTATE_MOVE;
3078                 boolean primary = (ti.dwFlags & OS.TOUCHEVENTF_PRIMARY) != 0;
3079                 int x = (int)OS.TOUCH_COORD_TO_PIXEL (ti.x);
3080                 int y = (int)OS.TOUCH_COORD_TO_PIXEL (ti.y);
3081                 touches [i] = new Touch (ti.dwID, inputSource, state, primary, x, y);
3082         }
3083         event.touches = touches;
3084         setInputState (event, SWT.Touch);
3085         postEvent (SWT.Touch, event);
3086 }
3087
3088 void setBackground () {
3089         Control control = findBackgroundControl ();
3090         if (control == null) control = this;
3091         if (control.backgroundImage != null) {
3092                 Shell shell = getShell ();
3093                 shell.releaseBrushes ();
3094                 setBackgroundImage (control.backgroundImage.handle);
3095         } else {
3096                 setBackgroundPixel (control.background == -1 ? control.defaultBackground() : control.background);
3097         }
3098 }
3099
3100 /**
3101  * Sets the receiver's background color to the color specified
3102  * by the argument, or to the default system color for the control
3103  * if the argument is null.
3104  * <p>
3105  * Note: This operation is a hint and may be overridden by the platform.
3106  * </p>
3107  * @param color the new color (or null)
3108  *
3109  * @exception IllegalArgumentException <ul>
3110  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3111  * </ul>
3112  * @exception SWTException <ul>
3113  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3114  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3115  * </ul>
3116  */
3117 public void setBackground (Color color) {
3118         checkWidget ();
3119         _setBackground (color);
3120         if (color != null) {
3121                 this.updateBackgroundMode ();
3122         }
3123 }
3124
3125 private void _setBackground (Color color) {
3126         int pixel = -1;
3127         int alpha = 255;
3128         if (color != null) {
3129                 if (color.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
3130                 pixel = color.handle;
3131                 alpha = color.getAlpha();
3132         }
3133         if (pixel == background && alpha == backgroundAlpha) return;
3134         background = pixel;
3135         backgroundAlpha = alpha;
3136         updateBackgroundColor ();
3137 }
3138
3139
3140 /**
3141  * Sets the receiver's background image to the image specified
3142  * by the argument, or to the default system color for the control
3143  * if the argument is null.  The background image is tiled to fill
3144  * the available space.
3145  * <p>
3146  * Note: This operation is a hint and may be overridden by the platform.
3147  * For example, on Windows the background of a Button cannot be changed.
3148  * </p>
3149  * @param image the new image (or null)
3150  *
3151  * @exception IllegalArgumentException <ul>
3152  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3153  *    <li>ERROR_INVALID_ARGUMENT - if the argument is not a bitmap</li>
3154  * </ul>
3155  * @exception SWTException <ul>
3156  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3157  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3158  * </ul>
3159  *
3160  * @since 3.2
3161  */
3162 public void setBackgroundImage (Image image) {
3163         checkWidget ();
3164         if (image != null) {
3165                 if (image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
3166                 if (image.type != SWT.BITMAP) error (SWT.ERROR_INVALID_ARGUMENT);
3167         }
3168         if (backgroundImage == image && backgroundAlpha > 0) return;
3169         backgroundAlpha = 255;
3170         backgroundImage = image;
3171         Shell shell = getShell ();
3172         shell.releaseBrushes ();
3173         updateBackgroundImage ();
3174 }
3175
3176 void setBackgroundImage (long hBitmap) {
3177         int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE;
3178         OS.RedrawWindow (handle, null, 0, flags);
3179 }
3180
3181 void setBackgroundPixel (int pixel) {
3182         int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE;
3183         OS.RedrawWindow (handle, null, 0, flags);
3184 }
3185
3186 /**
3187  * Sets the receiver's size and location in points to the rectangular
3188  * area specified by the arguments. The <code>x</code> and
3189  * <code>y</code> arguments are relative to the receiver's
3190  * parent (or its display if its parent is null), unless
3191  * the receiver is a shell. In this case, the <code>x</code>
3192  * and <code>y</code> arguments are relative to the display.
3193  * <p>
3194  * Note: Attempting to set the width or height of the
3195  * receiver to a negative number will cause that
3196  * value to be set to zero instead.
3197  * </p>
3198  * <p>
3199  * Note: On GTK, attempting to set the width or height of the
3200  * receiver to a number higher or equal 2^14 will cause them to be
3201  * set to (2^14)-1 instead.
3202  * </p>
3203  *
3204  * @param x the new x coordinate for the receiver
3205  * @param y the new y coordinate for the receiver
3206  * @param width the new width for the receiver
3207  * @param height the new height for the receiver
3208  *
3209  * @exception SWTException <ul>
3210  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3211  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3212  * </ul>
3213  */
3214 public void setBounds(int x, int y, int width, int height) {
3215         checkWidget ();
3216         x = DPIUtil.autoScaleUp(x);
3217         y = DPIUtil.autoScaleUp(y);
3218         width = DPIUtil.autoScaleUp(width);
3219         height = DPIUtil.autoScaleUp(height);
3220         setBoundsInPixels(x, y, width, height);
3221 }
3222
3223 void setBoundsInPixels (int x, int y, int width, int height) {
3224         int flags = OS.SWP_NOZORDER | OS.SWP_DRAWFRAME | OS.SWP_NOACTIVATE;
3225         setBoundsInPixels (x, y, Math.max (0, width), Math.max (0, height), flags);
3226 }
3227
3228 void setBoundsInPixels (int x, int y, int width, int height, int flags) {
3229         setBoundsInPixels (x, y, width, height, flags, true);
3230 }
3231
3232 void setBoundsInPixels (int x, int y, int width, int height, int flags, boolean defer) {
3233         if (findImageControl () != null) {
3234                 if (backgroundImage == null) flags |= OS.SWP_NOCOPYBITS;
3235         } else {
3236                 if (OS.GetWindow (handle, OS.GW_CHILD) == 0) {
3237                         if (OS.IsAppThemed ()) {
3238                                 if (findThemeControl () != null) flags |= OS.SWP_NOCOPYBITS;
3239                         }
3240                 }
3241         }
3242         long topHandle = topHandle ();
3243         if (defer && parent != null) {
3244                 forceResize ();
3245                 if (parent.lpwp != null) {
3246                         int index = 0;
3247                         WINDOWPOS [] lpwp = parent.lpwp;
3248                         while (index < lpwp.length) {
3249                                 if (lpwp [index] == null) break;
3250                                 index ++;
3251                         }
3252                         if (index == lpwp.length) {
3253                                 WINDOWPOS [] newLpwp = new WINDOWPOS [lpwp.length + 4];
3254                                 System.arraycopy (lpwp, 0, newLpwp, 0, lpwp.length);
3255                                 parent.lpwp = lpwp = newLpwp;
3256                         }
3257                         WINDOWPOS wp = new WINDOWPOS ();
3258                         wp.hwnd = topHandle;
3259                         wp.x = x;
3260                         wp.y = y;
3261                         wp.cx = width;
3262                         wp.cy = height;
3263                         wp.flags = flags;
3264                         lpwp [index] = wp;
3265                         return;
3266                 }
3267         }
3268         OS.SetWindowPos (topHandle, 0, x, y, width, height, flags);
3269 }
3270
3271 /**
3272  * Sets the receiver's size and location in points to the rectangular
3273  * area specified by the argument. The <code>x</code> and
3274  * <code>y</code> fields of the rectangle are relative to
3275  * the receiver's parent (or its display if its parent is null).
3276  * <p>
3277  * Note: Attempting to set the width or height of the
3278  * receiver to a negative number will cause that
3279  * value to be set to zero instead.
3280  * </p>
3281  * <p>
3282  * Note: On GTK, attempting to set the width or height of the
3283  * receiver to a number higher or equal 2^14 will cause them to be
3284  * set to (2^14)-1 instead.
3285  * </p>
3286  *
3287  * @param rect the new bounds for the receiver
3288  *
3289  * @exception SWTException <ul>
3290  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3291  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3292  * </ul>
3293  */
3294 public void setBounds (Rectangle rect) {
3295         checkWidget ();
3296         if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
3297         setBoundsInPixels(DPIUtil.autoScaleUp(rect));
3298 }
3299
3300 void setBoundsInPixels (Rectangle rect) {
3301         setBoundsInPixels (rect.x, rect.y, rect.width, rect.height);
3302 }
3303
3304 /**
3305  * If the argument is <code>true</code>, causes the receiver to have
3306  * all mouse events delivered to it until the method is called with
3307  * <code>false</code> as the argument.  Note that on some platforms,
3308  * a mouse button must currently be down for capture to be assigned.
3309  *
3310  * @param capture <code>true</code> to capture the mouse, and <code>false</code> to release it
3311  *
3312  * @exception SWTException <ul>
3313  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3314  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3315  * </ul>
3316  */
3317 public void setCapture (boolean capture) {
3318         checkWidget ();
3319         if (capture) {
3320                 OS.SetCapture (handle);
3321         } else {
3322                 if (OS.GetCapture () == handle) {
3323                         OS.ReleaseCapture ();
3324                 }
3325         }
3326 }
3327
3328 void setCursor () {
3329         long lParam = OS.MAKELPARAM (OS.HTCLIENT, OS.WM_MOUSEMOVE);
3330         OS.SendMessage (handle, OS.WM_SETCURSOR, handle, lParam);
3331 }
3332
3333 /**
3334  * Sets the receiver's cursor to the cursor specified by the
3335  * argument, or to the default cursor for that kind of control
3336  * if the argument is null.
3337  * <p>
3338  * When the mouse pointer passes over a control its appearance
3339  * is changed to match the control's cursor.
3340  * </p>
3341  *
3342  * @param cursor the new cursor (or null)
3343  *
3344  * @exception IllegalArgumentException <ul>
3345  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3346  * </ul>
3347  * @exception SWTException <ul>
3348  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3349  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3350  * </ul>
3351  */
3352 public void setCursor (Cursor cursor) {
3353         checkWidget ();
3354         if (cursor != null && cursor.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
3355         this.cursor = cursor;
3356         long hwndCursor = OS.GetCapture ();
3357         if (hwndCursor == 0) {
3358                 POINT pt = new POINT ();
3359                 if (!OS.GetCursorPos (pt)) return;
3360                 long hwnd = hwndCursor = OS.WindowFromPoint (pt);
3361                 while (hwnd != 0 && hwnd != handle) {
3362                         hwnd = OS.GetParent (hwnd);
3363                 }
3364                 if (hwnd == 0) return;
3365         }
3366         Control control = display.getControl (hwndCursor);
3367         if (control == null) control = this;
3368         control.setCursor ();
3369 }
3370
3371 void setDefaultFont () {
3372         long hFont = display.getSystemFont ().handle;
3373         OS.SendMessage (handle, OS.WM_SETFONT, hFont, 0);
3374 }
3375
3376 /**
3377  * Sets the receiver's drag detect state. If the argument is
3378  * <code>true</code>, the receiver will detect drag gestures,
3379  * otherwise these gestures will be ignored.
3380  *
3381  * @param dragDetect the new drag detect state
3382  *
3383  * @exception SWTException <ul>
3384  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3385  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3386  * </ul>
3387  *
3388  * @since 3.3
3389  */
3390 public void setDragDetect (boolean dragDetect) {
3391         checkWidget ();
3392         if (dragDetect) {
3393                 state |= DRAG_DETECT;
3394         } else {
3395                 state &= ~DRAG_DETECT;
3396         }
3397         enableDrag (dragDetect);
3398 }
3399
3400 /**
3401  * Enables the receiver if the argument is <code>true</code>,
3402  * and disables it otherwise. A disabled control is typically
3403  * not selectable from the user interface and draws with an
3404  * inactive or "grayed" look.
3405  *
3406  * @param enabled the new enabled state
3407  *
3408  * @exception SWTException <ul>
3409  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3410  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3411  * </ul>
3412  */
3413 public void setEnabled (boolean enabled) {
3414         checkWidget ();
3415         /*
3416         * Feature in Windows.  If the receiver has focus, disabling
3417         * the receiver causes no window to have focus.  The fix is
3418         * to assign focus to the first ancestor window that takes
3419         * focus.  If no window will take focus, set focus to the
3420         * desktop.
3421         */
3422         Control control = null;
3423         boolean fixFocus = false;
3424         if (!enabled) {
3425                 if (display.focusEvent != SWT.FocusOut) {
3426                         control = display.getFocusControl ();
3427                         fixFocus = isFocusAncestor (control);
3428                 }
3429         }
3430         enableWidget (enabled);
3431         if (fixFocus) fixFocus (control);
3432 }
3433
3434 /**
3435  * Causes the receiver to have the <em>keyboard focus</em>,
3436  * such that all keyboard events will be delivered to it.  Focus
3437  * reassignment will respect applicable platform constraints.
3438  *
3439  * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.
3440  *
3441  * @exception SWTException <ul>
3442  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3443  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3444  * </ul>
3445  *
3446  * @see #forceFocus
3447  */
3448 public boolean setFocus () {
3449         checkWidget ();
3450         if ((style & SWT.NO_FOCUS) != 0) return false;
3451         return forceFocus ();
3452 }
3453
3454 /**
3455  * Sets the font that the receiver will use to paint textual information
3456  * to the font specified by the argument, or to the default font for that
3457  * kind of control if the argument is null.
3458  *
3459  * @param font the new font (or null)
3460  *
3461  * @exception IllegalArgumentException <ul>
3462  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3463  * </ul>
3464  * @exception SWTException <ul>
3465  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3466  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3467  * </ul>
3468  */
3469 public void setFont (Font font) {
3470         checkWidget ();
3471         long hFont = 0;
3472         if (font != null) {
3473                 if (font.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
3474                 hFont = font.handle;
3475         }
3476         this.font = font;
3477         if (hFont == 0) hFont = defaultFont ();
3478         OS.SendMessage (handle, OS.WM_SETFONT, hFont, 1);
3479 }
3480
3481 /**
3482  * Sets the receiver's foreground color to the color specified
3483  * by the argument, or to the default system color for the control
3484  * if the argument is null.
3485  * <p>
3486  * Note: This operation is a hint and may be overridden by the platform.
3487  * </p>
3488  * @param color the new color (or null)
3489  *
3490  * @exception IllegalArgumentException <ul>
3491  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
3492  * </ul>
3493  * @exception SWTException <ul>
3494  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3495  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3496  * </ul>
3497  */
3498 public void setForeground (Color color) {
3499         checkWidget ();
3500         int pixel = -1;
3501         if (color != null) {
3502                 if (color.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
3503                 pixel = color.handle;
3504         }
3505         if (pixel == foreground) return;
3506         foreground = pixel;
3507         setForegroundPixel (pixel);
3508 }
3509
3510 void setForegroundPixel (int pixel) {
3511         OS.InvalidateRect (handle, null, true);
3512 }
3513
3514 /**
3515  * Sets the layout data associated with the receiver to the argument.
3516  *
3517  * @param layoutData the new layout data for the receiver.
3518  *
3519  * @exception SWTException <ul>
3520  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3521  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3522  * </ul>
3523  */
3524 public void setLayoutData (Object layoutData) {
3525         checkWidget ();
3526         this.layoutData = layoutData;
3527 }
3528
3529 /**
3530  * Sets the receiver's location to the point specified by
3531  * the arguments which are relative to the receiver's
3532  * parent (or its display if its parent is null), unless
3533  * the receiver is a shell. In this case, the point is
3534  * relative to the display.
3535  *
3536  * @param x the new x coordinate for the receiver
3537  * @param y the new y coordinate for the receiver
3538  *
3539  * @exception SWTException <ul>
3540  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3541  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3542  * </ul>
3543  */
3544 public void setLocation (int x, int y) {
3545         checkWidget ();
3546         x = DPIUtil.autoScaleUp(x);
3547         y = DPIUtil.autoScaleUp(y);
3548         setLocationInPixels(x, y);
3549 }
3550
3551 void setLocationInPixels (int x, int y) {
3552         int flags = OS.SWP_NOSIZE | OS.SWP_NOZORDER | OS.SWP_NOACTIVATE | OS.SWP_DRAWFRAME;
3553         setBoundsInPixels (x, y, 0, 0, flags);
3554 }
3555
3556 /**
3557  * Sets the receiver's location to the point specified by
3558  * the arguments which are relative to the receiver's
3559  * parent (or its display if its parent is null), unless
3560  * the receiver is a shell. In this case, the point is
3561  * relative to the display.
3562  *
3563  * @param location the new location for the receiver
3564  *
3565  * @exception SWTException <ul>
3566  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3567  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3568  * </ul>
3569  */
3570 public void setLocation (Point location) {
3571         checkWidget ();
3572         if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
3573         location = DPIUtil.autoScaleUp(location);
3574         setLocationInPixels(location.x, location.y);
3575 }
3576
3577 /**
3578  * Sets the receiver's pop up menu to the argument.
3579  * All controls may optionally have a pop up
3580  * menu that is displayed when the user requests one for
3581  * the control. The sequence of key strokes, button presses
3582  * and/or button releases that are used to request a pop up
3583  * menu is platform specific.
3584  * <p>
3585  * Note: Disposing of a control that has a pop up menu will
3586  * dispose of the menu.  To avoid this behavior, set the
3587  * menu to null before the control is disposed.
3588  * </p>
3589  *
3590  * @param menu the new pop up menu
3591  *
3592  * @exception IllegalArgumentException <ul>
3593  *    <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li>
3594  *    <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
3595  *    <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>
3596  * </ul>
3597  * @exception SWTException <ul>
3598  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3599  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3600  * </ul>
3601  */
3602 public void setMenu (Menu menu) {
3603         checkWidget ();
3604         if (menu != null) {
3605                 if (menu.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
3606                 if ((menu.style & SWT.POP_UP) == 0) {
3607                         error (SWT.ERROR_MENU_NOT_POP_UP);
3608                 }
3609                 if (menu.parent != menuShell ()) {
3610                         error (SWT.ERROR_INVALID_PARENT);
3611                 }
3612         }
3613         this.menu = menu;
3614 }
3615
3616 /**
3617  * Sets the orientation of the receiver, which must be one
3618  * of the constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
3619  * <p>
3620  *
3621  * @param orientation new orientation style
3622  *
3623  * @exception SWTException <ul>
3624  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3625  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3626  * </ul>
3627  *
3628  * @since 3.7
3629  */
3630 public void setOrientation (int orientation) {
3631         checkWidget ();
3632         int flags = SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT;
3633         if ((orientation & flags) == 0 || (orientation & flags) == flags) return;
3634         style &= ~SWT.MIRRORED;
3635         style &= ~flags;
3636         style |= orientation & flags;
3637         style &= ~SWT.FLIP_TEXT_DIRECTION;
3638         updateOrientation ();
3639         checkMirrored ();
3640 }
3641
3642 boolean setRadioFocus (boolean tabbing) {
3643         return false;
3644 }
3645
3646 boolean setRadioSelection (boolean value) {
3647         return false;
3648 }
3649
3650 /**
3651  * If the argument is <code>false</code>, causes subsequent drawing
3652  * operations in the receiver to be ignored. No drawing of any kind
3653  * can occur in the receiver until the flag is set to true.
3654  * Graphics operations that occurred while the flag was
3655  * <code>false</code> are lost. When the flag is set to <code>true</code>,
3656  * the entire widget is marked as needing to be redrawn.  Nested calls
3657  * to this method are stacked.
3658  * <p>
3659  * Note: This operation is a hint and may not be supported on some
3660  * platforms or for some widgets.
3661  * </p>
3662  *
3663  * @param redraw the new redraw state
3664  *
3665  * @exception SWTException <ul>
3666  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3667  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3668  * </ul>
3669  *
3670  * @see #redraw(int, int, int, int, boolean)
3671  * @see #update()
3672  */
3673 public void setRedraw (boolean redraw) {
3674         checkWidget ();
3675         /*
3676          * Feature in Windows.  When WM_SETREDRAW is used to turn
3677          * off drawing in a widget, it clears the WS_VISIBLE bits
3678          * and then sets them when redraw is turned back on.  This
3679          * means that WM_SETREDRAW will make a widget unexpectedly
3680          * visible.  The fix is to track the visibility state while
3681          * drawing is turned off and restore it when drawing is
3682          * turned back on.
3683          */
3684         if (drawCount == 0) {
3685                 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
3686                 if ((bits & OS.WS_VISIBLE) == 0) state |= HIDDEN;
3687         }
3688         if (redraw) {
3689                 if (--drawCount == 0) {
3690                         long topHandle = topHandle ();
3691                         OS.SendMessage (topHandle, OS.WM_SETREDRAW, 1, 0);
3692                         if (handle != topHandle) OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0);
3693                         if ((state & HIDDEN) != 0) {
3694                                 state &= ~HIDDEN;
3695                                 OS.ShowWindow (topHandle, OS.SW_HIDE);
3696                                 if (handle != topHandle) OS.ShowWindow (handle, OS.SW_HIDE);
3697                         } else {
3698                                 int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
3699                                 OS.RedrawWindow (topHandle, null, 0, flags);
3700                         }
3701                 }
3702         } else {
3703                 if (drawCount++ == 0) {
3704                         long topHandle = topHandle ();
3705                         OS.SendMessage (topHandle, OS.WM_SETREDRAW, 0, 0);
3706                         if (handle != topHandle) OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0);
3707                 }
3708         }
3709 }
3710
3711 /**
3712  * Sets the shape of the control to the region specified
3713  * by the argument.  When the argument is null, the
3714  * default shape of the control is restored.
3715  *
3716  * @param region the region that defines the shape of the control (or null)
3717  *
3718  * @exception IllegalArgumentException <ul>
3719  *    <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li>
3720  * </ul>
3721  * @exception SWTException <ul>
3722  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3723  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3724  * </ul>
3725  *
3726  * @since 3.4
3727  */
3728 public void setRegion (Region region) {
3729         checkWidget ();
3730         if (region != null && region.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
3731         long hRegion = 0;
3732         if (region != null) {
3733                 hRegion = OS.CreateRectRgn (0, 0, 0, 0);
3734                 OS.CombineRgn (hRegion, region.handle, hRegion, OS.RGN_OR);
3735         }
3736         OS.SetWindowRgn (handle, hRegion, true);
3737         this.region = region;
3738 }
3739
3740 /**
3741  * Sets the receiver's size to the point specified by the arguments.
3742  * <p>
3743  * Note: Attempting to set the width or height of the
3744  * receiver to a negative number will cause that
3745  * value to be set to zero instead.
3746  * </p>
3747  * <p>
3748  * Note: On GTK, attempting to set the width or height of the
3749  * receiver to a number higher or equal 2^14 will cause them to be
3750  * set to (2^14)-1 instead.
3751  * </p>
3752  *
3753  * @param width the new width in points for the receiver
3754  * @param height the new height in points for the receiver
3755  *
3756  * @exception SWTException <ul>
3757  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3758  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3759  * </ul>
3760  */
3761 public void setSize (int width, int height) {
3762         checkWidget ();
3763         width = DPIUtil.autoScaleUp(width);
3764         height = DPIUtil.autoScaleUp(height);
3765         setSizeInPixels(width, height);
3766 }
3767
3768 void setSizeInPixels (int width, int height) {
3769         int flags = OS.SWP_NOMOVE | OS.SWP_NOZORDER | OS.SWP_DRAWFRAME | OS.SWP_NOACTIVATE;
3770         setBoundsInPixels (0, 0, Math.max (0, width), Math.max (0, height), flags);
3771 }
3772
3773 /**
3774  * Sets the receiver's size to the point specified by the argument.
3775  * <p>
3776  * Note: Attempting to set the width or height of the
3777  * receiver to a negative number will cause them to be
3778  * set to zero instead.
3779  * </p>
3780  * <p>
3781  * Note: On GTK, attempting to set the width or height of the
3782  * receiver to a number higher or equal 2^14 will cause them to be
3783  * set to (2^14)-1 instead.
3784  * </p>
3785  *
3786  * @param size the new size in points for the receiver
3787  *
3788  * @exception IllegalArgumentException <ul>
3789  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
3790  * </ul>
3791  * @exception SWTException <ul>
3792  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3793  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3794  * </ul>
3795  */
3796 public void setSize (Point size) {
3797         checkWidget ();
3798         if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
3799         size = DPIUtil.autoScaleUp(size);
3800         setSizeInPixels(size.x, size.y);
3801 }
3802
3803 @Override
3804 boolean setTabItemFocus () {
3805         if (!isShowing ()) return false;
3806         return forceFocus ();
3807 }
3808
3809 /**
3810  * Sets the base text direction (a.k.a. "paragraph direction") of the receiver,
3811  * which must be one of the constants <code>SWT.LEFT_TO_RIGHT</code>,
3812  * <code>SWT.RIGHT_TO_LEFT</code>, or <code>SWT.AUTO_TEXT_DIRECTION</code>.
3813  * <p>
3814  * <code>setOrientation</code> would override this value with the text direction
3815  * that is consistent with the new orientation.
3816  * </p>
3817  * <p>
3818  * <b>Warning</b>: This API is currently only implemented on Windows.
3819  * It doesn't set the base text direction on GTK and Cocoa.
3820  * </p>
3821  *
3822  * @param textDirection the base text direction style
3823  *
3824  * @exception SWTException <ul>
3825  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3826  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3827  * </ul>
3828  *
3829  * @see SWT#LEFT_TO_RIGHT
3830  * @see SWT#RIGHT_TO_LEFT
3831  * @see SWT#AUTO_TEXT_DIRECTION
3832  * @see SWT#FLIP_TEXT_DIRECTION
3833  *
3834  * @since 3.102
3835  */
3836 public void setTextDirection(int textDirection) {
3837         checkWidget ();
3838         textDirection &= (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT);
3839         updateTextDirection (textDirection);
3840         if (textDirection == AUTO_TEXT_DIRECTION) {
3841                 state |= HAS_AUTO_DIRECTION;
3842         } else {
3843                 state &= ~HAS_AUTO_DIRECTION;
3844         }
3845 }
3846
3847 /**
3848  * Sets the receiver's tool tip text to the argument, which
3849  * may be null indicating that the default tool tip for the
3850  * control will be shown. For a control that has a default
3851  * tool tip, such as the Tree control on Windows, setting
3852  * the tool tip text to an empty string replaces the default,
3853  * causing no tool tip text to be shown.
3854  * <p>
3855  * The mnemonic indicator (character '&amp;') is not displayed in a tool tip.
3856  * To display a single '&amp;' in the tool tip, the character '&amp;' can be
3857  * escaped by doubling it in the string.
3858  * </p>
3859  * <p>
3860  * NOTE: This operation is a hint and behavior is platform specific, on Windows
3861  * for CJK-style mnemonics of the form " (&amp;C)" at the end of the tooltip text
3862  * are not shown in tooltip.
3863  * </p>
3864  *
3865  * @param string the new tool tip text (or null)
3866  *
3867  * @exception SWTException <ul>
3868  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3869  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3870  * </ul>
3871  */
3872 public void setToolTipText (String string) {
3873         checkWidget ();
3874         toolTipText = string;
3875         setToolTipText (getShell (), string);
3876 }
3877
3878 void setToolTipText (Shell shell, String string) {
3879         shell.setToolTipText (handle, string);
3880 }
3881
3882 /**
3883  * Sets whether this control should send touch events (by default controls do not).
3884  * Setting this to <code>false</code> causes the receiver to send gesture events
3885  * instead.  No exception is thrown if a touch-based input device is not
3886  * detected (this can be determined with <code>Display#getTouchEnabled()</code>).
3887  *
3888  * @param enabled the new touch-enabled state
3889  *
3890  * @exception SWTException <ul>
3891  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3892  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3893  *    </ul>
3894  *
3895  * @see Display#getTouchEnabled
3896  *
3897  * @since 3.7
3898  */
3899 public void setTouchEnabled(boolean enabled) {
3900         checkWidget();
3901         if (enabled) {
3902                 OS.RegisterTouchWindow(handle, 0);
3903         } else {
3904                 OS.UnregisterTouchWindow(handle);
3905         }
3906 }
3907
3908 /**
3909  * Marks the receiver as visible if the argument is <code>true</code>,
3910  * and marks it invisible otherwise.
3911  * <p>
3912  * If one of the receiver's ancestors is not visible or some
3913  * other condition makes the receiver not visible, marking
3914  * it visible may not actually cause it to be displayed.
3915  * </p>
3916  *
3917  * @param visible the new visibility state
3918  *
3919  * @exception SWTException <ul>
3920  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
3921  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
3922  * </ul>
3923  */
3924 public void setVisible (boolean visible) {
3925         checkWidget ();
3926         if (!getDrawing()) {
3927                 if (((state & HIDDEN) == 0) == visible) return;
3928         } else {
3929                 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
3930                 if (((bits & OS.WS_VISIBLE) != 0) == visible) return;
3931         }
3932         if (visible) {
3933                 sendEvent (SWT.Show);
3934                 if (isDisposed ()) return;
3935         }
3936
3937         /*
3938         * Feature in Windows.  If the receiver has focus, hiding
3939         * the receiver causes no window to have focus.  The fix is
3940         * to assign focus to the first ancestor window that takes
3941         * focus.  If no window will take focus, set focus to the
3942         * desktop.
3943         */
3944         Control control = null;
3945         boolean fixFocus = false;
3946         if (!visible) {
3947                 if (display.focusEvent != SWT.FocusOut) {
3948                         control = display.getFocusControl ();
3949                         fixFocus = isFocusAncestor (control);
3950                 }
3951         }
3952         if (!getDrawing()) {
3953                 state = visible ? state & ~HIDDEN : state | HIDDEN;
3954         } else {
3955                 showWidget (visible);
3956                 if (isDisposed ()) return;
3957         }
3958         if (!visible) {
3959                 sendEvent (SWT.Hide);
3960                 if (isDisposed ()) return;
3961         }
3962         if (fixFocus) fixFocus (control);
3963 }
3964
3965 void sort (int [] items) {
3966         /* Shell Sort from K&R, pg 108 */
3967         int length = items.length;
3968         for (int gap=length/2; gap>0; gap/=2) {
3969                 for (int i=gap; i<length; i++) {
3970                         for (int j=i-gap; j>=0; j-=gap) {
3971                                 if (items [j] <= items [j + gap]) {
3972                                         int swap = items [j];
3973                                         items [j] = items [j + gap];
3974                                         items [j + gap] = swap;
3975                                 }
3976                         }
3977                 }
3978         }
3979 }
3980
3981 void subclass () {
3982         long oldProc = windowProc ();
3983         long newProc = display.windowProc;
3984         if (oldProc == newProc) return;
3985         OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, newProc);
3986 }
3987
3988 /**
3989  * Returns a point which is the result of converting the
3990  * argument, which is specified in display relative coordinates,
3991  * to coordinates relative to the receiver.
3992  * <p>
3993  * NOTE: To properly map a rectangle or a corner of a rectangle on a right-to-left platform, use
3994  * {@link Display#map(Control, Control, Rectangle)}.
3995  * </p>
3996  *
3997  * @param x the x coordinate in points to be translated
3998  * @param y the y coordinate in points to be translated
3999  * @return the translated coordinates
4000  *
4001  * @exception SWTException <ul>
4002  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4003  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4004  * </ul>
4005  *
4006  * @since 2.1
4007  */
4008 public Point toControl (int x, int y) {
4009         checkWidget ();
4010         return DPIUtil.autoScaleDown(toControlInPixels(DPIUtil.autoScaleUp(x), DPIUtil.autoScaleUp(y)));
4011 }
4012
4013 Point toControlInPixels (int x, int y) {
4014         POINT pt = new POINT ();
4015         pt.x = x;  pt.y = y;
4016         OS.ScreenToClient (handle, pt);
4017         return new Point (pt.x, pt.y);
4018 }
4019
4020 /**
4021  * Returns a point which is the result of converting the
4022  * argument, which is specified in display relative coordinates,
4023  * to coordinates relative to the receiver.
4024  * <p>
4025  * NOTE: To properly map a rectangle or a corner of a rectangle on a right-to-left platform, use
4026  * {@link Display#map(Control, Control, Rectangle)}.
4027  * </p>
4028  *
4029  * @param point the point to be translated (must not be null)
4030  * @return the translated coordinates
4031  *
4032  * @exception IllegalArgumentException <ul>
4033  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
4034  * </ul>
4035  * @exception SWTException <ul>
4036  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4037  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4038  * </ul>
4039  */
4040 public Point toControl (Point point) {
4041         checkWidget ();
4042         if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
4043         point = DPIUtil.autoScaleUp(point);
4044         return DPIUtil.autoScaleDown(toControlInPixels(point.x, point.y));
4045 }
4046
4047 /**
4048  * Returns a point which is the result of converting the
4049  * argument, which is specified in coordinates relative to
4050  * the receiver, to display relative coordinates.
4051  * <p>
4052  * NOTE: To properly map a rectangle or a corner of a rectangle on a right-to-left platform, use
4053  * {@link Display#map(Control, Control, Rectangle)}.
4054  * </p>
4055  *
4056  * @param x the x coordinate to be translated
4057  * @param y the y coordinate to be translated
4058  * @return the translated coordinates
4059  *
4060  * @exception SWTException <ul>
4061  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4062  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4063  * </ul>
4064  *
4065  * @since 2.1
4066  */
4067 public Point toDisplay (int x, int y) {
4068         checkWidget ();
4069         return DPIUtil.autoScaleDown(toDisplayInPixels(DPIUtil.autoScaleUp(x), DPIUtil.autoScaleUp(y)));
4070 }
4071
4072 Point toDisplayInPixels (int x, int y) {
4073         POINT pt = new POINT ();
4074         pt.x = x;  pt.y = y;
4075         OS.ClientToScreen (handle, pt);
4076         return new Point (pt.x, pt.y);
4077 }
4078
4079 /**
4080  * Returns a point which is the result of converting the
4081  * argument, which is specified in coordinates relative to
4082  * the receiver, to display relative coordinates.
4083  * <p>
4084  * NOTE: To properly map a rectangle or a corner of a rectangle on a right-to-left platform, use
4085  * {@link Display#map(Control, Control, Rectangle)}.
4086  * </p>
4087  *
4088  * @param point the point to be translated (must not be null)
4089  * @return the translated coordinates
4090  *
4091  * @exception IllegalArgumentException <ul>
4092  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
4093  * </ul>
4094  * @exception SWTException <ul>
4095  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4096  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4097  * </ul>
4098  */
4099 public Point toDisplay (Point point) {
4100         checkWidget ();
4101         if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
4102         point = DPIUtil.autoScaleUp(point);
4103         return DPIUtil.autoScaleDown(toDisplayInPixels(point.x, point.y));
4104 }
4105
4106 long topHandle () {
4107         return handle;
4108 }
4109
4110 boolean translateAccelerator (MSG msg) {
4111         return menuShell ().translateAccelerator (msg);
4112 }
4113
4114 boolean translateMnemonic (Event event, Control control) {
4115         if (control == this) return false;
4116         if (!isVisible () || !isEnabled ()) return false;
4117         event.doit = mnemonicMatch (event.character);
4118         return traverse (event);
4119 }
4120
4121 boolean translateMnemonic (MSG msg) {
4122         if (msg.wParam < 0x20) return false;
4123         long hwnd = msg.hwnd;
4124         if (OS.GetKeyState (OS.VK_MENU) >= 0) {
4125                 long code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0);
4126                 if ((code & OS.DLGC_WANTALLKEYS) != 0) return false;
4127                 if ((code & OS.DLGC_BUTTON) == 0) return false;
4128         }
4129         Decorations shell = menuShell ();
4130         if (shell.isVisible () && shell.isEnabled ()) {
4131                 display.lastAscii = (int)msg.wParam;
4132                 display.lastNull = display.lastDead = false;
4133                 Event event = new Event ();
4134                 event.detail = SWT.TRAVERSE_MNEMONIC;
4135                 if (setKeyState (event, SWT.Traverse, msg.wParam, msg.lParam)) {
4136                         return translateMnemonic (event, null) || shell.translateMnemonic (event, this);
4137                 }
4138         }
4139         return false;
4140 }
4141
4142 boolean translateTraversal (MSG msg) {
4143         long hwnd = msg.hwnd;
4144         int key = (int)msg.wParam;
4145         if (key == OS.VK_MENU) {
4146                 if ((msg.lParam & 0x40000000) == 0) {
4147                         OS.SendMessage (hwnd, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
4148                 }
4149                 return false;
4150         }
4151         int detail = SWT.TRAVERSE_NONE;
4152         boolean doit = true, all = false;
4153         boolean lastVirtual = false;
4154         int lastKey = key, lastAscii = 0;
4155         switch (key) {
4156                 case OS.VK_ESCAPE: {
4157                         all = true;
4158                         lastAscii = 27;
4159                         long code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0);
4160                         if ((code & OS.DLGC_WANTALLKEYS) != 0) {
4161                                 /*
4162                                 * Use DLGC_HASSETSEL to determine that the control
4163                                 * is a text widget.  A text widget normally wants
4164                                 * all keys except VK_ESCAPE.  If this bit is not
4165                                 * set, then assume the control wants all keys,
4166                                 * including VK_ESCAPE.
4167                                 */
4168                                 if ((code & OS.DLGC_HASSETSEL) == 0) doit = false;
4169                         }
4170                         detail = SWT.TRAVERSE_ESCAPE;
4171                         break;
4172                 }
4173                 case OS.VK_RETURN: {
4174                         all = true;
4175                         lastAscii = '\r';
4176                         long code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0);
4177                         if ((code & OS.DLGC_WANTALLKEYS) != 0) doit = false;
4178                         detail = SWT.TRAVERSE_RETURN;
4179                         break;
4180                 }
4181                 case OS.VK_TAB: {
4182                         lastAscii = '\t';
4183                         boolean next = OS.GetKeyState (OS.VK_SHIFT) >= 0;
4184                         long code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0);
4185                         if ((code & (OS.DLGC_WANTTAB | OS.DLGC_WANTALLKEYS)) != 0) {
4186                                 /*
4187                                 * Use DLGC_HASSETSEL to determine that the control is a
4188                                 * text widget.  If the control is a text widget, then
4189                                 * Ctrl+Tab and Shift+Tab should traverse out of the widget.
4190                                 * If the control is not a text widget, the correct behavior
4191                                 * is to give every character, including Tab, Ctrl+Tab and
4192                                 * Shift+Tab to the control.
4193                                 */
4194                                 if ((code & OS.DLGC_HASSETSEL) != 0) {
4195                                         if (next && OS.GetKeyState (OS.VK_CONTROL) >= 0) {
4196                                                 doit = false;
4197                                         }
4198                                 } else {
4199                                         doit = false;
4200                                 }
4201                         }
4202                         detail = next ? SWT.TRAVERSE_TAB_NEXT : SWT.TRAVERSE_TAB_PREVIOUS;
4203                         break;
4204                 }
4205                 case OS.VK_UP:
4206                 case OS.VK_LEFT:
4207                 case OS.VK_DOWN:
4208                 case OS.VK_RIGHT: {
4209                         lastVirtual = true;
4210                         long code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0);
4211                         if ((code & (OS.DLGC_WANTARROWS /*| OS.DLGC_WANTALLKEYS*/)) != 0) doit = false;
4212                         boolean next = key == OS.VK_DOWN || key == OS.VK_RIGHT;
4213                         if (parent != null && (parent.style & SWT.MIRRORED) != 0) {
4214                                 if (key == OS.VK_LEFT || key == OS.VK_RIGHT) next = !next;
4215                         }
4216                         detail = next ? SWT.TRAVERSE_ARROW_NEXT : SWT.TRAVERSE_ARROW_PREVIOUS;
4217                         break;
4218                 }
4219                 case OS.VK_PRIOR:
4220                 case OS.VK_NEXT: {
4221                         all = true;
4222                         lastVirtual = true;
4223                         if (OS.GetKeyState (OS.VK_CONTROL) >= 0) return false;
4224                         long code = OS.SendMessage (hwnd, OS.WM_GETDLGCODE, 0, 0);
4225                         if ((code & OS.DLGC_WANTALLKEYS) != 0) {
4226                                 /*
4227                                 * Use DLGC_HASSETSEL to determine that the control is a
4228                                 * text widget.  If the control is a text widget, then
4229                                 * Ctrl+PgUp and Ctrl+PgDn should traverse out of the widget.
4230                                 */
4231                                 if ((code & OS.DLGC_HASSETSEL) == 0) doit = false;
4232                         }
4233                         detail = key == OS.VK_PRIOR ? SWT.TRAVERSE_PAGE_PREVIOUS : SWT.TRAVERSE_PAGE_NEXT;
4234                         break;
4235                 }
4236                 default:
4237                         return false;
4238         }
4239         Event event = new Event ();
4240         event.doit = doit;
4241         event.detail = detail;
4242         display.lastKey = lastKey;
4243         display.lastAscii = lastAscii;
4244         display.lastVirtual = lastVirtual;
4245         display.lastNull = display.lastDead = false;
4246         if (!setKeyState (event, SWT.Traverse, msg.wParam, msg.lParam)) return false;
4247         Shell shell = getShell ();
4248         Control control = this;
4249         do {
4250                 if (control.traverse (event)) {
4251                         OS.SendMessage (hwnd, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
4252                         return true;
4253                 }
4254                 if (!event.doit && control.hooks (SWT.Traverse)) return false;
4255                 if (control == shell) return false;
4256                 control = control.parent;
4257         } while (all && control != null);
4258         return false;
4259 }
4260
4261 boolean traverse (Event event) {
4262         /*
4263         * It is possible (but unlikely), that application
4264         * code could have disposed the widget in the traverse
4265         * event.  If this happens, return true to stop further
4266         * event processing.
4267         */
4268         sendEvent (SWT.Traverse, event);
4269         if (isDisposed ()) return true;
4270         if (!event.doit) return false;
4271         switch (event.detail) {
4272                 case SWT.TRAVERSE_NONE:                 return true;
4273                 case SWT.TRAVERSE_ESCAPE:                       return traverseEscape ();
4274                 case SWT.TRAVERSE_RETURN:                       return traverseReturn ();
4275                 case SWT.TRAVERSE_TAB_NEXT:             return traverseGroup (true);
4276                 case SWT.TRAVERSE_TAB_PREVIOUS: return traverseGroup (false);
4277                 case SWT.TRAVERSE_ARROW_NEXT:           return traverseItem (true);
4278                 case SWT.TRAVERSE_ARROW_PREVIOUS:       return traverseItem (false);
4279                 case SWT.TRAVERSE_MNEMONIC:             return traverseMnemonic (event.character);
4280                 case SWT.TRAVERSE_PAGE_NEXT:            return traversePage (true);
4281                 case SWT.TRAVERSE_PAGE_PREVIOUS:        return traversePage (false);
4282         }
4283         return false;
4284 }
4285
4286 /**
4287  * Based on the argument, perform one of the expected platform
4288  * traversal action. The argument should be one of the constants:
4289  * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>,
4290  * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>,
4291  * <code>SWT.TRAVERSE_ARROW_NEXT</code>, <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>,
4292  * <code>SWT.TRAVERSE_PAGE_NEXT</code> and <code>SWT.TRAVERSE_PAGE_PREVIOUS</code>.
4293  *
4294  * @param traversal the type of traversal
4295  * @return true if the traversal succeeded
4296  *
4297  * @exception SWTException <ul>
4298  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4299  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4300  * </ul>
4301  */
4302 public boolean traverse (int traversal) {
4303         checkWidget ();
4304         Event event = new Event ();
4305         event.doit = true;
4306         event.detail = traversal;
4307         return traverse (event);
4308 }
4309
4310 /**
4311  * Performs a platform traversal action corresponding to a <code>KeyDown</code> event.
4312  *
4313  * <p>Valid traversal values are
4314  * <code>SWT.TRAVERSE_NONE</code>, <code>SWT.TRAVERSE_MNEMONIC</code>,
4315  * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>,
4316  * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>,
4317  * <code>SWT.TRAVERSE_ARROW_NEXT</code>, <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>,
4318  * <code>SWT.TRAVERSE_PAGE_NEXT</code> and <code>SWT.TRAVERSE_PAGE_PREVIOUS</code>.
4319  * If <code>traversal</code> is <code>SWT.TRAVERSE_NONE</code> then the Traverse
4320  * event is created with standard values based on the KeyDown event.  If
4321  * <code>traversal</code> is one of the other traversal constants then the Traverse
4322  * event is created with this detail, and its <code>doit</code> is taken from the
4323  * KeyDown event.
4324  * </p>
4325  *
4326  * @param traversal the type of traversal, or <code>SWT.TRAVERSE_NONE</code> to compute
4327  * this from <code>event</code>
4328  * @param event the KeyDown event
4329  *
4330  * @return <code>true</code> if the traversal succeeded
4331  *
4332  * @exception IllegalArgumentException <ul>
4333  *   <li>ERROR_NULL_ARGUMENT if the event is null</li>
4334  * </ul>
4335  * @exception SWTException <ul>
4336  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4337  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4338  * </ul>
4339  *
4340  * @since 3.6
4341  */
4342 public boolean traverse (int traversal, Event event) {
4343         checkWidget ();
4344         if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
4345         return traverse (traversal, event.character, event.keyCode, event.keyLocation, event.stateMask, event.doit);
4346 }
4347
4348 /**
4349  * Performs a platform traversal action corresponding to a <code>KeyDown</code> event.
4350  *
4351  * <p>Valid traversal values are
4352  * <code>SWT.TRAVERSE_NONE</code>, <code>SWT.TRAVERSE_MNEMONIC</code>,
4353  * <code>SWT.TRAVERSE_ESCAPE</code>, <code>SWT.TRAVERSE_RETURN</code>,
4354  * <code>SWT.TRAVERSE_TAB_NEXT</code>, <code>SWT.TRAVERSE_TAB_PREVIOUS</code>,
4355  * <code>SWT.TRAVERSE_ARROW_NEXT</code>, <code>SWT.TRAVERSE_ARROW_PREVIOUS</code>,
4356  * <code>SWT.TRAVERSE_PAGE_NEXT</code> and <code>SWT.TRAVERSE_PAGE_PREVIOUS</code>.
4357  * If <code>traversal</code> is <code>SWT.TRAVERSE_NONE</code> then the Traverse
4358  * event is created with standard values based on the KeyDown event.  If
4359  * <code>traversal</code> is one of the other traversal constants then the Traverse
4360  * event is created with this detail, and its <code>doit</code> is taken from the
4361  * KeyDown event.
4362  * </p>
4363  *
4364  * @param traversal the type of traversal, or <code>SWT.TRAVERSE_NONE</code> to compute
4365  * this from <code>event</code>
4366  * @param event the KeyDown event
4367  *
4368  * @return <code>true</code> if the traversal succeeded
4369  *
4370  * @exception IllegalArgumentException <ul>
4371  *   <li>ERROR_NULL_ARGUMENT if the event is null</li>
4372  * </ul>
4373  * @exception SWTException <ul>
4374  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4375  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4376  * </ul>
4377  *
4378  * @since 3.6
4379  */
4380 public boolean traverse (int traversal, KeyEvent event) {
4381         checkWidget ();
4382         if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
4383         return traverse (traversal, event.character, event.keyCode, event.keyLocation, event.stateMask, event.doit);
4384 }
4385
4386 boolean traverse (int traversal, char character, int keyCode, int keyLocation, int stateMask, boolean doit) {
4387         if (traversal == SWT.TRAVERSE_NONE) {
4388                 switch (keyCode) {
4389                         case SWT.ESC: {
4390                                 traversal = SWT.TRAVERSE_ESCAPE;
4391                                 doit = true;
4392                                 break;
4393                         }
4394                         case SWT.CR: {
4395                                 traversal = SWT.TRAVERSE_RETURN;
4396                                 doit = true;
4397                                 break;
4398                         }
4399                         case SWT.ARROW_DOWN:
4400                         case SWT.ARROW_RIGHT: {
4401                                 traversal = SWT.TRAVERSE_ARROW_NEXT;
4402                                 doit = false;
4403                                 break;
4404                         }
4405                         case SWT.ARROW_UP:
4406                         case SWT.ARROW_LEFT: {
4407                                 traversal = SWT.TRAVERSE_ARROW_PREVIOUS;
4408                                 doit = false;
4409                                 break;
4410                         }
4411                         case SWT.TAB: {
4412                                 traversal = (stateMask & SWT.SHIFT) != 0 ? SWT.TRAVERSE_TAB_PREVIOUS : SWT.TRAVERSE_TAB_NEXT;
4413                                 doit = true;
4414                                 break;
4415                         }
4416                         case SWT.PAGE_DOWN: {
4417                                 if ((stateMask & SWT.CTRL) != 0) {
4418                                         traversal = SWT.TRAVERSE_PAGE_NEXT;
4419                                         doit = true;
4420                                 }
4421                                 break;
4422                         }
4423                         case SWT.PAGE_UP: {
4424                                 if ((stateMask & SWT.CTRL) != 0) {
4425                                         traversal = SWT.TRAVERSE_PAGE_PREVIOUS;
4426                                         doit = true;
4427                                 }
4428                                 break;
4429                         }
4430                         default: {
4431                                 if (character != 0 && (stateMask & (SWT.ALT | SWT.CTRL)) == SWT.ALT) {
4432                                         traversal = SWT.TRAVERSE_MNEMONIC;
4433                                         doit = true;
4434                                 }
4435                                 break;
4436                         }
4437                 }
4438         }
4439
4440         Event event = new Event ();
4441         event.character = character;
4442         event.detail = traversal;
4443         event.doit = doit;
4444         event.keyCode = keyCode;
4445         event.keyLocation = keyLocation;
4446         event.stateMask = stateMask;
4447
4448         Shell shell = getShell ();
4449         boolean all = false;
4450         switch (traversal) {
4451                 case SWT.TRAVERSE_ESCAPE:
4452                 case SWT.TRAVERSE_RETURN:
4453                 case SWT.TRAVERSE_PAGE_NEXT:
4454                 case SWT.TRAVERSE_PAGE_PREVIOUS: {
4455                         all = true;
4456                         // FALL THROUGH
4457                 }
4458                 case SWT.TRAVERSE_ARROW_NEXT:
4459                 case SWT.TRAVERSE_ARROW_PREVIOUS:
4460                 case SWT.TRAVERSE_TAB_NEXT:
4461                 case SWT.TRAVERSE_TAB_PREVIOUS: {
4462                         /* traversal is a valid traversal action */
4463                         break;
4464                 }
4465                 case SWT.TRAVERSE_MNEMONIC: {
4466                         return translateMnemonic (event, null) || shell.translateMnemonic (event, this);
4467                 }
4468                 default: {
4469                         /* traversal is not a valid traversal action */
4470                         return false;
4471                 }
4472         }
4473
4474         Control control = this;
4475         do {
4476                 if (control.traverse (event)) {
4477                         OS.SendMessage (handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
4478                         return true;
4479                 }
4480                 if (!event.doit && control.hooks (SWT.Traverse)) return false;
4481                 if (control == shell) return false;
4482                 control = control.parent;
4483         } while (all && control != null);
4484         return false;
4485 }
4486
4487 boolean traverseEscape () {
4488         return false;
4489 }
4490
4491 boolean traverseGroup (boolean next) {
4492         Control root = computeTabRoot ();
4493         Widget group = computeTabGroup ();
4494         Widget [] list = root.computeTabList ();
4495         int length = list.length;
4496         int index = 0;
4497         while (index < length) {
4498                 if (list [index] == group) break;
4499                 index++;
4500         }
4501         /*
4502         * It is possible (but unlikely), that application
4503         * code could have disposed the widget in focus in
4504         * or out events.  Ensure that a disposed widget is
4505         * not accessed.
4506         */
4507         if (index == length) return false;
4508         int start = index, offset = (next) ? 1 : -1;
4509         while ((index = ((index + offset + length) % length)) != start) {
4510                 Widget widget = list [index];
4511                 if (!widget.isDisposed () && widget.setTabGroupFocus ()) {
4512                         return true;
4513                 }
4514         }
4515         if (group.isDisposed ()) return false;
4516         return group.setTabGroupFocus ();
4517 }
4518
4519 boolean traverseItem (boolean next) {
4520         Control [] children = parent._getChildren ();
4521         int length = children.length;
4522         int index = 0;
4523         while (index < length) {
4524                 if (children [index] == this) break;
4525                 index++;
4526         }
4527         /*
4528         * It is possible (but unlikely), that application
4529         * code could have disposed the widget in focus in
4530         * or out events.  Ensure that a disposed widget is
4531         * not accessed.
4532         */
4533         if (index == length) return false;
4534         int start = index, offset = (next) ? 1 : -1;
4535         while ((index = (index + offset + length) % length) != start) {
4536                 Control child = children [index];
4537                 if (!child.isDisposed () && child.isTabItem ()) {
4538                         if (child.setTabItemFocus ()) return true;
4539                 }
4540         }
4541         return false;
4542 }
4543
4544 boolean traverseMnemonic (char key) {
4545         if (mnemonicHit (key)) {
4546                 OS.SendMessage (handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
4547                 return true;
4548         }
4549         return false;
4550 }
4551
4552 boolean traversePage (boolean next) {
4553         return false;
4554 }
4555
4556 boolean traverseReturn () {
4557         return false;
4558 }
4559
4560 void unsubclass () {
4561         long newProc = windowProc ();
4562         long oldProc = display.windowProc;
4563         if (oldProc == newProc) return;
4564         OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, newProc);
4565 }
4566
4567 /**
4568  * Forces all outstanding paint requests for the widget
4569  * to be processed before this method returns. If there
4570  * are no outstanding paint request, this method does
4571  * nothing.
4572  * <p>
4573  * Note: This method does not cause a redraw.
4574  * </p>
4575  *
4576  * @exception SWTException <ul>
4577  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4578  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4579  * </ul>
4580  *
4581  * @see #redraw()
4582  * @see #redraw(int, int, int, int, boolean)
4583  * @see PaintListener
4584  * @see SWT#Paint
4585  */
4586 public void update () {
4587         checkWidget ();
4588         update (false);
4589 }
4590
4591 void update (boolean all) {
4592 //      checkWidget ();
4593         int flags = OS.RDW_UPDATENOW;
4594         if (all) flags |= OS.RDW_ALLCHILDREN;
4595         OS.RedrawWindow (handle, null, 0, flags);
4596 }
4597
4598 void updateBackgroundColor () {
4599         Control control = findBackgroundControl ();
4600         if (control == null) control = this;
4601         setBackgroundPixel (control.background);
4602 }
4603
4604 void updateBackgroundImage () {
4605         Control control = findBackgroundControl ();
4606         Image image = control != null ? control.backgroundImage : backgroundImage;
4607         setBackgroundImage (image != null ? image.handle : 0);
4608 }
4609
4610 void updateBackgroundMode () {
4611         int oldState = state & PARENT_BACKGROUND;
4612         checkBackground ();
4613         if (oldState != (state & PARENT_BACKGROUND)) {
4614                 setBackground ();
4615         }
4616 }
4617
4618 void updateFont (Font oldFont, Font newFont) {
4619         if (getFont ().equals (oldFont)) setFont (newFont);
4620 }
4621
4622 void updateLayout (boolean resize, boolean all) {
4623         /* Do nothing */
4624 }
4625
4626 void updateOrientation () {
4627         int bits  = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
4628         if ((style & SWT.RIGHT_TO_LEFT) != 0) {
4629                 bits |= OS.WS_EX_LAYOUTRTL;
4630         } else {
4631                 bits &= ~OS.WS_EX_LAYOUTRTL;
4632         }
4633         bits &= ~OS.WS_EX_RTLREADING;
4634         OS.SetWindowLong (handle, OS.GWL_EXSTYLE, bits);
4635         OS.InvalidateRect (handle, null, true);
4636 }
4637
4638 boolean updateTextDirection (int textDirection) {
4639         if (textDirection == AUTO_TEXT_DIRECTION) {
4640                 textDirection = resolveTextDirection();
4641                 state |= HAS_AUTO_DIRECTION;
4642         } else {
4643                 state &= ~HAS_AUTO_DIRECTION;
4644         }
4645         if (textDirection == 0) return false;
4646         int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
4647         /*
4648         * OS.WS_EX_RTLREADING means that the text direction is opposite to the
4649         * natural one for the current layout. So text direction would be RTL when
4650         * one and only one of the flags OS.WS_EX_LAYOUTRTL | OS.WS_EX_RTLREADING is
4651         * on.
4652         */
4653         int flags = OS.WS_EX_LAYOUTRTL | OS.WS_EX_RTLREADING;
4654         boolean oldRtl = ((bits & flags) != 0 && (bits & flags) != flags);
4655         boolean newRtl = textDirection == SWT.RIGHT_TO_LEFT;
4656         if (newRtl == oldRtl) return false;
4657         oldRtl = (bits & OS.WS_EX_LAYOUTRTL) != 0;
4658         if (newRtl != oldRtl) {
4659                 bits |= OS.WS_EX_RTLREADING;
4660                 style |= SWT.FLIP_TEXT_DIRECTION;
4661         } else {
4662                 bits &= ~OS.WS_EX_RTLREADING;
4663                 style &= ~SWT.FLIP_TEXT_DIRECTION;
4664         }
4665         OS.SetWindowLong (handle, OS.GWL_EXSTYLE, bits);
4666         OS.InvalidateRect (handle, null, true);
4667         return true;
4668 }
4669
4670 CREATESTRUCT widgetCreateStruct () {
4671         return null;
4672 }
4673
4674 int widgetExtStyle () {
4675         int bits = 0;
4676         if ((style & SWT.BORDER) != 0) bits |= OS.WS_EX_CLIENTEDGE;
4677 //      if ((style & SWT.BORDER) != 0) {
4678 //              if ((style & SWT.FLAT) == 0) bits |= OS.WS_EX_CLIENTEDGE;
4679 //      }
4680         bits |= OS.WS_EX_NOINHERITLAYOUT;
4681         if ((style & SWT.RIGHT_TO_LEFT) != 0) bits |= OS.WS_EX_LAYOUTRTL;
4682         if ((style & SWT.FLIP_TEXT_DIRECTION) != 0) bits |= OS.WS_EX_RTLREADING;
4683         return bits;
4684 }
4685
4686 long widgetParent () {
4687         return parent.handle;
4688 }
4689
4690 int widgetStyle () {
4691         /* Force clipping of siblings by setting WS_CLIPSIBLINGS */
4692         int bits = OS.WS_CHILD | OS.WS_VISIBLE | OS.WS_CLIPSIBLINGS;
4693 //      if ((style & SWT.BORDER) != 0) {
4694 //              if ((style & SWT.FLAT) != 0) bits |= OS.WS_BORDER;
4695 //      }
4696         return bits;
4697
4698         /*
4699         * This code is intentionally commented.  When clipping
4700         * of both siblings and children is not enforced, it is
4701         * possible for application code to draw outside of the
4702         * control.
4703         */
4704 //      int bits = OS.WS_CHILD | OS.WS_VISIBLE;
4705 //      if ((style & SWT.CLIP_SIBLINGS) != 0) bits |= OS.WS_CLIPSIBLINGS;
4706 //      if ((style & SWT.CLIP_CHILDREN) != 0) bits |= OS.WS_CLIPCHILDREN;
4707 //      return bits;
4708 }
4709
4710 /**
4711  * Changes the parent of the widget to be the one provided.
4712  * Returns <code>true</code> if the parent is successfully changed.
4713  *
4714  * @param parent the new parent for the control.
4715  * @return <code>true</code> if the parent is changed and <code>false</code> otherwise.
4716  *
4717  * @exception IllegalArgumentException <ul>
4718  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
4719  *    <li>ERROR_NULL_ARGUMENT - if the parent is <code>null</code></li>
4720  * </ul>
4721  * @exception SWTException <ul>
4722  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
4723  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
4724  *      </ul>
4725  */
4726 public boolean setParent (Composite parent) {
4727         checkWidget ();
4728         if (parent == null) error (SWT.ERROR_NULL_ARGUMENT);
4729         if (parent.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
4730         if (this.parent == parent) return true;
4731         if (!isReparentable ()) return false;
4732         releaseParent ();
4733         Shell newShell = parent.getShell (), oldShell = getShell ();
4734         Decorations newDecorations = parent.menuShell (), oldDecorations = menuShell ();
4735         if (oldShell != newShell || oldDecorations != newDecorations) {
4736                 Menu [] menus = oldShell.findMenus (this);
4737                 fixChildren (newShell, oldShell, newDecorations, oldDecorations, menus);
4738         }
4739         long topHandle = topHandle ();
4740         if (OS.SetParent (topHandle, parent.handle) == 0) return false;
4741         this.parent = parent;
4742         int flags = OS.SWP_NOSIZE | OS.SWP_NOMOVE | OS.SWP_NOACTIVATE;
4743         OS.SetWindowPos (topHandle, OS.HWND_BOTTOM, 0, 0, 0, 0, flags);
4744         reskin (SWT.ALL);
4745         return true;
4746 }
4747
4748 abstract TCHAR windowClass ();
4749
4750 abstract long windowProc ();
4751
4752 long windowProc (long hwnd, int msg, long wParam, long lParam) {
4753         Display display = this.display;
4754         LRESULT result = null;
4755         switch (msg) {
4756                 case OS.WM_ACTIVATE:                    result = WM_ACTIVATE (wParam, lParam); break;
4757                 case OS.WM_CAPTURECHANGED:              result = WM_CAPTURECHANGED (wParam, lParam); break;
4758                 case OS.WM_CHANGEUISTATE:               result = WM_CHANGEUISTATE (wParam, lParam); break;
4759                 case OS.WM_CHAR:                                result = WM_CHAR (wParam, lParam); break;
4760                 case OS.WM_CLEAR:                               result = WM_CLEAR (wParam, lParam); break;
4761                 case OS.WM_CLOSE:                               result = WM_CLOSE (wParam, lParam); break;
4762                 case OS.WM_COMMAND:                             result = WM_COMMAND (wParam, lParam); break;
4763                 case OS.WM_CONTEXTMENU:                 result = WM_CONTEXTMENU (wParam, lParam); break;
4764                 case OS.WM_CTLCOLORBTN:
4765                 case OS.WM_CTLCOLORDLG:
4766                 case OS.WM_CTLCOLOREDIT:
4767                 case OS.WM_CTLCOLORLISTBOX:
4768                 case OS.WM_CTLCOLORMSGBOX:
4769                 case OS.WM_CTLCOLORSCROLLBAR:
4770                 case OS.WM_CTLCOLORSTATIC:              result = WM_CTLCOLOR (wParam, lParam); break;
4771                 case OS.WM_CUT:                                 result = WM_CUT (wParam, lParam); break;
4772                 case OS.WM_DESTROY:                             result = WM_DESTROY (wParam, lParam); break;
4773                 case OS.WM_DRAWITEM:                    result = WM_DRAWITEM (wParam, lParam); break;
4774                 case OS.WM_ENDSESSION:                  result = WM_ENDSESSION (wParam, lParam); break;
4775                 case OS.WM_ENTERIDLE:                   result = WM_ENTERIDLE (wParam, lParam); break;
4776                 case OS.WM_ERASEBKGND:                  result = WM_ERASEBKGND (wParam, lParam); break;
4777                 case OS.WM_GESTURE:                             result = WM_GESTURE (wParam, lParam); break;
4778                 case OS.WM_GETDLGCODE:                  result = WM_GETDLGCODE (wParam, lParam); break;
4779                 case OS.WM_GETFONT:                             result = WM_GETFONT (wParam, lParam); break;
4780                 case OS.WM_GETOBJECT:                   result = WM_GETOBJECT (wParam, lParam); break;
4781                 case OS.WM_GETMINMAXINFO:               result = WM_GETMINMAXINFO (wParam, lParam); break;
4782                 case OS.WM_HELP:                                result = WM_HELP (wParam, lParam); break;
4783                 case OS.WM_HSCROLL:                             result = WM_HSCROLL (wParam, lParam); break;
4784                 case OS.WM_IME_CHAR:                    result = WM_IME_CHAR (wParam, lParam); break;
4785                 case OS.WM_IME_COMPOSITION:             result = WM_IME_COMPOSITION (wParam, lParam); break;
4786                 case OS.WM_IME_COMPOSITION_START:       result = WM_IME_COMPOSITION_START (wParam, lParam); break;
4787                 case OS.WM_IME_ENDCOMPOSITION:  result = WM_IME_ENDCOMPOSITION (wParam, lParam); break;
4788                 case OS.WM_INITMENUPOPUP:               result = WM_INITMENUPOPUP (wParam, lParam); break;
4789                 case OS.WM_INPUTLANGCHANGE:             result = WM_INPUTLANGCHANGE (wParam, lParam); break;
4790                 case OS.WM_HOTKEY:                              result = WM_HOTKEY (wParam, lParam); break;
4791                 case OS.WM_KEYDOWN:                             result = WM_KEYDOWN (wParam, lParam); break;
4792                 case OS.WM_KEYUP:                               result = WM_KEYUP (wParam, lParam); break;
4793                 case OS.WM_KILLFOCUS:                   result = WM_KILLFOCUS (wParam, lParam); break;
4794                 case OS.WM_LBUTTONDBLCLK:               result = WM_LBUTTONDBLCLK (wParam, lParam); break;
4795                 case OS.WM_LBUTTONDOWN:                 result = WM_LBUTTONDOWN (wParam, lParam); break;
4796                 case OS.WM_LBUTTONUP:                   result = WM_LBUTTONUP (wParam, lParam); break;
4797                 case OS.WM_MBUTTONDBLCLK:               result = WM_MBUTTONDBLCLK (wParam, lParam); break;
4798                 case OS.WM_MBUTTONDOWN:                 result = WM_MBUTTONDOWN (wParam, lParam); break;
4799                 case OS.WM_MBUTTONUP:                   result = WM_MBUTTONUP (wParam, lParam); break;
4800                 case OS.WM_MEASUREITEM:                 result = WM_MEASUREITEM (wParam, lParam); break;
4801                 case OS.WM_MENUCHAR:                    result = WM_MENUCHAR (wParam, lParam); break;
4802                 case OS.WM_MENUSELECT:                  result = WM_MENUSELECT (wParam, lParam); break;
4803                 case OS.WM_MOUSEACTIVATE:               result = WM_MOUSEACTIVATE (wParam, lParam); break;
4804                 case OS.WM_MOUSEHOVER:                  result = WM_MOUSEHOVER (wParam, lParam); break;
4805                 case OS.WM_MOUSELEAVE:                  result = WM_MOUSELEAVE (wParam, lParam); break;
4806                 case OS.WM_MOUSEMOVE:                   result = WM_MOUSEMOVE (wParam, lParam); break;
4807                 case OS.WM_MOUSEWHEEL:                  result = WM_MOUSEWHEEL (wParam, lParam); break;
4808                 case OS.WM_MOUSEHWHEEL:                 result = WM_MOUSEHWHEEL (wParam, lParam); break;
4809                 case OS.WM_MOVE:                                result = WM_MOVE (wParam, lParam); break;
4810                 case OS.WM_NCACTIVATE:                  result = WM_NCACTIVATE (wParam, lParam); break;
4811                 case OS.WM_NCCALCSIZE:                  result = WM_NCCALCSIZE (wParam, lParam); break;
4812                 case OS.WM_NCHITTEST:                   result = WM_NCHITTEST (wParam, lParam); break;
4813                 case OS.WM_NCLBUTTONDOWN:               result = WM_NCLBUTTONDOWN (wParam, lParam); break;
4814                 case OS.WM_NCPAINT:                             result = WM_NCPAINT (wParam, lParam); break;
4815                 case OS.WM_NOTIFY:                              result = WM_NOTIFY (wParam, lParam); break;
4816                 case OS.WM_PAINT:                               result = WM_PAINT (wParam, lParam); break;
4817                 case OS.WM_ENTERMENULOOP:               result = WM_ENTERMENULOOP (wParam, lParam); break;
4818                 case OS.WM_EXITMENULOOP:                result = WM_EXITMENULOOP (wParam, lParam); break;
4819                 case OS.WM_ENTERSIZEMOVE:               result = WM_ENTERSIZEMOVE (wParam, lParam); break;
4820                 case OS.WM_EXITSIZEMOVE:                result = WM_EXITSIZEMOVE (wParam, lParam); break;
4821                 case OS.WM_PARENTNOTIFY:                result = WM_PARENTNOTIFY (wParam, lParam); break;
4822                 case OS.WM_PASTE:                               result = WM_PASTE (wParam, lParam); break;
4823                 case OS.WM_PRINT:                               result = WM_PRINT (wParam, lParam); break;
4824                 case OS.WM_PRINTCLIENT:                 result = WM_PRINTCLIENT (wParam, lParam); break;
4825                 case OS.WM_QUERYENDSESSION:             result = WM_QUERYENDSESSION (wParam, lParam); break;
4826                 case OS.WM_QUERYOPEN:                   result = WM_QUERYOPEN (wParam, lParam); break;
4827                 case OS.WM_RBUTTONDBLCLK:               result = WM_RBUTTONDBLCLK (wParam, lParam); break;
4828                 case OS.WM_RBUTTONDOWN:                 result = WM_RBUTTONDOWN (wParam, lParam); break;
4829                 case OS.WM_RBUTTONUP:                   result = WM_RBUTTONUP (wParam, lParam); break;
4830                 case OS.WM_SETCURSOR:                   result = WM_SETCURSOR (wParam, lParam); break;
4831                 case OS.WM_SETFOCUS:                    result = WM_SETFOCUS (wParam, lParam); break;
4832                 case OS.WM_SETFONT:                             result = WM_SETFONT (wParam, lParam); break;
4833                 case OS.WM_SETTINGCHANGE:               result = WM_SETTINGCHANGE (wParam, lParam); break;
4834                 case OS.WM_SETREDRAW:                   result = WM_SETREDRAW (wParam, lParam); break;
4835                 case OS.WM_SHOWWINDOW:                  result = WM_SHOWWINDOW (wParam, lParam); break;
4836                 case OS.WM_SIZE:                                result = WM_SIZE (wParam, lParam); break;
4837                 case OS.WM_SYSCHAR:                             result = WM_SYSCHAR (wParam, lParam); break;
4838                 case OS.WM_SYSCOLORCHANGE:              result = WM_SYSCOLORCHANGE (wParam, lParam); break;
4839                 case OS.WM_SYSCOMMAND:                  result = WM_SYSCOMMAND (wParam, lParam); break;
4840                 case OS.WM_SYSKEYDOWN:                  result = WM_SYSKEYDOWN (wParam, lParam); break;
4841                 case OS.WM_SYSKEYUP:                    result = WM_SYSKEYUP (wParam, lParam); break;
4842                 case OS.WM_TABLET_FLICK:                result = WM_TABLET_FLICK (wParam, lParam); break;
4843                 case OS.WM_TIMER:                               result = WM_TIMER (wParam, lParam); break;
4844                 case OS.WM_TOUCH:                               result = WM_TOUCH (wParam, lParam); break;
4845                 case OS.WM_UNDO:                                result = WM_UNDO (wParam, lParam); break;
4846                 case OS.WM_UNINITMENUPOPUP:             result = WM_UNINITMENUPOPUP (wParam, lParam); break;
4847                 case OS.WM_UPDATEUISTATE:               result = WM_UPDATEUISTATE (wParam, lParam); break;
4848                 case OS.WM_VSCROLL:                             result = WM_VSCROLL (wParam, lParam); break;
4849                 case OS.WM_WINDOWPOSCHANGED:    result = WM_WINDOWPOSCHANGED (wParam, lParam); break;
4850                 case OS.WM_WINDOWPOSCHANGING:   result = WM_WINDOWPOSCHANGING (wParam, lParam); break;
4851                 case OS.WM_XBUTTONDBLCLK:               result = WM_XBUTTONDBLCLK (wParam, lParam); break;
4852                 case OS.WM_XBUTTONDOWN:                 result = WM_XBUTTONDOWN (wParam, lParam); break;
4853                 case OS.WM_XBUTTONUP:                   result = WM_XBUTTONUP (wParam, lParam); break;
4854                 case OS.WM_DPICHANGED:                  result = WM_DPICHANGED (wParam, lParam); break;
4855         }
4856         if (result != null) return result.value;
4857         // widget could be disposed at this point
4858         display.sendPreExternalEventDispatchEvent ();
4859         try {
4860                 return callWindowProc (hwnd, msg, wParam, lParam);
4861         } finally {
4862                 // widget could be disposed at this point
4863                 display.sendPostExternalEventDispatchEvent ();
4864         }
4865 }
4866
4867 LRESULT WM_ACTIVATE (long wParam, long lParam) {
4868         return null;
4869 }
4870
4871 LRESULT WM_CAPTURECHANGED (long wParam, long lParam) {
4872         return wmCaptureChanged (handle, wParam, lParam);
4873 }
4874
4875 LRESULT WM_CHANGEUISTATE (long wParam, long lParam) {
4876         if ((state & IGNORE_WM_CHANGEUISTATE) != 0) return LRESULT.ZERO;
4877         return null;
4878 }
4879
4880 LRESULT WM_CHAR (long wParam, long lParam) {
4881         return wmChar (handle, wParam, lParam);
4882 }
4883
4884 LRESULT WM_CLEAR (long wParam, long lParam) {
4885         return null;
4886 }
4887
4888 LRESULT WM_CLOSE (long wParam, long lParam) {
4889         return null;
4890 }
4891
4892 LRESULT WM_COMMAND (long wParam, long lParam) {
4893         /*
4894         * When the WM_COMMAND message is sent from a
4895         * menu, the HWND parameter in LPARAM is zero.
4896         */
4897         if (lParam == 0) {
4898                 Decorations shell = menuShell ();
4899                 if (shell.isEnabled ()) {
4900                         int id = OS.LOWORD (wParam);
4901                         MenuItem item = display.getMenuItem (id);
4902                         if (item != null && item.isEnabled ()) {
4903                                 return item.wmCommandChild (wParam, lParam);
4904                         }
4905                 }
4906                 return null;
4907         }
4908         Control control = display.getControl (lParam);
4909         if (control == null) return null;
4910         return control.wmCommandChild (wParam, lParam);
4911 }
4912
4913 LRESULT WM_CONTEXTMENU (long wParam, long lParam) {
4914         return wmContextMenu (handle, wParam, lParam);
4915 }
4916
4917 LRESULT WM_CTLCOLOR (long wParam, long lParam) {
4918         Control control = display.getControl (lParam);
4919         if (control == null) return null;
4920         return control.wmColorChild (wParam, lParam);
4921 }
4922
4923 LRESULT WM_CUT (long wParam, long lParam) {
4924         return null;
4925 }
4926
4927 LRESULT WM_DESTROY (long wParam, long lParam) {
4928         OS.KillTimer (this.handle, Menu.ID_TOOLTIP_TIMER);
4929         return null;
4930 }
4931
4932 LRESULT WM_DPICHANGED (long wParam, long lParam) {
4933         // Map DPI to Zoom and compare
4934         int nativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam));
4935         int newSWTZoom = DPIUtil.getZoomForAutoscaleProperty (nativeZoom);
4936         int oldSWTZoom = DPIUtil.getDeviceZoom();
4937
4938         // Throw the DPI change event if zoom value changes
4939         if (newSWTZoom != oldSWTZoom) {
4940                 Event event = new Event();
4941                 event.type = SWT.ZoomChanged;
4942                 event.widget = this;
4943                 event.detail = newSWTZoom;
4944                 event.doit = true;
4945                 notifyListeners(SWT.ZoomChanged, event);
4946                 return LRESULT.ZERO;
4947         }
4948         return LRESULT.ONE;
4949 }
4950
4951 LRESULT WM_DRAWITEM (long wParam, long lParam) {
4952         DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT ();
4953         OS.MoveMemory (struct, lParam, DRAWITEMSTRUCT.sizeof);
4954         if (struct.CtlType == OS.ODT_MENU) {
4955                 MenuItem item = display.getMenuItem (struct.itemID);
4956                 if (item == null) return null;
4957                 return item.wmDrawChild (wParam, lParam);
4958         }
4959         Control control = display.getControl (struct.hwndItem);
4960         if (control == null) return null;
4961         return control.wmDrawChild (wParam, lParam);
4962 }
4963
4964 LRESULT WM_ENDSESSION (long wParam, long lParam) {
4965         return null;
4966 }
4967
4968 LRESULT WM_ENTERIDLE (long wParam, long lParam) {
4969         return null;
4970 }
4971
4972 LRESULT WM_ENTERMENULOOP (long wParam, long lParam) {
4973         display.externalEventLoop = true;
4974         return null;
4975 }
4976
4977 LRESULT WM_ENTERSIZEMOVE (long wParam, long lParam) {
4978         display.externalEventLoop = true;
4979         return null;
4980 }
4981
4982 LRESULT WM_ERASEBKGND (long wParam, long lParam) {
4983         if ((state & DRAW_BACKGROUND) != 0) {
4984                 if (findImageControl () != null) return LRESULT.ONE;
4985         }
4986         if ((state & THEME_BACKGROUND) != 0) {
4987                 if (OS.IsAppThemed ()) {
4988                         if (findThemeControl () != null) return LRESULT.ONE;
4989                 }
4990         }
4991         return null;
4992 }
4993
4994 LRESULT WM_EXITMENULOOP (long wParam, long lParam) {
4995         display.externalEventLoop = false;
4996         return null;
4997 }
4998
4999 LRESULT WM_EXITSIZEMOVE (long wParam, long lParam) {
5000         display.externalEventLoop = false;
5001         return null;
5002 }
5003
5004 LRESULT WM_GESTURE (long wParam, long lParam) {
5005         if (hooks (SWT.Gesture) || filters (SWT.Gesture)) {
5006                 GESTUREINFO gi = new GESTUREINFO ();
5007                 gi.cbSize = GESTUREINFO.sizeof;
5008                 if (OS.GetGestureInfo (lParam, gi)) {
5009                         if (!sendGestureEvent (gi)) {
5010                                 OS.CloseGestureInfoHandle (lParam);
5011                                 return LRESULT.ZERO;
5012                         }
5013                 }
5014         }
5015         return null;
5016 }
5017
5018 LRESULT WM_GETDLGCODE (long wParam, long lParam) {
5019         return null;
5020 }
5021
5022 LRESULT WM_GETFONT (long wParam, long lParam) {
5023         return null;
5024 }
5025
5026 LRESULT WM_GETOBJECT (long wParam, long lParam) {
5027         if (accessible != null) {
5028                 long result = accessible.internal_WM_GETOBJECT (wParam, lParam);
5029                 if (result != 0) return new LRESULT (result);
5030         }
5031         return null;
5032 }
5033
5034 LRESULT WM_GETMINMAXINFO (long wParam, long lParam) {
5035         return null;
5036 }
5037
5038 LRESULT WM_HOTKEY (long wParam, long lParam) {
5039         return null;
5040 }
5041
5042 LRESULT WM_HELP (long wParam, long lParam) {
5043         HELPINFO lphi = new HELPINFO ();
5044         OS.MoveMemory (lphi, lParam, HELPINFO.sizeof);
5045         Decorations shell = menuShell ();
5046         if (!shell.isEnabled ()) return null;
5047         if (lphi.iContextType == OS.HELPINFO_MENUITEM) {
5048                 MenuItem item = display.getMenuItem (lphi.iCtrlId);
5049                 if (item != null && item.isEnabled ()) {
5050                         Widget widget = null;
5051                         if (item.hooks (SWT.Help)) {
5052                                 widget = item;
5053                         } else {
5054                                 Menu menu = item.parent;
5055                                 if (menu.hooks (SWT.Help)) widget = menu;
5056                         }
5057                         if (widget != null) {
5058                                 long hwndShell = shell.handle;
5059                                 OS.SendMessage (hwndShell, OS.WM_CANCELMODE, 0, 0);
5060                                 widget.postEvent (SWT.Help);
5061                                 return LRESULT.ONE;
5062                         }
5063                 }
5064                 return null;
5065         }
5066         if (hooks (SWT.Help)) {
5067                 postEvent (SWT.Help);
5068                 return LRESULT.ONE;
5069         }
5070         return null;
5071 }
5072
5073 LRESULT WM_HSCROLL (long wParam, long lParam) {
5074         Control control = display.getControl (lParam);
5075         if (control == null) return null;
5076         return control.wmScrollChild (wParam, lParam);
5077 }
5078
5079 LRESULT WM_IME_CHAR (long wParam, long lParam) {
5080         return wmIMEChar (handle, wParam, lParam);
5081 }
5082
5083 LRESULT WM_IME_COMPOSITION (long wParam, long lParam) {
5084         return null;
5085 }
5086
5087 LRESULT WM_IME_COMPOSITION_START (long wParam, long lParam) {
5088         return null;
5089 }
5090
5091 LRESULT WM_IME_ENDCOMPOSITION (long wParam, long lParam) {
5092         return null;
5093 }
5094
5095 LRESULT WM_UNINITMENUPOPUP (long wParam, long lParam) {
5096         Menu hiddenMenu = menuShell ().findMenu (wParam);
5097         if (hiddenMenu != null) {
5098                 Shell shell = getShell ();
5099                 hiddenMenu.sendEvent (SWT.Hide);
5100                 if (hiddenMenu == shell.activeMenu) shell.activeMenu = null;
5101         }
5102         return null;
5103 }
5104
5105 LRESULT WM_INITMENUPOPUP (long wParam, long lParam) {
5106
5107         /* Ignore WM_INITMENUPOPUP for an accelerator */
5108         if (display.accelKeyHit) return null;
5109
5110         /*
5111         * If the high order word of LPARAM is non-zero,
5112         * the menu is the system menu and we can ignore
5113         * WPARAM.  Otherwise, use WPARAM to find the menu.
5114         */
5115         Shell shell = getShell ();
5116         Menu oldMenu = shell.activeMenu, newMenu = null;
5117         if (OS.HIWORD (lParam) == 0) {
5118                 newMenu = menuShell ().findMenu (wParam);
5119                 if (newMenu != null) newMenu.update ();
5120         }
5121         Menu menu = newMenu;
5122         while (menu != null && menu != oldMenu) {
5123                 menu = menu.getParentMenu ();
5124         }
5125         if (menu == null) {
5126                 menu = shell.activeMenu;
5127                 while (menu != null) {
5128                         /*
5129                         * It is possible (but unlikely), that application
5130                         * code could have disposed the widget in the hide
5131                         * event.  If this happens, stop searching up the
5132                         * ancestor list because there is no longer a link
5133                         * to follow.
5134                         */
5135                         menu.sendEvent (SWT.Hide);
5136                         if (menu.isDisposed ()) break;
5137                         menu = menu.getParentMenu ();
5138                         Menu ancestor = newMenu;
5139                         while (ancestor != null && ancestor != menu) {
5140                                 ancestor = ancestor.getParentMenu ();
5141                         }
5142                         if (ancestor != null) break;
5143                 }
5144         }
5145
5146         /*
5147         * The shell and the new menu may be disposed because of
5148         * sending the hide event to the ancestor menus but setting
5149         * a field to null in a disposed shell is not harmful.
5150         */
5151         if (newMenu != null && newMenu.isDisposed ()) newMenu = null;
5152         shell.activeMenu = newMenu;
5153
5154         /* Send the show event */
5155         if (newMenu != null && newMenu != oldMenu) {
5156                 newMenu.sendEvent (SWT.Show);
5157                 // widget could be disposed at this point
5158         }
5159         return null;
5160 }
5161
5162 LRESULT WM_INPUTLANGCHANGE (long wParam, long lParam) {
5163         menuShell().destroyAccelerators();
5164         return null;
5165 }
5166
5167 LRESULT WM_KEYDOWN (long wParam, long lParam) {
5168         return wmKeyDown (handle, wParam, lParam);
5169 }
5170
5171 LRESULT WM_KEYUP (long wParam, long lParam) {
5172         return wmKeyUp (handle, wParam, lParam);
5173 }
5174
5175 LRESULT WM_KILLFOCUS (long wParam, long lParam) {
5176         return wmKillFocus (handle, wParam, lParam);
5177 }
5178
5179 LRESULT WM_LBUTTONDBLCLK (long wParam, long lParam) {
5180         return wmLButtonDblClk (handle, wParam, lParam);
5181 }
5182
5183 LRESULT WM_LBUTTONDOWN (long wParam, long lParam) {
5184         return wmLButtonDown (handle, wParam, lParam);
5185 }
5186
5187 LRESULT WM_LBUTTONUP (long wParam, long lParam) {
5188         return wmLButtonUp (handle, wParam, lParam);
5189 }
5190
5191 LRESULT WM_MBUTTONDBLCLK (long wParam, long lParam) {
5192         return wmMButtonDblClk (handle, wParam, lParam);
5193 }
5194
5195 LRESULT WM_MBUTTONDOWN (long wParam, long lParam) {
5196         return wmMButtonDown (handle, wParam, lParam);
5197 }
5198
5199 LRESULT WM_MBUTTONUP (long wParam, long lParam) {
5200         return wmMButtonUp (handle, wParam, lParam);
5201 }
5202
5203 LRESULT WM_MEASUREITEM (long wParam, long lParam) {
5204         MEASUREITEMSTRUCT struct = new MEASUREITEMSTRUCT ();
5205         OS.MoveMemory (struct, lParam, MEASUREITEMSTRUCT.sizeof);
5206         if (struct.CtlType == OS.ODT_MENU) {
5207                 MenuItem item = display.getMenuItem (struct.itemID);
5208                 if (item == null) return null;
5209                 return item.wmMeasureChild (wParam, lParam);
5210         }
5211         long hwnd = OS.GetDlgItem (handle, struct.CtlID);
5212         Control control = display.getControl (hwnd);
5213         if (control == null) return null;
5214         return control.wmMeasureChild (wParam, lParam);
5215 }
5216
5217 LRESULT WM_MENUCHAR (long wParam, long lParam) {
5218         /*
5219         * Feature in Windows.  When the user types Alt+<key>
5220         * and <key> does not match a mnemonic in the System
5221         * menu or the menu bar, Windows beeps.  This beep is
5222         * unexpected and unwanted by applications that look
5223         * for Alt+<key>.  The fix is to detect the case and
5224         * stop Windows from beeping by closing the menu.
5225         */
5226         int type = OS.HIWORD (wParam);
5227         if (type == 0 || type == OS.MF_SYSMENU) {
5228                 display.mnemonicKeyHit = false;
5229                 return new LRESULT (OS.MAKELRESULT (0, OS.MNC_CLOSE));
5230         }
5231         return null;
5232 }
5233
5234 LRESULT WM_MENUSELECT (long wParam, long lParam) {
5235         int code = OS.HIWORD (wParam);
5236         Shell shell = getShell ();
5237         OS.KillTimer (this.handle, Menu.ID_TOOLTIP_TIMER);
5238         if (activeMenu != null)
5239                 activeMenu.hideCurrentToolTip ();
5240         if (code == 0xFFFF && lParam == 0) {
5241                 Menu menu = shell.activeMenu;
5242                 while (menu != null) {
5243                         /*
5244                         * When the user cancels any menu that is not the
5245                         * menu bar, assume a mnemonic key was pressed to open
5246                         * the menu from WM_SYSCHAR.  When the menu was invoked
5247                         * using the mouse, this assumption is wrong but not
5248                         * harmful.  This variable is only used in WM_SYSCHAR
5249                         * and WM_SYSCHAR is only sent after the user has pressed
5250                         * a mnemonic.
5251                         */
5252                         display.mnemonicKeyHit = true;
5253                         /*
5254                         * It is possible (but unlikely), that application
5255                         * code could have disposed the widget in the hide
5256                         * event.  If this happens, stop searching up the
5257                         * parent list because there is no longer a link
5258                         * to follow.
5259                         */
5260                         menu.sendEvent (SWT.Hide);
5261                         if (menu.isDisposed ()) break;
5262                         menu = menu.getParentMenu ();
5263                 }
5264                 /*
5265                 * The shell may be disposed because of sending the hide
5266                 * event to the last active menu menu but setting a field
5267                 * to null in a destroyed widget is not harmful.
5268                 */
5269                 shell.activeMenu = null;
5270                 return null;
5271         }
5272         if ((code & OS.MF_SYSMENU) != 0) return null;
5273         if ((code & OS.MF_HILITE) != 0) {
5274                 MenuItem item = null;
5275                 Decorations menuShell = menuShell ();
5276                 if ((code & OS.MF_POPUP) != 0) {
5277                         int index = OS.LOWORD (wParam);
5278                         MENUITEMINFO info = new MENUITEMINFO ();
5279                         info.cbSize = MENUITEMINFO.sizeof;
5280                         info.fMask = OS.MIIM_SUBMENU;
5281                         if (OS.GetMenuItemInfo (lParam, index, true, info)) {
5282                                 Menu newMenu = menuShell.findMenu (info.hSubMenu);
5283                                 if (newMenu != null) {
5284                                         item = newMenu.cascade;
5285                                         activeMenu = newMenu;
5286                                         activeMenu.selectedMenuItem = newMenu.cascade;
5287                                         OS.SetTimer (this.handle, Menu.ID_TOOLTIP_TIMER, OS.TTM_GETDELAYTIME, 0);
5288                                 }
5289                         }
5290                 } else {
5291                         Menu newMenu = menuShell.findMenu (lParam);
5292                         if (newMenu != null) {
5293                                 int id = OS.LOWORD (wParam);
5294                                 item = display.getMenuItem (id);
5295                         }
5296                         activeMenu = (newMenu == null) ? menu : newMenu;
5297                         if (item != null && activeMenu != null) {
5298                                 activeMenu.selectedMenuItem = item;
5299                                 OS.SetTimer (this.handle, Menu.ID_TOOLTIP_TIMER, OS.TTM_GETDELAYTIME, 0);
5300                         }
5301                 }
5302                 if (item != null) item.sendEvent (SWT.Arm);
5303         }
5304         return null;
5305 }
5306
5307 LRESULT WM_MOUSEACTIVATE (long wParam, long lParam) {
5308         return null;
5309 }
5310
5311 LRESULT WM_MOUSEHOVER (long wParam, long lParam) {
5312         return wmMouseHover (handle, wParam, lParam);
5313 }
5314
5315 LRESULT WM_MOUSELEAVE (long wParam, long lParam) {
5316         getShell ().fixToolTip ();
5317         return wmMouseLeave (handle, wParam, lParam);
5318 }
5319
5320 LRESULT WM_MOUSEMOVE (long wParam, long lParam) {
5321         return wmMouseMove (handle, wParam, lParam);
5322 }
5323
5324 LRESULT WM_MOUSEWHEEL (long wParam, long lParam) {
5325         return wmMouseWheel (handle, wParam, lParam);
5326 }
5327
5328 LRESULT WM_MOUSEHWHEEL (long wParam, long lParam) {
5329         return wmMouseHWheel (handle, wParam, lParam);
5330 }
5331
5332 LRESULT WM_MOVE (long wParam, long lParam) {
5333         state |= MOVE_OCCURRED;
5334         if (findImageControl () != null) {
5335                 if (this != getShell ()) redrawChildren ();
5336         } else {
5337                 if ((state & THEME_BACKGROUND) != 0) {
5338                         if (OS.IsAppThemed ()) {
5339                                 if (OS.IsWindowVisible (handle)) {
5340                                         if (findThemeControl () != null) redrawChildren ();
5341                                 }
5342                         }
5343                 }
5344         }
5345         if ((state & MOVE_DEFERRED) == 0) sendEvent (SWT.Move);
5346         // widget could be disposed at this point
5347         return null;
5348 }
5349
5350 LRESULT WM_NCACTIVATE (long wParam, long lParam) {
5351         return null;
5352 }
5353
5354 LRESULT WM_NCCALCSIZE (long wParam, long lParam) {
5355         return null;
5356 }
5357
5358 LRESULT WM_NCHITTEST (long wParam, long lParam) {
5359         if (!OS.IsWindowEnabled (handle)) return null;
5360         if (!isActive ()) return new LRESULT (OS.HTTRANSPARENT);
5361         return null;
5362 }
5363
5364 LRESULT WM_NCLBUTTONDOWN (long wParam, long lParam) {
5365         return null;
5366 }
5367
5368 LRESULT WM_NCPAINT (long wParam, long lParam) {
5369         return wmNCPaint (handle, wParam, lParam);
5370 }
5371
5372 LRESULT WM_NOTIFY (long wParam, long lParam) {
5373         NMHDR hdr = new NMHDR ();
5374         OS.MoveMemory (hdr, lParam, NMHDR.sizeof);
5375         return wmNotify (hdr, wParam, lParam);
5376 }
5377
5378 LRESULT WM_PAINT (long wParam, long lParam) {
5379         if ((state & DISPOSE_SENT) != 0) return LRESULT.ZERO;
5380         return wmPaint (handle, wParam, lParam);
5381 }
5382
5383 LRESULT WM_PARENTNOTIFY (long wParam, long lParam) {
5384         return null;
5385 }
5386
5387 LRESULT WM_PASTE (long wParam, long lParam) {
5388         return null;
5389 }
5390
5391 LRESULT WM_PRINT (long wParam, long lParam) {
5392         return wmPrint (handle, wParam, lParam);
5393 }
5394
5395 LRESULT WM_PRINTCLIENT (long wParam, long lParam) {
5396         return null;
5397 }
5398
5399 LRESULT WM_QUERYENDSESSION (long wParam, long lParam) {
5400         return null;
5401 }
5402
5403 LRESULT WM_QUERYOPEN (long wParam, long lParam) {
5404         return null;
5405 }
5406
5407 LRESULT WM_RBUTTONDBLCLK (long wParam, long lParam) {
5408         return wmRButtonDblClk (handle, wParam, lParam);
5409 }
5410
5411 LRESULT WM_RBUTTONDOWN (long wParam, long lParam) {
5412         return wmRButtonDown (handle, wParam, lParam);
5413 }
5414
5415 LRESULT WM_RBUTTONUP (long wParam, long lParam) {
5416         return wmRButtonUp (handle, wParam, lParam);
5417 }
5418
5419 LRESULT WM_SETCURSOR (long wParam, long lParam) {
5420         int hitTest = (short) OS.LOWORD (lParam);
5421         if (hitTest == OS.HTCLIENT) {
5422                 Control control = display.getControl (wParam);
5423                 if (control == null) return null;
5424                 Cursor cursor = control.findCursor ();
5425                 if (cursor != null) {
5426                         OS.SetCursor (cursor.handle);
5427                         return LRESULT.ONE;
5428                 }
5429         }
5430         return null;
5431 }
5432
5433 LRESULT WM_SETFOCUS (long wParam, long lParam) {
5434         return wmSetFocus (handle, wParam, lParam);
5435 }
5436
5437 LRESULT WM_SETTINGCHANGE (long wParam, long lParam) {
5438         return null;
5439 }
5440
5441 LRESULT WM_SETFONT (long wParam, long lParam) {
5442         return null;
5443 }
5444
5445 LRESULT WM_SETREDRAW (long wParam, long lParam) {
5446         return null;
5447 }
5448
5449 LRESULT WM_SHOWWINDOW (long wParam, long lParam) {
5450         return null;
5451 }
5452
5453 LRESULT WM_SIZE (long wParam, long lParam) {
5454         state |= RESIZE_OCCURRED;
5455         if ((state & RESIZE_DEFERRED) == 0) sendEvent (SWT.Resize);
5456         // widget could be disposed at this point
5457         return null;
5458 }
5459
5460 LRESULT WM_SYSCHAR (long wParam, long lParam) {
5461         return wmSysChar (handle, wParam, lParam);
5462 }
5463
5464 LRESULT WM_SYSCOLORCHANGE (long wParam, long lParam) {
5465         return null;
5466 }
5467
5468 LRESULT WM_SYSCOMMAND (long wParam, long lParam) {
5469         /*
5470         * Check to see if the command is a system command or
5471         * a user menu item that was added to the System menu.
5472         * When a user item is added to the System menu,
5473         * WM_SYSCOMMAND must always return zero.
5474         *
5475         * NOTE: This is undocumented.
5476         */
5477         if ((wParam & 0xF000) == 0) {
5478                 Decorations shell = menuShell ();
5479                 if (shell.isEnabled ()) {
5480                         MenuItem item = display.getMenuItem (OS.LOWORD (wParam));
5481                         if (item != null) item.wmCommandChild (wParam, lParam);
5482                 }
5483                 return LRESULT.ZERO;
5484         }
5485
5486         /* Process the System Command */
5487         int cmd = (int)wParam & 0xFFF0;
5488         switch (cmd) {
5489                 case OS.SC_KEYMENU:
5490                         /*
5491                         * When lParam is zero, one of F10, Shift+F10, Ctrl+F10 or
5492                         * Ctrl+Shift+F10 was pressed.  If there is no menu bar and
5493                         * the focus control is interested in keystrokes, give the
5494                         * key to the focus control.  Normally, F10 with no menu bar
5495                         * moves focus to the System menu but this can be achieved
5496                         * using Alt+Space.  To allow the application to see F10,
5497                         * avoid running the default window proc.
5498                         *
5499                         * NOTE:  When F10 is pressed, WM_SYSCOMMAND is sent to the
5500                         * shell, not the focus control.  This is undocumented Windows
5501                         * behavior.
5502                         */
5503                         if (lParam == 0) {
5504                                 Decorations shell = menuShell ();
5505                                 Menu menu = shell.getMenuBar ();
5506                                 if (menu == null) {
5507                                         Control control = display._getFocusControl ();
5508                                         if (control != null) {
5509                                                 if (control.hooks (SWT.KeyDown) || control.hooks (SWT.KeyUp)) {
5510                                                         display.mnemonicKeyHit = false;
5511                                                         return LRESULT.ZERO;
5512                                                 }
5513                                         }
5514                                 }
5515                         } else {
5516                                 /*
5517                                 * When lParam is not zero, Alt+<key> was pressed.  If the
5518                                 * application is interested in keystrokes and there is a
5519                                 * menu bar, check to see whether the key that was pressed
5520                                 * matches a mnemonic on the menu bar.  Normally, Windows
5521                                 * matches the first character of a menu item as well as
5522                                 * matching the mnemonic character.  To allow the application
5523                                 * to see the keystrokes in this case, avoid running the default
5524                                 * window proc.
5525                                 *
5526                                 * NOTE: When the user types Alt+Space, the System menu is
5527                                 * activated.  In this case the application should not see
5528                                 * the keystroke.
5529                                 */
5530                                 if (hooks (SWT.KeyDown) || hooks (SWT.KeyUp)) {
5531                                         if (lParam != ' ') {
5532                                                 Decorations shell = menuShell ();
5533                                                 Menu menu = shell.getMenuBar ();
5534                                                 if (menu != null) {
5535                                                         char key = (char) lParam;
5536                                                         if (key != 0) {
5537                                                                 key = Character.toUpperCase (key);
5538                                                                 MenuItem [] items = menu.getItems ();
5539                                                                 for (int i=0; i<items.length; i++) {
5540                                                                         MenuItem item = items [i];
5541                                                                         String text = item.getText ();
5542                                                                         char mnemonic = findMnemonic (text);
5543                                                                         if (text.length () > 0 && mnemonic == 0) {
5544                                                                                 char ch = text.charAt (0);
5545                                                                                 if (Character.toUpperCase (ch) == key) {
5546                                                                                         display.mnemonicKeyHit = false;
5547                                                                                         return LRESULT.ZERO;
5548                                                                                 }
5549                                                                         }
5550                                                                 }
5551                                                         }
5552                                                 } else {
5553                                                         display.mnemonicKeyHit = false;
5554                                                 }
5555                                         }
5556                                 }
5557                         }
5558                         // FALL THROUGH
5559                 case OS.SC_HSCROLL:
5560                 case OS.SC_VSCROLL:
5561                         /*
5562                         * Do not allow keyboard traversal of the menu bar
5563                         * or scrolling when the shell is not enabled.
5564                         */
5565                         Decorations shell = menuShell ();
5566                         if (!shell.isEnabled () || !shell.isActive ()) {
5567                                 return LRESULT.ZERO;
5568                         }
5569                         break;
5570                 case OS.SC_MINIMIZE:
5571                         /* Save the focus widget when the shell is minimized */
5572                         menuShell ().saveFocus ();
5573                         break;
5574         }
5575         return null;
5576 }
5577
5578 LRESULT WM_SYSKEYDOWN (long wParam, long lParam) {
5579         return wmSysKeyDown (handle, wParam, lParam);
5580 }
5581
5582 LRESULT WM_SYSKEYUP (long wParam, long lParam) {
5583         return wmSysKeyUp (handle, wParam, lParam);
5584 }
5585
5586 LRESULT WM_TABLET_FLICK (long wParam, long lParam) {
5587         if (!hooks (SWT.Gesture) && !filters (SWT.Gesture)) return null;
5588         Event event = new Event ();
5589         FLICK_DATA fData = new FLICK_DATA ();
5590         long [] source = new long [1];
5591         source[0] = wParam;
5592         OS.MoveMemory (fData, source, OS.FLICK_DATA_sizeof ());
5593         FLICK_POINT fPoint = new FLICK_POINT ();
5594         source [0] = lParam;
5595         OS.MoveMemory (fPoint, source, OS.FLICK_POINT_sizeof ());
5596
5597         switch (fData.iFlickDirection) {
5598                 case OS.FLICKDIRECTION_RIGHT:
5599                         event.xDirection = 1;
5600                         event.yDirection = 0;
5601                         break;
5602                 case OS.FLICKDIRECTION_UPRIGHT:
5603                         event.xDirection = 1;
5604                         event.yDirection = -1;
5605                         break;
5606                 case OS.FLICKDIRECTION_UP:
5607                         event.xDirection = 0;
5608                         event.yDirection = -1;
5609                         break;
5610                 case OS.FLICKDIRECTION_UPLEFT:
5611                         event.xDirection = -1;
5612                         event.yDirection = -1;
5613                         break;
5614                 case OS.FLICKDIRECTION_LEFT:
5615                         event.xDirection = -1;
5616                         event.yDirection = 0;
5617                         break;
5618                 case OS.FLICKDIRECTION_DOWNLEFT:
5619                         event.xDirection = -1;
5620                         event.yDirection = 1;
5621                         break;
5622                 case OS.FLICKDIRECTION_DOWN:
5623                         event.xDirection = 0;
5624                         event.yDirection = 1;
5625                         break;
5626                 case OS.FLICKDIRECTION_DOWNRIGHT:
5627                         event.xDirection = 1;
5628                         event.yDirection = 1;
5629                         break;
5630         }
5631         event.setLocationInPixels(fPoint.x, fPoint.y);
5632         event.type = SWT.Gesture;
5633         event.detail = SWT.GESTURE_SWIPE;
5634         setInputState (event, SWT.Gesture);
5635         sendEvent (SWT.Gesture, event);
5636         return event.doit ? null : LRESULT.ONE;
5637 }
5638
5639 LRESULT WM_TOUCH (long wParam, long lParam) {
5640         LRESULT result = null;
5641         if (hooks (SWT.Touch) || filters (SWT.Touch)) {
5642                 int cInputs = OS.LOWORD (wParam);
5643                 long hHeap = OS.GetProcessHeap ();
5644                 long pInputs = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY,  cInputs * TOUCHINPUT.sizeof);
5645                 if (pInputs != 0) {
5646                         if (OS.GetTouchInputInfo (lParam, cInputs, pInputs, TOUCHINPUT.sizeof)) {
5647                                 TOUCHINPUT ti [] = new TOUCHINPUT [cInputs];
5648                                 for (int i = 0; i < cInputs; i++){
5649                                         ti [i] = new TOUCHINPUT ();
5650                                         OS.MoveMemory (ti [i], pInputs + i * TOUCHINPUT.sizeof, TOUCHINPUT.sizeof);
5651                                 }
5652                                 sendTouchEvent (ti);
5653                                 OS.CloseTouchInputHandle (lParam);
5654                                 result = LRESULT.ZERO;
5655                         }
5656                         OS.HeapFree (hHeap, 0, pInputs);
5657                 }
5658         }
5659         return result;
5660 }
5661
5662 LRESULT WM_TIMER (long wParam, long lParam) {
5663         if (wParam == Menu.ID_TOOLTIP_TIMER && activeMenu != null) {
5664                 OS.KillTimer (this.handle, Menu.ID_TOOLTIP_TIMER);
5665                 activeMenu.wmTimer (wParam, lParam);
5666         }
5667         return null;
5668 }
5669
5670 LRESULT WM_UNDO (long wParam, long lParam) {
5671         return null;
5672 }
5673
5674 LRESULT WM_UPDATEUISTATE (long wParam, long lParam) {
5675         return null;
5676 }
5677
5678 LRESULT WM_VSCROLL (long wParam, long lParam) {
5679         Control control = display.getControl (lParam);
5680         if (control == null) return null;
5681         return control.wmScrollChild (wParam, lParam);
5682 }
5683
5684 LRESULT WM_WINDOWPOSCHANGED (long wParam, long lParam) {
5685         try {
5686                 display.resizeCount++;
5687                 long code = callWindowProc (handle, OS.WM_WINDOWPOSCHANGED, wParam, lParam);
5688                 return code == 0 ? LRESULT.ZERO : new LRESULT (code);
5689         } finally {
5690                 --display.resizeCount;
5691         }
5692 }
5693
5694 LRESULT WM_WINDOWPOSCHANGING (long wParam, long lParam) {
5695         /*
5696         * Bug in Windows.  When WM_SETREDRAW is used to turn off drawing
5697         * for a control and the control is moved or resized, Windows does
5698         * not redraw the area where the control once was in the parent.
5699         * The fix is to detect this case and redraw the area.
5700         */
5701         if (!getDrawing()) {
5702                 Shell shell = getShell ();
5703                 if (shell != this) {
5704                         WINDOWPOS lpwp = new WINDOWPOS ();
5705                         OS.MoveMemory (lpwp, lParam, WINDOWPOS.sizeof);
5706                         if ((lpwp.flags & OS.SWP_NOMOVE) == 0 || (lpwp.flags & OS.SWP_NOSIZE) == 0) {
5707                                 RECT rect = new RECT ();
5708                                 OS.GetWindowRect (topHandle (), rect);
5709                                 int width = rect.right - rect.left;
5710                                 int height = rect.bottom - rect.top;
5711                                 if (width != 0 && height != 0) {
5712                                         long hwndParent = parent == null ? 0 : parent.handle;
5713                                         OS.MapWindowPoints (0, hwndParent, rect, 2);
5714                                         long rgn1 = OS.CreateRectRgn (rect.left, rect.top, rect.right, rect.bottom);
5715                                         long rgn2 = OS.CreateRectRgn (lpwp.x, lpwp.y, lpwp.x + lpwp.cx, lpwp.y + lpwp.cy);
5716                                         OS.CombineRgn (rgn1, rgn1, rgn2, OS.RGN_DIFF);
5717                                         int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
5718                                         OS.RedrawWindow (hwndParent, null, rgn1, flags);
5719                                         OS.DeleteObject (rgn1);
5720                                         OS.DeleteObject (rgn2);
5721                                 }
5722                         }
5723                 }
5724         }
5725         return null;
5726 }
5727
5728 LRESULT WM_XBUTTONDBLCLK (long wParam, long lParam) {
5729         return wmXButtonDblClk (handle, wParam, lParam);
5730 }
5731
5732 LRESULT WM_XBUTTONDOWN (long wParam, long lParam) {
5733         return wmXButtonDown (handle, wParam, lParam);
5734 }
5735
5736 LRESULT WM_XBUTTONUP (long wParam, long lParam) {
5737         return wmXButtonUp (handle, wParam, lParam);
5738 }
5739
5740 LRESULT wmColorChild (long wParam, long lParam) {
5741         Control control = findBackgroundControl ();
5742         if (control == null) {
5743                 if ((state & THEME_BACKGROUND) != 0) {
5744                         if (OS.IsAppThemed ()) {
5745                                 control = findThemeControl ();
5746                                 if (control != null) {
5747                                         RECT rect = new RECT ();
5748                                         OS.GetClientRect (handle, rect);
5749                                         OS.SetTextColor (wParam, getForegroundPixel ());
5750                                         OS.SetBkColor (wParam, getBackgroundPixel ());
5751                                         fillThemeBackground (wParam, control, rect);
5752                                         OS.SetBkMode (wParam, OS.TRANSPARENT);
5753                                         return new LRESULT (OS.GetStockObject (OS.NULL_BRUSH));
5754                                 }
5755                         }
5756                 }
5757                 if (foreground == -1) return null;
5758         }
5759         if (control == null) control = this;
5760         int forePixel = getForegroundPixel ();
5761         int backPixel = control.getBackgroundPixel ();
5762         OS.SetTextColor (wParam, forePixel);
5763         OS.SetBkColor (wParam, backPixel);
5764         if (control.backgroundImage != null) {
5765                 RECT rect = new RECT ();
5766                 OS.GetClientRect (handle, rect);
5767                 long hwnd = control.handle;
5768                 long hBitmap = control.backgroundImage.handle;
5769                 OS.MapWindowPoints (handle, hwnd, rect, 2);
5770                 POINT lpPoint = new POINT ();
5771                 OS.GetWindowOrgEx (wParam, lpPoint);
5772                 OS.SetBrushOrgEx (wParam, -rect.left - lpPoint.x, -rect.top - lpPoint.y, lpPoint);
5773                 long hBrush = findBrush (hBitmap, OS.BS_PATTERN);
5774                 if ((state & DRAW_BACKGROUND) != 0) {
5775                         long hOldBrush = OS.SelectObject (wParam, hBrush);
5776                         OS.MapWindowPoints (hwnd, handle, rect, 2);
5777                         OS.PatBlt (wParam, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY);
5778                         OS.SelectObject (wParam, hOldBrush);
5779                 }
5780                 OS.SetBkMode (wParam, OS.TRANSPARENT);
5781                 return new LRESULT (hBrush);
5782         }
5783         long hBrush = findBrush (backPixel, OS.BS_SOLID);
5784         if ((state & DRAW_BACKGROUND) != 0) {
5785                 RECT rect = new RECT ();
5786                 OS.GetClientRect (handle, rect);
5787                 long hOldBrush = OS.SelectObject (wParam, hBrush);
5788                 OS.PatBlt (wParam, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY);
5789                 OS.SelectObject (wParam, hOldBrush);
5790         }
5791         return new LRESULT (hBrush);
5792 }
5793
5794 LRESULT wmCommandChild (long wParam, long lParam) {
5795         return null;
5796 }
5797
5798 LRESULT wmDrawChild (long wParam, long lParam) {
5799         return null;
5800 }
5801
5802 LRESULT wmMeasureChild (long wParam, long lParam) {
5803         return null;
5804 }
5805
5806 LRESULT wmNotify (NMHDR hdr, long wParam, long lParam) {
5807         Control control = display.getControl (hdr.hwndFrom);
5808         if (control == null) return null;
5809         return control.wmNotifyChild (hdr, wParam, lParam);
5810 }
5811
5812 LRESULT wmNotifyChild (NMHDR hdr, long wParam, long lParam) {
5813         return null;
5814 }
5815
5816 LRESULT wmScrollChild (long wParam, long lParam) {
5817         return null;
5818 }
5819
5820 }
5821