diff options
author | Steve Northover <steve> | 2005-05-06 20:27:29 +0000 |
---|---|---|
committer | Steve Northover <steve> | 2005-05-06 20:27:29 +0000 |
commit | 999cd70b792d3ba6318eaa17a83f0d788d0c9764 (patch) | |
tree | f45efd715efeab20f049a9688ab966ff3f012cec | |
parent | 039da5b6cb01deacaa42e0c472d7c59171188a10 (diff) | |
download | eclipse.platform.swt-999cd70b792d3ba6318eaa17a83f0d788d0c9764.tar.gz eclipse.platform.swt-999cd70b792d3ba6318eaa17a83f0d788d0c9764.tar.xz eclipse.platform.swt-999cd70b792d3ba6318eaa17a83f0d788d0c9764.zip |
31066 - Buttons with alpha images on non-XP
-rwxr-xr-x | bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java | 153 | ||||
-rwxr-xr-x | bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java | 169 |
2 files changed, 203 insertions, 119 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java index df2cb0d9f1..0e49e5592a 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java @@ -42,24 +42,25 @@ import org.eclipse.swt.events.*; public class Button extends Control { String text = ""; - Image image; + Image image, image2; ImageList imageList; boolean ignoreMouse; static final int ButtonProc; static final TCHAR ButtonClass = new TCHAR (0,"BUTTON", true); static final char [] SCROLLBAR = new char [] {'S', 'C', 'R', 'O', 'L', 'L', 'B', 'A', 'R', 0}; - static final int CheckWidth, CheckHeight; + static final int CHECK_WIDTH, CHECK_HEIGHT; + static final int ICON_WIDTH = 128, ICON_HEIGHT = 128; static { int hBitmap = OS.LoadBitmap (0, OS.OBM_CHECKBOXES); if (hBitmap == 0) { - CheckWidth = OS.GetSystemMetrics (OS.IsWinCE ? OS.SM_CXSMICON : OS.SM_CXVSCROLL); - CheckHeight = OS.GetSystemMetrics (OS.IsWinCE ? OS.SM_CYSMICON : OS.SM_CYVSCROLL); + CHECK_WIDTH = OS.GetSystemMetrics (OS.IsWinCE ? OS.SM_CXSMICON : OS.SM_CXVSCROLL); + CHECK_HEIGHT = OS.GetSystemMetrics (OS.IsWinCE ? OS.SM_CYSMICON : OS.SM_CYVSCROLL); } else { BITMAP bitmap = new BITMAP (); OS.GetObject (hBitmap, BITMAP.sizeof, bitmap); OS.DeleteObject (hBitmap); - CheckWidth = bitmap.bmWidth / 4; - CheckHeight = bitmap.bmHeight / 3; + CHECK_WIDTH = bitmap.bmWidth / 4; + CHECK_HEIGHT = bitmap.bmHeight / 3; } WNDCLASS lpWndClass = new WNDCLASS (); OS.GetClassInfo (0, ButtonClass, lpWndClass); @@ -106,6 +107,82 @@ public Button (Composite parent, int style) { super (parent, checkStyle (style)); } +void _setImage (Image image) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + OS.SendMessage (handle, OS.BCM_SETIMAGELIST, 0, 0); + if (imageList != null) imageList.dispose (); + imageList = null; + if (image != null) { + imageList = new ImageList (); + imageList.add (image); + BUTTON_IMAGELIST buttonImageList = new BUTTON_IMAGELIST (); + buttonImageList.himl = imageList.getHandle (); + if ((style & SWT.LEFT) != 0) buttonImageList.uAlign = OS.BUTTON_IMAGELIST_ALIGN_LEFT; + if ((style & SWT.CENTER) != 0) buttonImageList.uAlign = OS.BUTTON_IMAGELIST_ALIGN_CENTER; + if ((style & SWT.RIGHT) != 0) buttonImageList.uAlign = OS.BUTTON_IMAGELIST_ALIGN_RIGHT; + TCHAR buffer = new TCHAR (getCodePage (), "", true); + OS.SetWindowText (handle, buffer); + OS.SendMessage (handle, OS.BCM_SETIMAGELIST, 0, buttonImageList); + } else { + TCHAR buffer = new TCHAR (getCodePage (), text, true); + OS.SetWindowText (handle, buffer); + OS.SendMessage (handle, OS.BCM_SETIMAGELIST, 0, 0); + } + } else { + int hImage = 0, imageBits = 0, fImageType = 0; + if (image != null) { + if (image2 != null) image2.dispose (); + image2 = null; + switch (image.type) { + case SWT.BITMAP: { + Rectangle rect = image.getBounds (); + ImageData data = image.getImageData (); + switch (data.getTransparencyType ()) { + case SWT.TRANSPARENCY_PIXEL: + if (rect.width <= ICON_WIDTH && rect.height <= ICON_HEIGHT) { + image2 = new Image (display, data, data.getTransparencyMask ()); + hImage = image2.handle; + imageBits = OS.BS_ICON; + fImageType = OS.IMAGE_ICON; + break; + } + //FALL THROUGH + case SWT.TRANSPARENCY_ALPHA: + image2 = new Image (display, rect.width, rect.height); + GC gc = new GC (image2); + gc.setBackground (getBackground ()); + gc.fillRectangle (rect); + gc.drawImage (image, 0, 0); + gc.dispose (); + hImage = image2.handle; + imageBits = OS.BS_BITMAP; + fImageType = OS.IMAGE_BITMAP; + break; + case SWT.TRANSPARENCY_NONE: + hImage = image.handle; + imageBits = OS.BS_BITMAP; + fImageType = OS.IMAGE_BITMAP; + break; + } + break; + } + case SWT.ICON: { + hImage = image.handle; + imageBits = OS.BS_ICON; + fImageType = OS.IMAGE_ICON; + break; + } + } + } + int newBits = OS.GetWindowLong (handle, OS.GWL_STYLE); + int oldBits = newBits; + newBits &= ~(OS.BS_BITMAP | OS.BS_ICON); + newBits |= imageBits; + if (newBits != oldBits) OS.SetWindowLong (handle, OS.GWL_STYLE, newBits); + OS.SendMessage (handle, OS.BM_SETIMAGE, fImageType, hImage); + } +} + /** * Adds the listener to the collection of listeners who will * be notified when the control is selected, by sending @@ -228,8 +305,8 @@ public Point computeSize (int wHint, int hHint, boolean changed) { } } if ((style & (SWT.CHECK | SWT.RADIO)) != 0) { - width += CheckWidth + extra; - height = Math.max (height, CheckHeight + 3); + width += CHECK_WIDTH + extra; + height = Math.max (height, CHECK_HEIGHT + 3); } if ((style & (SWT.PUSH | SWT.TOGGLE)) != 0) { width += 12; height += 10; @@ -375,10 +452,12 @@ boolean mnemonicMatch (char key) { void releaseWidget () { super.releaseWidget (); - text = null; - image = null; if (imageList != null) imageList.dispose (); imageList = null; + if (image2 != null) image2.dispose (); + image2 = null; + text = null; + image = null; } /** @@ -508,51 +587,8 @@ void setDefault (boolean value) { */ public void setImage (Image image) { checkWidget (); - this.image = image; - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - OS.SendMessage (handle, OS.BCM_SETIMAGELIST, 0, 0); - if (imageList != null) imageList.dispose (); - imageList = null; - if (image != null) { - if (image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); - imageList = new ImageList (); - imageList.add (image); - BUTTON_IMAGELIST buttonImageList = new BUTTON_IMAGELIST (); - buttonImageList.himl = imageList.getHandle (); - if ((style & SWT.LEFT) != 0) buttonImageList.uAlign = OS.BUTTON_IMAGELIST_ALIGN_LEFT; - if ((style & SWT.CENTER) != 0) buttonImageList.uAlign = OS.BUTTON_IMAGELIST_ALIGN_CENTER; - if ((style & SWT.RIGHT) != 0) buttonImageList.uAlign = OS.BUTTON_IMAGELIST_ALIGN_RIGHT; - TCHAR buffer = new TCHAR (getCodePage (), "", true); - OS.SetWindowText (handle, buffer); - OS.SendMessage (handle, OS.BCM_SETIMAGELIST, 0, buttonImageList); - } else { - TCHAR buffer = new TCHAR (getCodePage (), text, true); - OS.SetWindowText (handle, buffer); - OS.SendMessage (handle, OS.BCM_SETIMAGELIST, 0, 0); - } - } else { - int hImage = 0, imageBits = 0, fImageType = 0; - if (image != null) { - if (image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); - hImage = image.handle; - switch (image.type) { - case SWT.BITMAP: - imageBits = OS.BS_BITMAP; - fImageType = OS.IMAGE_BITMAP; - break; - case SWT.ICON: - imageBits = OS.BS_ICON; - fImageType = OS.IMAGE_ICON; - break; - } - } - int newBits = OS.GetWindowLong (handle, OS.GWL_STYLE); - int oldBits = newBits; - newBits &= ~(OS.BS_BITMAP | OS.BS_ICON); - newBits |= imageBits; - if (newBits != oldBits) OS.SetWindowLong (handle, OS.GWL_STYLE, newBits); - OS.SendMessage (handle, OS.BM_SETIMAGE, fImageType, hImage); - } + if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); + _setImage (this.image = image); } boolean setRadioFocus () { @@ -734,6 +770,13 @@ LRESULT WM_SETFOCUS (int wParam, int lParam) { return result; } +LRESULT WM_SYSCOLORCHANGE (int wParam, int lParam) { + LRESULT result = super.WM_SYSCOLORCHANGE (wParam, lParam); + if (result != null) return result; + if (image2 != null) _setImage (image); + return result; +} + LRESULT wmColorChild (int wParam, int lParam) { LRESULT result = super.wmColorChild (wParam, lParam); if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java index b70aa6185d..68ebbfae5c 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java @@ -39,10 +39,11 @@ import org.eclipse.swt.graphics.*; */ public class Label extends Control { String text = ""; - Image image; + Image image, image2; int font; static final int LabelProc; static final TCHAR LabelClass = new TCHAR (0, "STATIC", true); + static final int ICON_WIDTH = 128, ICON_HEIGHT = 128; static { WNDCLASS lpWndClass = new WNDCLASS (); OS.GetClassInfo (0, LabelClass, lpWndClass); @@ -90,6 +91,98 @@ public Label (Composite parent, int style) { super (parent, checkStyle (style)); } +void _setImage (Image image) { + boolean hasAlpha = false; + int hImage = 0, imageBits = 0, fImageType = 0; + if (image != null) { + switch (image.type) { + case SWT.BITMAP: { + if (image2 != null) image2.dispose (); + image2 = null; + ImageData data = image.getImageData (); + if (OS.COMCTL32_MAJOR < 6) { + Rectangle rect = image.getBounds (); + switch (data.getTransparencyType ()) { + case SWT.TRANSPARENCY_PIXEL: + if (rect.width <= ICON_WIDTH && rect.height <= ICON_HEIGHT) { + image2 = new Image (display, data, data.getTransparencyMask ()); + hImage = image2.handle; + imageBits = OS.SS_ICON; + fImageType = OS.IMAGE_ICON; + break; + } + //FALL THROUGH + case SWT.TRANSPARENCY_ALPHA: + image2 = new Image (display, rect.width, rect.height); + GC gc = new GC (image2); + gc.setBackground (getBackground ()); + gc.fillRectangle (rect); + gc.drawImage (image, 0, 0); + gc.dispose (); + hImage = image2.handle; + imageBits = OS.SS_BITMAP; + fImageType = OS.IMAGE_BITMAP; + break; + case SWT.TRANSPARENCY_NONE: + hImage = image.handle; + imageBits = OS.SS_BITMAP; + fImageType = OS.IMAGE_BITMAP; + break; + } + break; + } else { + if (data.alpha != -1 || data.alphaData != null || data.transparentPixel != -1) { + hasAlpha = true; + hImage = createAlphaFromMask (image.handle, data.alpha, data.alphaData, data.transparentPixel); + } else { + hImage = image.handle; + } + imageBits = OS.SS_BITMAP; + fImageType = OS.IMAGE_BITMAP; + } + break; + } + case SWT.ICON: { + hImage = image.handle; + imageBits = OS.SS_ICON; + fImageType = OS.IMAGE_ICON; + break; + } + } + } + RECT rect = new RECT (); + OS.GetWindowRect (handle, rect); + int newBits = OS.GetWindowLong (handle, OS.GWL_STYLE); + int oldBits = newBits; + newBits &= ~(OS.SS_BITMAP | OS.SS_ICON); + newBits |= imageBits | OS.SS_REALSIZEIMAGE | OS.SS_CENTERIMAGE; + if (newBits != oldBits) { + OS.SetWindowLong (handle, OS.GWL_STYLE, newBits); + } + OS.SendMessage (handle, OS.STM_SETIMAGE, fImageType, hImage); + + /* + * When STM_SETIMAGE encounters a bitmap with alpha information, + * it takes a copy of the bitmap. Therefore the bitmap that was + * created to preserve transparency can be deleted right away. + */ + if (hasAlpha && hImage != 0) OS.DeleteObject (hImage); + + /* + * Feature in Windows. When STM_SETIMAGE is used to set the + * image for a static control, Windows either streches the image + * to fit the control or shrinks the control to fit the image. + * While not stricly wrong, neither of these is desirable. + * The fix is to stop Windows from stretching the image by + * using SS_REALSIZEIMAGE and SS_CENTERIMAGE, allow Windows + * to shrink the control, and then restore the control to the + * original size. + */ + int flags = OS.SWP_NOZORDER | OS.SWP_DRAWFRAME | OS.SWP_NOACTIVATE | OS.SWP_NOMOVE; + SetWindowPos (handle, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, flags); + OS.InvalidateRect (handle, null, true); +} + int callWindowProc (int hwnd, int msg, int wParam, int lParam) { if (handle == 0) return 0; return OS.CallWindowProc (LabelProc, hwnd, msg, wParam, lParam); @@ -360,6 +453,8 @@ boolean mnemonicMatch (char key) { void releaseWidget () { super.releaseWidget (); + if (image2 != null) image2.dispose (); + image2 = null; text = null; image = null; } @@ -423,69 +518,8 @@ public void setAlignment (int alignment) { public void setImage (Image image) { checkWidget (); if ((style & SWT.SEPARATOR) != 0) return; - int hImage = 0, imageBits = 0, fImageType = 0; - if (image != null) { - if (image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); - switch (image.type) { - case SWT.BITMAP: { - if (OS.COMCTL32_MAJOR < 6) { - hImage = image.handle; - } else { - ImageData data = image.getImageData (); - if (data.alpha != -1 || data.alphaData != null || data.transparentPixel != -1) { - hImage = createAlphaFromMask (image.handle, data.alpha, data.alphaData, data.transparentPixel); - } else { - hImage = image.handle; - } - } - imageBits = OS.SS_BITMAP; - fImageType = OS.IMAGE_BITMAP; - break; - } - case SWT.ICON: { - hImage = image.handle; - imageBits = OS.SS_ICON; - fImageType = OS.IMAGE_ICON; - break; - } - default: - return; - } - } - this.image = image; - RECT rect = new RECT (); - OS.GetWindowRect (handle, rect); - int newBits = OS.GetWindowLong (handle, OS.GWL_STYLE); - int oldBits = newBits; - newBits &= ~(OS.SS_BITMAP | OS.SS_ICON); - newBits |= imageBits | OS.SS_REALSIZEIMAGE | OS.SS_CENTERIMAGE; - if (newBits != oldBits) { - OS.SetWindowLong (handle, OS.GWL_STYLE, newBits); - } - OS.SendMessage (handle, OS.STM_SETIMAGE, fImageType, hImage); - - /* - * When STM_SETIMAGE encounters a bitmap with alpha information, - * it takes a copy of the bitmap. Therefore the bitmap that was - * created to preserve transparency can be deleted right away. - */ - if (image != null && image.handle != hImage) { - OS.DeleteObject (hImage); - } - - /* - * Feature in Windows. When STM_SETIMAGE is used to set the - * image for a static control, Windows either streches the image - * to fit the control or shrinks the control to fit the image. - * While not stricly wrong, neither of these is desirable. - * The fix is to stop Windows from stretching the image by - * using SS_REALSIZEIMAGE and SS_CENTERIMAGE, allow Windows - * to shrink the control, and then restore the control to the - * original size. - */ - int flags = OS.SWP_NOZORDER | OS.SWP_DRAWFRAME | OS.SWP_NOACTIVATE | OS.SWP_NOMOVE; - SetWindowPos (handle, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, flags); - OS.InvalidateRect (handle, null, true); + if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); + _setImage (this.image = image); } /** @@ -697,6 +731,13 @@ LRESULT wmColorChild (int wParam, int lParam) { return result; } +LRESULT WM_SYSCOLORCHANGE (int wParam, int lParam) { + LRESULT result = super.WM_SYSCOLORCHANGE (wParam, lParam); + if (result != null) return result; + if (image2 != null) _setImage (image); + return result; +} + LRESULT wmDrawChild (int wParam, int lParam) { DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT (); OS.MoveMemory (struct, lParam, DRAWITEMSTRUCT.sizeof); |