зеркало из https://github.com/mono/ikvm-fork.git
fix the missing alpha chanel on windows shell icons
This commit is contained in:
Родитель
76fb68033d
Коммит
51a08412cf
|
@ -57,6 +57,10 @@ import java.io.IOException;
|
||||||
import java.io.ObjectStreamException;
|
import java.io.ObjectStreamException;
|
||||||
|
|
||||||
import cli.System.Drawing.Bitmap;
|
import cli.System.Drawing.Bitmap;
|
||||||
|
import cli.System.Drawing.Imaging.BitmapData;
|
||||||
|
import cli.System.Drawing.Imaging.ImageLockMode;
|
||||||
|
import cli.System.Drawing.Imaging.PixelFormat;
|
||||||
|
import cli.System.Runtime.InteropServices.Marshal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Volker Berlin
|
* @author Volker Berlin
|
||||||
|
@ -314,9 +318,12 @@ public class Win32ShellFolder2 extends ShellFolder{
|
||||||
fileChooserIcons = new Image[47];
|
fileChooserIcons = new Image[47];
|
||||||
|
|
||||||
try{
|
try{
|
||||||
cli.System.IntPtr handle = getFileChooserBitmapHandle();
|
int[] data = getFileChooserBitmapHandle();
|
||||||
Bitmap bitmap = Bitmap.FromHbitmap(handle);
|
Bitmap bitmap = new Bitmap(data.length/16, 16, PixelFormat.wrap(PixelFormat.Format32bppArgb));
|
||||||
DeleteObject(handle);
|
BitmapData bitmapData = bitmap.LockBits(new cli.System.Drawing.Rectangle(0,0,bitmap.get_Width(), bitmap.get_Height()), ImageLockMode.wrap(ImageLockMode.WriteOnly), PixelFormat.wrap(PixelFormat.Format32bppArgb));
|
||||||
|
Marshal.Copy(data, 0, bitmapData.get_Scan0(), data.length);
|
||||||
|
bitmap.UnlockBits(bitmapData);
|
||||||
|
|
||||||
for(int i = 0; i < fileChooserIcons.length; i++){
|
for(int i = 0; i < fileChooserIcons.length; i++){
|
||||||
cli.System.Drawing.Rectangle rect = new cli.System.Drawing.Rectangle(16 * i, 0, 16, 16);
|
cli.System.Drawing.Rectangle rect = new cli.System.Drawing.Rectangle(16 * i, 0, 16, 16);
|
||||||
Bitmap icon = bitmap.Clone(rect, bitmap.get_PixelFormat());
|
Bitmap icon = bitmap.Clone(rect, bitmap.get_PixelFormat());
|
||||||
|
@ -329,7 +336,7 @@ public class Win32ShellFolder2 extends ShellFolder{
|
||||||
return fileChooserIcons[idx];
|
return fileChooserIcons[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native cli.System.IntPtr getFileChooserBitmapHandle();
|
private static native int[] getFileChooserBitmapHandle();
|
||||||
|
|
||||||
private static native boolean DeleteObject(cli.System.IntPtr hDc);
|
private static native boolean DeleteObject(cli.System.IntPtr hDc);
|
||||||
|
|
||||||
|
@ -398,12 +405,18 @@ public class Win32ShellFolder2 extends ShellFolder{
|
||||||
public Image getIcon(final boolean getLargeIcon) {
|
public Image getIcon(final boolean getLargeIcon) {
|
||||||
Image icon = getLargeIcon ? largeIcon : smallIcon;
|
Image icon = getLargeIcon ? largeIcon : smallIcon;
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
|
int size = getLargeIcon ? 32 : 16;
|
||||||
cli.System.IntPtr hIcon = getIcon( getPath(), getLargeIcon);
|
cli.System.IntPtr hIcon = getIcon( getPath(), getLargeIcon);
|
||||||
if(hIcon.ToInt32() == 0){
|
if(hIcon.ToInt32() == 0){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Bitmap bitmap = Bitmap.FromHicon(hIcon);
|
|
||||||
DeleteObject(hIcon);
|
DeleteObject(hIcon);
|
||||||
|
int[] iconPixels = getIconBits(hIcon, size);
|
||||||
|
Bitmap bitmap = new Bitmap(size, size, PixelFormat.wrap(PixelFormat.Format32bppArgb));
|
||||||
|
BitmapData bitmapData = bitmap.LockBits(new cli.System.Drawing.Rectangle(0,0,size, size), ImageLockMode.wrap(ImageLockMode.WriteOnly), PixelFormat.wrap(PixelFormat.Format32bppArgb));
|
||||||
|
Marshal.Copy(iconPixels, 0, bitmapData.get_Scan0(), iconPixels.length);
|
||||||
|
bitmap.UnlockBits(bitmapData);
|
||||||
|
|
||||||
icon = new BufferedImage(bitmap);
|
icon = new BufferedImage(bitmap);
|
||||||
if (getLargeIcon) {
|
if (getLargeIcon) {
|
||||||
largeIcon = icon;
|
largeIcon = icon;
|
||||||
|
@ -417,4 +430,6 @@ public class Win32ShellFolder2 extends ShellFolder{
|
||||||
// Return the icon of a file system shell folder in the form of an HICON
|
// Return the icon of a file system shell folder in the form of an HICON
|
||||||
private static native cli.System.IntPtr getIcon(String absolutePath, boolean getLargeIcon);
|
private static native cli.System.IntPtr getIcon(String absolutePath, boolean getLargeIcon);
|
||||||
|
|
||||||
|
private static native int[] getIconBits(cli.System.IntPtr hIcon, int iconSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4945,6 +4945,70 @@ namespace IKVM.NativeCode.sun.awt.shell
|
||||||
public string szTypeName;
|
public string szTypeName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[DllImport("msvcrt.dll", SetLastError = false)]
|
||||||
|
static extern IntPtr memcpy(IntPtr dest, IntPtr src, int count);
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan,
|
||||||
|
uint cScanLines, int[] lpvBits, ref BITMAPINFO lpbmi, uint uUsage);
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
public static extern int BitBlt(IntPtr hdcDst, int xDst, int yDst, int w, int h, IntPtr hdcSrc, int xSrc, int ySrc, int rop);
|
||||||
|
static int SRCCOPY = 0x00CC0020;
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr GetDC(IntPtr hwnd);
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
static extern int GetObject(IntPtr hgdiobj, int cbBuffer, ref BITMAPINFO lpvObject);
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
public static extern int DeleteDC(IntPtr hdc);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct ICONINFO
|
||||||
|
{
|
||||||
|
public bool fIcon; // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies
|
||||||
|
// an icon; FALSE specifies a cursor.
|
||||||
|
public Int32 xHotspot; // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot
|
||||||
|
// spot is always in the center of the icon, and this member is ignored.
|
||||||
|
public Int32 yHotspot; // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot
|
||||||
|
// spot is always in the center of the icon, and this member is ignored.
|
||||||
|
public IntPtr hbmMask; // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon,
|
||||||
|
// this bitmask is formatted so that the upper half is the icon AND bitmask and the lower half is
|
||||||
|
// the icon XOR bitmask. Under this condition, the height should be an even multiple of two. If
|
||||||
|
// this structure defines a color icon, this mask only defines the AND bitmask of the icon.
|
||||||
|
public IntPtr hbmColor; // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this
|
||||||
|
// structure defines a black and white icon. The AND bitmask of hbmMask is applied with the SRCAND
|
||||||
|
// flag to the destination; subsequently, the color bitmap is applied (using XOR) to the
|
||||||
|
// destination by using the SRCINVERT flag.
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct BITMAPINFO
|
||||||
|
{
|
||||||
|
public uint biSize;
|
||||||
|
public int biWidth, biHeight;
|
||||||
|
public short biPlanes, biBitCount;
|
||||||
|
public uint biCompression, biSizeImage;
|
||||||
|
public int biXPelsPerMeter, biYPelsPerMeter;
|
||||||
|
public uint biClrUsed, biClrImportant;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
|
||||||
|
public uint[] cols;
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("shell32.dll")]
|
[DllImport("shell32.dll")]
|
||||||
private static extern int FindExecutable(string lpFile, string lpDirectory, StringBuilder lpResult);
|
private static extern int FindExecutable(string lpFile, string lpDirectory, StringBuilder lpResult);
|
||||||
|
|
||||||
|
@ -5007,6 +5071,53 @@ namespace IKVM.NativeCode.sun.awt.shell
|
||||||
return shinfo.hIcon;
|
return shinfo.hIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int[] getIconBits(IntPtr hIcon, int iconSize)
|
||||||
|
{
|
||||||
|
ICONINFO iconInfo;
|
||||||
|
if (GetIconInfo(hIcon, out iconInfo))
|
||||||
|
{
|
||||||
|
IntPtr hWnd = new IntPtr(0);
|
||||||
|
IntPtr dc = GetDC(hWnd);
|
||||||
|
BITMAPINFO bmi = new BITMAPINFO();
|
||||||
|
bmi.biSize = 40;
|
||||||
|
bmi.biWidth = iconSize;
|
||||||
|
bmi.biHeight = -iconSize;
|
||||||
|
bmi.biPlanes = 1;
|
||||||
|
bmi.biBitCount = 32;
|
||||||
|
bmi.biCompression = 0;
|
||||||
|
int intArrSize = iconSize * iconSize;
|
||||||
|
int[] iconBits = new int[intArrSize];
|
||||||
|
GetDIBits(dc, iconInfo.hbmColor, 0, (uint)iconSize, iconBits, ref bmi, 0);
|
||||||
|
bool hasAlpha = false;
|
||||||
|
bool isXP = (Environment.OSVersion.Version.Major >= 6) || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor>=1);
|
||||||
|
if (isXP) {
|
||||||
|
for (int i = 0; i < iconBits.Length; i++)
|
||||||
|
{
|
||||||
|
if ((iconBits[i] & 0xFF000000) != 0)
|
||||||
|
{
|
||||||
|
hasAlpha = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasAlpha)
|
||||||
|
{
|
||||||
|
int[] maskBits = new int[intArrSize];
|
||||||
|
GetDIBits(dc, iconInfo.hbmMask, 0, (uint)iconSize, maskBits, ref bmi, 0);
|
||||||
|
for (int i = 0; i < iconBits.Length; i++)
|
||||||
|
{
|
||||||
|
if (maskBits[i] == 0) {
|
||||||
|
iconBits[i] = (int)((uint)iconBits[i] | 0xFF000000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DeleteObject(iconInfo.hbmColor);
|
||||||
|
DeleteObject(iconInfo.hbmMask);
|
||||||
|
return iconBits;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static int getAttribute(string path)
|
public static int getAttribute(string path)
|
||||||
{
|
{
|
||||||
SHFILEINFO shinfo = new SHFILEINFO();
|
SHFILEINFO shinfo = new SHFILEINFO();
|
||||||
|
@ -5026,7 +5137,7 @@ namespace IKVM.NativeCode.sun.awt.shell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntPtr getFileChooserBitmapHandle()
|
public static int[] getFileChooserBitmapHandle()
|
||||||
{
|
{
|
||||||
// Code copied from ShellFolder2.cpp Java_sun_awt_shell_Win32ShellFolder2_getFileChooserBitmapBits
|
// Code copied from ShellFolder2.cpp Java_sun_awt_shell_Win32ShellFolder2_getFileChooserBitmapBits
|
||||||
IntPtr libShell32 = LoadLibrary("shell32.dll");
|
IntPtr libShell32 = LoadLibrary("shell32.dll");
|
||||||
|
@ -5035,12 +5146,31 @@ namespace IKVM.NativeCode.sun.awt.shell
|
||||||
IntPtr hBitmap = isVista ?
|
IntPtr hBitmap = isVista ?
|
||||||
LoadImageName(libShell32, "IDB_TB_SH_DEF_16", IMAGE_BITMAP, 0, 0, 0) :
|
LoadImageName(libShell32, "IDB_TB_SH_DEF_16", IMAGE_BITMAP, 0, 0, 0) :
|
||||||
LoadImageID(libShell32, 216, IMAGE_BITMAP, 0, 0, 0);
|
LoadImageID(libShell32, 216, IMAGE_BITMAP, 0, 0, 0);
|
||||||
if (hBitmap.ToInt32() != 0)
|
if (hBitmap.ToInt32() == 0)
|
||||||
{
|
{
|
||||||
return hBitmap;
|
|
||||||
}
|
|
||||||
IntPtr libComCtl32 = LoadLibrary("comctl32.dll");
|
IntPtr libComCtl32 = LoadLibrary("comctl32.dll");
|
||||||
return LoadImageID(libComCtl32, 124, IMAGE_BITMAP, 0, 0, 0);
|
hBitmap = LoadImageID(libComCtl32, 124, IMAGE_BITMAP, 0, 0, 0);
|
||||||
|
}
|
||||||
|
if (hBitmap.ToInt32() == 0)
|
||||||
|
{
|
||||||
|
return new int[768*16];
|
||||||
|
}
|
||||||
|
BITMAPINFO bmi = new BITMAPINFO();
|
||||||
|
GetObject(hBitmap, Marshal.SizeOf(bmi), ref bmi);
|
||||||
|
int width = bmi.biWidth;
|
||||||
|
int height = bmi.biHeight;
|
||||||
|
bmi.biSize = 40;
|
||||||
|
bmi.biHeight = -bmi.biHeight;
|
||||||
|
bmi.biPlanes = 1;
|
||||||
|
bmi.biBitCount = 32;
|
||||||
|
bmi.biCompression = 0;
|
||||||
|
IntPtr hwnd = new IntPtr(0);
|
||||||
|
IntPtr dc = GetDC(hwnd);
|
||||||
|
int[] data = new int[width*height];
|
||||||
|
GetDIBits(dc, hBitmap, (uint)0, (uint)height, data, ref bmi, 0);
|
||||||
|
DeleteObject(hBitmap);
|
||||||
|
ReleaseDC(hwnd, dc);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntPtr getIconResource(String libName, int iconID, int cxDesired, int cyDesired)
|
public static IntPtr getIconResource(String libName, int iconID, int cxDesired, int cyDesired)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче