Index: win/tkWinWm.c ================================================================== --- win/tkWinWm.c +++ win/tkWinWm.c @@ -676,10 +676,54 @@ * Results: * BOOL - TRUE for success, FALSE for failure * *---------------------------------------------------------------------- */ + +static BOOL +SetSizeAndColorFromHICON( /* Helper for AdjustIconImagePointers */ + HICON hicon, + LPICONIMAGE lpImage) +{ + ICONINFO info; + BOOL bRes; + BITMAP bmp; + + memset(&info, 0, sizeof(info)); + + bRes = GetIconInfo(hicon, &info); + if (!bRes) { + return FALSE; + } + + if (info.hbmColor) { + const int nWrittenBytes = GetObject(info.hbmColor, sizeof(bmp), &bmp); + + if (nWrittenBytes > 0) { + lpImage->Width = bmp.bmWidth; + lpImage->Height = bmp.bmHeight; + lpImage->Colors = bmp.bmBitsPixel; + } + } else if (info.hbmMask) { + // Icon has no color plane, image data stored in mask + const int nWrittenBytes = GetObject(info.hbmMask, sizeof(bmp), &bmp); + + if (nWrittenBytes > 0) { + lpImage->Width = bmp.bmWidth; + lpImage->Height = bmp.bmHeight / 2; + lpImage->Colors = 1; + } + } + + if (info.hbmColor) { + DeleteObject(info.hbmColor); + } + if (info.hbmMask) { + DeleteObject(info.hbmMask); + } + return TRUE; +} static BOOL AdjustIconImagePointers( LPICONIMAGE lpImage) { @@ -696,28 +740,14 @@ */ lpImage->lpbi = (LPBITMAPINFO) lpImage->lpBits; /* - * Width - simple enough. - */ - - lpImage->Width = lpImage->lpbi->bmiHeader.biWidth; - - /* - * Icons are stored in funky format where height is doubled so account for - * that. - */ - - lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight)/2; - - /* - * How many colors? - */ - - lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes - * lpImage->lpbi->bmiHeader.biBitCount; + * Width, height, and number of colors. + */ + + SetSizeAndColorFromHICON(lpImage->hIcon, lpImage); /* * XOR bits follow the header and color table. */ @@ -763,28 +793,20 @@ /* * Let the OS do the real work :) */ - hIcon = (HICON) CreateIconFromResourceEx(lpIcon->lpBits, - lpIcon->dwNumBytes, isIcon, 0x00030000, - (*(LPBITMAPINFOHEADER) lpIcon->lpBits).biWidth, - (*(LPBITMAPINFOHEADER) lpIcon->lpBits).biHeight/2, 0); + hIcon = (HICON)CreateIconFromResourceEx(lpIcon->lpBits, + lpIcon->dwNumBytes, isIcon, 0x00030000, 0, 0, 0); /* - * It failed, odds are good we're on NT so try the non-Ex way. + * It failed, the non-Ex way might work as a fallback. */ if (hIcon == NULL) { - /* - * We would break on NT if we try with a 16bpp image. - */ - - if (lpIcon->lpbi->bmiHeader.biBitCount != 16) { - hIcon = CreateIconFromResource(lpIcon->lpBits, lpIcon->dwNumBytes, - isIcon, 0x00030000); - } + hIcon = CreateIconFromResource(lpIcon->lpBits, lpIcon->dwNumBytes, + isIcon, 0x00030000); } return hIcon; } /* @@ -1678,21 +1700,21 @@ "error reading file: %s", Tcl_PosixError(interp))); goto readError; } /* - * Set the internal pointers appropriately. + * Create the icon from the resource, and set the internal pointers appropriately. */ + lpIR->IconImages[i].hIcon = + MakeIconOrCursorFromResource(&lpIR->IconImages[i], isIcon); if (!AdjustIconImagePointers(&lpIR->IconImages[i])) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "Error converting to internal format", -1)); Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "FORMAT", NULL); goto readError; } - lpIR->IconImages[i].hIcon = - MakeIconOrCursorFromResource(&lpIR->IconImages[i], isIcon); } /* * Clean up */