913 pIcon->Release();
914 }
915 return (jlong)hIcon;
916 }
917
918
919 /*
920 * Class: sun_awt_shell_Win32ShellFolder2
921 * Method: disposeIcon
922 * Signature: (J)V
923 */
924 JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_disposeIcon
925 (JNIEnv* env, jclass cls, jlong hicon)
926 {
927 fn_DestroyIcon((HICON)hicon);
928 }
929
930 /*
931 * Class: sun_awt_shell_Win32ShellFolder2
932 * Method: getIconBits
933 * Signature: (JI)[I
934 */
935 JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
936 (JNIEnv* env, jclass cls, jlong hicon, jint iconSize)
937 {
938 jintArray iconBits = NULL;
939
940 // Get the icon info
941 ICONINFO iconInfo;
942 if (fn_GetIconInfo((HICON)hicon, &iconInfo)) {
943 // Get the screen DC
944 HDC dc = GetDC(NULL);
945 if (dc != NULL) {
946 // Set up BITMAPINFO
947 BITMAPINFO bmi;
948 memset(&bmi, 0, sizeof(BITMAPINFO));
949 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
950 bmi.bmiHeader.biWidth = iconSize;
951 bmi.bmiHeader.biHeight = -iconSize;
952 bmi.bmiHeader.biPlanes = 1;
953 bmi.bmiHeader.biBitCount = 32;
954 bmi.bmiHeader.biCompression = BI_RGB;
955 // Extract the color bitmap
956 int nBits = iconSize * iconSize;
957 long colorBits[1024];
958 GetDIBits(dc, iconInfo.hbmColor, 0, iconSize, colorBits, &bmi, DIB_RGB_COLORS);
959 // XP supports alpha in some icons, and depending on device.
960 // This should take precedence over the icon mask bits.
961 BOOL hasAlpha = FALSE;
962 if (IS_WINXP) {
963 for (int i = 0; i < nBits; i++) {
964 if ((colorBits[i] & 0xff000000) != 0) {
965 hasAlpha = TRUE;
966 break;
967 }
968 }
969 }
970 if (!hasAlpha) {
971 // Extract the mask bitmap
972 long maskBits[1024];
973 GetDIBits(dc, iconInfo.hbmMask, 0, iconSize, maskBits, &bmi, DIB_RGB_COLORS);
974 // Copy the mask alphas into the color bits
975 for (int i = 0; i < nBits; i++) {
976 if (maskBits[i] == 0) {
977 colorBits[i] |= 0xff000000;
978 }
979 }
980 }
981 // Release DC
982 ReleaseDC(NULL, dc);
983 // Create java array
984 iconBits = env->NewIntArray(nBits);
985 if (!(env->ExceptionCheck())) {
986 // Copy values to java array
987 env->SetIntArrayRegion(iconBits, 0, nBits, colorBits);
988 }
989 }
990 // Fix 4745575 GDI Resource Leak
991 // MSDN
992 // GetIconInfo creates bitmaps for the hbmMask and hbmColor members of ICONINFO.
993 // The calling application must manage these bitmaps and delete them when they
994 // are no longer necessary.
995 ::DeleteObject(iconInfo.hbmColor);
996 ::DeleteObject(iconInfo.hbmMask);
997 }
998 return iconBits;
999 }
1000
1001 /*
1002 * Class: sun_awt_shell_Win32ShellFolder2
1003 * Method: getStandardViewButton0
1004 * Signature: (I)[I
1005 */
1006 JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getStandardViewButton0
1007 (JNIEnv* env, jclass cls, jint iconIndex)
1008 {
1009 jintArray result = NULL;
1010
1011 // Create a toolbar
1012 HWND hWndToolbar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
1013 0, 0, 0, 0, 0,
1014 NULL, NULL, NULL, NULL);
1015
1016 if (hWndToolbar != NULL) {
1017 SendMessage(hWndToolbar, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);
1018
1019 HIMAGELIST hImageList = (HIMAGELIST) SendMessage(hWndToolbar, TB_GETIMAGELIST, 0, 0);
1020
1021 if (hImageList != NULL) {
1022 HICON hIcon = ImageList_GetIcon(hImageList, iconIndex, ILD_TRANSPARENT);
1023
1024 if (hIcon != NULL) {
1025 result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon), 16);
1026
1027 DestroyIcon(hIcon);
1028 }
1029
1030 ImageList_Destroy(hImageList);
1031 }
1032
1033 DestroyWindow(hWndToolbar);
1034 }
1035
1036 return result;
1037 }
1038
1039 /*
1040 * Class: sun_awt_shell_Win32ShellFolder2
1041 * Method: getSystemIcon
1042 * Signature: (I)J
1043 */
1044 JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getSystemIcon
1045 (JNIEnv* env, jclass cls, jint iconID)
|
913 pIcon->Release();
914 }
915 return (jlong)hIcon;
916 }
917
918
919 /*
920 * Class: sun_awt_shell_Win32ShellFolder2
921 * Method: disposeIcon
922 * Signature: (J)V
923 */
924 JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_disposeIcon
925 (JNIEnv* env, jclass cls, jlong hicon)
926 {
927 fn_DestroyIcon((HICON)hicon);
928 }
929
930 /*
931 * Class: sun_awt_shell_Win32ShellFolder2
932 * Method: getIconBits
933 * Signature: (J)[I
934 */
935 JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
936 (JNIEnv* env, jclass cls, jlong hicon)
937 {
938 const int MAX_ICON_SIZE = 128;
939 int iconSize = 0;
940 jintArray iconBits = NULL;
941
942 BITMAP bmp;
943 memset(&bmp, 0, sizeof(BITMAP));
944
945 // Get the icon info
946 ICONINFO iconInfo;
947 if (fn_GetIconInfo((HICON)hicon, &iconInfo)) {
948 // Get the screen DC
949 HDC dc = GetDC(NULL);
950 if (dc != NULL) {
951 // find out the icon size in order to deal with different sizes
952 // delivered depending on HiDPI mode or SD DPI mode.
953 if (iconInfo.hbmColor) {
954 const int nWrittenBytes = GetObject(iconInfo.hbmColor, sizeof(bmp), &bmp);
955 if(nWrittenBytes > 0) {
956 iconSize = bmp.bmWidth;
957 }
958 } else if (iconInfo.hbmMask) {
959 // Icon has no color plane, image data stored in mask
960 const int nWrittenBytes = GetObject(iconInfo.hbmMask, sizeof(bmp), &bmp);
961 if (nWrittenBytes > 0) {
962 iconSize = bmp.bmWidth;
963 }
964 }
965 // limit iconSize to MAX_ICON_SIZE, so that the colorBits and maskBits
966 // arrays are big enough.
967 // (logic: rather show bad icons than overrun the array size)
968 iconSize = iconSize > MAX_ICON_SIZE ? MAX_ICON_SIZE : iconSize;
969
970 // Set up BITMAPINFO
971 BITMAPINFO bmi;
972 memset(&bmi, 0, sizeof(BITMAPINFO));
973 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
974 bmi.bmiHeader.biWidth = iconSize;
975 bmi.bmiHeader.biHeight = -iconSize;
976 bmi.bmiHeader.biPlanes = 1;
977 bmi.bmiHeader.biBitCount = 32;
978 bmi.bmiHeader.biCompression = BI_RGB;
979 // Extract the color bitmap
980 int nBits = iconSize * iconSize;
981 long colorBits[MAX_ICON_SIZE * MAX_ICON_SIZE];
982 GetDIBits(dc, iconInfo.hbmColor, 0, iconSize, colorBits, &bmi, DIB_RGB_COLORS);
983 // XP supports alpha in some icons, and depending on device.
984 // This should take precedence over the icon mask bits.
985 BOOL hasAlpha = FALSE;
986 if (IS_WINXP) {
987 for (int i = 0; i < nBits; i++) {
988 if ((colorBits[i] & 0xff000000) != 0) {
989 hasAlpha = TRUE;
990 break;
991 }
992 }
993 }
994 if (!hasAlpha) {
995 // Extract the mask bitmap
996 long maskBits[MAX_ICON_SIZE * MAX_ICON_SIZE];
997 GetDIBits(dc, iconInfo.hbmMask, 0, iconSize, maskBits, &bmi, DIB_RGB_COLORS);
998 // Copy the mask alphas into the color bits
999 for (int i = 0; i < nBits; i++) {
1000 if (maskBits[i] == 0) {
1001 colorBits[i] |= 0xff000000;
1002 }
1003 }
1004 }
1005 // Release DC
1006 ReleaseDC(NULL, dc);
1007 // Create java array
1008 iconBits = env->NewIntArray(nBits);
1009 if (!(env->ExceptionCheck())) {
1010 // Copy values to java array
1011 env->SetIntArrayRegion(iconBits, 0, nBits, colorBits);
1012 }
1013 }
1014 // Fix 4745575 GDI Resource Leak
1015 // MSDN
1016 // GetIconInfo creates bitmaps for the hbmMask and hbmColor members of ICONINFO.
1017 // The calling application must manage these bitmaps and delete them when they
1018 // are no longer necessary.
1019 ::DeleteObject(iconInfo.hbmColor);
1020 ::DeleteObject(iconInfo.hbmMask);
1021 }
1022 return iconBits;
1023 }
1024
1025 /*
1026 * Class: sun_awt_shell_Win32ShellFolder2
1027 * Method: getStandardViewButton0
1028 * Signature: (I)[I
1029 */
1030 JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getStandardViewButton0
1031 (JNIEnv* env, jclass cls, jint iconIndex, jboolean smallIcon)
1032 {
1033 jintArray result = NULL;
1034 WPARAM size = smallIcon ? (WPARAM)IDB_VIEW_SMALL_COLOR : (WPARAM)IDB_VIEW_LARGE_COLOR;
1035
1036 // Create a toolbar
1037 HWND hWndToolbar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
1038 0, 0, 0, 0, 0,
1039 NULL, NULL, NULL, NULL);
1040
1041 if (hWndToolbar != NULL) {
1042 SendMessage(hWndToolbar, TB_LOADIMAGES, size, (LPARAM)HINST_COMMCTRL);
1043
1044 HIMAGELIST hImageList = (HIMAGELIST) SendMessage(hWndToolbar, TB_GETIMAGELIST, 0, 0);
1045
1046 if (hImageList != NULL) {
1047 HICON hIcon = ImageList_GetIcon(hImageList, iconIndex, ILD_TRANSPARENT);
1048
1049 if (hIcon != NULL) {
1050 result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon));
1051
1052 DestroyIcon(hIcon);
1053 }
1054
1055 ImageList_Destroy(hImageList);
1056 }
1057
1058 DestroyWindow(hWndToolbar);
1059 }
1060
1061 return result;
1062 }
1063
1064 /*
1065 * Class: sun_awt_shell_Win32ShellFolder2
1066 * Method: getSystemIcon
1067 * Signature: (I)J
1068 */
1069 JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getSystemIcon
1070 (JNIEnv* env, jclass cls, jint iconID)
|