| 703 | } |
| 704 | |
| 705 | void* FileDialog::m_getIcon(const std::filesystem::path& path) |
| 706 | { |
| 707 | #ifdef _WIN32 |
| 708 | if (m_icons.count(path.u8string()) > 0) |
| 709 | return m_icons[path.u8string()]; |
| 710 | |
| 711 | std::string pathU8 = path.u8string(); |
| 712 | |
| 713 | std::error_code ec; |
| 714 | m_icons[pathU8] = nullptr; |
| 715 | |
| 716 | DWORD attrs = 0; |
| 717 | UINT flags = SHGFI_ICON | SHGFI_LARGEICON; |
| 718 | if (!std::filesystem::exists(path, ec)) { |
| 719 | flags |= SHGFI_USEFILEATTRIBUTES; |
| 720 | attrs = FILE_ATTRIBUTE_DIRECTORY; |
| 721 | } |
| 722 | |
| 723 | SHFILEINFOW fileInfo = { 0 }; |
| 724 | std::wstring pathW = path.wstring(); |
| 725 | for (int i = 0; i < pathW.size(); i++) |
| 726 | if (pathW[i] == '/') |
| 727 | pathW[i] = '\\'; |
| 728 | SHGetFileInfoW(pathW.c_str(), attrs, &fileInfo, sizeof(SHFILEINFOW), flags); |
| 729 | |
| 730 | if (fileInfo.hIcon == nullptr) |
| 731 | return nullptr; |
| 732 | |
| 733 | // check if icon is already loaded |
| 734 | auto itr = std::find(m_iconIndices.begin(), m_iconIndices.end(), fileInfo.iIcon); |
| 735 | if (itr != m_iconIndices.end()) { |
| 736 | const std::string& existingIconFilepath = m_iconFilepaths[itr - m_iconIndices.begin()]; |
| 737 | m_icons[pathU8] = m_icons[existingIconFilepath]; |
| 738 | return m_icons[pathU8]; |
| 739 | } |
| 740 | |
| 741 | m_iconIndices.push_back(fileInfo.iIcon); |
| 742 | m_iconFilepaths.push_back(pathU8); |
| 743 | |
| 744 | ICONINFO iconInfo = { 0 }; |
| 745 | GetIconInfo(fileInfo.hIcon, &iconInfo); |
| 746 | |
| 747 | if (iconInfo.hbmColor == nullptr) |
| 748 | return nullptr; |
| 749 | |
| 750 | DIBSECTION ds; |
| 751 | GetObject(iconInfo.hbmColor, sizeof(ds), &ds); |
| 752 | int byteSize = ds.dsBm.bmWidth * ds.dsBm.bmHeight * (ds.dsBm.bmBitsPixel / 8); |
| 753 | |
| 754 | if (byteSize == 0) |
| 755 | return nullptr; |
| 756 | |
| 757 | uint8_t* data = (uint8_t*)malloc(byteSize); |
| 758 | GetBitmapBits(iconInfo.hbmColor, byteSize, data); |
| 759 | |
| 760 | m_icons[pathU8] = this->CreateTexture(data, ds.dsBm.bmWidth, ds.dsBm.bmHeight, 0); |
| 761 | |
| 762 | free(data); |
nothing calls this directly
no outgoing calls
no test coverage detected