1 /*******************************************************************************
2 * Copyright (c) 2000, 2019 IBM Corporation and others.
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/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.widgets;
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.graphics.*;
19 import org.eclipse.swt.internal.*;
20 import org.eclipse.swt.internal.win32.*;
23 * Instances of this class provide the appearance and
24 * behavior of <code>Shells</code>, but are not top
25 * level shells or dialogs. Class <code>Shell</code>
26 * shares a significant amount of code with this class,
29 * IMPORTANT: This class was intended to be abstract and
30 * should <em>never</em> be referenced or instantiated.
31 * Instead, the class <code>Shell</code> should be used.
34 * Instances are always displayed in one of the maximized,
35 * minimized or normal states:
39 * When an instance is marked as <em>maximized</em>, the
40 * window manager will typically resize it to fill the
41 * entire visible area of the display, and the instance
42 * is usually put in a state where it can not be resized
43 * (even if it has style <code>RESIZE</code>) until it is
44 * no longer maximized.
46 * When an instance is in the <em>normal</em> state (neither
47 * maximized or minimized), its appearance is controlled by
48 * the style constants which were specified when it was created
49 * and the restrictions of the window manager (see below).
51 * When an instance has been marked as <em>minimized</em>,
52 * its contents (client area) will usually not be visible,
53 * and depending on the window manager, it may be
54 * "iconified" (that is, replaced on the desktop by a small
55 * simplified representation of itself), relocated to a
56 * distinguished area of the screen, or hidden. Combinations
57 * of these changes are also possible.
60 * Note: The styles supported by this class must be treated
61 * as <em>HINT</em>s, since the window manager for the
62 * desktop on which the instance is visible has ultimate
63 * control over the appearance and behavior of decorations.
64 * For example, some window managers only support resizable
65 * windows and will always assume the RESIZE style, even if
68 * <dt><b>Styles:</b></dt>
69 * <dd>BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP, TOOL</dd>
70 * <dt><b>Events:</b></dt>
73 * Class <code>SWT</code> provides two "convenience constants"
74 * for the most commonly required style combinations:
76 * <dt><code>SHELL_TRIM</code></dt>
78 * the result of combining the constants which are required
79 * to produce a typical application top level shell: (that
80 * is, <code>CLOSE | TITLE | MIN | MAX | RESIZE</code>)
82 * <dt><code>DIALOG_TRIM</code></dt>
84 * the result of combining the constants which are required
85 * to produce a typical application dialog shell: (that
86 * is, <code>TITLE | CLOSE | BORDER</code>)
90 * IMPORTANT: This class is intended to be subclassed <em>only</em>
91 * within the SWT implementation.
98 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
99 * @noextend This class is not intended to be subclassed by clients.
101 public class Decorations extends Canvas {
102 Image image, smallImage, largeImage;
107 Button defaultButton, saveDefault;
110 boolean moved, resized, opened;
111 int oldX = OS.CW_USEDEFAULT, oldY = OS.CW_USEDEFAULT;
112 int oldWidth = OS.CW_USEDEFAULT, oldHeight = OS.CW_USEDEFAULT;
113 RECT maxRect = new RECT();
116 * Prevents uninitialized instances from being created outside the package.
122 * Constructs a new instance of this class given its parent
123 * and a style value describing its behavior and appearance.
125 * The style value is either one of the style constants defined in
126 * class <code>SWT</code> which is applicable to instances of this
127 * class, or must be built by <em>bitwise OR</em>'ing together
128 * (that is, using the <code>int</code> "|" operator) two or more
129 * of those <code>SWT</code> style constants. The class description
130 * lists the style constants that are applicable to the class.
131 * Style bits are also inherited from superclasses.
134 * @param parent a composite control which will be the parent of the new instance (cannot be null)
135 * @param style the style of control to construct
137 * @exception IllegalArgumentException <ul>
138 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
140 * @exception SWTException <ul>
141 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
142 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
153 * @see SWT#SHELL_TRIM
154 * @see SWT#DIALOG_TRIM
157 * @see Widget#checkSubclass
158 * @see Widget#getStyle
160 public Decorations (Composite parent, int style) {
161 super (parent, checkStyle (style));
164 void _setMaximized (boolean maximized) {
165 swFlags = maximized ? OS.SW_SHOWMAXIMIZED : OS.SW_RESTORE;
166 if (!OS.IsWindowVisible (handle)) return;
167 if (maximized == OS.IsZoomed (handle)) return;
168 OS.ShowWindow (handle, swFlags);
169 OS.UpdateWindow (handle);
172 void _setMinimized (boolean minimized) {
173 swFlags = minimized ? OS.SW_SHOWMINNOACTIVE : OS.SW_RESTORE;
174 if (!OS.IsWindowVisible (handle)) return;
175 if (minimized == OS.IsIconic (handle)) return;
177 if (flags == OS.SW_SHOWMINNOACTIVE && handle == OS.GetActiveWindow ()) {
178 flags = OS.SW_MINIMIZE;
180 OS.ShowWindow (handle, flags);
181 OS.UpdateWindow (handle);
184 void addMenu (Menu menu) {
185 if (menus == null) menus = new Menu [4];
186 for (int i=0; i<menus.length; i++) {
187 if (menus [i] == null) {
192 Menu [] newMenus = new Menu [menus.length + 4];
193 newMenus [menus.length] = menu;
194 System.arraycopy (menus, 0, newMenus, 0, menus.length);
200 * This code is intentionally commented. On some platforms,
201 * the ON_TOP style creates a shell that will stay on top
202 * of every other shell on the desktop. Using SetWindowPos ()
203 * with HWND_TOP caused problems on Windows 98 so this code is
204 * commented out until this functionality is specified and
205 * the problems are fixed.
207 // if ((style & SWT.ON_TOP) != 0) {
208 // int flags = OS.SWP_NOSIZE | OS.SWP_NOMOVE | OS.SWP_NOACTIVATE;
209 // OS.SetWindowPos (handle, OS.HWND_TOP, 0, 0, 0, 0, flags);
211 OS.BringWindowToTop (handle);
212 // widget could be disposed at this point
216 static int checkStyle (int style) {
217 if ((style & SWT.NO_TRIM) != 0) {
218 style &= ~(SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.BORDER);
219 } else if ((style & SWT.NO_MOVE) != 0) {
222 if ((style & (SWT.MENU | SWT.MIN | SWT.MAX | SWT.CLOSE)) != 0) {
227 * If either WS_MINIMIZEBOX or WS_MAXIMIZEBOX are set,
228 * we must also set WS_SYSMENU or the buttons will not
231 if ((style & (SWT.MIN | SWT.MAX)) != 0) style |= SWT.CLOSE;
234 * Both WS_SYSMENU and WS_CAPTION must be set in order
235 * to for the system menu to appear.
237 if ((style & SWT.CLOSE) != 0) style |= SWT.TITLE;
240 * Bug in Windows. The WS_CAPTION style must be
241 * set when the window is resizable or it does not
245 * This code is intentionally commented. It seems
246 * that this problem originally in Windows 3.11,
247 * has been fixed in later versions. Because the
248 * exact nature of the drawing problem is unknown,
249 * keep the commented code around in case it comes
252 // if ((style & SWT.RESIZE) != 0) style |= SWT.TITLE;
258 void checkBorder () {
262 void checkComposited (Composite parent) {
267 void checkOpened () {
268 if (!opened) resized = false;
272 protected void checkSubclass () {
273 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
277 long callWindowProc (long hwnd, int msg, long wParam, long lParam) {
278 if (handle == 0) return 0;
279 return OS.DefMDIChildProc (hwnd, msg, wParam, lParam);
282 void closeWidget () {
283 Event event = new Event ();
284 sendEvent (SWT.Close, event);
285 if (event.doit && !isDisposed ()) dispose ();
288 int compare (ImageData data1, ImageData data2, int width, int height, int depth) {
289 int value1 = Math.abs (data1.width - width), value2 = Math.abs (data2.width - width);
290 if (value1 == value2) {
291 int transparent1 = data1.getTransparencyType ();
292 int transparent2 = data2.getTransparencyType ();
293 if (transparent1 == transparent2) {
294 if (data1.depth == data2.depth) return 0;
295 return data1.depth > data2.depth && data1.depth <= depth ? -1 : 1;
297 if (transparent1 == SWT.TRANSPARENCY_ALPHA) return -1;
298 if (transparent2 == SWT.TRANSPARENCY_ALPHA) return 1;
299 if (transparent1 == SWT.TRANSPARENCY_MASK) return -1;
300 if (transparent2 == SWT.TRANSPARENCY_MASK) return 1;
301 if (transparent1 == SWT.TRANSPARENCY_PIXEL) return -1;
302 if (transparent2 == SWT.TRANSPARENCY_PIXEL) return 1;
305 return value1 < value2 ? -1 : 1;
309 Widget computeTabGroup () {
314 Control computeTabRoot () {
318 @Override Rectangle computeTrimInPixels (int x, int y, int width, int height) {
321 /* Get the size of the trimmings */
322 RECT rect = new RECT ();
323 OS.SetRect (rect, x, y, x + width, y + height);
324 int bits1 = OS.GetWindowLong (handle, OS.GWL_STYLE);
325 int bits2 = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
326 boolean hasMenu = OS.GetMenu (handle) != 0;
327 OS.AdjustWindowRectEx (rect, bits1, hasMenu, bits2);
329 /* Get the size of the scroll bars */
330 if (horizontalBar != null) rect.bottom += OS.GetSystemMetrics (OS.SM_CYHSCROLL);
331 if (verticalBar != null) rect.right += OS.GetSystemMetrics (OS.SM_CXVSCROLL);
333 /* Compute the height of the menu bar */
335 RECT testRect = new RECT ();
336 OS.SetRect (testRect, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
337 OS.SendMessage (handle, OS.WM_NCCALCSIZE, 0, testRect);
338 while ((testRect.bottom - testRect.top) < height) {
339 if (testRect.bottom - testRect.top == 0) break;
340 rect.top -= OS.GetSystemMetrics (OS.SM_CYMENU) - OS.GetSystemMetrics (OS.SM_CYBORDER);
341 OS.SetRect (testRect, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
342 OS.SendMessage (handle, OS.WM_NCCALCSIZE, 0, testRect);
345 return new Rectangle (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
348 void createAccelerators () {
350 MenuItem [] items = display.items;
351 if (menuBar == null || items == null) {
354 ACCEL accel = new ACCEL ();
355 byte [] buffer1 = new byte [ACCEL.sizeof];
356 byte [] buffer2 = new byte [items.length * ACCEL.sizeof];
357 for (int i=0; i<items.length; i++) {
358 MenuItem item = items [i];
359 if (item != null && item.accelerator != 0) {
360 Menu menu = item.parent;
361 if (menu.parent == this) {
362 while (menu != null && menu != menuBar) {
363 menu = menu.getParentMenu ();
365 if (menu == menuBar && item.fillAccel (accel)) {
366 OS.MoveMemory (buffer1, accel, ACCEL.sizeof);
367 System.arraycopy (buffer1, 0, buffer2, nAccel * ACCEL.sizeof, ACCEL.sizeof);
373 if (nAccel != 0) hAccel = OS.CreateAcceleratorTable (buffer2, nAccel);
377 void createHandle () {
378 super.createHandle ();
379 if (parent != null || ((style & SWT.TOOL) != 0)) {
386 void createWidget () {
387 super.createWidget ();
388 swFlags = OS.SW_SHOWNOACTIVATE;
392 void destroyAccelerators () {
393 if (hAccel != 0 && hAccel != -1) OS.DestroyAcceleratorTable (hAccel);
398 public void dispose () {
399 if (isDisposed()) return;
400 if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
401 if (!(this instanceof Shell)) {
402 if (!traverseDecorations (true)) {
403 Shell shell = getShell ();
411 Menu findMenu (long hMenu) {
412 if (menus == null) return null;
413 for (int i=0; i<menus.length; i++) {
414 Menu menu = menus [i];
415 if (menu != null && hMenu == menu.handle) return menu;
420 void fixDecorations (Decorations newDecorations, Control control, Menu [] menus) {
421 if (this == newDecorations) return;
422 if (control == savedFocus) savedFocus = null;
423 if (control == defaultButton) defaultButton = null;
424 if (control == saveDefault) saveDefault = null;
425 if (menus == null) return;
426 Menu menu = control.menu;
429 while (index <menus.length) {
430 if (menus [index] == menu) {
431 control.setMenu (null);
436 menu.fixMenus (newDecorations);
437 destroyAccelerators ();
438 newDecorations.destroyAccelerators ();
442 @Override Rectangle getBoundsInPixels () {
444 if (OS.IsIconic (handle)) {
445 WINDOWPLACEMENT lpwndpl = new WINDOWPLACEMENT ();
446 lpwndpl.length = WINDOWPLACEMENT.sizeof;
447 OS.GetWindowPlacement (handle, lpwndpl);
448 if ((lpwndpl.flags & OS.WPF_RESTORETOMAXIMIZED) != 0) {
449 int width = maxRect.right - maxRect.left;
450 int height = maxRect.bottom - maxRect.top;
451 return new Rectangle (maxRect.left, maxRect.top, width, height);
453 int width = lpwndpl.right - lpwndpl.left;
454 int height = lpwndpl.bottom - lpwndpl.top;
455 return new Rectangle (lpwndpl.left, lpwndpl.top, width, height);
457 return super.getBoundsInPixels ();
460 @Override Rectangle getClientAreaInPixels () {
462 if (OS.IsIconic (handle)) {
463 WINDOWPLACEMENT lpwndpl = new WINDOWPLACEMENT ();
464 lpwndpl.length = WINDOWPLACEMENT.sizeof;
465 OS.GetWindowPlacement (handle, lpwndpl);
466 if ((lpwndpl.flags & OS.WPF_RESTORETOMAXIMIZED) != 0) {
467 return new Rectangle (0, 0, oldWidth, oldHeight);
469 int width = lpwndpl.right - lpwndpl.left;
470 int height = lpwndpl.bottom - lpwndpl.top;
472 * Feature in Windows. For some reason WM_NCCALCSIZE does
473 * not compute the client area when the window is minimized.
474 * The fix is to compute it using AdjustWindowRectEx() and
475 * GetSystemMetrics().
477 * NOTE: This code fails to compute the correct client area
478 * for a minimized window where the menu bar would wrap were
479 * the window restored. There is no fix for this problem at
482 if (horizontalBar != null) width -= OS.GetSystemMetrics (OS.SM_CYHSCROLL);
483 if (verticalBar != null) height -= OS.GetSystemMetrics (OS.SM_CXVSCROLL);
484 RECT rect = new RECT ();
485 int bits1 = OS.GetWindowLong (handle, OS.GWL_STYLE);
486 int bits2 = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
487 boolean hasMenu = OS.GetMenu (handle) != 0;
488 OS.AdjustWindowRectEx (rect, bits1, hasMenu, bits2);
489 width = Math.max (0, width - (rect.right - rect.left));
490 height = Math.max (0, height - (rect.bottom - rect.top));
491 return new Rectangle (0, 0, width, height);
493 return super.getClientAreaInPixels ();
497 * Returns the receiver's default button if one had
498 * previously been set, otherwise returns null.
500 * @return the default button or null
502 * @exception SWTException <ul>
503 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
504 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
507 * @see #setDefaultButton(Button)
509 public Button getDefaultButton () {
511 if (defaultButton != null && defaultButton.isDisposed ()) return null;
512 return defaultButton;
516 * Returns the receiver's image if it had previously been
517 * set using <code>setImage()</code>. The image is typically
518 * displayed by the window manager when the instance is
519 * marked as iconified, and may also be displayed somewhere
520 * in the trim when the instance is in normal or maximized
523 * Note: This method will return null if called before
524 * <code>setImage()</code> is called. It does not provide
525 * access to a window manager provided, "default" image
526 * even if one exists.
531 * @exception SWTException <ul>
532 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
533 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
536 public Image getImage () {
542 * Returns the receiver's images if they had previously been
543 * set using <code>setImages()</code>. Images are typically
544 * displayed by the window manager when the instance is
545 * marked as iconified, and may also be displayed somewhere
546 * in the trim when the instance is in normal or maximized
547 * states. Depending where the icon is displayed, the platform
548 * chooses the icon with the "best" attributes. It is expected
549 * that the array will contain the same icon rendered at different
550 * sizes, with different depth and transparency attributes.
553 * Note: This method will return an empty array if called before
554 * <code>setImages()</code> is called. It does not provide
555 * access to a window manager provided, "default" image
556 * even if one exists.
561 * @exception SWTException <ul>
562 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
563 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
568 public Image [] getImages () {
570 if (images == null) return new Image [0];
571 Image [] result = new Image [images.length];
572 System.arraycopy (images, 0, result, 0, images.length);
576 @Override Point getLocationInPixels () {
578 if (OS.IsIconic (handle)) {
579 WINDOWPLACEMENT lpwndpl = new WINDOWPLACEMENT ();
580 lpwndpl.length = WINDOWPLACEMENT.sizeof;
581 OS.GetWindowPlacement (handle, lpwndpl);
582 if ((lpwndpl.flags & OS.WPF_RESTORETOMAXIMIZED) != 0) {
583 return new Point (maxRect.left, maxRect.top);
585 return new Point (lpwndpl.left, lpwndpl.top);
587 return super.getLocationInPixels ();
591 * Returns <code>true</code> if the receiver is currently
592 * maximized, and false otherwise.
595 * @return the maximized state
597 * @exception SWTException <ul>
598 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
599 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
604 public boolean getMaximized () {
606 if (OS.IsWindowVisible (handle)) return OS.IsZoomed (handle);
607 return swFlags == OS.SW_SHOWMAXIMIZED;
611 * Returns the receiver's menu bar if one had previously
612 * been set, otherwise returns null.
614 * @return the menu bar or null
616 * @exception SWTException <ul>
617 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
618 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
621 public Menu getMenuBar () {
627 * Returns <code>true</code> if the receiver is currently
628 * minimized, and false otherwise.
631 * @return the minimized state
633 * @exception SWTException <ul>
634 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
635 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
640 public boolean getMinimized () {
642 if (OS.IsWindowVisible (handle)) return OS.IsIconic (handle);
643 return swFlags == OS.SW_SHOWMINNOACTIVE;
647 String getNameText () {
651 @Override Point getSizeInPixels () {
653 if (OS.IsIconic (handle)) {
654 WINDOWPLACEMENT lpwndpl = new WINDOWPLACEMENT ();
655 lpwndpl.length = WINDOWPLACEMENT.sizeof;
656 OS.GetWindowPlacement (handle, lpwndpl);
657 if ((lpwndpl.flags & OS.WPF_RESTORETOMAXIMIZED) != 0) {
658 int width = maxRect.right - maxRect.left;
659 int height = maxRect.bottom - maxRect.top;
660 return new Point (width, height);
662 int width = lpwndpl.right - lpwndpl.left;
663 int height = lpwndpl.bottom - lpwndpl.top;
664 return new Point (width, height);
666 return super.getSizeInPixels ();
670 * Returns the receiver's text, which is the string that the
671 * window manager will typically display as the receiver's
672 * <em>title</em>. If the text has not previously been set,
673 * returns an empty string.
677 * @exception SWTException <ul>
678 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
679 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
682 public String getText () {
684 int length = OS.GetWindowTextLength (handle);
685 if (length == 0) return "";
686 char [] buffer = new char [length + 1];
687 OS.GetWindowText (handle, buffer, length + 1);
688 return new String (buffer, 0, length);
692 public boolean isReparentable () {
695 * Feature in Windows. Calling SetParent() for a shell causes
696 * a kind of fake MDI to happen. It doesn't work well on Windows
697 * and is not supported on the other platforms. The fix is to
698 * disallow the SetParent().
704 boolean isTabGroup () {
706 * Can't test WS_TAB bits because they are the same as WS_MAXIMIZEBOX.
712 boolean isTabItem () {
714 * Can't test WS_TAB bits because they are the same as WS_MAXIMIZEBOX.
720 Decorations menuShell () {
725 void releaseChildren (boolean destroy) {
726 if (menuBar != null) {
727 menuBar.release (false);
730 super.releaseChildren (destroy);
732 for (int i=0; i<menus.length; i++) {
733 Menu menu = menus [i];
734 if (menu != null && !menu.isDisposed ()) {
743 void releaseWidget () {
744 super.releaseWidget ();
745 if (smallImage != null) smallImage.dispose ();
746 if (largeImage != null) largeImage.dispose ();
747 smallImage = largeImage = image = null;
750 defaultButton = saveDefault = null;
751 if (hAccel != 0 && hAccel != -1) OS.DestroyAcceleratorTable (hAccel);
755 void removeMenu (Menu menu) {
756 if (menus == null) return;
757 for (int i=0; i<menus.length; i++) {
758 if (menus [i] == menu) {
766 void reskinChildren (int flags) {
767 if (menuBar != null) menuBar.reskin (flags);
769 for (int i=0; i<menus.length; i++) {
770 Menu menu = menus [i];
771 if (menu != null) menu.reskin (flags);
774 super.reskinChildren (flags);
777 boolean restoreFocus () {
778 if (display.ignoreRestoreFocus) return true;
779 if (savedFocus != null && savedFocus.isDisposed ()) savedFocus = null;
780 if (savedFocus != null && savedFocus.setFocus ()) return true;
785 Control control = display._getFocusControl ();
786 if (control != null && control != this && this == control.menuShell ()) {
787 setSavedFocus (control);
792 void setBoundsInPixels (int x, int y, int width, int height, int flags, boolean defer) {
793 swFlags = OS.SW_SHOWNOACTIVATE;
794 if (OS.IsIconic (handle)) {
795 setPlacement (x, y, width, height, flags);
799 RECT rect = new RECT ();
800 OS.GetWindowRect (handle, rect);
801 boolean sameOrigin = true;
802 if ((OS.SWP_NOMOVE & flags) == 0) {
803 sameOrigin = rect.left == x && rect.top == y;
804 if (!sameOrigin) moved = true;
806 boolean sameExtent = true;
807 if ((OS.SWP_NOSIZE & flags) == 0) {
808 sameExtent = rect.right - rect.left == width && rect.bottom - rect.top == height;
809 if (!sameExtent) resized = true;
811 if (OS.IsZoomed (handle)) {
812 if (sameOrigin && sameExtent) return;
813 setPlacement (x, y, width, height, flags);
814 _setMaximized (false);
817 super.setBoundsInPixels (x, y, width, height, flags, defer);
821 * If the argument is not null, sets the receiver's default
822 * button to the argument, and if the argument is null, sets
823 * the receiver's default button to the first button which
824 * was set as the receiver's default button (called the
825 * <em>saved default button</em>). If no default button had
826 * previously been set, or the saved default button was
827 * disposed, the receiver's default button will be set to
830 * The default button is the button that is selected when
831 * the receiver is active and the user presses ENTER.
834 * @param button the new default button
836 * @exception IllegalArgumentException <ul>
837 * <li>ERROR_INVALID_ARGUMENT - if the button has been disposed</li>
838 * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
840 * @exception SWTException <ul>
841 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
842 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
845 public void setDefaultButton (Button button) {
847 if (button != null) {
848 if (button.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
849 if (button.menuShell () != this) error(SWT.ERROR_INVALID_PARENT);
851 setDefaultButton (button, true);
854 void setDefaultButton (Button button, boolean save) {
855 if (button == null) {
856 if (defaultButton == saveDefault) {
857 if (save) saveDefault = null;
861 if ((button.style & SWT.PUSH) == 0) return;
862 if (button == defaultButton) {
863 if (save) saveDefault = defaultButton;
867 if (defaultButton != null) {
868 if (!defaultButton.isDisposed ()) defaultButton.setDefault (false);
870 if ((defaultButton = button) == null) defaultButton = saveDefault;
871 if (defaultButton != null) {
872 if (!defaultButton.isDisposed ()) defaultButton.setDefault (true);
874 if (save) saveDefault = defaultButton;
875 if (saveDefault != null && saveDefault.isDisposed ()) saveDefault = null;
879 * Sets the receiver's image to the argument, which may
880 * be null. The image is typically displayed by the window
881 * manager when the instance is marked as iconified, and
882 * may also be displayed somewhere in the trim when the
883 * instance is in normal or maximized states.
885 * @param image the new image (or null)
887 * @exception IllegalArgumentException <ul>
888 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
890 * @exception SWTException <ul>
891 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
892 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
895 public void setImage (Image image) {
897 if (image != null && image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
899 setImages (image, null);
902 void setImages (Image image, Image [] images) {
903 if (smallImage != null) smallImage.dispose ();
904 if (largeImage != null) largeImage.dispose ();
905 smallImage = largeImage = null;
906 long hSmallIcon = 0, hLargeIcon = 0;
907 Image smallIcon = null, largeIcon = null;
909 smallIcon = largeIcon = image;
911 if (images != null && images.length > 0) {
912 int depth = display.getIconDepth ();
913 ImageData [] datas = null;
914 if (images.length > 1) {
915 Image [] bestImages = new Image [images.length];
916 System.arraycopy (images, 0, bestImages, 0, images.length);
917 datas = new ImageData [images.length];
918 for (int i=0; i<datas.length; i++) {
919 datas [i] = images [i].getImageData (DPIUtil.getDeviceZoom ());
922 sort (images, datas, OS.GetSystemMetrics (OS.SM_CXSMICON), OS.GetSystemMetrics (OS.SM_CYSMICON), depth);
924 smallIcon = images [0];
925 if (images.length > 1) {
926 sort (images, datas, OS.GetSystemMetrics (OS.SM_CXICON), OS.GetSystemMetrics (OS.SM_CYICON), depth);
928 largeIcon = images [0];
931 if (smallIcon != null) {
932 switch (smallIcon.type) {
934 smallImage = Display.createIcon (smallIcon);
935 hSmallIcon = smallImage.handle;
938 hSmallIcon = smallIcon.handle;
942 OS.SendMessage (handle, OS.WM_SETICON, OS.ICON_SMALL, hSmallIcon);
943 if (largeIcon != null) {
944 switch (largeIcon.type) {
946 largeImage = Display.createIcon (largeIcon);
947 hLargeIcon = largeImage.handle;
950 hLargeIcon = largeIcon.handle;
954 OS.SendMessage (handle, OS.WM_SETICON, OS.ICON_BIG, hLargeIcon);
957 * Bug in Windows. When WM_SETICON is used to remove an
958 * icon from the window trimmings for a window with the
959 * extended style bits WS_EX_DLGMODALFRAME, the window
960 * trimmings do not redraw to hide the previous icon.
961 * The fix is to force a redraw.
963 if (hSmallIcon == 0 && hLargeIcon == 0 && (style & SWT.BORDER) != 0) {
964 int flags = OS.RDW_FRAME | OS.RDW_INVALIDATE;
965 OS.RedrawWindow (handle, null, 0, flags);
970 * Sets the receiver's images to the argument, which may
971 * be an empty array. Images are typically displayed by the
972 * window manager when the instance is marked as iconified,
973 * and may also be displayed somewhere in the trim when the
974 * instance is in normal or maximized states. Depending where
975 * the icon is displayed, the platform chooses the icon with
976 * the "best" attributes. It is expected that the array will
977 * contain the same icon rendered at different sizes, with
978 * different depth and transparency attributes.
980 * @param images the new image array
982 * @exception IllegalArgumentException <ul>
983 * <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
984 * <li>ERROR_INVALID_ARGUMENT - if one of the images is null or has been disposed</li>
986 * @exception SWTException <ul>
987 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
988 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
993 public void setImages (Image [] images) {
995 if (images == null) error (SWT.ERROR_INVALID_ARGUMENT);
996 for (int i = 0; i < images.length; i++) {
997 if (images [i] == null || images [i].isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
999 this.images = images;
1000 setImages (null, images);
1004 * Sets the maximized state of the receiver.
1005 * If the argument is <code>true</code> causes the receiver
1006 * to switch to the maximized state, and if the argument is
1007 * <code>false</code> and the receiver was previously maximized,
1008 * causes the receiver to switch back to either the minimized
1011 * Note: The result of intermixing calls to <code>setMaximized(true)</code>
1012 * and <code>setMinimized(true)</code> will vary by platform. Typically,
1013 * the behavior will match the platform user's expectations, but not
1014 * always. This should be avoided if possible.
1017 * @param maximized the new maximized state
1019 * @exception SWTException <ul>
1020 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1021 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1024 * @see #setMinimized
1026 public void setMaximized (boolean maximized) {
1028 Display.lpStartupInfo = null;
1029 _setMaximized (maximized);
1033 * Sets the receiver's menu bar to the argument, which
1036 * @param menu the new menu bar
1038 * @exception IllegalArgumentException <ul>
1039 * <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>
1040 * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
1042 * @exception SWTException <ul>
1043 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1044 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1047 public void setMenuBar (Menu menu) {
1049 if (menuBar == menu) return;
1051 if (menu.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
1052 if ((menu.style & SWT.BAR) == 0) error (SWT.ERROR_MENU_NOT_BAR);
1053 if (menu.parent != this) error (SWT.ERROR_INVALID_PARENT);
1055 if (menu != null) display.removeBar (menu);
1057 long hMenu = menuBar != null ? menuBar.handle: 0;
1058 OS.SetMenu (handle, hMenu);
1059 destroyAccelerators ();
1063 * Sets the minimized stated of the receiver.
1064 * If the argument is <code>true</code> causes the receiver
1065 * to switch to the minimized state, and if the argument is
1066 * <code>false</code> and the receiver was previously minimized,
1067 * causes the receiver to switch back to either the maximized
1070 * Note: The result of intermixing calls to <code>setMaximized(true)</code>
1071 * and <code>setMinimized(true)</code> will vary by platform. Typically,
1072 * the behavior will match the platform user's expectations, but not
1073 * always. This should be avoided if possible.
1076 * @param minimized the new maximized state
1078 * @exception SWTException <ul>
1079 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1080 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1083 * @see #setMaximized
1085 public void setMinimized (boolean minimized) {
1087 Display.lpStartupInfo = null;
1088 _setMinimized (minimized);
1092 public void setOrientation (int orientation) {
1093 super.setOrientation (orientation);
1094 if (menus != null) {
1095 for (int i=0; i<menus.length; i++) {
1096 Menu menu = menus [i];
1097 if (menu != null && !menu.isDisposed () && (menu.getStyle () & SWT.POP_UP) != 0) {
1098 menu._setOrientation (menu.getOrientation ());
1106 * In order for an MDI child window to support
1107 * a menu bar, setParent () is needed to reset
1108 * the parent. Otherwise, the MDI child window
1109 * will appear as a separate shell. This is an
1110 * undocumented and possibly dangerous Windows
1113 long hwndParent = parent.handle;
1114 display.lockActiveWindow = true;
1115 OS.SetParent (handle, hwndParent);
1116 if (!OS.IsWindowVisible (hwndParent)) {
1117 OS.ShowWindow (handle, OS.SW_SHOWNA);
1119 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
1120 bits &= ~OS.WS_CHILD;
1121 OS.SetWindowLong (handle, OS.GWL_STYLE, bits | OS.WS_POPUP);
1122 OS.SetWindowLongPtr (handle, OS.GWLP_ID, 0);
1123 int flags = OS.SWP_NOSIZE | OS.SWP_NOMOVE | OS.SWP_NOACTIVATE;
1124 OS.SetWindowPos (handle, OS.HWND_BOTTOM, 0, 0, 0, 0, flags);
1125 display.lockActiveWindow = false;
1128 void setPlacement (int x, int y, int width, int height, int flags) {
1129 WINDOWPLACEMENT lpwndpl = new WINDOWPLACEMENT ();
1130 lpwndpl.length = WINDOWPLACEMENT.sizeof;
1131 OS.GetWindowPlacement (handle, lpwndpl);
1132 lpwndpl.showCmd = OS.SW_SHOWNA;
1133 if (OS.IsIconic (handle)) {
1134 lpwndpl.showCmd = OS.SW_SHOWMINNOACTIVE;
1136 if (OS.IsZoomed (handle)) {
1137 lpwndpl.showCmd = OS.SW_SHOWMAXIMIZED;
1140 boolean sameOrigin = true;
1141 if ((flags & OS.SWP_NOMOVE) == 0) {
1142 sameOrigin = lpwndpl.left != x || lpwndpl.top != y;
1143 lpwndpl.right = x + (lpwndpl.right - lpwndpl.left);
1144 lpwndpl.bottom = y + (lpwndpl.bottom - lpwndpl.top);
1148 boolean sameExtent = true;
1149 if ((flags & OS.SWP_NOSIZE) == 0) {
1150 sameExtent = lpwndpl.right - lpwndpl.left != width || lpwndpl.bottom - lpwndpl.top != height;
1151 lpwndpl.right = lpwndpl.left + width;
1152 lpwndpl.bottom = lpwndpl.top + height;
1154 OS.SetWindowPlacement (handle, lpwndpl);
1155 if (OS.IsIconic (handle)) {
1158 Point location = getLocationInPixels ();
1161 sendEvent (SWT.Move);
1162 if (isDisposed ()) return;
1166 Rectangle rect = getClientAreaInPixels ();
1167 oldWidth = rect.width;
1168 oldHeight = rect.height;
1169 sendEvent (SWT.Resize);
1170 if (isDisposed ()) return;
1171 if (layout != null) {
1172 markLayout (false, false);
1173 updateLayout (true, false);
1179 void setSavedFocus (Control control) {
1180 savedFocus = control;
1183 void setSystemMenu () {
1184 long hMenu = OS.GetSystemMenu (handle, false);
1185 if (hMenu == 0) return;
1186 int oldCount = OS.GetMenuItemCount (hMenu);
1187 if ((style & SWT.RESIZE) == 0) {
1188 OS.DeleteMenu (hMenu, OS.SC_SIZE, OS.MF_BYCOMMAND);
1190 if ((style & SWT.MIN) == 0) {
1191 OS.DeleteMenu (hMenu, OS.SC_MINIMIZE, OS.MF_BYCOMMAND);
1193 if ((style & SWT.MAX) == 0) {
1194 OS.DeleteMenu (hMenu, OS.SC_MAXIMIZE, OS.MF_BYCOMMAND);
1196 if ((style & (SWT.MIN | SWT.MAX)) == 0) {
1197 OS.DeleteMenu (hMenu, OS.SC_RESTORE, OS.MF_BYCOMMAND);
1199 int newCount = OS.GetMenuItemCount (hMenu);
1200 if ((style & SWT.CLOSE) == 0 || newCount != oldCount) {
1201 OS.DeleteMenu (hMenu, OS.SC_TASKLIST, OS.MF_BYCOMMAND);
1202 MENUITEMINFO info = new MENUITEMINFO ();
1203 info.cbSize = MENUITEMINFO.sizeof;
1204 info.fMask = OS.MIIM_ID;
1206 while (index < newCount) {
1207 if (OS.GetMenuItemInfo (hMenu, index, true, info)) {
1208 if (info.wID == OS.SC_CLOSE) break;
1212 if (index != newCount) {
1213 OS.DeleteMenu (hMenu, index - 1, OS.MF_BYPOSITION);
1214 if ((style & SWT.CLOSE) == 0) {
1215 OS.DeleteMenu (hMenu, OS.SC_CLOSE, OS.MF_BYCOMMAND);
1222 * Sets the receiver's text, which is the string that the
1223 * window manager will typically display as the receiver's
1224 * <em>title</em>, to the argument, which must not be null.
1226 * Note: If control characters like '\n', '\t' etc. are used
1227 * in the string, then the behavior is platform dependent.
1230 * @param string the new text
1232 * @exception IllegalArgumentException <ul>
1233 * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
1235 * @exception SWTException <ul>
1236 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1237 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1240 public void setText (String string) {
1242 if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
1243 /* Use the character encoding for the default locale */
1244 TCHAR buffer = new TCHAR (0, string, true);
1245 /* Ensure that the title appears in the task bar.*/
1246 if ((state & FOREIGN_HANDLE) != 0) {
1247 long hHeap = OS.GetProcessHeap ();
1248 int byteCount = buffer.length () * TCHAR.sizeof;
1249 long pszText = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
1250 OS.MoveMemory (pszText, buffer, byteCount);
1251 OS.DefWindowProc (handle, OS.WM_SETTEXT, 0, pszText);
1252 if (pszText != 0) OS.HeapFree (hHeap, 0, pszText);
1254 OS.SetWindowText (handle, buffer);
1256 if ((state & HAS_AUTO_DIRECTION) != 0) {
1257 updateTextDirection (AUTO_TEXT_DIRECTION);
1262 public void setVisible (boolean visible) {
1264 if (!getDrawing()) {
1265 if (((state & HIDDEN) == 0) == visible) return;
1267 if (visible == OS.IsWindowVisible (handle)) return;
1271 * It is possible (but unlikely), that application
1272 * code could have disposed the widget in the show
1273 * event. If this happens, just return.
1275 sendEvent (SWT.Show);
1276 if (isDisposed ()) return;
1277 if (!getDrawing()) {
1280 if (menuBar != null) {
1281 display.removeBar (menuBar);
1282 OS.DrawMenuBar (handle);
1284 STARTUPINFO lpStartUpInfo = Display.lpStartupInfo;
1285 if (lpStartUpInfo != null && (lpStartUpInfo.dwFlags & OS.STARTF_USESHOWWINDOW) != 0) {
1286 OS.ShowWindow (handle, lpStartUpInfo.wShowWindow);
1288 OS.ShowWindow (handle, swFlags);
1290 if (isDisposed ()) return;
1294 Point location = getLocationInPixels ();
1300 Rectangle rect = getClientAreaInPixels ();
1301 oldWidth = rect.width;
1302 oldHeight = rect.height;
1305 * Bug in Windows. On Vista using the Classic theme,
1306 * when the window is hung and UpdateWindow() is called,
1307 * nothing is drawn, and outstanding WM_PAINTs are cleared.
1308 * This causes pixel corruption. The fix is to avoid calling
1309 * update on hung windows.
1311 if (OS.IsAppThemed () || !OS.IsHungAppWindow (handle)) {
1312 OS.UpdateWindow (handle);
1316 if (OS.IsIconic (handle)) {
1317 swFlags = OS.SW_SHOWMINNOACTIVE;
1319 if (OS.IsZoomed (handle)) {
1320 swFlags = OS.SW_SHOWMAXIMIZED;
1322 swFlags = OS.SW_SHOWNOACTIVATE;
1325 if (!getDrawing()) {
1328 OS.ShowWindow (handle, OS.SW_HIDE);
1330 if (isDisposed ()) return;
1331 sendEvent (SWT.Hide);
1335 void sort (Image [] images, ImageData [] datas, int width, int height, int depth) {
1336 /* Shell Sort from K&R, pg 108 */
1337 int length = images.length;
1338 if (length <= 1) return;
1339 for (int gap=length/2; gap>0; gap/=2) {
1340 for (int i=gap; i<length; i++) {
1341 for (int j=i-gap; j>=0; j-=gap) {
1342 if (compare (datas [j], datas [j + gap], width, height, depth) >= 0) {
1343 Image swap = images [j];
1344 images [j] = images [j + gap];
1345 images [j + gap] = swap;
1346 ImageData swapData = datas [j];
1347 datas [j] = datas [j + gap];
1348 datas [j + gap] = swapData;
1356 boolean translateAccelerator (MSG msg) {
1357 if (!isEnabled () || !isActive ()) return false;
1358 if (menuBar != null && !menuBar.isEnabled ()) return false;
1359 if (translateMDIAccelerator (msg) || translateMenuAccelerator (msg)) return true;
1360 Decorations decorations = parent.menuShell ();
1361 return decorations.translateAccelerator (msg);
1364 boolean translateMenuAccelerator (MSG msg) {
1365 if (hAccel == -1) createAccelerators ();
1366 return hAccel != 0 && OS.TranslateAccelerator (handle, hAccel, msg) != 0;
1369 boolean translateMDIAccelerator (MSG msg) {
1370 if (!(this instanceof Shell)) {
1371 Shell shell = getShell ();
1372 long hwndMDIClient = shell.hwndMDIClient;
1373 if (hwndMDIClient != 0 && OS.TranslateMDISysAccel (hwndMDIClient, msg)) {
1376 if (msg.message == OS.WM_KEYDOWN) {
1377 if (OS.GetKeyState (OS.VK_CONTROL) >= 0) return false;
1378 switch ((int)(msg.wParam)) {
1380 OS.PostMessage (handle, OS.WM_CLOSE, 0, 0);
1383 if (traverseDecorations (true)) return true;
1387 if (msg.message == OS.WM_SYSKEYDOWN) {
1388 switch ((int)(msg.wParam)) {
1390 OS.PostMessage (shell.handle, OS.WM_CLOSE, 0, 0);
1399 boolean traverseDecorations (boolean next) {
1400 Control [] children = parent._getChildren ();
1401 int length = children.length;
1403 while (index < length) {
1404 if (children [index] == this) break;
1408 * It is possible (but unlikely), that application
1409 * code could have disposed the widget in focus in
1410 * or out events. Ensure that a disposed widget is
1413 int start = index, offset = (next) ? 1 : -1;
1414 while ((index = (index + offset + length) % length) != start) {
1415 Control child = children [index];
1416 if (!child.isDisposed () && child instanceof Decorations) {
1417 if (child.setFocus ()) return true;
1424 boolean traverseItem (boolean next) {
1429 boolean traverseReturn () {
1430 if (defaultButton == null || defaultButton.isDisposed ()) return false;
1431 if (!defaultButton.isVisible () || !defaultButton.isEnabled ()) return false;
1432 defaultButton.click ();
1437 CREATESTRUCT widgetCreateStruct () {
1438 return new CREATESTRUCT ();
1442 int widgetExtStyle () {
1443 int bits = super.widgetExtStyle () | OS.WS_EX_MDICHILD;
1444 bits &= ~OS.WS_EX_CLIENTEDGE;
1445 if ((style & SWT.NO_TRIM) != 0) return bits;
1446 if ((style & SWT.RESIZE) != 0) return bits;
1447 if ((style & SWT.BORDER) != 0) bits |= OS.WS_EX_DLGMODALFRAME;
1452 long widgetParent () {
1453 Shell shell = getShell ();
1454 return shell.hwndMDIClient ();
1458 int widgetStyle () {
1460 * Clear WS_VISIBLE and WS_TABSTOP. NOTE: In Windows, WS_TABSTOP
1461 * has the same value as WS_MAXIMIZEBOX so these bits cannot be
1462 * used to control tabbing.
1464 int bits = super.widgetStyle () & ~(OS.WS_TABSTOP | OS.WS_VISIBLE);
1466 /* Set the title bits and no-trim bits */
1467 bits &= ~OS.WS_BORDER;
1468 if ((style & SWT.NO_TRIM) != 0) {
1469 if (parent == null) {
1470 bits |= OS.WS_SYSMENU | OS.WS_MINIMIZEBOX;
1474 if ((style & SWT.TITLE) != 0) bits |= OS.WS_CAPTION;
1476 /* Set the min and max button bits */
1477 if ((style & SWT.MIN) != 0) bits |= OS.WS_MINIMIZEBOX;
1478 if ((style & SWT.MAX) != 0) bits |= OS.WS_MAXIMIZEBOX;
1480 /* Set the resize, dialog border or border bits */
1481 if ((style & SWT.RESIZE) != 0) {
1482 bits |= OS.WS_THICKFRAME;
1483 } else if ((style & SWT.BORDER) == 0) {
1484 bits |= OS.WS_BORDER;
1487 /* Set the system menu and close box bits */
1488 if ((style & SWT.CLOSE) != 0) bits |= OS.WS_SYSMENU;
1494 long windowProc (long hwnd, int msg, long wParam, long lParam) {
1496 case Display.SWT_GETACCEL:
1497 case Display.SWT_GETACCELCOUNT:
1498 if (hAccel == -1) createAccelerators ();
1499 return msg == Display.SWT_GETACCELCOUNT ? nAccel : hAccel;
1501 return super.windowProc (hwnd, msg, wParam, lParam);
1505 LRESULT WM_ACTIVATE (long wParam, long lParam) {
1506 LRESULT result = super.WM_ACTIVATE (wParam, lParam);
1507 if (result != null) return result;
1509 * Feature in AWT. When an AWT Window is activated,
1510 * for some reason, it seems to forward the WM_ACTIVATE
1511 * message to the parent. Normally, the parent is an
1512 * AWT Frame. When AWT is embedded in SWT, the SWT
1513 * shell gets the WM_ACTIVATE and assumes that it came
1514 * from Windows. When an SWT shell is activated it
1515 * restores focus to the last control that had focus.
1516 * If this control is an embedded composite, it takes
1517 * focus from the AWT Window. The fix is to ignore
1518 * WM_ACTIVATE messages that come from AWT Windows.
1520 if (OS.GetParent (lParam) == handle) {
1521 char [] buffer = new char [128];
1522 int length = OS.GetClassName (lParam, buffer, buffer.length);
1523 String className = new String (buffer, 0, length);
1524 if (className.equals (Display.AWT_WINDOW_CLASS)) {
1525 return LRESULT.ZERO;
1528 int loWord = OS.LOWORD (wParam);
1531 * When the high word of wParam is non-zero, the activation
1532 * state of the window is being changed while the window is
1533 * minimized. If this is the case, do not report activation
1534 * events or restore the focus.
1536 if (OS.HIWORD (wParam) != 0) return result;
1537 Control control = display.findControl (lParam);
1538 if (control == null || control instanceof Shell) {
1539 if (this instanceof Shell) {
1540 Event event = new Event ();
1541 event.detail = loWord == OS.WA_CLICKACTIVE ? SWT.MouseDown : SWT.None;
1542 sendEvent (SWT.Activate, event);
1543 if (isDisposed ()) return LRESULT.ZERO;
1546 if (restoreFocus ()) return LRESULT.ZERO;
1548 Display display = this.display;
1549 boolean lockWindow = display.isXMouseActive ();
1550 if (lockWindow) display.lockActiveWindow = true;
1551 Control control = display.findControl (lParam);
1552 if (control == null || control instanceof Shell) {
1553 if (this instanceof Shell) {
1554 sendEvent (SWT.Deactivate);
1555 if (!isDisposed ()) {
1556 Shell shell = getShell ();
1557 shell.setActiveControl (null);
1558 // widget could be disposed at this point
1562 if (lockWindow) display.lockActiveWindow = false;
1563 if (isDisposed ()) return LRESULT.ZERO;
1570 LRESULT WM_CLOSE (long wParam, long lParam) {
1571 LRESULT result = super.WM_CLOSE (wParam, lParam);
1572 if (result != null) return result;
1573 if (isEnabled () && isActive ()) closeWidget ();
1574 return LRESULT.ZERO;
1578 LRESULT WM_KILLFOCUS (long wParam, long lParam) {
1579 LRESULT result = super.WM_KILLFOCUS (wParam, lParam);
1585 LRESULT WM_MOVE (long wParam, long lParam) {
1587 Point location = getLocationInPixels ();
1588 if (location.x == oldX && location.y == oldY) {
1594 return super.WM_MOVE (wParam, lParam);
1598 LRESULT WM_NCACTIVATE (long wParam, long lParam) {
1599 LRESULT result = super.WM_NCACTIVATE (wParam, lParam);
1600 if (result != null) return result;
1602 if (display.lockActiveWindow) return LRESULT.ZERO;
1603 Control control = display.findControl (lParam);
1604 if (control != null) {
1605 Shell shell = getShell ();
1606 Decorations decorations = control.menuShell ();
1607 if (decorations.getShell () == shell) {
1608 if (this instanceof Shell) return LRESULT.ONE;
1609 if (display.ignoreRestoreFocus) {
1610 if (display.lastHittest != OS.HTCLIENT) {
1611 result = LRESULT.ONE;
1617 if (!(this instanceof Shell)) {
1618 long hwndShell = getShell().handle;
1619 OS.SendMessage (hwndShell, OS.WM_NCACTIVATE, wParam, lParam);
1625 LRESULT WM_QUERYOPEN (long wParam, long lParam) {
1626 LRESULT result = super.WM_QUERYOPEN (wParam, lParam);
1627 if (result != null) return result;
1628 sendEvent (SWT.Deiconify);
1629 // widget could be disposed at this point
1634 LRESULT WM_SETFOCUS (long wParam, long lParam) {
1635 LRESULT result = super.WM_SETFOCUS (wParam, lParam);
1636 if (isDisposed ()) return result;
1637 if (savedFocus != this) restoreFocus ();
1642 LRESULT WM_SIZE (long wParam, long lParam) {
1643 LRESULT result = null;
1644 boolean changed = true;
1646 int newWidth = 0, newHeight = 0;
1647 switch ((int)wParam) {
1648 case OS.SIZE_MAXIMIZED:
1649 OS.GetWindowRect (handle, maxRect);
1650 case OS.SIZE_RESTORED:
1651 newWidth = OS.LOWORD (lParam);
1652 newHeight = OS.HIWORD (lParam);
1654 case OS.SIZE_MINIMIZED:
1655 Rectangle rect = getClientAreaInPixels ();
1656 newWidth = rect.width;
1657 newHeight = rect.height;
1660 changed = newWidth != oldWidth || newHeight != oldHeight;
1662 oldWidth = newWidth;
1663 oldHeight = newHeight;
1667 result = super.WM_SIZE (wParam, lParam);
1668 if (isDisposed ()) return result;
1670 if (wParam == OS.SIZE_MINIMIZED) {
1671 sendEvent (SWT.Iconify);
1672 // widget could be disposed at this point
1678 LRESULT WM_SYSCOMMAND (long wParam, long lParam) {
1679 LRESULT result = super.WM_SYSCOMMAND (wParam, lParam);
1680 if (result != null) return result;
1681 if (!(this instanceof Shell)) {
1682 int cmd = (int)wParam & 0xFFF0;
1685 OS.PostMessage (handle, OS.WM_CLOSE, 0, 0);
1686 return LRESULT.ZERO;
1688 case OS.SC_NEXTWINDOW: {
1689 traverseDecorations (true);
1690 return LRESULT.ZERO;
1698 LRESULT WM_WINDOWPOSCHANGING (long wParam, long lParam) {
1699 LRESULT result = super.WM_WINDOWPOSCHANGING (wParam, lParam);
1700 if (result != null) return result;
1701 if (display.lockActiveWindow) {
1702 WINDOWPOS lpwp = new WINDOWPOS ();
1703 OS.MoveMemory (lpwp, lParam, WINDOWPOS.sizeof);
1704 lpwp.flags |= OS.SWP_NOZORDER;
1705 OS.MoveMemory (lParam, lpwp, WINDOWPOS.sizeof);