comparison org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/widgets/Shell.d @ 0:6dd524f61e62

add dwt win and basic java stuff
author Frank Benoit <benoit@tionex.de>
date Mon, 02 Mar 2009 14:44:16 +0100
parents
children d46287db17ed
comparison
equal deleted inserted replaced
-1:000000000000 0:6dd524f61e62
1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module org.eclipse.swt.widgets.Shell;
14
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.SWTException;
17 import org.eclipse.swt.events.ShellListener;
18 import org.eclipse.swt.graphics.Cursor;
19 import org.eclipse.swt.graphics.GC;
20 import org.eclipse.swt.graphics.Point;
21 import org.eclipse.swt.graphics.Rectangle;
22 import org.eclipse.swt.graphics.Region;
23 import org.eclipse.swt.internal.win32.OS;
24
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Decorations;
27 import org.eclipse.swt.widgets.Control;
28 import org.eclipse.swt.widgets.Menu;
29 import org.eclipse.swt.widgets.ToolTip;
30 import org.eclipse.swt.widgets.Display;
31 import org.eclipse.swt.widgets.TypedListener;
32 import org.eclipse.swt.widgets.Event;
33
34 import java.lang.all;
35
36 /**
37 * Instances of this class represent the "windows"
38 * which the desktop or "window manager" is managing.
39 * Instances that do not have a parent (that is, they
40 * are built using the constructor, which takes a
41 * <code>Display</code> as the argument) are described
42 * as <em>top level</em> shells. Instances that do have
43 * a parent are described as <em>secondary</em> or
44 * <em>dialog</em> shells.
45 * <p>
46 * Instances are always displayed in one of the maximized,
47 * minimized or normal states:
48 * <ul>
49 * <li>
50 * When an instance is marked as <em>maximized</em>, the
51 * window manager will typically resize it to fill the
52 * entire visible area of the display, and the instance
53 * is usually put in a state where it can not be resized
54 * (even if it has style <code>RESIZE</code>) until it is
55 * no longer maximized.
56 * </li><li>
57 * When an instance is in the <em>normal</em> state (neither
58 * maximized or minimized), its appearance is controlled by
59 * the style constants which were specified when it was created
60 * and the restrictions of the window manager (see below).
61 * </li><li>
62 * When an instance has been marked as <em>minimized</em>,
63 * its contents (client area) will usually not be visible,
64 * and depending on the window manager, it may be
65 * "iconified" (that is, replaced on the desktop by a small
66 * simplified representation of itself), relocated to a
67 * distinguished area of the screen, or hidden. Combinations
68 * of these changes are also possible.
69 * </li>
70 * </ul>
71 * </p><p>
72 * The <em>modality</em> of an instance may be specified using
73 * style bits. The modality style bits are used to determine
74 * whether input is blocked for other shells on the display.
75 * The <code>PRIMARY_MODAL</code> style allows an instance to block
76 * input to its parent. The <code>APPLICATION_MODAL</code> style
77 * allows an instance to block input to every other shell in the
78 * display. The <code>SYSTEM_MODAL</code> style allows an instance
79 * to block input to all shells, including shells belonging to
80 * different applications.
81 * </p><p>
82 * Note: The styles supported by this class are treated
83 * as <em>HINT</em>s, since the window manager for the
84 * desktop on which the instance is visible has ultimate
85 * control over the appearance and behavior of decorations
86 * and modality. For example, some window managers only
87 * support resizable windows and will always assume the
88 * RESIZE style, even if it is not set. In addition, if a
89 * modality style is not supported, it is "upgraded" to a
90 * more restrictive modality style that is supported. For
91 * example, if <code>PRIMARY_MODAL</code> is not supported,
92 * it would be upgraded to <code>APPLICATION_MODAL</code>.
93 * A modality style may also be "downgraded" to a less
94 * restrictive style. For example, most operating systems
95 * no longer support <code>SYSTEM_MODAL</code> because
96 * it can freeze up the desktop, so this is typically
97 * downgraded to <code>APPLICATION_MODAL</code>.
98 * <dl>
99 * <dt><b>Styles:</b></dt>
100 * <dd>BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP, TOOL</dd>
101 * <dd>APPLICATION_MODAL, MODELESS, PRIMARY_MODAL, SYSTEM_MODAL</dd>
102 * <dt><b>Events:</b></dt>
103 * <dd>Activate, Close, Deactivate, Deiconify, Iconify</dd>
104 * </dl>
105 * Class <code>SWT</code> provides two "convenience constants"
106 * for the most commonly required style combinations:
107 * <dl>
108 * <dt><code>SHELL_TRIM</code></dt>
109 * <dd>
110 * the result of combining the constants which are required
111 * to produce a typical application top level shell: (that
112 * is, <code>CLOSE | TITLE | MIN | MAX | RESIZE</code>)
113 * </dd>
114 * <dt><code>DIALOG_TRIM</code></dt>
115 * <dd>
116 * the result of combining the constants which are required
117 * to produce a typical application dialog shell: (that
118 * is, <code>TITLE | CLOSE | BORDER</code>)
119 * </dd>
120 * </dl>
121 * </p>
122 * <p>
123 * Note: Only one of the styles APPLICATION_MODAL, MODELESS,
124 * PRIMARY_MODAL and SYSTEM_MODAL may be specified.
125 * </p><p>
126 * IMPORTANT: This class is not intended to be subclassed.
127 * </p>
128 *
129 * @see Decorations
130 * @see SWT
131 * @see <a href="http://www.eclipse.org/swt/snippets/#shell">Shell snippets</a>
132 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
133 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
134 */
135 public class Shell : Decorations {
136
137 alias Decorations.setBounds setBounds;
138 alias Decorations.setParent setParent;
139 alias Decorations.setToolTipText setToolTipText;
140
141 Menu activeMenu;
142 ToolTip [] toolTips;
143 HIMC hIMC;
144 HWND hwndMDIClient_;
145 TCHAR* lpstrTip;
146 HANDLE toolTipHandle_;
147 HANDLE balloonTipHandle_;
148 int minWidth = SWT.DEFAULT, minHeight = SWT.DEFAULT;
149 HBRUSH [] brushes;
150 bool showWithParent, fullScreen, wasMaximized;
151 String toolTitle, balloonTitle;
152 HICON toolIcon;
153 HICON balloonIcon;
154 WNDPROC windowProc_;
155 Control lastActive;
156 static if( OS.IsWinCE ){
157 SHACTIVATEINFO psai;
158 }
159 static /+const+/ WNDPROC ToolTipProc;
160 static /+const+/ WNDPROC DialogProc;
161 static if( OS.IsWinCE ){
162 static const TCHAR[] DialogClass = "Dialog\0"w;
163 }
164 else{
165 static const TCHAR[] DialogClass = "#32770\0"w;
166 }
167 const static int [] SYSTEM_COLORS = [
168 OS.COLOR_BTNFACE,
169 OS.COLOR_WINDOW,
170 OS.COLOR_BTNTEXT,
171 OS.COLOR_WINDOWTEXT,
172 OS.COLOR_HIGHLIGHT,
173 OS.COLOR_SCROLLBAR,
174 ];
175 final static int BRUSHES_SIZE = 32;
176
177 private static bool static_this_completed = false;
178 private static void static_this() {
179 if( static_this_completed ){
180 return;
181 }
182 synchronized {
183 if( static_this_completed ){
184 return;
185 }
186 WNDCLASS lpWndClass;
187 OS.GetClassInfo (null, DialogClass.ptr, &lpWndClass);
188 DialogProc = lpWndClass.lpfnWndProc;
189 static_this_completed = true;
190 }
191 }
192
193 /**
194 * Constructs a new instance of this class. This is equivalent
195 * to calling <code>Shell((Display) null)</code>.
196 *
197 * @exception SWTException <ul>
198 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
199 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
200 * </ul>
201 */
202 public this () {
203 this (cast(Display) null);
204 }
205
206 /**
207 * Constructs a new instance of this class given only the style
208 * value describing its behavior and appearance. This is equivalent
209 * to calling <code>Shell((Display) null, style)</code>.
210 * <p>
211 * The style value is either one of the style constants defined in
212 * class <code>SWT</code> which is applicable to instances of this
213 * class, or must be built by <em>bitwise OR</em>'ing together
214 * (that is, using the <code>int</code> "|" operator) two or more
215 * of those <code>SWT</code> style constants. The class description
216 * lists the style constants that are applicable to the class.
217 * Style bits are also inherited from superclasses.
218 * </p>
219 *
220 * @param style the style of control to construct
221 *
222 * @exception SWTException <ul>
223 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
224 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
225 * </ul>
226 *
227 * @see SWT#BORDER
228 * @see SWT#CLOSE
229 * @see SWT#MIN
230 * @see SWT#MAX
231 * @see SWT#RESIZE
232 * @see SWT#TITLE
233 * @see SWT#NO_TRIM
234 * @see SWT#SHELL_TRIM
235 * @see SWT#DIALOG_TRIM
236 * @see SWT#MODELESS
237 * @see SWT#PRIMARY_MODAL
238 * @see SWT#APPLICATION_MODAL
239 * @see SWT#SYSTEM_MODAL
240 */
241 public this (int style) {
242 this (cast(Display) null, style);
243 }
244
245 /**
246 * Constructs a new instance of this class given only the display
247 * to create it on. It is created with style <code>SWT.SHELL_TRIM</code>.
248 * <p>
249 * Note: Currently, null can be passed in for the display argument.
250 * This has the effect of creating the shell on the currently active
251 * display if there is one. If there is no current display, the
252 * shell is created on a "default" display. <b>Passing in null as
253 * the display argument is not considered to be good coding style,
254 * and may not be supported in a future release of SWT.</b>
255 * </p>
256 *
257 * @param display the display to create the shell on
258 *
259 * @exception SWTException <ul>
260 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
261 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
262 * </ul>
263 */
264 public this (Display display) {
265 this (display, OS.IsWinCE ? SWT.NONE : SWT.SHELL_TRIM);
266 }
267
268 /**
269 * Constructs a new instance of this class given the display
270 * to create it on and a style value describing its behavior
271 * and appearance.
272 * <p>
273 * The style value is either one of the style constants defined in
274 * class <code>SWT</code> which is applicable to instances of this
275 * class, or must be built by <em>bitwise OR</em>'ing together
276 * (that is, using the <code>int</code> "|" operator) two or more
277 * of those <code>SWT</code> style constants. The class description
278 * lists the style constants that are applicable to the class.
279 * Style bits are also inherited from superclasses.
280 * </p><p>
281 * Note: Currently, null can be passed in for the display argument.
282 * This has the effect of creating the shell on the currently active
283 * display if there is one. If there is no current display, the
284 * shell is created on a "default" display. <b>Passing in null as
285 * the display argument is not considered to be good coding style,
286 * and may not be supported in a future release of SWT.</b>
287 * </p>
288 *
289 * @param display the display to create the shell on
290 * @param style the style of control to construct
291 *
292 * @exception SWTException <ul>
293 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
294 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
295 * </ul>
296 *
297 * @see SWT#BORDER
298 * @see SWT#CLOSE
299 * @see SWT#MIN
300 * @see SWT#MAX
301 * @see SWT#RESIZE
302 * @see SWT#TITLE
303 * @see SWT#NO_TRIM
304 * @see SWT#SHELL_TRIM
305 * @see SWT#DIALOG_TRIM
306 * @see SWT#MODELESS
307 * @see SWT#PRIMARY_MODAL
308 * @see SWT#APPLICATION_MODAL
309 * @see SWT#SYSTEM_MODAL
310 */
311 public this (Display display, int style) {
312 this (display, null, style, null, false);
313 }
314
315 this (Display display, Shell parent, int style, HWND handle, bool embedded) {
316 static_this();
317 super ();
318 checkSubclass ();
319 if (display is null) display = Display.getCurrent ();
320 if (display is null) display = Display.getDefault ();
321 if (!display.isValidThread ()) {
322 error (SWT.ERROR_THREAD_INVALID_ACCESS);
323 }
324 if (parent !is null && parent.isDisposed ()) {
325 error (SWT.ERROR_INVALID_ARGUMENT);
326 }
327 this.style = checkStyle (style);
328 this.parent = parent;
329 this.display = display;
330 this.handle = handle;
331 if (handle !is null && !embedded) {
332 state |= FOREIGN_HANDLE;
333 }
334 createWidget ();
335 }
336
337 /**
338 * Constructs a new instance of this class given only its
339 * parent. It is created with style <code>SWT.DIALOG_TRIM</code>.
340 * <p>
341 * Note: Currently, null can be passed in for the parent.
342 * This has the effect of creating the shell on the currently active
343 * display if there is one. If there is no current display, the
344 * shell is created on a "default" display. <b>Passing in null as
345 * the parent is not considered to be good coding style,
346 * and may not be supported in a future release of SWT.</b>
347 * </p>
348 *
349 * @param parent a shell which will be the parent of the new instance
350 *
351 * @exception IllegalArgumentException <ul>
352 * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
353 * </ul>
354 * @exception SWTException <ul>
355 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
356 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
357 * </ul>
358 */
359 public this (Shell parent) {
360 this (parent, OS.IsWinCE ? SWT.NONE : SWT.DIALOG_TRIM);
361 }
362
363 /**
364 * Constructs a new instance of this class given its parent
365 * and a style value describing its behavior and appearance.
366 * <p>
367 * The style value is either one of the style constants defined in
368 * class <code>SWT</code> which is applicable to instances of this
369 * class, or must be built by <em>bitwise OR</em>'ing together
370 * (that is, using the <code>int</code> "|" operator) two or more
371 * of those <code>SWT</code> style constants. The class description
372 * lists the style constants that are applicable to the class.
373 * Style bits are also inherited from superclasses.
374 * </p><p>
375 * Note: Currently, null can be passed in for the parent.
376 * This has the effect of creating the shell on the currently active
377 * display if there is one. If there is no current display, the
378 * shell is created on a "default" display. <b>Passing in null as
379 * the parent is not considered to be good coding style,
380 * and may not be supported in a future release of SWT.</b>
381 * </p>
382 *
383 * @param parent a shell which will be the parent of the new instance
384 * @param style the style of control to construct
385 *
386 * @exception IllegalArgumentException <ul>
387 * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
388 * </ul>
389 * @exception SWTException <ul>
390 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
391 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
392 * </ul>
393 *
394 * @see SWT#BORDER
395 * @see SWT#CLOSE
396 * @see SWT#MIN
397 * @see SWT#MAX
398 * @see SWT#RESIZE
399 * @see SWT#TITLE
400 * @see SWT#NO_TRIM
401 * @see SWT#SHELL_TRIM
402 * @see SWT#DIALOG_TRIM
403 * @see SWT#ON_TOP
404 * @see SWT#TOOL
405 * @see SWT#MODELESS
406 * @see SWT#PRIMARY_MODAL
407 * @see SWT#APPLICATION_MODAL
408 * @see SWT#SYSTEM_MODAL
409 */
410 public this (Shell parent, int style) {
411 this (parent !is null ? parent.display : null, parent, style, null, false);
412 }
413
414 /**
415 * Invokes platform specific functionality to allocate a new shell
416 * that is embedded.
417 * <p>
418 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
419 * API for <code>Shell</code>. It is marked public only so that it
420 * can be shared within the packages provided by SWT. It is not
421 * available on all platforms, and should never be called from
422 * application code.
423 * </p>
424 *
425 * @param display the display for the shell
426 * @param handle the handle for the shell
427 * @return a new shell object containing the specified display and handle
428 */
429 public static Shell win32_new (Display display, HWND handle) {
430 return new Shell (display, null, SWT.NO_TRIM, handle, true);
431 }
432
433 /**
434 * Invokes platform specific functionality to allocate a new shell
435 * that is not embedded.
436 * <p>
437 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
438 * API for <code>Shell</code>. It is marked public only so that it
439 * can be shared within the packages provided by SWT. It is not
440 * available on all platforms, and should never be called from
441 * application code.
442 * </p>
443 *
444 * @param display the display for the shell
445 * @param handle the handle for the shell
446 * @return a new shell object containing the specified display and handle
447 *
448 * @since 3.3
449 */
450 public static Shell internal_new (Display display, HWND handle) {
451 return new Shell (display, null, SWT.NO_TRIM, handle, false);
452 }
453
454 static int checkStyle (int style) {
455 style = Decorations.checkStyle (style);
456 style &= ~SWT.TRANSPARENT;
457 int mask = SWT.SYSTEM_MODAL | SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL;
458 int bits = style & ~mask;
459 if ((style & SWT.SYSTEM_MODAL) !is 0) return bits | SWT.SYSTEM_MODAL;
460 if ((style & SWT.APPLICATION_MODAL) !is 0) return bits | SWT.APPLICATION_MODAL;
461 if ((style & SWT.PRIMARY_MODAL) !is 0) return bits | SWT.PRIMARY_MODAL;
462 return bits;
463 }
464
465 /**
466 * Adds the listener to the collection of listeners who will
467 * be notified when operations are performed on the receiver,
468 * by sending the listener one of the messages defined in the
469 * <code>ShellListener</code> interface.
470 *
471 * @param listener the listener which should be notified
472 *
473 * @exception IllegalArgumentException <ul>
474 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
475 * </ul>
476 * @exception SWTException <ul>
477 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
478 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
479 * </ul>
480 *
481 * @see ShellListener
482 * @see #removeShellListener
483 */
484 public void addShellListener (ShellListener listener) {
485 checkWidget ();
486 if (listener is null) error (SWT.ERROR_NULL_ARGUMENT);
487 TypedListener typedListener = new TypedListener (listener);
488 addListener (SWT.Close,typedListener);
489 addListener (SWT.Iconify,typedListener);
490 addListener (SWT.Deiconify,typedListener);
491 addListener (SWT.Activate, typedListener);
492 addListener (SWT.Deactivate, typedListener);
493 }
494
495 HANDLE balloonTipHandle () {
496 if (balloonTipHandle_ is null) createBalloonTipHandle ();
497 return balloonTipHandle_;
498 }
499
500 override int callWindowProc (HWND hwnd, int msg, int wParam, int lParam) {
501 if (handle is null) return 0;
502 if (hwnd is toolTipHandle_ || hwnd is balloonTipHandle_) {
503 return OS.CallWindowProc (ToolTipProc, hwnd, msg, wParam, lParam);
504 }
505 if (hwndMDIClient_ !is null) {
506 return OS.DefFrameProc (hwnd, hwndMDIClient_, msg, wParam, lParam);
507 }
508 if (windowProc_ !is null) {
509 return OS.CallWindowProc (windowProc_, hwnd, msg, wParam, lParam);
510 }
511 if ((style & SWT.TOOL) !is 0) {
512 int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX | SWT.BORDER | SWT.RESIZE;
513 if ((style & trim) is 0) return OS.DefWindowProc (hwnd, msg, wParam, lParam);
514 }
515 if (parent !is null) {
516 switch (msg) {
517 case OS.WM_KILLFOCUS:
518 case OS.WM_SETFOCUS:
519 return OS.DefWindowProc (hwnd, msg, wParam, lParam);
520 default:
521 }
522 return OS.CallWindowProc (DialogProc, hwnd, msg, wParam, lParam);
523 }
524 return OS.DefWindowProc (hwnd, msg, wParam, lParam);
525 }
526
527 /**
528 * Requests that the window manager close the receiver in
529 * the same way it would be closed when the user clicks on
530 * the "close box" or performs some other platform specific
531 * key or mouse combination that indicates the window
532 * should be removed.
533 *
534 * @exception SWTException <ul>
535 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
536 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
537 * </ul>
538 *
539 * @see SWT#Close
540 * @see #dispose
541 */
542 public void close () {
543 checkWidget ();
544 closeWidget ();
545 }
546
547 void createBalloonTipHandle () {
548 balloonTipHandle_ = OS.CreateWindowEx (
549 0,
550 OS.TOOLTIPS_CLASS.ptr,
551 null,
552 OS.TTS_ALWAYSTIP | OS.TTS_NOPREFIX | OS.TTS_BALLOON,
553 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0,
554 handle,
555 null,
556 OS.GetModuleHandle (null),
557 null);
558 if (balloonTipHandle_ is null) error (SWT.ERROR_NO_HANDLES);
559 if (ToolTipProc is null) {
560 ToolTipProc = cast(WNDPROC) OS.GetWindowLongPtr (balloonTipHandle_, OS.GWLP_WNDPROC);
561 }
562 /*
563 * Feature in Windows. Despite the fact that the
564 * tool tip text contains \r\n, the tooltip will
565 * not honour the new line unless TTM_SETMAXTIPWIDTH
566 * is set. The fix is to set TTM_SETMAXTIPWIDTH to
567 * a large value.
568 */
569 OS.SendMessage (balloonTipHandle_, OS.TTM_SETMAXTIPWIDTH, 0, 0x7FFF);
570 display.addControl (balloonTipHandle_, this);
571 OS.SetWindowLongPtr (balloonTipHandle_, OS.GWLP_WNDPROC, display.windowProc);
572 }
573
574 override void createHandle () {
575 bool embedded = handle !is null && (state & FOREIGN_HANDLE) is 0;
576
577 /*
578 * On Windows 98 and NT, setting a window to be the
579 * top most window using HWND_TOPMOST can result in a
580 * parent dialog shell being moved behind its parent
581 * if the dialog has a sibling that is currently on top
582 * This only occurs using SetWindowPos (), not when the
583 * handle is created.
584 */
585 /*
586 * The following code is intentionally commented.
587 */
588 // if ((style & SWT.ON_TOP) !is 0) display.lockActiveWindow = true;
589 if (handle is null || embedded) {
590 super.createHandle ();
591 } else {
592 state |= CANVAS;
593 if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) is 0) {
594 state |= THEME_BACKGROUND;
595 }
596 windowProc_ = cast(WNDPROC) OS.GetWindowLong (handle, OS.GWL_WNDPROC);
597 }
598
599 /*
600 * The following code is intentionally commented.
601 */
602 // if ((style & SWT.ON_TOP) !is 0) display.lockActiveWindow = false;
603
604 if (!embedded) {
605 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
606 bits &= ~(OS.WS_OVERLAPPED | OS.WS_CAPTION);
607 static if (!OS.IsWinCE) bits |= OS.WS_POPUP;
608 if ((style & SWT.TITLE) !is 0) bits |= OS.WS_CAPTION;
609 if ((style & SWT.NO_TRIM) is 0) {
610 if ((style & (SWT.BORDER | SWT.RESIZE)) is 0) bits |= OS.WS_BORDER;
611 }
612 /*
613 * Bug in Windows. When the WS_CAPTION bits are cleared using
614 * SetWindowLong(), Windows does not resize the client area of
615 * the window to get rid of the caption until the first resize.
616 * The fix is to use SetWindowPos() with SWP_DRAWFRAME to force
617 * the frame to be redrawn and resized.
618 */
619 OS.SetWindowLong (handle, OS.GWL_STYLE, bits);
620 int flags = OS.SWP_DRAWFRAME | OS.SWP_NOMOVE | OS.SWP_NOSIZE | OS.SWP_NOZORDER | OS.SWP_NOACTIVATE;
621 SetWindowPos (handle, null, 0, 0, 0, 0, flags);
622 static if (OS.IsWinCE) _setMaximized (true);
623 static if (OS.IsPPC) {
624 psai = new SHACTIVATEINFO ();
625 psai.cbSize = SHACTIVATEINFO.sizeof;
626 }
627 }
628 if (OS.IsDBLocale) {
629 hIMC = OS.ImmCreateContext ();
630 if (hIMC !is null) OS.ImmAssociateContext (handle, hIMC);
631 }
632 }
633
634 void createToolTip (ToolTip toolTip) {
635 int id = 0;
636 if (toolTips is null) toolTips = new ToolTip [4];
637 while (id < toolTips.length && toolTips [id] !is null) id++;
638 if (id is toolTips.length) {
639 ToolTip [] newToolTips = new ToolTip [toolTips.length + 4];
640 System.arraycopy (toolTips, 0, newToolTips, 0, toolTips.length);
641 toolTips = newToolTips;
642 }
643 toolTips [id] = toolTip;
644 toolTip.id = id + Display.ID_START;
645 static if (OS.IsWinCE) return;
646 TOOLINFO lpti;
647 lpti.cbSize = OS.TOOLINFO_sizeof;
648 lpti.hwnd = handle;
649 lpti.uId = toolTip.id;
650 lpti.uFlags = OS.TTF_TRACK;
651 lpti.lpszText = OS.LPSTR_TEXTCALLBACK;
652 OS.SendMessage (toolTip.hwndToolTip (), OS.TTM_ADDTOOL, 0, &lpti);
653 }
654
655 void createToolTipHandle () {
656 toolTipHandle_ = OS.CreateWindowEx (
657 0,
658 OS.TOOLTIPS_CLASS.ptr,
659 null,
660 OS.TTS_ALWAYSTIP | OS.TTS_NOPREFIX,
661 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0,
662 handle,
663 null,
664 OS.GetModuleHandle (null),
665 null);
666 if (toolTipHandle_ is null) error (SWT.ERROR_NO_HANDLES);
667 if (ToolTipProc is null) {
668 ToolTipProc = cast(WNDPROC) OS.GetWindowLongPtr (toolTipHandle_, OS.GWLP_WNDPROC);
669 }
670 /*
671 * Feature in Windows. Despite the fact that the
672 * tool tip text contains \r\n, the tooltip will
673 * not honour the new line unless TTM_SETMAXTIPWIDTH
674 * is set. The fix is to set TTM_SETMAXTIPWIDTH to
675 * a large value.
676 */
677 OS.SendMessage (toolTipHandle_, OS.TTM_SETMAXTIPWIDTH, 0, 0x7FFF);
678 display.addControl (toolTipHandle_, this);
679 OS.SetWindowLongPtr (toolTipHandle_, OS.GWLP_WNDPROC, display.windowProc);
680 }
681
682 override void deregister () {
683 super.deregister ();
684 if (toolTipHandle_ !is null) display.removeControl (toolTipHandle_);
685 if (balloonTipHandle_ !is null) display.removeControl (balloonTipHandle_);
686 }
687
688 void destroyToolTip (ToolTip toolTip) {
689 if (toolTips is null) return;
690 toolTips [toolTip.id - Display.ID_START] = null;
691 static if (OS.IsWinCE) return;
692 if (balloonTipHandle_ !is null) {
693 TOOLINFO lpti;
694 lpti.cbSize = OS.TOOLINFO_sizeof;
695 lpti.uId = toolTip.id;
696 lpti.hwnd = handle;
697 OS.SendMessage (balloonTipHandle_, OS.TTM_DELTOOL, 0, &lpti);
698 }
699 toolTip.id = -1;
700 }
701
702 override void destroyWidget () {
703 fixActiveShell ();
704 super.destroyWidget ();
705 }
706
707 override public void dispose () {
708 /*
709 * This code is intentionally commented. On some
710 * platforms, the owner window is repainted right
711 * away when a dialog window exits. This behavior
712 * is currently unspecified.
713 */
714 // /*
715 // * Note: It is valid to attempt to dispose a widget
716 // * more than once. If this happens, fail silently.
717 // */
718 // if (!isValidWidget ()) return;
719 // if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
720 // Display oldDisplay = display;
721 super.dispose ();
722 // widget is disposed at this point
723 // if (oldDisplay !is null) oldDisplay.update ();
724 }
725
726 override void enableWidget (bool enabled) {
727 if (enabled) {
728 state &= ~DISABLED;
729 } else {
730 state |= DISABLED;
731 }
732 if (Display.TrimEnabled) {
733 if (isActive ()) setItemEnabled (OS.SC_CLOSE, enabled);
734 } else {
735 OS.EnableWindow (handle, enabled);
736 }
737 }
738
739 override HBRUSH findBrush (int value, int lbStyle) {
740 if (lbStyle is OS.BS_SOLID) {
741 for (int i=0; i<SYSTEM_COLORS.length; i++) {
742 if (value is OS.GetSysColor (SYSTEM_COLORS [i])) {
743 return OS.GetSysColorBrush (SYSTEM_COLORS [i]);
744 }
745 }
746 }
747 if (brushes is null) brushes = new HBRUSH [BRUSHES_SIZE];
748 LOGBRUSH logBrush;
749 for (int i=0; i<brushes.length; i++) {
750 HBRUSH hBrush = brushes [i];
751 if (hBrush is null) break;
752 OS.GetObject (hBrush, LOGBRUSH.sizeof, &logBrush);
753 switch (logBrush.lbStyle) {
754 case OS.BS_SOLID:
755 if (lbStyle is OS.BS_SOLID) {
756 if (logBrush.lbColor is value) return hBrush;
757 }
758 break;
759 case OS.BS_PATTERN:
760 if (lbStyle is OS.BS_PATTERN) {
761 if (logBrush.lbHatch is value) return hBrush;
762 }
763 break;
764 default:
765 }
766 }
767 int length_ = brushes.length;
768 HBRUSH hBrush = brushes [--length_];
769 if (hBrush !is null) OS.DeleteObject (hBrush);
770 System.arraycopy (brushes, 0, brushes, 1, length_);
771 switch (lbStyle) {
772 case OS.BS_SOLID:
773 hBrush = OS.CreateSolidBrush (value);
774 break;
775 case OS.BS_PATTERN:
776 hBrush = OS.CreatePatternBrush ( cast(HBITMAP) value);
777 break;
778 default:
779 }
780 return brushes [0] = hBrush;
781 }
782
783 override Control findBackgroundControl () {
784 return background !is -1 || backgroundImage !is null ? this : null;
785 }
786
787 override Cursor findCursor () {
788 return cursor;
789 }
790
791 override Control findThemeControl () {
792 return null;
793 }
794
795 ToolTip findToolTip (int id) {
796 if (toolTips is null) return null;
797 id = id - Display.ID_START;
798 return 0 <= id && id < toolTips.length ? toolTips [id] : null;
799 }
800
801 void fixActiveShell () {
802 /*
803 * Feature in Windows. When the active shell is disposed
804 * or hidden, Windows normally makes the parent shell active
805 * and assigns focus. This does not happen when the parent
806 * shell is disabled. Instead, Windows assigns focus to the
807 * next shell on the desktop (possibly a shell in another
808 * application). The fix is to activate the disabled parent
809 * shell before disposing or hiding the active shell.
810 */
811 auto hwndParent = OS.GetParent (handle);
812 if (hwndParent !is null && handle is OS.GetActiveWindow ()) {
813 if (!OS.IsWindowEnabled (hwndParent) && OS.IsWindowVisible (hwndParent)) {
814 OS.SetActiveWindow (hwndParent);
815 }
816 }
817 }
818
819 void fixShell (Shell newShell, Control control) {
820 if (this is newShell) return;
821 if (control is lastActive) setActiveControl (null);
822 String toolTipText = control.toolTipText_;
823 if (toolTipText !is null) {
824 control.setToolTipText (this, null);
825 control.setToolTipText (newShell, toolTipText);
826 }
827 }
828
829 void fixToolTip () {
830 /*
831 * Bug in Windows. On XP, when a tooltip is
832 * hidden due to a time out or mouse press,
833 * the tooltip remains active although no
834 * longer visible and won't show again until
835 * another tooltip becomes active. If there
836 * is only one tooltip in the window, it will
837 * never show again. The fix is to remove the
838 * current tooltip and add it again every time
839 * the mouse leaves the control.
840 */
841 if (OS.COMCTL32_MAJOR >= 6) {
842 if (toolTipHandle_ is null) return;
843 TOOLINFO lpti;
844 lpti.cbSize = OS.TOOLINFO_sizeof;
845 if (OS.SendMessage (toolTipHandle_, OS.TTM_GETCURRENTTOOL, 0, &lpti) !is 0) {
846 if ((lpti.uFlags & OS.TTF_IDISHWND) !is 0) {
847 OS.SendMessage (toolTipHandle_, OS.TTM_DELTOOL, 0, &lpti);
848 OS.SendMessage (toolTipHandle_, OS.TTM_ADDTOOL, 0, &lpti);
849 }
850 }
851 }
852 }
853
854 /**
855 * If the receiver is visible, moves it to the top of the
856 * drawing order for the display on which it was created
857 * (so that all other shells on that display, which are not
858 * the receiver's children will be drawn behind it) and forces
859 * the window manager to make the shell active.
860 *
861 * @exception SWTException <ul>
862 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
863 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
864 * </ul>
865 *
866 * @since 2.0
867 * @see Control#moveAbove
868 * @see Control#setFocus
869 * @see Control#setVisible
870 * @see Display#getActiveShell
871 * @see Decorations#setDefaultButton(Button)
872 * @see Shell#open
873 * @see Shell#setActive
874 */
875 public void forceActive () {
876 checkWidget ();
877 if(!isVisible()) return;
878 OS.SetForegroundWindow (handle);
879 }
880
881 override void forceResize () {
882 /* Do nothing */
883 }
884
885 /**
886 * Returns the receiver's alpha value. The alpha value
887 * is between 0 (transparent) and 255 (opaque).
888 *
889 * @return the alpha value
890 *
891 * @exception SWTException <ul>
892 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
893 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
894 * </ul>
895 *
896 * @since 3.4
897 */
898 public int getAlpha () {
899 checkWidget ();
900 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) {
901 ubyte [1] pbAlpha;
902 if (OS.GetLayeredWindowAttributes (handle, null, pbAlpha.ptr, null)) {
903 return pbAlpha [0] & 0xFF;
904 }
905 }
906 return 0xFF;
907 }
908
909 override public Rectangle getBounds () {
910 checkWidget ();
911 static if (!OS.IsWinCE) {
912 if (OS.IsIconic (handle)) return super.getBounds ();
913 }
914 RECT rect;
915 OS.GetWindowRect (handle, &rect);
916 int width = rect.right - rect.left;
917 int height = rect.bottom - rect.top;
918 return new Rectangle (rect.left, rect.top, width, height);
919 }
920
921 ToolTip getCurrentToolTip () {
922 if (toolTipHandle_ !is null) {
923 ToolTip tip = getCurrentToolTip (toolTipHandle_);
924 if (tip !is null) return tip;
925 }
926 if (balloonTipHandle_ !is null) {
927 ToolTip tip = getCurrentToolTip (balloonTipHandle_);
928 if (tip !is null) return tip;
929 }
930 return null;
931 }
932
933 ToolTip getCurrentToolTip (HWND hwndToolTip) {
934 if (hwndToolTip is null) return null;
935 if (OS.SendMessage (hwndToolTip, OS.TTM_GETCURRENTTOOL, 0, 0) !is 0) {
936 TOOLINFO lpti;
937 lpti.cbSize = OS.TOOLINFO_sizeof;
938 if (OS.SendMessage (hwndToolTip, OS.TTM_GETCURRENTTOOL, 0, &lpti) !is 0) {
939 if ((lpti.uFlags & OS.TTF_IDISHWND) is 0) return findToolTip (lpti.uId);
940 }
941 }
942 return null;
943 }
944
945 override public bool getEnabled () {
946 checkWidget ();
947 return (state & DISABLED) is 0;
948 }
949
950 /**
951 * Returns <code>true</code> if the receiver is currently
952 * in fullscreen state, and false otherwise.
953 * <p>
954 *
955 * @return the fullscreen state
956 *
957 * @exception SWTException <ul>
958 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
959 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
960 * </ul>
961 *
962 * @since 3.4
963 */
964 public bool getFullScreen () {
965 checkWidget();
966 return fullScreen;
967 }
968
969 /**
970 * Returns the receiver's input method editor mode. This
971 * will be the result of bitwise OR'ing together one or
972 * more of the following constants defined in class
973 * <code>SWT</code>:
974 * <code>NONE</code>, <code>ROMAN</code>, <code>DBCS</code>,
975 * <code>PHONETIC</code>, <code>NATIVE</code>, <code>ALPHA</code>.
976 *
977 * @return the IME mode
978 *
979 * @exception SWTException <ul>
980 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
981 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
982 * </ul>
983 *
984 * @see SWT
985 */
986 public int getImeInputMode () {
987 checkWidget ();
988 if (!OS.IsDBLocale) return 0;
989 auto hIMC = OS.ImmGetContext (handle);
990 uint lpfdwConversion, lpfdwSentence;
991 bool open = cast(bool) OS.ImmGetOpenStatus (hIMC);
992 if (open) open = cast(bool) OS.ImmGetConversionStatus (hIMC, &lpfdwConversion, &lpfdwSentence);
993 OS.ImmReleaseContext (handle, hIMC);
994 if (!open) return SWT.NONE;
995 int result = 0;
996 if ((lpfdwConversion & OS.IME_CMODE_ROMAN) !is 0) result |= SWT.ROMAN;
997 if ((lpfdwConversion & OS.IME_CMODE_FULLSHAPE) !is 0) result |= SWT.DBCS;
998 if ((lpfdwConversion & OS.IME_CMODE_KATAKANA) !is 0) return result | SWT.PHONETIC;
999 if ((lpfdwConversion & OS.IME_CMODE_NATIVE) !is 0) return result | SWT.NATIVE;
1000 return result | SWT.ALPHA;
1001 }
1002
1003 override public Point getLocation () {
1004 checkWidget ();
1005 static if (!OS.IsWinCE) {
1006 if (OS.IsIconic (handle)) {
1007 return super.getLocation ();
1008 }
1009 }
1010 RECT rect;
1011 OS.GetWindowRect (handle, &rect);
1012 return new Point (rect.left, rect.top);
1013 }
1014
1015 public bool getMaximized () {
1016 checkWidget ();
1017 return !fullScreen && super.getMaximized ();
1018 }
1019
1020 /**
1021 * Returns a point describing the minimum receiver's size. The
1022 * x coordinate of the result is the minimum width of the receiver.
1023 * The y coordinate of the result is the minimum height of the
1024 * receiver.
1025 *
1026 * @return the receiver's size
1027 *
1028 * @exception SWTException <ul>
1029 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1030 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1031 * </ul>
1032 *
1033 * @since 3.1
1034 */
1035 public Point getMinimumSize () {
1036 checkWidget ();
1037 int width = Math.max (0, minWidth);
1038 int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
1039 if ((style & SWT.NO_TRIM) is 0 && (style & trim) !is 0) {
1040 width = Math.max (width, OS.GetSystemMetrics (OS.SM_CXMINTRACK));
1041 }
1042 int height = Math.max (0, minHeight);
1043 if ((style & SWT.NO_TRIM) is 0 && (style & trim) !is 0) {
1044 if ((style & SWT.RESIZE) !is 0) {
1045 height = Math.max (height, OS.GetSystemMetrics (OS.SM_CYMINTRACK));
1046 } else {
1047 RECT rect;
1048 int bits1 = OS.GetWindowLong (handle, OS.GWL_STYLE);
1049 int bits2 = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
1050 OS.AdjustWindowRectEx (&rect, bits1, false, bits2);
1051 height = Math.max (height, rect.bottom - rect.top);
1052 }
1053 }
1054 return new Point (width, height);
1055 }
1056
1057 /**
1058 * Returns the region that defines the shape of the shell,
1059 * or null if the shell has the default shape.
1060 *
1061 * @return the region that defines the shape of the shell (or null)
1062 *
1063 * @exception SWTException <ul>
1064 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1065 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1066 * </ul>
1067 *
1068 * @since 3.0
1069 *
1070 */
1071 public Region getRegion () {
1072 /* This method is needed for the @since 3.0 Javadoc */
1073 checkWidget ();
1074 return region;
1075 }
1076
1077 override public Shell getShell () {
1078 checkWidget ();
1079 return this;
1080 }
1081
1082 override public Point getSize () {
1083 checkWidget ();
1084 static if (!OS.IsWinCE) {
1085 if (OS.IsIconic (handle)) return super.getSize ();
1086 }
1087 RECT rect;
1088 OS.GetWindowRect (handle, &rect);
1089 int width = rect.right - rect.left;
1090 int height = rect.bottom - rect.top;
1091 return new Point (width, height);
1092 }
1093
1094 /**
1095 * Returns an array containing all shells which are
1096 * descendants of the receiver.
1097 * <p>
1098 * @return the dialog shells
1099 *
1100 * @exception SWTException <ul>
1101 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1102 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1103 * </ul>
1104 */
1105 public Shell [] getShells () {
1106 checkWidget ();
1107 int count = 0;
1108 Shell [] shells = display.getShells ();
1109 for (int i=0; i<shells.length; i++) {
1110 Control shell = shells [i];
1111 do {
1112 shell = shell.parent;
1113 } while (shell !is null && shell !is this);
1114 if (shell is this) count++;
1115 }
1116 int index = 0;
1117 Shell [] result = new Shell [count];
1118 for (int i=0; i<shells.length; i++) {
1119 Control shell = shells [i];
1120 do {
1121 shell = shell.parent;
1122 } while (shell !is null && shell !is this);
1123 if (shell is this) {
1124 result [index++] = shells [i];
1125 }
1126 }
1127 return result;
1128 }
1129
1130 override Composite findDeferredControl () {
1131 return layoutCount > 0 ? this : null;
1132 }
1133
1134 override public bool isEnabled () {
1135 checkWidget ();
1136 return getEnabled ();
1137 }
1138
1139 override public bool isVisible () {
1140 checkWidget ();
1141 return getVisible ();
1142 }
1143
1144 HWND hwndMDIClient () {
1145 if (hwndMDIClient_ is null) {
1146 int widgetStyle = OS.MDIS_ALLCHILDSTYLES | OS.WS_CHILD | OS.WS_CLIPCHILDREN | OS.WS_CLIPSIBLINGS;
1147 hwndMDIClient_ = OS.CreateWindowEx (
1148 0,
1149 StrToTCHARz("MDICLIENT"),
1150 null,
1151 widgetStyle,
1152 0, 0, 0, 0,
1153 handle,
1154 null,
1155 OS.GetModuleHandle (null),
1156 new CREATESTRUCT ());
1157 // OS.ShowWindow (hwndMDIClient_, OS.SW_SHOW);
1158 }
1159 return hwndMDIClient_;
1160 }
1161
1162 /**
1163 * Moves the receiver to the top of the drawing order for
1164 * the display on which it was created (so that all other
1165 * shells on that display, which are not the receiver's
1166 * children will be drawn behind it), marks it visible,
1167 * sets the focus and asks the window manager to make the
1168 * shell active.
1169 *
1170 * @exception SWTException <ul>
1171 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1172 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1173 * </ul>
1174 *
1175 * @see Control#moveAbove
1176 * @see Control#setFocus
1177 * @see Control#setVisible
1178 * @see Display#getActiveShell
1179 * @see Decorations#setDefaultButton(Button)
1180 * @see Shell#setActive
1181 * @see Shell#forceActive
1182 */
1183 public void open () {
1184 checkWidget ();
1185 STARTUPINFO* lpStartUpInfo = Display.lpStartupInfo;
1186 if (lpStartUpInfo is null || (lpStartUpInfo.dwFlags & OS.STARTF_USESHOWWINDOW) is 0) {
1187 bringToTop ();
1188 if (isDisposed ()) return;
1189 }
1190 /*
1191 * Feature on WinCE PPC. A new application becomes
1192 * the foreground application only if it has at least
1193 * one visible window before the event loop is started.
1194 * The workaround is to explicitly force the shell to
1195 * be the foreground window.
1196 */
1197 static if (OS.IsWinCE) OS.SetForegroundWindow (handle);
1198 OS.SendMessage (handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
1199 setVisible (true);
1200 if (isDisposed ()) return;
1201 /*
1202 * Bug in Windows XP. Despite the fact that an icon has been
1203 * set for a window, the task bar displays the wrong icon the
1204 * first time the window is made visible with ShowWindow() after
1205 * a call to BringToTop(), when a long time elapses between the
1206 * ShowWindow() and the time the event queue is read. The icon
1207 * in the window trimming is correct but the one in the task
1208 * bar does not get updated. The fix is to call PeekMessage()
1209 * with the flag PM_NOREMOVE and PM_QS_SENDMESSAGE to respond
1210 * to a cross thread WM_GETICON.
1211 *
1212 * NOTE: This allows other cross thread messages to be delivered,
1213 * most notably WM_ACTIVATE.
1214 */
1215 MSG msg;
1216 int flags = OS.PM_NOREMOVE | OS.PM_NOYIELD | OS.PM_QS_SENDMESSAGE;
1217 OS.PeekMessage (&msg, null, 0, 0, flags);
1218 if (!restoreFocus () && !traverseGroup (true)) setFocus ();
1219 }
1220
1221 public bool print (GC gc) {
1222 checkWidget ();
1223 if (gc is null) error (SWT.ERROR_NULL_ARGUMENT);
1224 if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
1225 return false;
1226 }
1227
1228 override void register () {
1229 super.register ();
1230 if (toolTipHandle_ !is null) display.addControl (toolTipHandle_, this);
1231 if (balloonTipHandle_ !is null) display.addControl (balloonTipHandle_, this);
1232 }
1233
1234 void releaseBrushes () {
1235 if (brushes !is null) {
1236 for (int i=0; i<brushes.length; i++) {
1237 if (brushes [i] !is null) OS.DeleteObject (brushes [i]);
1238 }
1239 }
1240 brushes = null;
1241 }
1242
1243 override void releaseChildren (bool destroy) {
1244 Shell [] shells = getShells ();
1245 for (int i=0; i<shells.length; i++) {
1246 Shell shell = shells [i];
1247 if (shell !is null && !shell.isDisposed ()) {
1248 shell.release (false);
1249 }
1250 }
1251 if (toolTips !is null) {
1252 for (int i=0; i<toolTips.length; i++) {
1253 ToolTip toolTip = toolTips [i];
1254 if (toolTip !is null && !toolTip.isDisposed ()) {
1255 toolTip.release (false);
1256 }
1257 }
1258 }
1259 toolTips = null;
1260 super.releaseChildren (destroy);
1261 }
1262
1263 override void releaseHandle () {
1264 super.releaseHandle ();
1265 hwndMDIClient_ = null;
1266 }
1267
1268 override void releaseParent () {
1269 /* Do nothing */
1270 }
1271
1272 override void releaseWidget () {
1273 super.releaseWidget ();
1274 releaseBrushes ();
1275 activeMenu = null;
1276 display.clearModal (this);
1277 if (lpstrTip !is null) {
1278 auto hHeap = OS.GetProcessHeap ();
1279 OS.HeapFree (hHeap, 0, lpstrTip);
1280 }
1281 lpstrTip = null;
1282 toolTipHandle_ = balloonTipHandle_ = null;
1283 if (OS.IsDBLocale) {
1284 if (hIMC !is null) OS.ImmDestroyContext (hIMC);
1285 }
1286 lastActive = null;
1287 toolTitle = balloonTitle = null;
1288 }
1289
1290 override void removeMenu (Menu menu) {
1291 super.removeMenu (menu);
1292 if (menu is activeMenu) activeMenu = null;
1293 }
1294
1295 /**
1296 * Removes the listener from the collection of listeners who will
1297 * be notified when operations are performed on the receiver.
1298 *
1299 * @param listener the listener which should no longer be notified
1300 *
1301 * @exception IllegalArgumentException <ul>
1302 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1303 * </ul>
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 * @see ShellListener
1310 * @see #addShellListener
1311 */
1312 public void removeShellListener (ShellListener listener) {
1313 checkWidget ();
1314 if (listener is null) error (SWT.ERROR_NULL_ARGUMENT);
1315 if (eventTable is null) return;
1316 eventTable.unhook (SWT.Close, listener);
1317 eventTable.unhook (SWT.Iconify,listener);
1318 eventTable.unhook (SWT.Deiconify,listener);
1319 eventTable.unhook (SWT.Activate, listener);
1320 eventTable.unhook (SWT.Deactivate, listener);
1321 }
1322
1323 LRESULT selectPalette (HPALETTE hPalette) {
1324 auto hDC = OS.GetDC (handle);
1325 auto hOld = OS.SelectPalette (hDC, hPalette, false);
1326 int result = OS.RealizePalette (hDC);
1327 if (result > 0) {
1328 OS.InvalidateRect (handle, null, true);
1329 } else {
1330 OS.SelectPalette (hDC, hOld, true);
1331 OS.RealizePalette (hDC);
1332 }
1333 OS.ReleaseDC (handle, hDC);
1334 return (result > 0) ? LRESULT.ONE : LRESULT.ZERO;
1335 }
1336
1337 bool sendKeyEvent (int type, int msg, int /*long*/ wParam, int /*long*/ lParam, Event event) {
1338 if (!isEnabled () || !isActive ()) return false;
1339 return super.sendKeyEvent (type, msg, wParam, lParam, event);
1340 }
1341
1342 /**
1343 * If the receiver is visible, moves it to the top of the
1344 * drawing order for the display on which it was created
1345 * (so that all other shells on that display, which are not
1346 * the receiver's children will be drawn behind it) and asks
1347 * the window manager to make the shell active
1348 *
1349 * @exception SWTException <ul>
1350 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1351 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1352 * </ul>
1353 *
1354 * @since 2.0
1355 * @see Control#moveAbove
1356 * @see Control#setFocus
1357 * @see Control#setVisible
1358 * @see Display#getActiveShell
1359 * @see Decorations#setDefaultButton(Button)
1360 * @see Shell#open
1361 * @see Shell#setActive
1362 */
1363 public void setActive () {
1364 checkWidget ();
1365 if (!isVisible ()) return;
1366 bringToTop ();
1367 // widget could be disposed at this point
1368 }
1369
1370 void setActiveControl (Control control) {
1371 if (control !is null && control.isDisposed ()) control = null;
1372 if (lastActive !is null && lastActive.isDisposed ()) lastActive = null;
1373 if (lastActive is control) return;
1374
1375 /*
1376 * Compute the list of controls to be activated and
1377 * deactivated by finding the first common parent
1378 * control.
1379 */
1380 Control [] activate = (control is null) ? new Control [0] : control.getPath ();
1381 Control [] deactivate = (lastActive is null) ? new Control [0] : lastActive.getPath ();
1382 lastActive = control;
1383 int index = 0, length = Math.min (activate.length, deactivate.length);
1384 while (index < length) {
1385 if (activate [index] !is deactivate [index]) break;
1386 index++;
1387 }
1388
1389 /*
1390 * It is possible (but unlikely), that application
1391 * code could have destroyed some of the widgets. If
1392 * this happens, keep processing those widgets that
1393 * are not disposed.
1394 */
1395 for (int i=deactivate.length-1; i>=index; --i) {
1396 if (!deactivate [i].isDisposed ()) {
1397 deactivate [i].sendEvent (SWT.Deactivate);
1398 }
1399 }
1400 for (int i=activate.length-1; i>=index; --i) {
1401 if (!activate [i].isDisposed ()) {
1402 activate [i].sendEvent (SWT.Activate);
1403 }
1404 }
1405 }
1406
1407 /**
1408 * Sets the receiver's alpha value which must be
1409 * between 0 (transparent) and 255 (opaque).
1410 * <p>
1411 * This operation requires the operating system's advanced
1412 * widgets subsystem which may not be available on some
1413 * platforms.
1414 * </p>
1415 * @param alpha the alpha value
1416 *
1417 * @exception SWTException <ul>
1418 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1419 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1420 * </ul>
1421 *
1422 * @since 3.4
1423 */
1424 public void setAlpha (int alpha) {
1425 checkWidget ();
1426 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) {
1427 alpha &= 0xFF;
1428 int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
1429 if (alpha is 0xFF) {
1430 OS.SetWindowLong (handle, OS.GWL_EXSTYLE, bits & ~OS.WS_EX_LAYERED);
1431 int flags = OS.RDW_ERASE | OS.RDW_INVALIDATE | OS.RDW_FRAME | OS.RDW_ALLCHILDREN;
1432 OS.RedrawWindow (handle, null, null, flags);
1433 } else {
1434 OS.SetWindowLong (handle, OS.GWL_EXSTYLE, bits | OS.WS_EX_LAYERED);
1435 OS.SetLayeredWindowAttributes (handle, 0, cast(byte)alpha, OS.LWA_ALPHA);
1436 }
1437 }
1438 }
1439
1440 override void setBounds (int x, int y, int width, int height, int flags, bool defer) {
1441 if (fullScreen) setFullScreen (false);
1442 /*
1443 * Bug in Windows. When a window has alpha and
1444 * SetWindowPos() is called with SWP_DRAWFRAME,
1445 * the contents of the window are copied rather
1446 * than allowing the windows underneath to draw.
1447 * This causes pixel corruption. The fix is to
1448 * clear the SWP_DRAWFRAME bits.
1449 */
1450 int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
1451 if ((bits & OS.WS_EX_LAYERED) !is 0) {
1452 flags &= ~OS.SWP_DRAWFRAME;
1453 }
1454 super.setBounds (x, y, width, height, flags, false);
1455 }
1456
1457 override public void setEnabled (bool enabled) {
1458 checkWidget ();
1459 if (((state & DISABLED) is 0) is enabled) return;
1460 super.setEnabled (enabled);
1461 if (enabled && handle is OS.GetActiveWindow ()) {
1462 if (!restoreFocus ()) traverseGroup (true);
1463 }
1464 }
1465
1466 /**
1467 * Sets the full screen state of the receiver.
1468 * If the argument is <code>true</code> causes the receiver
1469 * to switch to the full screen state, and if the argument is
1470 * <code>false</code> and the receiver was previously switched
1471 * into full screen state, causes the receiver to switch back
1472 * to either the maximmized or normal states.
1473 * <p>
1474 * Note: The result of intermixing calls to <code>setFullScreen(true)</code>,
1475 * <code>setMaximized(true)</code> and <code>setMinimized(true)</code> will
1476 * vary by platform. Typically, the behavior will match the platform user's
1477 * expectations, but not always. This should be avoided if possible.
1478 * </p>
1479 *
1480 * @param fullScreen the new fullscreen state
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.4
1488 */
1489 public void setFullScreen (bool fullScreen) {
1490 checkWidget();
1491 if (this.fullScreen is fullScreen) return;
1492 int stateFlags = fullScreen ? OS.SW_SHOWMAXIMIZED : OS.SW_RESTORE;
1493 int styleFlags = OS.GetWindowLong (handle, OS.GWL_STYLE);
1494 int mask = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
1495 if ((style & mask) !is 0) {
1496 if (fullScreen) {
1497 styleFlags = styleFlags & ~OS.WS_CAPTION;
1498 } else {
1499 styleFlags = styleFlags | OS.WS_CAPTION;
1500 }
1501 }
1502 if (fullScreen) wasMaximized = getMaximized ();
1503 bool visible = isVisible ();
1504 OS.SetWindowLong (handle, OS.GWL_STYLE, styleFlags);
1505 if (wasMaximized) {
1506 OS.ShowWindow (handle, OS.SW_HIDE);
1507 stateFlags = OS.SW_SHOWMAXIMIZED;
1508 }
1509 if (visible) OS.ShowWindow (handle, stateFlags);
1510 OS.UpdateWindow (handle);
1511 this.fullScreen = fullScreen;
1512 }
1513
1514 /**
1515 * Sets the input method editor mode to the argument which
1516 * should be the result of bitwise OR'ing together one or more
1517 * of the following constants defined in class <code>SWT</code>:
1518 * <code>NONE</code>, <code>ROMAN</code>, <code>DBCS</code>,
1519 * <code>PHONETIC</code>, <code>NATIVE</code>, <code>ALPHA</code>.
1520 *
1521 * @param mode the new IME mode
1522 *
1523 * @exception SWTException <ul>
1524 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1525 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1526 * </ul>
1527 *
1528 * @see SWT
1529 */
1530 public void setImeInputMode (int mode) {
1531 checkWidget ();
1532 if (!OS.IsDBLocale) return;
1533 bool imeOn = mode !is SWT.NONE;
1534 auto hIMC = OS.ImmGetContext (handle);
1535 OS.ImmSetOpenStatus (hIMC, imeOn);
1536 if (imeOn) {
1537 uint lpfdwConversion, lpfdwSentence;
1538 if (OS.ImmGetConversionStatus (hIMC, &lpfdwConversion, &lpfdwSentence)) {
1539 int newBits = 0;
1540 int oldBits = OS.IME_CMODE_NATIVE | OS.IME_CMODE_KATAKANA;
1541 if ((mode & SWT.PHONETIC) !is 0) {
1542 newBits = OS.IME_CMODE_KATAKANA | OS.IME_CMODE_NATIVE;
1543 oldBits = 0;
1544 } else {
1545 if ((mode & SWT.NATIVE) !is 0) {
1546 newBits = OS.IME_CMODE_NATIVE;
1547 oldBits = OS.IME_CMODE_KATAKANA;
1548 }
1549 }
1550 if ((mode & (SWT.DBCS | SWT.NATIVE)) !is 0) {
1551 newBits |= OS.IME_CMODE_FULLSHAPE;
1552 } else {
1553 oldBits |= OS.IME_CMODE_FULLSHAPE;
1554 }
1555 if ((mode & SWT.ROMAN) !is 0) {
1556 newBits |= OS.IME_CMODE_ROMAN;
1557 } else {
1558 oldBits |= OS.IME_CMODE_ROMAN;
1559 }
1560 lpfdwConversion |= newBits;
1561 lpfdwConversion &= ~oldBits;
1562 OS.ImmSetConversionStatus (hIMC, lpfdwConversion, lpfdwSentence);
1563 }
1564 }
1565 OS.ImmReleaseContext (handle, hIMC);
1566 }
1567
1568 /**
1569 * Sets the receiver's minimum size to the size specified by the arguments.
1570 * If the new minimum size is larger than the current size of the receiver,
1571 * the receiver is resized to the new minimum size.
1572 *
1573 * @param width the new minimum width for the receiver
1574 * @param height the new minimum height for the receiver
1575 *
1576 * @exception SWTException <ul>
1577 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1578 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1579 * </ul>
1580 *
1581 * @since 3.1
1582 */
1583 public void setMinimumSize (int width, int height) {
1584 checkWidget ();
1585 int widthLimit = 0, heightLimit = 0;
1586 int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
1587 if ((style & SWT.NO_TRIM) is 0 && (style & trim) !is 0) {
1588 widthLimit = OS.GetSystemMetrics (OS.SM_CXMINTRACK);
1589 if ((style & SWT.RESIZE) !is 0) {
1590 heightLimit = OS.GetSystemMetrics (OS.SM_CYMINTRACK);
1591 } else {
1592 RECT rect;
1593 int bits1 = OS.GetWindowLong (handle, OS.GWL_STYLE);
1594 int bits2 = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
1595 OS.AdjustWindowRectEx (&rect, bits1, false, bits2);
1596 heightLimit = rect.bottom - rect.top;
1597 }
1598 }
1599 minWidth = Math.max (widthLimit, width);
1600 minHeight = Math.max (heightLimit, height);
1601 Point size = getSize ();
1602 int newWidth = Math.max (size.x, minWidth);
1603 int newHeight = Math.max (size.y, minHeight);
1604 if (minWidth <= widthLimit) minWidth = SWT.DEFAULT;
1605 if (minHeight <= heightLimit) minHeight = SWT.DEFAULT;
1606 if (newWidth !is size.x || newHeight !is size.y) setSize (newWidth, newHeight);
1607 }
1608
1609 /**
1610 * Sets the receiver's minimum size to the size specified by the argument.
1611 * If the new minimum size is larger than the current size of the receiver,
1612 * the receiver is resized to the new minimum size.
1613 *
1614 * @param size the new minimum size for the receiver
1615 *
1616 * @exception IllegalArgumentException <ul>
1617 * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
1618 * </ul>
1619 * @exception SWTException <ul>
1620 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1621 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1622 * </ul>
1623 *
1624 * @since 3.1
1625 */
1626 public void setMinimumSize (Point size) {
1627 checkWidget ();
1628 if (size is null) error (SWT.ERROR_NULL_ARGUMENT);
1629 setMinimumSize (size.x, size.y);
1630 }
1631
1632 void setItemEnabled (int cmd, bool enabled) {
1633 auto hMenu = OS.GetSystemMenu (handle, false);
1634 if (hMenu is null) return;
1635 int flags = OS.MF_ENABLED;
1636 if (!enabled) flags = OS.MF_DISABLED | OS.MF_GRAYED;
1637 OS.EnableMenuItem (hMenu, cmd, OS.MF_BYCOMMAND | flags);
1638 }
1639
1640 override void setParent () {
1641 /* Do nothing. Not necessary for Shells */
1642 }
1643
1644 /**
1645 * Sets the shape of the shell to the region specified
1646 * by the argument. When the argument is null, the
1647 * default shape of the shell is restored. The shell
1648 * must be created with the style SWT.NO_TRIM in order
1649 * to specify a region.
1650 *
1651 * @param region the region that defines the shape of the shell (or null)
1652 *
1653 * @exception IllegalArgumentException <ul>
1654 * <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li>
1655 * </ul>
1656 * @exception SWTException <ul>
1657 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1658 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1659 * </ul>
1660 *
1661 * @since 3.0
1662 *
1663 */
1664 public void setRegion (Region region) {
1665 checkWidget ();
1666 if ((style & SWT.NO_TRIM) is 0) return;
1667 super.setRegion (region);
1668 }
1669
1670 void setToolTipText (HWND hwnd, String text) {
1671 static if (OS.IsWinCE) return;
1672 TOOLINFO lpti;
1673 lpti.cbSize = OS.TOOLINFO_sizeof;
1674 lpti.hwnd = handle;
1675 lpti.uId = cast(uint) hwnd;
1676 auto hwndToolTip = toolTipHandle ();
1677 if (text is null) {
1678 OS.SendMessage (hwndToolTip, OS.TTM_DELTOOL, 0, cast(int)&lpti);
1679 } else {
1680 if (OS.SendMessage (hwndToolTip, OS.TTM_GETTOOLINFO, 0, cast(int)&lpti) !is 0) {
1681 OS.SendMessage (hwndToolTip, OS.TTM_UPDATE, 0, 0);
1682 } else {
1683 lpti.uFlags = OS.TTF_IDISHWND | OS.TTF_SUBCLASS;
1684 lpti.lpszText = OS.LPSTR_TEXTCALLBACK;
1685 OS.SendMessage (hwndToolTip, OS.TTM_ADDTOOL, 0, cast(int)&lpti);
1686 }
1687 }
1688 }
1689
1690 void setToolTipText (NMTTDISPINFO* lpnmtdi, CHAR [] buffer) {
1691 /*
1692 * Ensure that the current position of the mouse
1693 * is inside the client area of the shell. This
1694 * prevents tool tips from popping up over the
1695 * shell trimmings.
1696 */
1697 if (!hasCursor ()) return;
1698 auto hHeap = OS.GetProcessHeap ();
1699 if (lpstrTip !is null) OS.HeapFree (hHeap, 0, lpstrTip);
1700 int byteCount = buffer.length;
1701 lpstrTip = cast(TCHAR*)OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
1702 OS.MoveMemory (lpstrTip, buffer.ptr, byteCount);
1703 lpnmtdi.lpszText = lpstrTip;
1704 }
1705
1706 void setToolTipText (NMTTDISPINFO* lpnmtdi, WCHAR [] buffer) {
1707 /*
1708 * Ensure that the current position of the mouse
1709 * is inside the client area of the shell. This
1710 * prevents tool tips from popping up over the
1711 * shell trimmings.
1712 */
1713 if (!hasCursor ()) return;
1714 auto hHeap = OS.GetProcessHeap ();
1715 if (lpstrTip !is null) OS.HeapFree (hHeap, 0, lpstrTip);
1716 int byteCount = buffer.length * 2;
1717 lpstrTip = cast(TCHAR*)OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
1718 OS.MoveMemory (lpstrTip, buffer.ptr, byteCount);
1719 lpnmtdi.lpszText = lpstrTip;
1720 }
1721
1722 void setToolTipTitle (HWND hwndToolTip, String text, HICON icon) {
1723 /*
1724 * Bug in Windows. For some reason, when TTM_SETTITLE
1725 * is used to set the title of a tool tip, Windows leaks
1726 * GDI objects. This happens even when TTM_SETTITLE is
1727 * called with TTI_NONE and NULL. The documentation
1728 * states that Windows copies the icon and that the
1729 * programmer must free the copy but does not provide
1730 * API to get the icon. For example, when TTM_SETTITLE
1731 * is called with ICON_ERROR, when TTM_GETTITLE is used
1732 * to query the title and the icon, the uTitleBitmap
1733 * field in the TTGETTITLE struct is zero. The fix
1734 * is to remember these values, only set them when then
1735 * change and leak less.
1736 *
1737 * NOTE: This only happens on Vista.
1738 */
1739 if (hwndToolTip !is toolTipHandle_ && hwndToolTip !is balloonTipHandle_) {
1740 return;
1741 }
1742 if (hwndToolTip is toolTipHandle_) {
1743 if (text is toolTitle || (toolTitle !is null && toolTitle.equals (text) )) {
1744 if (icon is toolIcon) return;
1745 }
1746 toolTitle = text;
1747 toolIcon = icon;
1748 } else {
1749 if (hwndToolTip is balloonTipHandle_) {
1750 if (text is balloonTitle || (balloonTitle !is null && balloonTitle.equals (text))) {
1751 if (icon is toolIcon) return;
1752 }
1753 balloonTitle = text;
1754 balloonIcon = icon;
1755 }
1756 }
1757 if (text !is null) {
1758 static if( OS.IsUnicode ){
1759 TCHAR* pszTitle = StrToTCHARz( text);
1760 }
1761 else {
1762 TCHAR* pszTitle = StrToTCHARz( text, getCodePage ());
1763 }
1764 OS.SendMessage (hwndToolTip, OS.TTM_SETTITLE, icon, cast(int)pszTitle);
1765 } else {
1766 OS.SendMessage (hwndToolTip, OS.TTM_SETTITLE, 0, 0);
1767 }
1768 }
1769
1770 override public void setVisible (bool visible) {
1771 checkWidget ();
1772 /*
1773 * Feature in Windows. When ShowWindow() is called used to hide
1774 * a window, Windows attempts to give focus to the parent. If the
1775 * parent is disabled by EnableWindow(), focus is assigned to
1776 * another windows on the desktop. This means that if you hide
1777 * a modal window before the parent is enabled, the parent will
1778 * not come to the front. The fix is to change the modal state
1779 * before hiding or showing a window so that this does not occur.
1780 */
1781 int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL;
1782 if ((style & mask) !is 0) {
1783 if (visible) {
1784 display.setModalShell (this);
1785 if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) !is 0) {
1786 display.setModalDialog (null);
1787 }
1788 Control control = display._getFocusControl ();
1789 if (control !is null && !control.isActive ()) {
1790 bringToTop ();
1791 if (isDisposed ()) return;
1792 }
1793 auto hwndShell = OS.GetActiveWindow ();
1794 if (hwndShell is null) {
1795 if (parent !is null) hwndShell = parent.handle;
1796 }
1797 if (hwndShell !is null) {
1798 OS.SendMessage (hwndShell, OS.WM_CANCELMODE, 0, 0);
1799 }
1800 OS.ReleaseCapture ();
1801 } else {
1802 display.clearModal (this);
1803 }
1804 } else {
1805 updateModal ();
1806 }
1807
1808 /*
1809 * Bug in Windows. Calling ShowOwnedPopups() to hide the
1810 * child windows of a hidden window causes the application
1811 * to be deactivated. The fix is to call ShowOwnedPopups()
1812 * to hide children before hiding the parent.
1813 */
1814 if (showWithParent && !visible) {
1815 static if (!OS.IsWinCE) OS.ShowOwnedPopups (handle, false);
1816 }
1817 if (!visible) fixActiveShell ();
1818 super.setVisible (visible);
1819 if (isDisposed ()) return;
1820 if (showWithParent !is visible) {
1821 showWithParent = visible;
1822 if (visible) {
1823 static if (!OS.IsWinCE) OS.ShowOwnedPopups (handle, true);
1824 }
1825 }
1826
1827 /* Make the splash screen appear in the task bar */
1828 if (visible) {
1829 if (parent !is null && (parent.state & FOREIGN_HANDLE) !is 0) {
1830 auto hwndParent = parent.handle;
1831 int style = OS.GetWindowLong (hwndParent, OS.GWL_EXSTYLE);
1832 if ((style & OS.WS_EX_TOOLWINDOW) !is 0) {
1833 OS.SetWindowLong (hwndParent, OS.GWL_EXSTYLE, style & ~OS.WS_EX_TOOLWINDOW);
1834 /*
1835 * Bug in Windows. The window does not show in the task bar when
1836 * WS_EX_TOOLWINDOW is removed after the window has already been shown.
1837 * The fix is to hide and shown the shell.
1838 */
1839 OS.ShowWindow (hwndParent, OS.SW_HIDE);
1840 OS.ShowWindow (hwndParent, OS.SW_RESTORE);
1841 }
1842 }
1843 }
1844 }
1845
1846 override void subclass () {
1847 super.subclass ();
1848 if (ToolTipProc !is null) {
1849 int /*long*/ newProc = display.windowProc;
1850 if (toolTipHandle_ !is null) {
1851 OS.SetWindowLongPtr (toolTipHandle_, OS.GWLP_WNDPROC, newProc);
1852 }
1853 if (balloonTipHandle_ !is null) {
1854 OS.SetWindowLongPtr (balloonTipHandle_, OS.GWLP_WNDPROC, newProc);
1855 }
1856 }
1857 }
1858
1859 HANDLE toolTipHandle () {
1860 if (toolTipHandle_ is null) createToolTipHandle ();
1861 return toolTipHandle_;
1862 }
1863
1864 override bool translateAccelerator (MSG* msg) {
1865 if (!isEnabled () || !isActive ()) return false;
1866 if (menuBar !is null && !menuBar.isEnabled ()) return false;
1867 return translateMDIAccelerator (msg) || translateMenuAccelerator (msg);
1868 }
1869
1870 override bool traverseEscape () {
1871 if (parent is null) return false;
1872 if (!isVisible () || !isEnabled ()) return false;
1873 close ();
1874 return true;
1875 }
1876
1877 override void unsubclass () {
1878 super.unsubclass ();
1879 if (ToolTipProc !is null) {
1880 if (toolTipHandle_ !is null) {
1881 OS.SetWindowLongPtr (toolTipHandle_, OS.GWLP_WNDPROC, cast(int)ToolTipProc);
1882 }
1883 if (toolTipHandle_ !is null) {
1884 OS.SetWindowLongPtr (toolTipHandle_, OS.GWLP_WNDPROC, cast(int)ToolTipProc);
1885 }
1886 }
1887 }
1888
1889 void updateModal () {
1890 if (Display.TrimEnabled) {
1891 setItemEnabled (OS.SC_CLOSE, isActive ());
1892 } else {
1893 OS.EnableWindow (handle, isActive ());
1894 }
1895 }
1896
1897 override CREATESTRUCT* widgetCreateStruct () {
1898 return null;
1899 }
1900
1901 override HWND widgetParent () {
1902 if (handle !is null) return handle;
1903 return parent !is null ? parent.handle : null;
1904 }
1905
1906 override int widgetExtStyle () {
1907 int bits = super.widgetExtStyle () & ~OS.WS_EX_MDICHILD;
1908 if ((style & SWT.TOOL) !is 0) bits |= OS.WS_EX_TOOLWINDOW;
1909
1910 /*
1911 * Feature in Windows. When a window that does not have a parent
1912 * is created, it is automatically added to the Windows Task Bar,
1913 * even when it has no title. The fix is to use WS_EX_TOOLWINDOW
1914 * which does not cause the window to appear in the Task Bar.
1915 */
1916 static if (!OS.IsWinCE) {
1917 if (parent is null) {
1918 if ((style & SWT.ON_TOP) !is 0) {
1919 int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
1920 if ((style & SWT.NO_TRIM) !is 0 || (style & trim) is 0) {
1921 bits |= OS.WS_EX_TOOLWINDOW;
1922 }
1923 }
1924 }
1925 }
1926
1927 /*
1928 * Bug in Windows 98 and NT. Creating a window with the
1929 * WS_EX_TOPMOST extended style can result in a dialog shell
1930 * being moved behind its parent. The exact case where this
1931 * happens is a shell with two dialog shell children where
1932 * each dialog child has another hidden dialog child with
1933 * the WS_EX_TOPMOST extended style. Clicking on either of
1934 * the visible dialogs causes them to become active but move
1935 * to the back, behind the parent shell. The fix is to
1936 * disallow the WS_EX_TOPMOST extended style on Windows 98
1937 * and NT.
1938 */
1939 if (parent !is null) {
1940 if (OS.IsWin95) return bits;
1941 if (OS.WIN32_VERSION < OS.VERSION (4, 10)) {
1942 return bits;
1943 }
1944 }
1945 if ((style & SWT.ON_TOP) !is 0) bits |= OS.WS_EX_TOPMOST;
1946 return bits;
1947 }
1948
1949 override String windowClass () {
1950 static if (OS.IsSP) return DialogClass;
1951 if ((style & SWT.TOOL) !is 0) {
1952 int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX | SWT.BORDER | SWT.RESIZE;
1953 if ((style & trim) is 0) return TCHARsToStr( display.windowShadowClass );
1954 }
1955 return parent !is null ? TCHARzToStr(DialogClass.ptr) : super.windowClass ();
1956 }
1957
1958 override int windowProc () {
1959 if (windowProc_ !is null) return cast(int) windowProc_;
1960 static if (OS.IsSP) return cast(int) DialogProc;
1961 if ((style & SWT.TOOL) !is 0) {
1962 int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX | SWT.BORDER | SWT.RESIZE;
1963 if ((style & trim) is 0) return super.windowProc ();
1964 }
1965 return parent !is null ? cast(int) DialogProc : super.windowProc ();
1966 }
1967
1968 override int windowProc (HWND hwnd, int msg, int wParam, int lParam) {
1969 if (handle is null) return 0;
1970 if (hwnd is toolTipHandle_ || hwnd is balloonTipHandle_) {
1971 switch (msg) {
1972 case OS.WM_TIMER: {
1973 if (wParam !is ToolTip.TIMER_ID) break;
1974 ToolTip tip = getCurrentToolTip (hwnd);
1975 if (tip !is null && tip.autoHide) {
1976 tip.setVisible (false);
1977 }
1978 break;
1979 }
1980 case OS.WM_LBUTTONDOWN: {
1981 ToolTip tip = getCurrentToolTip (hwnd);
1982 if (tip !is null) {
1983 tip.setVisible (false);
1984 tip.postEvent (SWT.Selection);
1985 }
1986 break;
1987 }
1988 default:
1989 }
1990 return callWindowProc (hwnd, msg, wParam, lParam);
1991 }
1992 return super.windowProc (hwnd, msg, wParam, lParam);
1993 }
1994
1995 override int widgetStyle () {
1996 int bits = super.widgetStyle ();
1997 if (handle !is null) return bits | OS.WS_CHILD;
1998 bits &= ~OS.WS_CHILD;
1999 /*
2000 * Feature in WinCE. Calling CreateWindowEx () with WS_OVERLAPPED
2001 * and a parent window causes the new window to become a WS_CHILD of
2002 * the parent instead of a dialog child. The fix is to use WS_POPUP
2003 * for a window with a parent.
2004 *
2005 * Feature in WinCE PPC. A window without a parent with WS_POPUP
2006 * always shows on top of the Pocket PC 'Today Screen'. The fix
2007 * is to not set WS_POPUP for a window without a parent on WinCE
2008 * devices.
2009 *
2010 * NOTE: WS_POPUP causes CreateWindowEx () to ignore CW_USEDEFAULT
2011 * and causes the default window location and size to be zero.
2012 */
2013 static if (OS.IsWinCE) {
2014 if (OS.IsSP) return bits | OS.WS_POPUP;
2015 return parent is null ? bits : bits | OS.WS_POPUP;
2016 }
2017
2018 /*
2019 * Use WS_OVERLAPPED for all windows, either dialog or top level
2020 * so that CreateWindowEx () will respect CW_USEDEFAULT and set
2021 * the default window location and size.
2022 *
2023 * NOTE: When a WS_OVERLAPPED window is created, Windows gives
2024 * the new window WS_CAPTION style bits. These two constants are
2025 * as follows:
2026 *
2027 * WS_OVERLAPPED = 0
2028 * WS_CAPTION = WS_BORDER | WS_DLGFRAME
2029 *
2030 */
2031 return bits | OS.WS_OVERLAPPED | OS.WS_CAPTION;
2032 }
2033
2034 override LRESULT WM_ACTIVATE (int wParam, int lParam) {
2035 static if (OS.IsPPC) {
2036 /*
2037 * Note: this does not work when we get WM_ACTIVATE prior
2038 * to adding a listener.
2039 */
2040 if (hooks (SWT.HardKeyDown) || hooks (SWT.HardKeyUp)) {
2041 int fActive = OS.LOWORD (wParam);
2042 int /*long*/ hwnd = fActive !is 0 ? handle : 0;
2043 for (int bVk=OS.VK_APP1; bVk<=OS.VK_APP6; bVk++) {
2044 OS.SHSetAppKeyWndAssoc (cast(byte) bVk, hwnd);
2045 }
2046 }
2047 /* Restore SIP state when window is activated */
2048 if (OS.LOWORD (wParam) !is 0) {
2049 OS.SHSipPreference (handle, psai.fSipUp is 0 ? OS.SIP_DOWN : OS.SIP_UP);
2050 }
2051 }
2052
2053 /*
2054 * Bug in Windows XP. When a Shell is deactivated, the
2055 * IME composition window does not go away. This causes
2056 * repaint issues. The fix is to commit the composition
2057 * string.
2058 */
2059 if (OS.WIN32_VERSION >= OS.VERSION (5, 1)) {
2060 if (OS.LOWORD (wParam) is 0 && OS.IsDBLocale && hIMC !is null) {
2061 if (OS.ImmGetOpenStatus (hIMC)) {
2062 OS.ImmNotifyIME (hIMC, OS.NI_COMPOSITIONSTR, OS.CPS_COMPLETE, 0);
2063 }
2064 }
2065 }
2066
2067 /* Process WM_ACTIVATE */
2068 LRESULT result = super.WM_ACTIVATE (wParam, lParam);
2069 if (OS.LOWORD (wParam) is 0) {
2070 if (lParam is 0 || (cast(HANDLE)lParam !is toolTipHandle_ && cast(HANDLE)lParam !is balloonTipHandle_)) {
2071 ToolTip tip = getCurrentToolTip ();
2072 if (tip !is null) tip.setVisible (false);
2073 }
2074 }
2075 return parent !is null ? LRESULT.ZERO : result;
2076 }
2077
2078 override LRESULT WM_COMMAND (int wParam, int lParam) {
2079 static if (OS.IsPPC) {
2080 /*
2081 * Note in WinCE PPC: Close the Shell when the "Done Button" has
2082 * been pressed. lParam is either 0 (PocketPC 2002) or the handle
2083 * to the Shell (PocketPC).
2084 */
2085 int loWord = OS.LOWORD (wParam);
2086 if (loWord is OS.IDOK && (lParam is 0 || lParam is handle)) {
2087 OS.PostMessage (handle, OS.WM_CLOSE, 0, 0);
2088 return LRESULT.ZERO;
2089 }
2090 }
2091 /*
2092 * Feature in Windows. On PPC, the menu is not actually an HMENU.
2093 * By observation, it is a tool bar that is configured to look like
2094 * a menu. Therefore, when the PPC menu sends WM_COMMAND messages,
2095 * lParam is not zero because the WM_COMMAND was not sent from a menu.
2096 * Sub menu item events originate from the menu bar. Top menu items
2097 * events originate from a tool bar. The fix is to detect the source
2098 * of the WM_COMMAND and set lParam to zero to pretend that the message
2099 * came from a real Windows menu, not a tool bar.
2100 */
2101 static if (OS.IsPPC || OS.IsSP) {
2102 if (menuBar !is null) {
2103 auto hwndCB = menuBar.hwndCB;
2104 if (lParam !is 0 && hwndCB !is null) {
2105 if (lParam is hwndCB) {
2106 return super.WM_COMMAND (wParam, 0);
2107 } else {
2108 int /*long*/ hwndChild = OS.GetWindow (hwndCB, OS.GW_CHILD);
2109 if (lParam is hwndChild) return super.WM_COMMAND (wParam, 0);
2110 }
2111 }
2112 }
2113 }
2114 return super.WM_COMMAND (wParam, lParam);
2115 }
2116
2117 override LRESULT WM_DESTROY (int wParam, int lParam) {
2118 LRESULT result = super.WM_DESTROY (wParam, lParam);
2119 /*
2120 * When the shell is a WS_CHILD window of a non-SWT
2121 * window, the destroy code does not get called because
2122 * the non-SWT window does not call dispose (). Instead,
2123 * the destroy code is called here in WM_DESTROY.
2124 */
2125 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
2126 if ((bits & OS.WS_CHILD) !is 0) {
2127 releaseParent ();
2128 release (false);
2129 }
2130 return result;
2131 }
2132
2133 override LRESULT WM_ERASEBKGND (int wParam, int lParam) {
2134 LRESULT result = super.WM_ERASEBKGND (wParam, lParam);
2135 if (result !is null) return result;
2136 /*
2137 * Feature in Windows. When a shell is resized by dragging
2138 * the resize handles, Windows temporarily fills in black
2139 * rectangles where the new contents of the shell should
2140 * draw. The fix is to always draw the background of shells.
2141 *
2142 * NOTE: This only happens on Vista.
2143 */
2144 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) {
2145 drawBackground (cast(HDC)wParam);
2146 return LRESULT.ONE;
2147 }
2148 return result;
2149 }
2150
2151 override LRESULT WM_ENTERIDLE (int wParam, int lParam) {
2152 LRESULT result = super.WM_ENTERIDLE (wParam, lParam);
2153 if (result !is null) return result;
2154 if (display.runMessages) {
2155 if (display.runAsyncMessages (false)) display.wakeThread ();
2156 }
2157 return result;
2158 }
2159
2160 override LRESULT WM_GETMINMAXINFO (int wParam, int lParam) {
2161 LRESULT result = super.WM_GETMINMAXINFO (wParam, lParam);
2162 if (result !is null) return result;
2163 if (minWidth !is SWT.DEFAULT || minHeight !is SWT.DEFAULT) {
2164 MINMAXINFO* info = cast(MINMAXINFO*)lParam;
2165 //OS.MoveMemory (info, lParam, MINMAXINFO.sizeof);
2166 if (minWidth !is SWT.DEFAULT) info.ptMinTrackSize.x = minWidth;
2167 if (minHeight !is SWT.DEFAULT) info.ptMinTrackSize.y = minHeight;
2168 //OS.MoveMemory (lParam, info, MINMAXINFO.sizeof);
2169 return LRESULT.ZERO;
2170 }
2171 return result;
2172 }
2173
2174 override LRESULT WM_MOUSEACTIVATE (int wParam, int lParam) {
2175 LRESULT result = super.WM_MOUSEACTIVATE (wParam, lParam);
2176 if (result !is null) return result;
2177
2178 /*
2179 * Check for WM_MOUSEACTIVATE when an MDI shell is active
2180 * and stop the normal shell activation but allow the mouse
2181 * down to be delivered.
2182 */
2183 int hittest = cast(short) OS.LOWORD (lParam);
2184 switch (hittest) {
2185 case OS.HTERROR:
2186 case OS.HTTRANSPARENT:
2187 case OS.HTNOWHERE:
2188 break;
2189 default: {
2190 Control control = display._getFocusControl ();
2191 if (control !is null) {
2192 Decorations decorations = control.menuShell ();
2193 if (decorations.getShell () is this && decorations !is this) {
2194 display.ignoreRestoreFocus = true;
2195 display.lastHittest = hittest;
2196 display.lastHittestControl = null;
2197 if (hittest is OS.HTMENU || hittest is OS.HTSYSMENU) {
2198 display.lastHittestControl = control;
2199 return null;
2200 }
2201 if (OS.IsWin95 && hittest is OS.HTCAPTION) {
2202 display.lastHittestControl = control;
2203 }
2204 return new LRESULT (OS.MA_NOACTIVATE);
2205 }
2206 }
2207 }
2208 }
2209 if (hittest is OS.HTMENU) return null;
2210
2211 /*
2212 * Get the current location of the cursor,
2213 * not the location of the cursor when the
2214 * WM_MOUSEACTIVATE was generated. This is
2215 * strictly incorrect but is necessary in
2216 * order to support Activate and Deactivate
2217 * events for embedded widgets that have
2218 * their own event loop. In that case, the
2219 * cursor location reported by GetMessagePos()
2220 * is the one for our event loop, not the
2221 * embedded widget's event loop.
2222 */
2223 POINT pt;
2224 if (!OS.GetCursorPos (&pt)) {
2225 int pos = OS.GetMessagePos ();
2226 OS.POINTSTOPOINT (pt, pos);
2227 }
2228 auto hwnd = OS.WindowFromPoint (pt);
2229 if (hwnd is null) return null;
2230 Control control = display.findControl (hwnd);
2231
2232 /*
2233 * When a shell is created with SWT.ON_TOP and SWT.NO_FOCUS,
2234 * do not activate the shell when the user clicks on the
2235 * the client area or on the border or a control within the
2236 * shell that does not take focus.
2237 */
2238 if (control !is null && (control.state & CANVAS) !is 0) {
2239 if ((control.style & SWT.NO_FOCUS) !is 0) {
2240 int bits = SWT.ON_TOP | SWT.NO_FOCUS;
2241 if ((style & bits) is bits) {
2242 if (hittest is OS.HTBORDER || hittest is OS.HTCLIENT) {
2243 return new LRESULT (OS.MA_NOACTIVATE);
2244 }
2245 }
2246 }
2247 }
2248
2249 int /*long*/ code = callWindowProc (handle, OS.WM_MOUSEACTIVATE, wParam, lParam);
2250 setActiveControl (control);
2251 return new LRESULT (code);
2252 }
2253
2254 override LRESULT WM_MOVE (int wParam, int lParam) {
2255 LRESULT result = super.WM_MOVE (wParam, lParam);
2256 if (result !is null) return result;
2257 ToolTip tip = getCurrentToolTip ();
2258 if (tip !is null) tip.setVisible (false);
2259 return result;
2260 }
2261
2262 override LRESULT WM_NCHITTEST (int wParam, int lParam) {
2263 if (!OS.IsWindowEnabled (handle)) return null;
2264 if (!isEnabled () || !isActive ()) {
2265 if (!Display.TrimEnabled) return new LRESULT (OS.HTNOWHERE);
2266 int /*long*/ hittest = callWindowProc (handle, OS.WM_NCHITTEST, wParam, lParam);
2267 if (hittest is OS.HTCLIENT || hittest is OS.HTMENU) hittest = OS.HTBORDER;
2268 return new LRESULT (hittest);
2269 }
2270 if (menuBar !is null && !menuBar.getEnabled ()) {
2271 int /*long*/ hittest = callWindowProc (handle, OS.WM_NCHITTEST, wParam, lParam);
2272 if (hittest is OS.HTMENU) hittest = OS.HTBORDER;
2273 return new LRESULT (hittest);
2274 }
2275 return null;
2276 }
2277
2278 override LRESULT WM_NCLBUTTONDOWN (int wParam, int lParam) {
2279 LRESULT result = super.WM_NCLBUTTONDOWN (wParam, lParam);
2280 if (result !is null) return result;
2281 /*
2282 * When the normal activation was interrupted in WM_MOUSEACTIVATE
2283 * because the active shell was an MDI shell, set the active window
2284 * to the top level shell but lock the active window and stop focus
2285 * changes. This allows the user to interact the top level shell
2286 * in the normal manner.
2287 */
2288 if (!display.ignoreRestoreFocus) return result;
2289 Display display = this.display;
2290 HWND hwndActive;
2291 bool fixActive = OS.IsWin95 && display.lastHittest is OS.HTCAPTION;
2292 if (fixActive) hwndActive = OS.SetActiveWindow (handle);
2293 display.lockActiveWindow = true;
2294 int /*long*/ code = callWindowProc (handle, OS.WM_NCLBUTTONDOWN, wParam, lParam);
2295 display.lockActiveWindow = false;
2296 if (fixActive) OS.SetActiveWindow (hwndActive);
2297 Control focusControl = display.lastHittestControl;
2298 if (focusControl !is null && !focusControl.isDisposed ()) {
2299 focusControl.setFocus ();
2300 }
2301 display.lastHittestControl = null;
2302 display.ignoreRestoreFocus = false;
2303 return new LRESULT (code);
2304 }
2305
2306 override LRESULT WM_PALETTECHANGED (int wParam, int lParam) {
2307 if ( cast(HANDLE)wParam !is handle) {
2308 auto hPalette = display.hPalette;
2309 if (hPalette !is null) return selectPalette (hPalette);
2310 }
2311 return super.WM_PALETTECHANGED (wParam, lParam);
2312 }
2313
2314 override LRESULT WM_QUERYNEWPALETTE (int wParam, int lParam) {
2315 auto hPalette = display.hPalette;
2316 if (hPalette !is null) return selectPalette (hPalette);
2317 return super.WM_QUERYNEWPALETTE (wParam, lParam);
2318 }
2319
2320 override LRESULT WM_SETCURSOR (int wParam, int lParam) {
2321 /*
2322 * Feature in Windows. When the shell is disabled
2323 * by a Windows standard dialog (like a MessageBox
2324 * or FileDialog), clicking in the shell does not
2325 * bring the shell or the dialog to the front. The
2326 * fix is to detect this case and bring the shell
2327 * forward.
2328 */
2329 int msg = OS.HIWORD (lParam);
2330 if (msg is OS.WM_LBUTTONDOWN) {
2331 if (!Display.TrimEnabled) {
2332 Shell modalShell = display.getModalShell ();
2333 if (modalShell !is null && !isActive ()) {
2334 auto hwndModal = modalShell.handle;
2335 if (OS.IsWindowEnabled (hwndModal)) {
2336 OS.SetActiveWindow (hwndModal);
2337 }
2338 }
2339 }
2340 if (!OS.IsWindowEnabled (handle)) {
2341 static if (!OS.IsWinCE) {
2342 auto hwndPopup = OS.GetLastActivePopup (handle);
2343 if (hwndPopup !is null && hwndPopup !is handle) {
2344 if (display.getControl (hwndPopup) is null) {
2345 if (OS.IsWindowEnabled (hwndPopup)) {
2346 OS.SetActiveWindow (hwndPopup);
2347 }
2348 }
2349 }
2350 }
2351 }
2352 }
2353 /*
2354 * When the shell that contains a cursor is disabled,
2355 * WM_SETCURSOR is called with HTERROR. Normally,
2356 * when a control is disabled, the parent will get
2357 * mouse and cursor events. In the case of a disabled
2358 * shell, there is no enabled parent. In order to
2359 * show the cursor when a shell is disabled, it is
2360 * necessary to override WM_SETCURSOR when called
2361 * with HTERROR to set the cursor but only when the
2362 * mouse is in the client area of the shell.
2363 */
2364 int hitTest = cast(short) OS.LOWORD (lParam);
2365 if (hitTest is OS.HTERROR) {
2366 if (!getEnabled ()) {
2367 Control control = display.getControl (cast(HANDLE)wParam);
2368 if (control is this && cursor !is null) {
2369 POINT pt;
2370 int pos = OS.GetMessagePos ();
2371 OS.POINTSTOPOINT (pt, pos);
2372 OS.ScreenToClient (handle, &pt);
2373 RECT rect;
2374 OS.GetClientRect (handle, &rect);
2375 if (OS.PtInRect (&rect, pt)) {
2376 OS.SetCursor (cursor.handle);
2377 switch (msg) {
2378 case OS.WM_LBUTTONDOWN:
2379 case OS.WM_RBUTTONDOWN:
2380 case OS.WM_MBUTTONDOWN:
2381 case OS.WM_XBUTTONDOWN:
2382 OS.MessageBeep (OS.MB_OK);
2383 default:
2384 }
2385 return LRESULT.ONE;
2386 }
2387 }
2388 }
2389 }
2390 return super.WM_SETCURSOR (wParam, lParam);
2391 }
2392
2393 override LRESULT WM_SETTINGCHANGE (int wParam, int lParam) {
2394 LRESULT result = super.WM_SETTINGCHANGE (wParam, lParam);
2395 if (result !is null) return result;
2396 static if (OS.IsPPC) {
2397 if (wParam is OS.SPI_SETSIPINFO) {
2398 /*
2399 * The SIP is in a new state. Cache its new value.
2400 * Resize the Shell if it has the style SWT.RESIZE.
2401 * Note that SHHandleWMSettingChange resizes the
2402 * Shell and also updates the cached state.
2403 */
2404 if ((style & SWT.RESIZE) !is 0) {
2405 OS.SHHandleWMSettingChange (handle, wParam, lParam, psai);
2406 return LRESULT.ZERO;
2407 } else {
2408 SIPINFO pSipInfo;
2409 pSipInfo.cbSize = SIPINFO.sizeof;
2410 OS.SipGetInfo (&pSipInfo);
2411 psai.fSipUp = pSipInfo.fdwFlags & OS.SIPF_ON;
2412 }
2413 }
2414 }
2415 return result;
2416 }
2417
2418 override LRESULT WM_SHOWWINDOW (int wParam, int lParam) {
2419 LRESULT result = super.WM_SHOWWINDOW (wParam, lParam);
2420 if (result !is null) return result;
2421 /*
2422 * Bug in Windows. If the shell is hidden while the parent
2423 * is iconic, Windows shows the shell when the parent is
2424 * deiconified. This does not happen if the shell is hidden
2425 * while the parent is not an icon. The fix is to track
2426 * visible state for the shell and refuse to show the shell
2427 * when the parent is shown.
2428 */
2429 if (lParam is OS.SW_PARENTOPENING) {
2430 Control control = this;
2431 while (control !is null) {
2432 Shell shell = control.getShell ();
2433 if (!shell.showWithParent) return LRESULT.ZERO;
2434 control = control.parent;
2435 }
2436 }
2437 return result;
2438 }
2439
2440 override LRESULT WM_SYSCOMMAND (int wParam, int lParam) {
2441 LRESULT result = super.WM_SYSCOMMAND (wParam, lParam);
2442 if (result !is null) return result;
2443 /*
2444 * Feature in Windows. When the last visible window in
2445 * a process minimized, Windows swaps out the memory for
2446 * the process. The assumption is that the user can no
2447 * longer interact with the window, so the memory can be
2448 * released to other applications. However, for programs
2449 * that use a lot of memory, swapping the memory back in
2450 * can take a long time, sometimes minutes. The fix is
2451 * to intercept WM_SYSCOMMAND looking for SC_MINIMIZE
2452 * and use ShowWindow() with SW_SHOWMINIMIZED to minimize
2453 * the window, rather than running the default window proc.
2454 *
2455 * NOTE: The default window proc activates the next
2456 * top-level window in the Z-order while ShowWindow()
2457 * with SW_SHOWMINIMIZED does not. There is no fix for
2458 * this at this time.
2459 */
2460 if (OS.IsWinNT) {
2461 int cmd = wParam & 0xFFF0;
2462 switch (cmd) {
2463 case OS.SC_MINIMIZE:
2464 long memory = RuntimeTotalMemory ();
2465 if (memory >= 32 * 1024 * 1024) {
2466 OS.ShowWindow (handle, OS.SW_SHOWMINIMIZED);
2467 return LRESULT.ZERO;
2468 }
2469 default:
2470 }
2471 }
2472 return result;
2473 }
2474
2475 override LRESULT WM_WINDOWPOSCHANGING (int wParam, int lParam) {
2476 LRESULT result = super.WM_WINDOWPOSCHANGING (wParam,lParam);
2477 if (result !is null) return result;
2478 auto lpwp = cast(WINDOWPOS*)lParam;
2479 //OS.MoveMemory (lpwp, lParam, WINDOWPOS.sizeof);
2480 if ((lpwp.flags & OS.SWP_NOSIZE) is 0) {
2481 lpwp.cx = Math.max (lpwp.cx, minWidth);
2482 int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
2483 if ((style & SWT.NO_TRIM) is 0 && (style & trim) !is 0) {
2484 lpwp.cx = Math.max (lpwp.cx, OS.GetSystemMetrics (OS.SM_CXMINTRACK));
2485 }
2486 lpwp.cy = Math.max (lpwp.cy, minHeight);
2487 if ((style & SWT.NO_TRIM) is 0 && (style & trim) !is 0) {
2488 if ((style & SWT.RESIZE) !is 0) {
2489 lpwp.cy = Math.max (lpwp.cy, OS.GetSystemMetrics (OS.SM_CYMINTRACK));
2490 } else {
2491 RECT rect;
2492 int bits1 = OS.GetWindowLong (handle, OS.GWL_STYLE);
2493 int bits2 = OS.GetWindowLong (handle, OS.GWL_EXSTYLE);
2494 OS.AdjustWindowRectEx (&rect, bits1, false, bits2);
2495 lpwp.cy = Math.max (lpwp.cy, rect.bottom - rect.top);
2496 }
2497 }
2498 //OS.MoveMemory (lParam, lpwp, WINDOWPOS.sizeof);
2499 }
2500 return result;
2501 }
2502 }
2503