Mercurial > projects > dwt-win
diff dwt/widgets/Display.d @ 213:36f5cb12e1a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 17 May 2008 17:34:28 +0200 |
parents | ab60f3309436 |
children | a8fed3e56433 |
line wrap: on
line diff
--- a/dwt/widgets/Display.d Mon May 05 00:12:38 2008 +0200 +++ b/dwt/widgets/Display.d Sat May 17 17:34:28 2008 +0200 @@ -30,9 +30,11 @@ import dwt.graphics.Rectangle; import dwt.graphics.Resource; import dwt.internal.ImageList; +import dwt.internal.Library; import dwt.internal.win32.OS; import dwt.widgets.Control; +import dwt.widgets.Dialog; import dwt.widgets.Tray; import dwt.widgets.Event; import dwt.widgets.EventTable; @@ -143,7 +145,7 @@ * platforms and should never be accessed from application code. * </p> */ - public MSG msg; + public MSG* msg; /* Windows and Events */ Event [] eventQueue; @@ -157,9 +159,9 @@ EventTable eventTable, filterTable; /* Widget Table */ + int freeSlot; int [] indexTable; Control lastControl, lastGetControl; - int freeSlot; HANDLE lastHwnd; HWND lastGetHwnd; Control [] controlTable; @@ -228,8 +230,8 @@ //Callback msgFilterCallback; //int msgFilterProc_, HHOOK filterHook; - MSG hookMsg; - bool runDragDrop = true; + bool runDragDrop = true, dragCancelled = false; + MSG* hookMsg; /* Idle Hook */ //Callback foregroundIdleCallback; @@ -248,8 +250,9 @@ /* Sync/Async Widget Communication */ Synchronizer synchronizer; - bool runMessages = true, runMessagesInIdle = false; + bool runMessages = true, runMessagesInIdle = false, runMessagesInMessageProc = true; static const String RUN_MESSAGES_IN_IDLE_KEY = "org.eclipse.swt.internal.win32.runMessagesInIdle"; //$NON-NLS-1$ + static final String RUN_MESSAGES_IN_MESSAGE_PROC_KEY = "dwt.internal.win32.runMessagesInMessageProc"; //$NON-NLS-1$ Thread thread; /* Display Shutdown */ @@ -260,16 +263,17 @@ int nextTrayId; /* Timers */ - int [] timerIds; + int /*long*/ [] timerIds; Runnable [] timerList; - int nextTimerId = SETTINGS_ID + 1; + int /*long*/ nextTimerId = SETTINGS_ID + 1; static const int SETTINGS_ID = 100; static const int SETTINGS_DELAY = 2000; /* Keyboard and Mouse */ - RECT clickRect; + RECT* clickRect; int clickCount, lastTime, lastButton; HWND lastClickHwnd; + int scrollRemainder; int lastKey, lastAscii, lastMouse; bool lastVirtual, lastNull, lastDead; ubyte [256] keyboard; @@ -308,6 +312,15 @@ /* Table */ char [] tableBuffer; + NMHDR* hdr; + NMLVDISPINFO* plvfi; + HWND hwndParent; + int columnCount; + bool [] columnVisible; + + /* Resize and move recursion */ + int resizeCount; + static final int RESIZE_LIMIT = 4; /* Display Data */ Object data; @@ -404,7 +417,7 @@ /* Modality */ Shell [] modalShells; - Shell modalDialogShell; + Dialog modalDialog; static bool TrimEnabled = false; /* Private DWT Window Messages */ @@ -417,6 +430,7 @@ static const int SWT_RUNASYNC = OS.WM_APP + 6; static int SWT_TASKBARCREATED; static int SWT_RESTORECARET; + static int DI_GETDRAGIMAGE; /* Workaround for Adobe Reader 7.0 */ int hitCount; @@ -490,6 +504,8 @@ */ public this (DeviceData data) { static_this(); + msg = new MSG(); + hookMsg = new MSG(); super (data); synchronizer = new Synchronizer (this); cursors = new Cursor [DWT.CURSOR_HAND + 1]; @@ -534,7 +550,7 @@ static if (USE_PROPERTY) { OS.SetProp (handle, cast(wchar*)SWT_OBJECT_INDEX, cast(void*) freeSlot + 1); } else { - OS.SetWindowLong (handle, OS.GWL_USERDATA, freeSlot + 1); + OS.SetWindowLongPtr (handle, OS.GWLP_USERDATA, freeSlot + 1); } int oldSlot = freeSlot; freeSlot = indexTable [oldSlot]; @@ -692,8 +708,10 @@ * @see #syncExec */ public void asyncExec (Runnable runnable) { - if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); - synchronizer.asyncExec (runnable); + synchronized (Device.classinfo) { + if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); + synchronizer.asyncExec (runnable); + } } /** @@ -732,11 +750,13 @@ if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); } -static synchronized void checkDisplay (Thread thread, bool multiple) { - for (int i=0; i<Displays.length; i++) { - if (Displays [i] !is null) { - if (!multiple) DWT.error (DWT.ERROR_NOT_IMPLEMENTED, null, " [multiple displays]"); - if (Displays [i].thread is thread) DWT.error (DWT.ERROR_THREAD_INVALID_ACCESS); +static void checkDisplay (Thread thread, bool multiple) { + synchronized (Device.classinfo) { + for (int i=0; i<Displays.length; i++) { + if (Displays [i] !is null) { + if (!multiple) DWT.error (DWT.ERROR_NOT_IMPLEMENTED, null, " [multiple displays]"); //$NON-NLS-1$ + if (Displays [i].thread is thread) DWT.error (DWT.ERROR_THREAD_INVALID_ACCESS); + } } } } @@ -845,8 +865,8 @@ bmiHeader.biCompression = OS.BI_RGB; byte [] bmi = new byte [BITMAPINFOHEADER.sizeof]; bmi[ 0 .. BITMAPINFOHEADER.sizeof ] = (cast(byte*)&bmiHeader)[ 0 .. BITMAPINFOHEADER.sizeof ]; - int[1] pBits; - auto memDib = OS.CreateDIBSection (null, cast(BITMAPINFO*)bmi.ptr, OS.DIB_RGB_COLORS, pBits.ptr, null, 0); + void* pBits; + auto memDib = OS.CreateDIBSection (null, cast(BITMAPINFO*)bmi.ptr, OS.DIB_RGB_COLORS, &pBits, null, 0); if (memDib is null) DWT.error (DWT.ERROR_NO_HANDLES); auto oldMemBitmap = OS.SelectObject (memHdc, memDib); BITMAP dibBM; @@ -882,7 +902,7 @@ } } } - byte [] srcData = (cast(byte*)pBits [0])[ 0 .. sizeInBytes].dup; + byte [] srcData = (cast(byte*)pBits)[ 0 .. sizeInBytes].dup; if (hMask !is null) { OS.SelectObject(srcHdc, hMask); for (int y = 0, dp = 0; y < imgHeight; ++y) { @@ -930,7 +950,7 @@ } } } - (cast(byte*)pBits [0])[ 0 .. sizeInBytes] = srcData[]; + (cast(byte*)pBits)[ 0 .. sizeInBytes] = srcData[]; OS.SelectObject (srcHdc, oldSrcBitmap); OS.SelectObject (memHdc, oldMemBitmap); OS.DeleteObject (srcHdc); @@ -959,8 +979,8 @@ bmiHeader.biBitCount = cast(short)32; bmiHeader.biCompression = OS.BI_RGB; byte [] bmi = (cast(byte*)&bmiHeader)[ 0 .. BITMAPINFOHEADER.sizeof]; - int [1] pBits; - auto memDib = OS.CreateDIBSection (null, cast(BITMAPINFO*)bmi.ptr, OS.DIB_RGB_COLORS, pBits.ptr, null, 0); + void* pBits; + auto memDib = OS.CreateDIBSection (null, cast(BITMAPINFO*)bmi.ptr, OS.DIB_RGB_COLORS, &pBits, null, 0); if (memDib is null) DWT.error (DWT.ERROR_NO_HANDLES); auto oldMemBitmap = OS.SelectObject (memHdc, memDib); BITMAP dibBM; @@ -1001,7 +1021,7 @@ OS.DeleteObject (srcHdc); OS.DeleteObject (memHdc); OS.ReleaseDC (null, hDC); - byte [] srcData = (cast(byte*)pBits[0])[ 0 .. sizeInBytes ].dup; + byte [] srcData = (cast(byte*)pBits)[ 0 .. sizeInBytes ].dup; if (alpha !is -1) { for (int y = 0, dp = 0; y < imgHeight; ++y) { for (int x = 0; x < imgWidth; ++x) { @@ -1028,7 +1048,7 @@ } } } - (cast(byte*)pBits[0])[ 0 .. sizeInBytes ] = srcData[]; + (cast(byte*)pBits)[ 0 .. sizeInBytes ] = srcData[]; return memDib; } @@ -1112,10 +1132,11 @@ return hMask; } -static synchronized void deregister (Display display) { - static_this(); - for (int i=0; i<Displays.length; i++) { - if (display is Displays [i]) Displays [i] = null; +static void deregister (Display display) { + synchronized (Device.classinfo) { + for (int i=0; i<Displays.length; i++) { + if (display is Displays [i]) Displays [i] = null; + } } } @@ -1294,6 +1315,7 @@ */ public Widget findWidget (HANDLE handle, int id) { checkDevice (); + //TODO - should ids be long Control control = getControl (handle); return control !is null ? control.findItem (cast(HANDLE) id) : null; } @@ -1315,8 +1337,9 @@ * * @since 3.3 */ -public Widget findWidget (Widget widget, int id) { +public Widget findWidget (Widget widget, int /*long*/ id) { checkDevice (); + //TODO - should ids be long if (cast(Control)widget) { return findWidget ((cast(Control) widget).handle, id); } @@ -1329,14 +1352,16 @@ } int foregroundIdleProc (int code, int wParam, int lParam) { - if (runMessages) { - if (code >= 0) { - if (getMessageCount () !is 0) { - if (runMessagesInIdle) { + if (code >= 0) { + if (runMessages && getMessageCount () !is 0) { + if (runMessagesInIdle) { + if (runMessagesInMessageProc) { OS.PostMessage (hwndMessage, SWT_RUNASYNC, 0, 0); + } else { + runAsyncMessages (false); } - wakeThread (); } + wakeThread (); } } return OS.CallNextHookEx (idleHook, code, wParam, lParam); @@ -1352,15 +1377,17 @@ * @param thread the user-interface thread * @return the display for the given thread */ -public static synchronized Display findDisplay (Thread thread) { +public static Display findDisplay (Thread thread) { static_this(); - for (int i=0; i<Displays.length; i++) { - Display display = Displays [i]; - if (display !is null && display.thread is thread) { - return display; + synchronized (Device.classinfo) { + for (int i=0; i<Displays.length; i++) { + Display display = Displays [i]; + if (display !is null && display.thread is thread) { + return display; + } } + return null; } - return null; } /** @@ -1382,7 +1409,8 @@ } /** - * Returns a rectangle describing the receiver's size and location. + * Returns a rectangle describing the receiver's size and location. Note that + * on multi-monitor systems the origin can be negative. * * @return the bounding rectangle * @@ -1412,7 +1440,7 @@ * * @return the current display */ -public static synchronized Display getCurrent () { +public static Display getCurrent () { static_this(); return findDisplay (Thread.getThis ()); } @@ -1421,12 +1449,11 @@ switch (type) { case DWT.MouseDown: int doubleClick = OS.GetDoubleClickTime (); - //if (clickRect is null) clickRect = new RECT (); + if (clickRect is null) clickRect = new RECT (); int deltaTime = Math.abs (lastTime - getLastEventTime ()); POINT pt; - pt.x = cast(short) (lParam & 0xFFFF); - pt.y = cast(short) (lParam >> 16); - if (lastClickHwnd is hwnd && lastButton is button && (deltaTime <= doubleClick) && OS.PtInRect (&clickRect, pt)) { + OS.POINTSTOPOINT (pt, lParam); + if (lastClickHwnd is hwnd && lastButton is button && (deltaTime <= doubleClick) && OS.PtInRect (clickRect, pt)) { clickCount++; } else { clickCount = 1; @@ -1438,8 +1465,8 @@ lastTime = getLastEventTime (); int xInset = OS.GetSystemMetrics (OS.SM_CXDOUBLECLK) / 2; int yInset = OS.GetSystemMetrics (OS.SM_CYDOUBLECLK) / 2; - int x = cast(short) (lParam & 0xFFFF), y = cast(short) (lParam >> 16); - OS.SetRect (&clickRect, x - xInset, y - yInset, x + xInset, y + yInset); + int x = OS.GET_X_LPARAM (lParam), y = OS.GET_Y_LPARAM (lParam); + OS.SetRect (clickRect, x - xInset, y - yInset, x + xInset, y + yInset); //FALL THROUGH case DWT.MouseUp: return clickCount; @@ -1489,7 +1516,7 @@ static if (USE_PROPERTY) { index = cast(int) OS.GetProp (handle, cast(wchar*)SWT_OBJECT_INDEX) - 1; } else { - index = OS.GetWindowLong (handle, OS.GWL_USERDATA) - 1; + index = OS.GetWindowLongPtr (handle, OS.GWLP_USERDATA) - 1; } if (0 <= index && index < controlTable.length) { Control control = controlTable [index]; @@ -1572,10 +1599,12 @@ * * @return the default display */ -public static synchronized Display getDefault () { +public static Display getDefault () { static_this(); - if (Default is null) Default = new Display (); - return Default; + synchronized (Device.classinfo) { + if (Default is null) Default = new Display (); + return Default; + } } //PORTING_TODO @@ -1616,6 +1645,9 @@ if (key ==/*eq*/RUN_MESSAGES_IN_IDLE_KEY) { return new ValueWrapperBool(runMessagesInIdle); } + if (key.equals (RUN_MESSAGES_IN_MESSAGE_PROC_KEY)) { + return new Boolean (runMessagesInMessageProc); + } if (keys.length is 0) return null; for (int i=0; i<keys.length; i++) { if (keys [i] ==/*eq*/key) return values [i]; @@ -1967,9 +1999,8 @@ return null; } -Shell getModalDialogShell () { - if (modalDialogShell !is null && modalDialogShell.isDisposed ()) modalDialogShell = null; - return modalDialogShell; +Dialog getModalDialog () { + return modalDialog; } /** @@ -2012,9 +2043,9 @@ //embeddedCallback = new Callback (this, "embeddedProc", 4); //$NON-NLS-1$ //embeddedProc_ = embeddedCallback.getAddress (); //if (embeddedProc_ is 0) error (DWT.ERROR_NO_MORE_CALLBACKS); - OS.SetWindowLong (embeddedHwnd, OS.GWL_WNDPROC, cast(int) &embeddedFunc); + OS.SetWindowLongPtr (embeddedHwnd, OS.GWLP_WNDPROC, cast(LONG_PTR) &embeddedFunc); } - if (code >= 0 && wParam !is OS.PM_NOREMOVE) { + if (code >= 0 && (wParam & OS.PM_REMOVE) !is 0) { MSG* msg = cast(MSG*)lParam; switch (msg.message) { case OS.WM_KEYDOWN: @@ -2167,6 +2198,23 @@ } /** + * Gets the synchronizer used by the display. + * + * @return the receiver's synchronizer + * + * @exception DWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + * + * @since 3.4 + */ +public Synchronizer getSynchronizer () { + checkDevice (); + return synchronizer; +} + +/** * Returns the thread that has invoked <code>syncExec</code> * or null if no such runnable is currently being invoked by * the user-interface thread. @@ -2182,8 +2230,10 @@ * </ul> */ public Thread getSyncThread () { - if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); - return synchronizer.syncThread; + synchronized (Device.classinfo) { + if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); + return synchronizer.syncThread; + } } /** @@ -2414,8 +2464,10 @@ * </ul> */ public Thread getThread () { - if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); - return thread; + synchronized (Device.classinfo) { + if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); + return thread; + } } HTHEME hButtonTheme () { @@ -2475,7 +2527,7 @@ data.style |= DWT.LEFT_TO_RIGHT; } data.device = this; - data.hFont = getSystemFont ().handle; + data.font = getSystemFont (); } return hDC; } @@ -2513,6 +2565,29 @@ lpWndClass.lpfnWndProc = &windowProcFunc; lpWndClass.style = OS.CS_BYTEALIGNWINDOW | OS.CS_DBLCLKS; lpWndClass.hCursor = OS.LoadCursor (null, cast(wchar*)OS.IDC_ARROW); + + + //DWT_TODO: Check if this can be disabled for DWT + /+ + /* + * Set the default icon for the window class to IDI_APPLICATION. + * This is not necessary for native Windows applications but + * versions of Java starting at JDK 1.6 set the icon in the + * executable instead of leaving the default. + */ + if (!OS.IsWinCE && Library.JAVA_VERSION >= Library.JAVA_VERSION (1, 6, 0)) { + TCHAR[] lpszFile = NewTCHARs (0, OS.MAX_PATH); + while (OS.GetModuleFileName (0, lpszFile.ptr, lpszFile.length) is lpszFile.length) { + lpszFile = NewTCHARs (0, lpszFile.length + OS.MAX_PATH); + } + if (OS.ExtractIconEx (lpszFile.ptr, -1, null, null, 1) !is 0) { + String fileName = TCHARzToStr( lpszFile.ptr ); + if (fileName.endsWith ("java.exe") || fileName.endsWith ("javaw.exe")) { //$NON-NLS-1$ //$NON-NLS-2$ + lpWndClass.hIcon = OS.LoadIcon (0, OS.IDI_APPLICATION); + } + } + } + +/ int byteCount = windowClass_.length * TCHAR.sizeof; lpWndClass.lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount); OS.MoveMemory (lpWndClass.lpszClassName, windowClass_.ptr, byteCount); @@ -2520,7 +2595,9 @@ OS.HeapFree (hHeap, 0, lpWndClass.lpszClassName); /* Register the DWT drop shadow window class */ - if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) lpWndClass.style |= OS.CS_DROPSHADOW; + if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) { + lpWndClass.style |= OS.CS_DROPSHADOW; + } byteCount = windowShadowClass.length * TCHAR.sizeof; lpWndClass.lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount); OS.MoveMemory (lpWndClass.lpszClassName, windowShadowClass.ptr, byteCount); @@ -2540,7 +2617,7 @@ //messageCallback = new Callback (this, "messageProc", 4); //$NON-NLS-1$ //messageProc_ = messageCallback.getAddress (); //if (messageProc_ is 0) error (DWT.ERROR_NO_MORE_CALLBACKS); - OS.SetWindowLong (hwndMessage, OS.GWL_WNDPROC, cast(int) &messageProcFunc); + OS.SetWindowLongPtr (hwndMessage, OS.GWLP_WNDPROC, cast(LONG_PTR) &messageProcFunc); /* Create the filter hook */ static if (!OS.IsWinCE) { @@ -2561,6 +2638,7 @@ /* Register custom messages message */ SWT_TASKBARCREATED = OS.RegisterWindowMessage (StrToTCHARz ( "TaskbarCreated" )); SWT_RESTORECARET = OS.RegisterWindowMessage (StrToTCHARz ( "SWT_RESTORECARET")); + DI_GETDRAGIMAGE = OS.RegisterWindowMessage (StrToTCHARz ( "ShellGetDragImage")); //$NON-NLS-1$ /* Initialize OLE */ static if (!OS.IsWinCE) OS.OleInitialize (null); @@ -2988,9 +3066,10 @@ */ if (wParam !is 0) { if (!isXMouseActive ()) { - if (modalDialogShell !is null && modalDialogShell.isDisposed ()) modalDialogShell = null; - Shell modal = modalDialogShell !is null ? modalDialogShell : getModalShell (); - if (modal !is null) { + auto hwndActive = OS.GetActiveWindow (); + if (hwndActive !is null && OS.IsWindowEnabled (hwndActive)) break; + Shell modal = modalDialog !is null ? modalDialog.parent : getModalShell (); + if (modal !is null && !modal.isDisposed ()) { auto hwndModal = modal.handle; if (OS.IsWindowEnabled (hwndModal)) { modal.bringToTop (); @@ -3017,7 +3096,8 @@ * to run. In order to avoid running code after the display * has been disposed, exit from Java. */ - System.exit (0); + /* This code is intentionally commented */ +// System.exit (0); } break; } @@ -3027,7 +3107,15 @@ if (!event.doit) return 0; break; } + case OS.WM_DWMCOLORIZATIONCOLORCHANGED: { + OS.SetTimer (hwndMessage, SETTINGS_ID, SETTINGS_DELAY, null); + break; + } case OS.WM_SETTINGCHANGE: { + if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { + OS.SetTimer (hwndMessage, SETTINGS_ID, SETTINGS_DELAY, null); + break; + } switch (wParam) { case 0: case 1: @@ -3107,9 +3195,10 @@ int msgFilterProc (int code, int wParam, int lParam) { switch (code) { case OS.MSGF_COMMCTRL_BEGINDRAG: { - if (!runDragDrop) { - hookMsg = *cast(MSG*)lParam; + if (!runDragDrop && !dragCancelled) { + *hookMsg = *cast(MSG*)lParam; if (hookMsg.message is OS.WM_MOUSEMOVE) { + dragCancelled = true; OS.SendMessage (hookMsg.hwnd, OS.WM_CANCELMODE, 0, 0); } } @@ -3131,7 +3220,7 @@ case OS.MSGF_SCROLLBAR: case OS.MSGF_SIZE: { if (runMessages) { - hookMsg = *cast(MSG*)lParam; + *hookMsg = *cast(MSG*)lParam; if (hookMsg.message is OS.WM_NULL) { MSG msg; int flags = OS.PM_NOREMOVE | OS.PM_NOYIELD | OS.PM_QS_INPUT | OS.PM_QS_POSTMESSAGE; @@ -3224,118 +3313,120 @@ * */ public bool post (Event event) { - if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); - if (event is null) error (DWT.ERROR_NULL_ARGUMENT); - int type = event.type; - switch (type){ - case DWT.KeyDown: - case DWT.KeyUp: { + synchronized (Device.classinfo) { + if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); + if (event is null) error (DWT.ERROR_NULL_ARGUMENT); + int type = event.type; + switch (type){ + case DWT.KeyDown: + case DWT.KeyUp: { KEYBDINPUT inputs; inputs.wVk = cast(short) untranslateKey (event.keyCode); - if (inputs.wVk is 0) { - char key = event.character; - switch (key) { - case DWT.BS: inputs.wVk = cast(short) OS.VK_BACK; break; - case DWT.CR: inputs.wVk = cast(short) OS.VK_RETURN; break; - case DWT.DEL: inputs.wVk = cast(short) OS.VK_DELETE; break; - case DWT.ESC: inputs.wVk = cast(short) OS.VK_ESCAPE; break; - case DWT.TAB: inputs.wVk = cast(short) OS.VK_TAB; break; - /* - * Since there is no LF key on the keyboard, do not attempt - * to map LF to CR or attempt to post an LF key. - */ -// case DWT.LF: inputs.wVk = cast(short) OS.VK_RETURN; break; - case DWT.LF: return false; - default: { - static if (OS.IsWinCE) { - inputs.wVk = cast(int)OS.CharUpper (cast(wchar*) key); - } else { - inputs.wVk = OS.VkKeyScan (cast(short) wcsToMbcs (key, 0)); - if (inputs.wVk is -1) return false; - inputs.wVk &= 0xFF; + if (inputs.wVk is 0) { + char key = event.character; + switch (key) { + case DWT.BS: inputs.wVk = cast(short) OS.VK_BACK; break; + case DWT.CR: inputs.wVk = cast(short) OS.VK_RETURN; break; + case DWT.DEL: inputs.wVk = cast(short) OS.VK_DELETE; break; + case DWT.ESC: inputs.wVk = cast(short) OS.VK_ESCAPE; break; + case DWT.TAB: inputs.wVk = cast(short) OS.VK_TAB; break; + /* + * Since there is no LF key on the keyboard, do not attempt + * to map LF to CR or attempt to post an LF key. + */ +// case DWT.LF: inputs.wVk = cast(short) OS.VK_RETURN; break; + case DWT.LF: return false; + default: { + static if (OS.IsWinCE) { + inputs.wVk = cast(int)OS.CharUpper (cast(wchar*) key); + } else { + inputs.wVk = OS.VkKeyScan (cast(short) wcsToMbcs (key, 0)); + if (inputs.wVk is -1) return false; + inputs.wVk &= 0xFF; + } } } } - } - inputs.dwFlags = type is DWT.KeyUp ? OS.KEYEVENTF_KEYUP : 0; + inputs.dwFlags = type is DWT.KeyUp ? OS.KEYEVENTF_KEYUP : 0; auto hHeap = OS.GetProcessHeap (); auto pInputs = cast(INPUT*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, INPUT.sizeof); pInputs.type = OS.INPUT_KEYBOARD; - pInputs.ki = inputs; - //OS.MoveMemory (pInputs + 4, inputs, KEYBDINPUT.sizeof); - bool result = OS.SendInput (1, pInputs, INPUT.sizeof) !is 0; - OS.HeapFree (hHeap, 0, pInputs); - return result; - } - case DWT.MouseDown: - case DWT.MouseMove: - case DWT.MouseUp: - case DWT.MouseWheel: { - MOUSEINPUT inputs; - if (type is DWT.MouseMove){ - inputs.dwFlags = OS.MOUSEEVENTF_MOVE | OS.MOUSEEVENTF_ABSOLUTE; - int x= 0, y = 0, width = 0, height = 0; - if (OS.WIN32_VERSION >= OS.VERSION (5, 0)) { - inputs.dwFlags |= OS.MOUSEEVENTF_VIRTUALDESK; - x = OS.GetSystemMetrics (OS.SM_XVIRTUALSCREEN); - y = OS.GetSystemMetrics (OS.SM_YVIRTUALSCREEN); - width = OS.GetSystemMetrics (OS.SM_CXVIRTUALSCREEN); - height = OS.GetSystemMetrics (OS.SM_CYVIRTUALSCREEN); + //TODO - DWORD type of INPUT structure aligned to 8 bytes on 64 bit + pInputs.ki = inputs; + //OS.MoveMemory (pInputs + 4, inputs, KEYBDINPUT.sizeof); + bool result = OS.SendInput (1, pInputs, INPUT.sizeof) !is 0; + OS.HeapFree (hHeap, 0, pInputs); + return result; + } + case DWT.MouseDown: + case DWT.MouseMove: + case DWT.MouseUp: + case DWT.MouseWheel: { + MOUSEINPUT inputs; + if (type is DWT.MouseMove){ + inputs.dwFlags = OS.MOUSEEVENTF_MOVE | OS.MOUSEEVENTF_ABSOLUTE; + int x= 0, y = 0, width = 0, height = 0; + if (OS.WIN32_VERSION >= OS.VERSION (5, 0)) { + inputs.dwFlags |= OS.MOUSEEVENTF_VIRTUALDESK; + x = OS.GetSystemMetrics (OS.SM_XVIRTUALSCREEN); + y = OS.GetSystemMetrics (OS.SM_YVIRTUALSCREEN); + width = OS.GetSystemMetrics (OS.SM_CXVIRTUALSCREEN); + height = OS.GetSystemMetrics (OS.SM_CYVIRTUALSCREEN); + } else { + width = OS.GetSystemMetrics (OS.SM_CXSCREEN); + height = OS.GetSystemMetrics (OS.SM_CYSCREEN); + } + inputs.dx = ((event.x - x) * 65535 + width - 2) / (width - 1); + inputs.dy = ((event.y - y) * 65535 + height - 2) / (height - 1); } else { - width = OS.GetSystemMetrics (OS.SM_CXSCREEN); - height = OS.GetSystemMetrics (OS.SM_CYSCREEN); - } - inputs.dx = ((event.x - x) * 65535 + width - 2) / (width - 1); - inputs.dy = ((event.y - y) * 65535 + height - 2) / (height - 1); - } else { - if (type is DWT.MouseWheel) { - if (OS.WIN32_VERSION < OS.VERSION (5, 0)) return false; - inputs.dwFlags = OS.MOUSEEVENTF_WHEEL; - switch (event.detail) { - case DWT.SCROLL_PAGE: - inputs.mouseData = event.count * OS.WHEEL_DELTA; - break; - case DWT.SCROLL_LINE: - int value; - OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, &value, 0); - inputs.mouseData = event.count * OS.WHEEL_DELTA / value; - break; - default: return false; - } - } else { - switch (event.button) { - case 1: inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_LEFTDOWN : OS.MOUSEEVENTF_LEFTUP; break; - case 2: inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_MIDDLEDOWN : OS.MOUSEEVENTF_MIDDLEUP; break; - case 3: inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_RIGHTDOWN : OS.MOUSEEVENTF_RIGHTUP; break; - case 4: { - if (OS.WIN32_VERSION < OS.VERSION (5, 0)) return false; - inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_XDOWN : OS.MOUSEEVENTF_XUP; - inputs.mouseData = OS.XBUTTON1; - break; + if (type is DWT.MouseWheel) { + if (OS.WIN32_VERSION < OS.VERSION (5, 0)) return false; + inputs.dwFlags = OS.MOUSEEVENTF_WHEEL; + switch (event.detail) { + case DWT.SCROLL_PAGE: + inputs.mouseData = event.count * OS.WHEEL_DELTA; + break; + case DWT.SCROLL_LINE: + int value; + OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, &value, 0); + inputs.mouseData = event.count * OS.WHEEL_DELTA / value; + break; + default: return false; } - case 5: { - if (OS.WIN32_VERSION < OS.VERSION (5, 0)) return false; - inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_XDOWN : OS.MOUSEEVENTF_XUP; - inputs.mouseData = OS.XBUTTON2; - break; + } else { + switch (event.button) { + case 1: inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_LEFTDOWN : OS.MOUSEEVENTF_LEFTUP; break; + case 2: inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_MIDDLEDOWN : OS.MOUSEEVENTF_MIDDLEUP; break; + case 3: inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_RIGHTDOWN : OS.MOUSEEVENTF_RIGHTUP; break; + case 4: { + if (OS.WIN32_VERSION < OS.VERSION (5, 0)) return false; + inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_XDOWN : OS.MOUSEEVENTF_XUP; + inputs.mouseData = OS.XBUTTON1; + break; + } + case 5: { + if (OS.WIN32_VERSION < OS.VERSION (5, 0)) return false; + inputs.dwFlags = type is DWT.MouseDown ? OS.MOUSEEVENTF_XDOWN : OS.MOUSEEVENTF_XUP; + inputs.mouseData = OS.XBUTTON2; + break; + } + default: return false; } - default: return false; } } + auto hHeap = OS.GetProcessHeap (); + auto pInputs = cast(INPUT*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, INPUT.sizeof); + pInputs.type = OS.INPUT_MOUSE; + //TODO - DWORD type of INPUT structure aligned to 8 bytes on 64 bit + pInputs.mi = inputs; + bool result = OS.SendInput (1, pInputs, INPUT.sizeof) !is 0; + OS.HeapFree (hHeap, 0, pInputs); + return result; } - auto hHeap = OS.GetProcessHeap (); - auto pInputs = cast(INPUT*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, INPUT.sizeof); - pInputs.type = OS.INPUT_MOUSE; - //OS.MoveMemory(pInputs, [OS.INPUT_MOUSE], 4); - pInputs.mi = inputs; - //OS.MoveMemory (pInputs + 4, inputs, MOUSEINPUT.sizeof); - bool result = OS.SendInput (1, pInputs, INPUT.sizeof) !is 0; - OS.HeapFree (hHeap, 0, pInputs); - return result; + default: } - default: + return false; } - return false; } void postEvent (Event event) { @@ -3389,10 +3480,10 @@ lpStartupInfo = null; drawMenuBars (); runPopups (); - if (OS.PeekMessage (&msg, null, 0, 0, OS.PM_REMOVE)) { - if (!filterMessage (&msg)) { - OS.TranslateMessage (&msg); - OS.DispatchMessage (&msg); + if (OS.PeekMessage (msg, null, 0, 0, OS.PM_REMOVE)) { + if (!filterMessage (msg)) { + OS.TranslateMessage (msg); + OS.DispatchMessage (msg); } runDeferredEvents (); return true; @@ -3400,18 +3491,20 @@ return runMessages && runAsyncMessages (false); } -static synchronized void register (Display display) { +static void register (Display display) { static_this(); - for (int i=0; i<Displays.length; i++) { - if (Displays [i] is null) { - Displays [i] = display; - return; + synchronized (Device.classinfo) { + for (int i=0; i<Displays.length; i++) { + if (Displays [i] is null) { + Displays [i] = display; + return; + } } + Display [] newDisplays = new Display [Displays.length + 4]; + System.arraycopy (Displays, 0, newDisplays, 0, Displays.length); + newDisplays [Displays.length] = display; + Displays = newDisplays; } - Display [] newDisplays = new Display [Displays.length + 4]; - System.arraycopy (Displays, 0, newDisplays, 0, Displays.length); - newDisplays [Displays.length] = display; - Displays = newDisplays; } /** @@ -3563,18 +3656,31 @@ /* Release references */ thread = null; - //msg = null; + msg = null; + hookMsg = null; //keyboard = null; - modalDialogShell = null; + modalDialog = null; modalShells = null; data = null; keys = null; values = null; bars = popups = null; indexTable = null; + timerIds = null; controlTable = null; lastControl = lastGetControl = lastHittestControl = null; imageList = toolImageList = toolHotImageList = toolDisabledImageList = null; + timerList = null; + tableBuffer = null; + columnVisible = null; + eventTable = filterTable = null; + items = null; + clickRect = null; + hdr = null; + plvfi = null; + + /* Release handles */ + threadId = 0; } void releaseImageList (ImageList list) { @@ -3731,16 +3837,14 @@ static if (USE_PROPERTY) { index = cast(int)OS.RemoveProp (handle, cast(wchar*)SWT_OBJECT_INDEX) - 1; } else { - index = OS.GetWindowLong (handle, OS.GWL_USERDATA) - 1; + index = OS.GetWindowLongPtr (handle, OS.GWLP_USERDATA) - 1; + OS.SetWindowLongPtr (handle, OS.GWLP_USERDATA, 0); } if (0 <= index && index < controlTable.length) { control = controlTable [index]; controlTable [index] = null; indexTable [index] = freeSlot; freeSlot = index; - if (!USE_PROPERTY) { - OS.SetWindowLong (handle, OS.GWL_USERDATA, 0); - } } return control; } @@ -3838,7 +3942,7 @@ } } -bool runTimer (int id) { +bool runTimer (int /*long*/ id) { if (timerList !is null && timerIds !is null) { int index = 0; while (index <timerIds.length) { @@ -3999,6 +4103,11 @@ runMessagesInIdle = data !is null && data.value; return; } + if (key.equals (RUN_MESSAGES_IN_MESSAGE_PROC_KEY)) { + Boolean data = cast(Boolean) value; + runMessagesInMessageProc = data !is null && data.booleanValue (); + return; + } /* Remove the key/value pair */ if (value is null) { @@ -4086,9 +4195,8 @@ /* Do nothing */ } -void setModalDialogShell (Shell modalDailog) { - if (modalDialogShell !is null && modalDialogShell.isDisposed ()) modalDialogShell = null; - this.modalDialogShell = modalDailog; +void setModalDialog (Dialog modalDailog) { + this.modalDialog = modalDailog; Shell [] shells = getShells (); for (int i=0; i<shells.length; i++) shells [i].updateModal (); } @@ -4129,10 +4237,15 @@ public void setSynchronizer (Synchronizer synchronizer) { checkDevice (); if (synchronizer is null) error (DWT.ERROR_NULL_ARGUMENT); - if (this.synchronizer !is null) { - this.synchronizer.runAsyncMessages(true); + if (synchronizer is this.synchronizer) return; + Synchronizer oldSynchronizer; + synchronized (Device.classinfo) { + oldSynchronizer = this.synchronizer; + this.synchronizer = synchronizer; } - this.synchronizer = synchronizer; + if (oldSynchronizer !is null) { + oldSynchronizer.runAsyncMessages(true); + } } int shiftedKey (int key) { @@ -4200,7 +4313,11 @@ * @see #asyncExec */ public void syncExec (Runnable runnable) { - if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); + Synchronizer synchronizer; + synchronized (Device.classinfo) { + if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); + synchronizer = this.synchronizer; + } synchronizer.syncExec (runnable); } @@ -4234,13 +4351,13 @@ if (runnable is null) error (DWT.ERROR_NULL_ARGUMENT); assert( runnable ); if (timerList is null) timerList = new Runnable [4]; - if (timerIds is null) timerIds = new int [4]; + if (timerIds is null) timerIds = new int /*long*/ [4]; int index = 0; while (index < timerList.length) { if (timerList [index] is runnable) break; index++; } - int timerId = 0; + int /*long*/ timerId = 0; if (index !is timerList.length) { timerId = timerIds [index]; if (milliseconds < 0) { @@ -4261,7 +4378,7 @@ Runnable [] newTimerList = new Runnable [timerList.length + 4]; SimpleType!(Runnable).arraycopy (timerList, 0, newTimerList, 0, timerList.length); timerList = newTimerList; - int [] newTimerIds = new int [timerIds.length + 4]; + int /*long*/ [] newTimerIds = new int /*long*/ [timerIds.length + 4]; System.arraycopy (timerIds, 0, newTimerIds, 0, timerIds.length); timerIds = newTimerIds; } @@ -4395,9 +4512,11 @@ * @see #sleep */ public void wake () { - if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); - if (thread is Thread.getThis ()) return; - wakeThread (); + synchronized (Device.classinfo) { + if (isDisposed ()) error (DWT.ERROR_DEVICE_DISPOSED); + if (thread is Thread.getThis ()) return; + wakeThread (); + } } void wakeThread () { @@ -4451,6 +4570,27 @@ int windowProc (HWND hwnd, uint msg, uint wParam, int lParam) { /* + * Feature in Windows. On Vista only, it is faster to + * compute and answer the data for the visible columns + * of a table when scrolling, rather than just return + * the data for each column when asked. + */ + if (columnVisible !is null) { + if (msg is OS.WM_NOTIFY && hwndParent is hwnd) { + OS.MoveMemory (hdr, lParam, NMHDR.sizeof); + switch (hdr.code) { + case OS.LVN_GETDISPINFOA: + case OS.LVN_GETDISPINFOW: { + OS.MoveMemory (plvfi, lParam, NMLVDISPINFO.sizeof); + if (0 <= plvfi.item.iSubItem && plvfi.item.iSubItem < columnCount) { + if (!columnVisible [plvfi.item.iSubItem]) return 0; + } + break; + } + } + } + } + /* * Bug in Adobe Reader 7.0. For some reason, when Adobe * Reader 7.0 is deactivated from within Internet Explorer, * it sends thousands of consecutive WM_NCHITTEST messages @@ -4477,7 +4617,7 @@ static if (USE_PROPERTY) { index = cast(int)OS.GetProp (hwnd, cast(wchar*)SWT_OBJECT_INDEX) - 1; } else { - index = OS.GetWindowLong (hwnd, OS.GWL_USERDATA) - 1; + index = OS.GetWindowLongPtr (hwnd, OS.GWLP_USERDATA) - 1; } if (0 <= index && index < controlTable.length) { Control control = controlTable [index];