为菜单添加图标时,将已经添加过的图标转换的位图缓存到内存,避免重复执行HICON到HBITMAP的转换,减少GDI句柄的占用

This commit is contained in:
Zhong Yang
2022-03-19 18:40:40 +08:00
parent 9ed80bd693
commit 82402937de
3 changed files with 67 additions and 42 deletions
+2
View File
@@ -668,6 +668,7 @@ void CMusicPlayerApp::InitMenuResourse()
CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(2)->GetSafeHmenu(), 0, TRUE, m_icon_set.add.GetIcon(true));
CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_FILE, FALSE, m_icon_set.music);
CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_FOLDER, FALSE, m_icon_set.select_folder.GetIcon(true));
CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_URL, FALSE, m_icon_set.link.GetIcon(true));
CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(2)->GetSafeHmenu(), 1, TRUE, m_icon_set.close.GetIcon(true));
CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_RELOAD_PLAYLIST, FALSE, m_icon_set.loop_playlist.GetIcon(true));
CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SAVE_AS_NEW_PLAYLIST, FALSE, m_icon_set.save_new);
@@ -769,6 +770,7 @@ void CMusicPlayerApp::InitMenuResourse()
CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_OPTION_SETTINGS, FALSE, m_icon_set.setting.GetIcon(true));
//播放列表菜单
CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_FILE_OPEN_FOLDER, FALSE, m_icon_set.select_folder.GetIcon(true));
CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_FILE, FALSE, m_icon_set.music);
CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_FOLDER, FALSE, m_icon_set.select_folder.GetIcon(true));
CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_URL, FALSE, m_icon_set.link.GetIcon(true));
+62 -42
View File
@@ -32,6 +32,7 @@ CWICFactory::~CWICFactory()
//////////////////////////////////////////////////////////
typedef DWORD ARGB;
std::map<HICON, HBITMAP> CMenuIcon::m_icon_map;
CMenuIcon::CMenuIcon()
{
@@ -44,54 +45,14 @@ CMenuIcon::~CMenuIcon()
HRESULT CMenuIcon::AddIconToMenuItem(HMENU hmenu, int iMenuItem, BOOL fByPosition, HICON hicon)
{
#ifndef COMPILE_IN_WIN_XP
if (CWICFactory::GetWIC() == nullptr)
return 0;
HBITMAP hbmp = NULL;
IWICBitmap *pBitmap;
HRESULT hr = CWICFactory::GetWIC()->CreateBitmapFromHICON(hicon, &pBitmap);
if (SUCCEEDED(hr))
{
IWICFormatConverter *pConverter;
hr = CWICFactory::GetWIC()->CreateFormatConverter(&pConverter);
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(pBitmap, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom);
if (SUCCEEDED(hr))
{
UINT cx, cy;
hr = pConverter->GetSize(&cx, &cy);
if (SUCCEEDED(hr))
{
const SIZE sizIcon = { (int)cx, -(int)cy };
BYTE *pbBuffer;
hr = Create32BitHBITMAP(NULL, &sizIcon, reinterpret_cast<void **>(&pbBuffer), &hbmp);
if (SUCCEEDED(hr))
{
const UINT cbStride = cx * sizeof(ARGB);
const UINT cbBuffer = cy * cbStride;
hr = pConverter->CopyPixels(NULL, cbStride, cbBuffer, pbBuffer);
}
}
}
pConverter->Release();
}
pBitmap->Release();
}
HBITMAP hbmp{};
HRESULT hr = GetBitmapByIcon(hicon, hbmp);
if (SUCCEEDED(hr))
{
hr = AddBitmapToMenuItem(hmenu, iMenuItem, fByPosition, hbmp);
}
if (FAILED(hr))
{
DeleteObject(hbmp);
hbmp = NULL;
}
return hr;
#else
return 0;
@@ -143,3 +104,62 @@ HRESULT CMenuIcon::Create32BitHBITMAP(HDC hdc, const SIZE * psize, void ** ppvBi
}
return (NULL == *phBmp) ? E_OUTOFMEMORY : S_OK;
}
HRESULT CMenuIcon::GetBitmapByIcon(HICON hicon, HBITMAP& hbmp)
{
auto iter = m_icon_map.find(hicon);
if (iter != m_icon_map.end())
{
hbmp = iter->second;
return ERROR_SUCCESS;
}
else
{
if (CWICFactory::GetWIC() == nullptr)
return 0;
hbmp = NULL;
IWICBitmap* pBitmap;
HRESULT hr = CWICFactory::GetWIC()->CreateBitmapFromHICON(hicon, &pBitmap);
if (SUCCEEDED(hr))
{
IWICFormatConverter* pConverter;
hr = CWICFactory::GetWIC()->CreateFormatConverter(&pConverter);
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(pBitmap, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom);
if (SUCCEEDED(hr))
{
UINT cx, cy;
hr = pConverter->GetSize(&cx, &cy);
if (SUCCEEDED(hr))
{
const SIZE sizIcon = { (int)cx, -(int)cy };
BYTE* pbBuffer;
hr = Create32BitHBITMAP(NULL, &sizIcon, reinterpret_cast<void**>(&pbBuffer), &hbmp);
if (SUCCEEDED(hr))
{
const UINT cbStride = cx * sizeof(ARGB);
const UINT cbBuffer = cy * cbStride;
hr = pConverter->CopyPixels(NULL, cbStride, cbBuffer, pbBuffer);
}
}
}
pConverter->Release();
}
pBitmap->Release();
}
if (SUCCEEDED(hr))
{
m_icon_map[hicon] = hbmp;
}
if (FAILED(hr))
{
DeleteObject(hbmp);
hbmp = NULL;
}
return hr;
}
}
+3
View File
@@ -31,5 +31,8 @@ private:
static HRESULT AddBitmapToMenuItem(HMENU hmenu, int iItem, BOOL fByPosition, HBITMAP hbmp);
static void InitBitmapInfo(__out_bcount(cbInfo) BITMAPINFO *pbmi, ULONG cbInfo, LONG cx, LONG cy, WORD bpp);
static HRESULT Create32BitHBITMAP(HDC hdc, const SIZE *psize, __deref_opt_out void **ppvBits, __out HBITMAP* phBmp);
static HRESULT GetBitmapByIcon(HICON hicon, HBITMAP& hbmp);
static std::map<HICON, HBITMAP> m_icon_map;
};