001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Michael Danilov, Dmitry A. Durnev
019: * @version $Revision$
020: */package org.apache.harmony.awt.wtk.windows;
021:
022: import java.awt.Frame;
023: import java.awt.Image;
024: import java.awt.Insets;
025: import java.awt.Point;
026: import java.awt.Rectangle;
027:
028: import org.apache.harmony.awt.gl.MultiRectArea;
029: import org.apache.harmony.awt.gl.Surface;
030: import org.apache.harmony.awt.nativebridge.windows.Win32;
031: import org.apache.harmony.awt.nativebridge.windows.WinManagement;
032: import org.apache.harmony.awt.nativebridge.windows.WindowsDefs;
033: import org.apache.harmony.awt.wtk.CreationParams;
034: import org.apache.harmony.awt.wtk.NativeWindow;
035:
036: final class WinWindow implements NativeWindow {
037:
038: static final Win32 win32 = Win32.getInstance();
039: Surface surface;
040:
041: private final WinWindowFactory factory;
042:
043: final long hwnd;
044: boolean focusable;
045:
046: final boolean undecorated;
047: final boolean child;
048: final boolean popup;
049:
050: private boolean iconified;
051: private boolean maximized;
052:
053: Rectangle maximizedBounds;
054:
055: WinWindow(long hwnd, WinWindowFactory factory, CreationParams cp) {
056: this .hwnd = hwnd;
057: this .factory = factory;
058:
059: focusable = true;
060: if (cp != null) {
061: child = cp.child;
062: iconified = cp.iconified;
063: maximized = (cp.maximizedState == cp.MAXIMIZED);
064: popup = (cp.decorType == CreationParams.DECOR_TYPE_POPUP);
065: undecorated = (cp.decorType == CreationParams.DECOR_TYPE_UNDECOR)
066: || cp.undecorated || popup;
067: focusable = (cp.decorType != CreationParams.DECOR_TYPE_POPUP);
068: } else {
069: undecorated = false;
070: child = false;
071: popup = false;
072: }
073: }
074:
075: // for EmbeddedWindow
076: WinWindow(long hwnd, WinWindowFactory factory) {
077: this .hwnd = hwnd;
078: this .factory = factory;
079:
080: focusable = true;
081: child = true;
082: popup = false;
083: iconified = false;
084: maximized = false;
085: undecorated = true;
086: }
087:
088: void postCreate(CreationParams cp) {
089: if (cp == null) {
090: return;
091: }
092: if (!cp.resizable && !cp.child) {
093: modifyStyle(WindowsDefs.WS_SIZEBOX
094: | WindowsDefs.WS_MAXIMIZEBOX, false);
095: }
096: }
097:
098: boolean trackMouseEvent() {
099: Win32.TRACKMOUSEEVENT tme = win32.createTRACKMOUSEEVENT(false);
100: tme.set_cbSize(tme.size());
101: tme.set_dwFlags(WindowsDefs.TME_LEAVE);
102: tme.set_hwndTrack(hwnd);
103: int result = win32.TrackMouseEvent(tme);
104: return result != 0;
105: }
106:
107: public void setVisible(final boolean visible) {
108: WinEventQueue.Task task = new WinEventQueue.Task() {
109: @Override
110: public void perform() {
111: int cmd;
112: if (visible) {
113: cmd = iconified ? WindowsDefs.SW_SHOWMINNOACTIVE
114: : WindowsDefs.SW_SHOW;
115: } else {
116: cmd = WindowsDefs.SW_HIDE;
117: }
118:
119: win32.ShowWindow(hwnd, cmd);
120: }
121: };
122: factory.eventQueue.performTask(task);
123: }
124:
125: public void setBounds(final int x, final int y, final int w,
126: final int h, final int boundsMask) {
127: WinEventQueue.Task task = new WinEventQueue.Task() {
128: @Override
129: public void perform() {
130: if (iconified || maximized) {
131: setNotNormalBounds(x, y, w, h, boundsMask);
132: } else {
133: setNormalBounds(x, y, w, h, boundsMask);
134: }
135: }
136: };
137: factory.eventQueue.performTask(task);
138: }
139:
140: private void setNotNormalBounds(int x, int y, int w, int h,
141: int boundsMask) {
142: Win32.WINDOWPLACEMENT placement = win32
143: .createWINDOWPLACEMENT(false);
144: Win32.RECT rect = placement.get_rcNormalPosition();
145:
146: win32.GetWindowPlacement(hwnd, placement);
147: placement.set_length(placement.size());
148: placement.set_showCmd(iconified ? WindowsDefs.SW_MINIMIZE
149: : WindowsDefs.SW_SHOWNORMAL);
150:
151: if ((boundsMask & BOUNDS_NOMOVE) == 0) {
152: int oldX = rect.get_left();
153: int oldY = rect.get_top();
154:
155: rect.set_left(x);
156: rect.set_top(y);
157: rect.set_right(rect.get_right() + (x - oldX));
158: rect.set_bottom(rect.get_bottom() + (y - oldY));
159: }
160: if ((boundsMask & BOUNDS_NOSIZE) == 0) {
161: rect.set_right(rect.get_left() + w);
162: rect.set_bottom(rect.get_top() + h);
163: }
164:
165: win32.SetWindowPlacement(hwnd, placement);
166: }
167:
168: private void setNormalBounds(int x, int y, int w, int h,
169: int boundsMask) {
170: Rectangle bounds = getBounds();
171:
172: if ((bounds.x == x) && (bounds.y == y) && (bounds.width == w)
173: && (bounds.height == h)) {
174: win32.UpdateWindow(hwnd);
175: } else {
176: int flags = WindowsDefs.SWP_NOZORDER
177: | WindowsDefs.SWP_NOACTIVATE;
178: int dx = 0;
179: int dy = 0;
180:
181: if ((boundsMask & BOUNDS_NOMOVE) != 0) {
182: flags |= WindowsDefs.SWP_NOMOVE;
183: }
184: if ((boundsMask & BOUNDS_NOSIZE) != 0) {
185: flags |= WindowsDefs.SWP_NOSIZE;
186: }
187: if (child) {
188: long hwndParent = win32.GetParent(hwnd);
189: Insets insets = factory.getInsets(hwndParent);
190: dx = insets.left;
191: dy = insets.top;
192: flags |= WindowsDefs.SWP_NOCOPYBITS;
193: }
194:
195: win32.SetWindowPos(hwnd, 0, x - dx, y - dy, w, h, flags);
196: }
197: }
198:
199: public Rectangle getBounds() {
200: return factory.getWindowBounds(hwnd);
201: }
202:
203: public long getId() {
204: return hwnd;
205: }
206:
207: public Insets getInsets() {
208: return factory.getInsets(hwnd);
209: }
210:
211: public void setEnabled(final boolean value) {
212: WinEventQueue.Task task = new WinEventQueue.Task() {
213: @Override
214: public void perform() {
215: win32.EnableWindow(hwnd, value ? 1 : 0);
216: }
217: };
218: factory.eventQueue.performTask(task);
219: }
220:
221: public void dispose() {
222: WinEventQueue.Task task = new WinEventQueue.Task() {
223: @Override
224: public void perform() {
225: factory.remove(WinWindow.this );
226: win32.DestroyWindow(hwnd);
227: }
228: };
229: factory.eventQueue.performTask(task);
230: }
231:
232: /**
233: * @see org.apache.harmony.awt.wtk.NativeWindow#placeAfter(org.apache.harmony.awt.wtk.NativeWindow)
234: */
235: public void placeAfter(final NativeWindow w) {
236: WinEventQueue.Task task = new WinEventQueue.Task() {
237: @Override
238: public void perform() {
239: long hwndPrev = (w == null ? WindowsDefs.HWND_TOP : w
240: .getId());
241: int flags = WindowsDefs.SWP_NOMOVE
242: | WindowsDefs.SWP_NOSIZE;
243: win32.SetWindowPos(hwnd, hwndPrev, 0, 0, 0, 0, flags);
244: }
245: };
246: factory.eventQueue.performTask(task);
247: }
248:
249: public void toFront() {
250: WinEventQueue.Task task = new WinEventQueue.Task() {
251: @Override
252: public void perform() {
253: int flags = WindowsDefs.SWP_NOMOVE
254: | WindowsDefs.SWP_NOSIZE;
255: win32.SetWindowPos(hwnd, WindowsDefs.HWND_TOP, 0, 0, 0,
256: 0, flags);
257: win32.SetForegroundWindow(hwnd);
258: }
259: };
260: factory.eventQueue.performTask(task);
261: }
262:
263: public void toBack() {
264: WinEventQueue.Task task = new WinEventQueue.Task() {
265: @Override
266: public void perform() {
267: int flags = WindowsDefs.SWP_NOMOVE
268: | WindowsDefs.SWP_NOSIZE;
269: win32.SetWindowPos(hwnd, WindowsDefs.HWND_BOTTOM, 0, 0,
270: 0, 0, flags);
271: }
272: };
273: factory.eventQueue.performTask(task);
274: }
275:
276: public boolean setFocus(final boolean focus) {
277: WinEventQueue.Task task = new WinEventQueue.Task() {
278: @Override
279: public void perform() {
280: long res = win32.SetFocus(focus ? hwnd : 0);
281: returnValue = new Boolean(res != 0);
282: }
283: };
284: factory.eventQueue.performTask(task);
285: return ((Boolean) task.returnValue).booleanValue();
286: }
287:
288: public void setTitle(final String title) {
289: WinEventQueue.Task task = new WinEventQueue.Task() {
290: @Override
291: public void perform() {
292: win32.SetWindowTextW(hwnd, title);
293: }
294: };
295: factory.eventQueue.performTask(task);
296: }
297:
298: public void setResizable(final boolean value) {
299: WinEventQueue.Task task = new WinEventQueue.Task() {
300: @Override
301: public void perform() {
302: modifyStyle(WindowsDefs.WS_SIZEBOX
303: | WindowsDefs.WS_MAXIMIZEBOX, value);
304: }
305: };
306: factory.eventQueue.performTask(task);
307: }
308:
309: public void grabMouse() {
310: factory.mouseGrab.startManualGrab(hwnd);
311: }
312:
313: public void ungrabMouse() {
314: factory.mouseGrab.endManualGrab();
315: }
316:
317: /**
318: * Modify window style
319: * @param styleBits - style bits to add or remove
320: * @param value - if true set bits, remove otherwise
321: */
322: private void modifyStyle(int styleBits, boolean value) {
323: int style = factory.getWindowStyle(hwnd);
324: int newStyle = style;
325: if (value) {
326: newStyle |= styleBits;
327: } else {
328: newStyle &= ~styleBits;
329: }
330: if (style != newStyle) {
331: factory.setWindowStyle(hwnd, newStyle);
332: }
333: }
334:
335: public void setFocusable(boolean value) {
336: focusable = value;
337: }
338:
339: /**
340: * @see org.apache.harmony.awt.wtk.NativeWindow#isFocusable()
341: */
342: public boolean isFocusable() {
343: return focusable;
344: }
345:
346: /**
347: * Checks if pos is inside the client area
348: * @param pos - point to check (in screen coordinates)
349: * @return true if client area contains pos
350: */
351: boolean contains(Point pos) {
352: Win32.POINT pt = win32.createPOINT(false);
353: pt.set_x(pos.x);
354: pt.set_y(pos.y);
355: win32.ScreenToClient(hwnd, pt);
356: int x = pt.get_x();
357: int y = pt.get_y();
358:
359: Win32.RECT nativeRect = win32.createRECT(false);
360: win32.GetClientRect(hwnd, nativeRect);
361: Rectangle clientRect = factory.getRectBounds(nativeRect);
362:
363: return clientRect.contains(x, y);
364: }
365:
366: boolean isIconified() {
367: return iconified;
368: }
369:
370: void setIconified(boolean iconified) {
371: this .iconified = iconified;
372: }
373:
374: void setMaximized(boolean maximized) {
375: this .maximized = maximized;
376: }
377:
378: boolean isMaximized() {
379: return maximized;
380: }
381:
382: public void setState(final int state) {
383: WinEventQueue.Task task = new WinEventQueue.Task() {
384: @Override
385: public void perform() {
386: if (state == Frame.NORMAL) {
387: win32.ShowWindow(hwnd, WindowsDefs.SW_SHOWNORMAL);
388: } else if (state == Frame.MAXIMIZED_BOTH) {
389: win32.ShowWindow(hwnd, WindowsDefs.SW_MAXIMIZE);
390: } else {
391: Win32.WINDOWPLACEMENT placement = win32
392: .createWINDOWPLACEMENT(false);
393:
394: if (!iconified) {
395: win32.ShowWindow(hwnd, WindowsDefs.SW_MINIMIZE);
396: }
397: win32.GetWindowPlacement(hwnd, placement);
398: if ((state & Frame.MAXIMIZED_BOTH) > 0) {
399: maximized = true;
400: placement.set_flags(placement.get_flags()
401: | WindowsDefs.WPF_RESTORETOMAXIMIZED);
402: } else {
403: maximized = false;
404: placement.set_flags(placement.get_flags()
405: & ~WindowsDefs.WPF_RESTORETOMAXIMIZED);
406: }
407: win32.SetWindowPlacement(hwnd, placement);
408: }
409: }
410: };
411: factory.eventQueue.performTask(task);
412: }
413:
414: /**
415: * @see org.apache.harmony.awt.wtk.NativeWindow#setIconImage(java.awt.Image)
416: */
417: public void setIconImage(final Image image) {
418: WinEventQueue.Task task = new WinEventQueue.Task() {
419: @Override
420: public void perform() {
421: long hIcon = 0;
422: if (image != null) {
423: hIcon = WinIcons.createIcon(true, image, 0, 0);
424: }
425: win32.SendMessageW(hwnd, WindowsDefs.WM_SETICON,
426: WindowsDefs.ICON_BIG, hIcon);
427: win32.SendMessageW(hwnd, WindowsDefs.WM_SETICON,
428: WindowsDefs.ICON_SMALL, hIcon);
429: }
430: };
431: factory.eventQueue.performTask(task);
432:
433: }
434:
435: /**
436: * @see org.apache.harmony.awt.wtk.NativeWindow#setMaximizedBounds(java.awt.Rectangle)
437: */
438: public void setMaximizedBounds(Rectangle bounds) {
439: if (bounds == null) {
440: return;
441: }
442: maximizedBounds = new Rectangle(bounds);
443: }
444:
445: /**
446: * @see org.apache.harmony.awt.wtk.NativeWindow#getScreenPos()
447: */
448: public Point getScreenPos() {
449: Win32.RECT nativeRect = win32.createRECT(false);
450: win32.GetWindowRect(hwnd, nativeRect);
451:
452: Point pos = new Point(nativeRect.get_left(), nativeRect
453: .get_top());
454: return pos;
455: }
456:
457: /**
458: * @see org.apache.harmony.awt.wtk.NativeWindow#setAlwaysOnTop(boolean)
459: */
460: public void setAlwaysOnTop(final boolean value) {
461: WinEventQueue.Task task = new WinEventQueue.Task() {
462: @Override
463: public void perform() {
464: int hwndInsertAfter = (value ? WindowsDefs.HWND_TOPMOST
465: : WindowsDefs.HWND_NOTOPMOST);
466: int flags = WindowsDefs.SWP_NOMOVE
467: | WindowsDefs.SWP_NOSIZE
468: | WindowsDefs.SWP_NOACTIVATE;
469: win32.SetWindowPos(hwnd, hwndInsertAfter, 0, 0, 0, 0,
470: flags);
471: }
472: };
473: factory.eventQueue.performTask(task);
474: }
475:
476: public void setPacked(boolean packed) {
477: // nothing to do
478: }
479:
480: public MultiRectArea getObscuredRegion(Rectangle part) {
481: return WinManagement.getObscuredRegion(hwnd, part);
482: }
483:
484: public void setIMStyle() {
485: // set small title bar:
486: factory.setWindowExStyle(getId(),
487: WindowsDefs.WS_EX_PALETTEWINDOW);
488: // remove system menu & buttons:
489: modifyStyle(WindowsDefs.WS_SYSMENU, false);
490: }
491: }
|