80 lines
2.2 KiB
C++
Raw Normal View History

2024-11-05 15:46:45 +08:00

2024-04-02 15:36:52 +08:00
#include "BMP.h"
2024-11-05 15:46:45 +08:00
DECLARE_API bool extracticon2data(const wchar_t *name, void (*cb)(const char *, size_t))
2024-04-02 15:36:52 +08:00
{
2024-01-08 23:37:00 +08:00
HICON h1, h2;
2024-04-02 15:36:52 +08:00
2024-07-27 23:12:12 +08:00
if (UINT_MAX == ExtractIconExW(name, 0, &h1, &h2, 1))
return false;
2024-04-02 15:36:52 +08:00
if (h1 == 0)
2024-07-14 15:09:37 +08:00
return false;
2024-01-08 23:37:00 +08:00
HDC hdc = GetDC(NULL);
2024-07-27 23:12:12 +08:00
if (!hdc)
return false;
2024-01-08 23:37:00 +08:00
HDC memDC = CreateCompatibleDC(hdc);
2024-07-27 23:12:12 +08:00
if (!memDC)
return false;
2024-01-08 23:37:00 +08:00
ICONINFO iconInfo;
2024-07-27 23:12:12 +08:00
if (!GetIconInfo(h1, &iconInfo))
return false;
2024-01-08 23:37:00 +08:00
int iconWidth = iconInfo.xHotspot * 2;
int iconHeight = iconInfo.yHotspot * 2;
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, iconWidth, iconHeight);
2024-07-27 23:12:12 +08:00
if (!hBitmap)
return false;
2024-01-08 23:37:00 +08:00
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memDC, hBitmap);
2024-07-27 23:12:12 +08:00
if (!hOldBitmap)
return false;
if (!DrawIconEx(memDC, 0, 0, h1, iconWidth, iconHeight, 0, NULL, DI_NORMAL))
return false;
2024-01-08 23:37:00 +08:00
SelectObject(memDC, hOldBitmap);
DeleteDC(memDC);
2024-04-02 15:36:52 +08:00
BMP bmpp(iconWidth, iconHeight);
2024-01-08 23:37:00 +08:00
BITMAP bmp;
GetObject(hBitmap, sizeof(BITMAP), &bmp);
2024-04-02 15:36:52 +08:00
bmpp.bmp_info_header.bit_count = bmp.bmBitsPixel;
2024-01-08 23:37:00 +08:00
auto dwSize = bmp.bmWidthBytes * bmp.bmHeight;
bmpp.data.resize(dwSize);
2024-04-02 15:36:52 +08:00
auto dataptr = bmpp.data.data();
2024-07-27 23:12:12 +08:00
if (!GetBitmapBits(hBitmap, dwSize, dataptr))
return false;
2024-01-08 23:37:00 +08:00
DeleteObject(hBitmap);
2024-04-02 15:36:52 +08:00
std::vector<LONG> tmp;
2024-01-08 23:37:00 +08:00
tmp.resize(bmp.bmWidthBytes);
2024-04-02 15:36:52 +08:00
if (bmp.bmWidthBytes == bmp.bmHeight * 4)
{
bool allalpha0 = true;
for (int i = 0; i < bmpp.data.size() / 4; i++)
{
if (dataptr[i * 4 + 3] != 0)
{
allalpha0 = false;
break;
2024-01-08 23:37:00 +08:00
}
}
2024-04-02 15:36:52 +08:00
if (allalpha0)
{
for (int i = 0; i < bmpp.data.size() / 4; i++)
{
dataptr[i * 4 + 3] = 0xff;
2024-01-08 23:37:00 +08:00
}
}
}
2024-04-02 15:36:52 +08:00
for (int i = 0; i < bmp.bmHeight / 2; i++)
{
2024-01-08 23:37:00 +08:00
memcpy(tmp.data(), dataptr + i * bmp.bmWidthBytes, bmp.bmWidthBytes);
memcpy(dataptr + i * bmp.bmWidthBytes, dataptr + (bmp.bmHeight - 1 - i) * bmp.bmWidthBytes, bmp.bmWidthBytes);
2024-04-02 15:36:52 +08:00
memcpy(dataptr + (bmp.bmHeight - 1 - i) * bmp.bmWidthBytes, tmp.data(), bmp.bmWidthBytes);
}
2024-01-08 23:37:00 +08:00
std::string data;
2024-04-02 15:36:52 +08:00
bmpp.write_tomem(data);
2024-07-27 23:12:12 +08:00
cb(data.c_str(), data.size());
2024-07-14 15:09:37 +08:00
return true;
2024-01-08 23:37:00 +08:00
}