Skip to content

Commit e54b9f4

Browse files
committed
fix (WeaselUI): Fix memory leak / assertion error when switching to schemas with custom icons
Just separate the custom icons and built-in icons, and avoid calling `LoadIconW` on a CIcon with non-null HICON in it.
1 parent 93eec2d commit e54b9f4

2 files changed

Lines changed: 53 additions & 24 deletions

File tree

WeaselUI/WeaselPanel.cpp

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,34 @@
2525

2626
#pragma comment(lib, "Shcore.lib")
2727

28-
template <class t0, class t1, class t2>
29-
inline void LoadIconNecessary(t0& a, t1& b, t2& c, int d) {
30-
if (a == b)
28+
namespace {
29+
30+
void LoadCustomIconIfNecessary(std::wstring& loaded_path,
31+
const std::wstring& desired_path,
32+
CIcon& icon) {
33+
if (loaded_path == desired_path)
34+
return;
35+
loaded_path = desired_path;
36+
if (!icon.IsNull())
37+
icon.DestroyIcon();
38+
if (desired_path.empty())
3139
return;
32-
a = b;
33-
if (b.empty())
34-
c.LoadIconW(d, STATUS_ICON_SIZE, STATUS_ICON_SIZE, LR_DEFAULTCOLOR);
35-
else
36-
c = (HICON)LoadImage(NULL, b.c_str(), IMAGE_ICON, STATUS_ICON_SIZE,
37-
STATUS_ICON_SIZE, LR_LOADFROMFILE);
40+
HICON hIcon = static_cast<HICON>(
41+
::LoadImageW(NULL, desired_path.c_str(), IMAGE_ICON, //
42+
STATUS_ICON_SIZE, STATUS_ICON_SIZE, LR_LOADFROMFILE));
43+
if (hIcon)
44+
icon.Attach(hIcon);
3845
}
3946

47+
HICON GetCustomIconOrBuiltIn(const std::wstring& custom_icon_path,
48+
const CIcon& custom_icon,
49+
const CIcon& built_in_icon) {
50+
return (!custom_icon_path.empty() && !custom_icon.IsNull()) ? custom_icon
51+
: built_in_icon;
52+
}
53+
54+
} // namespace
55+
4056
static inline void ReconfigRoundInfo(IsToRoundStruct& rd,
4157
const int& i,
4258
const int& m_candidateCount) {
@@ -1081,28 +1097,37 @@ void WeaselPanel::DoPaint(CDCHandle dc) {
10811097
// status icon (I guess Metro IME stole my idea :)
10821098
if (m_layout->ShouldDisplayStatusIcon()) {
10831099
// decide if custom schema zhung icon to show
1084-
LoadIconNecessary(m_current_zhung_icon, m_style.current_zhung_icon,
1085-
m_iconEnabled, IDI_ZH);
1086-
LoadIconNecessary(m_current_ascii_icon, m_style.current_ascii_icon,
1087-
m_iconAlpha, IDI_EN);
1088-
LoadIconNecessary(m_current_half_icon, m_style.current_half_icon,
1089-
m_iconHalf, IDI_HALF_SHAPE);
1090-
LoadIconNecessary(m_current_full_icon, m_style.current_full_icon,
1091-
m_iconFull, IDI_FULL_SHAPE);
1100+
LoadCustomIconIfNecessary(m_current_zhung_icon,
1101+
m_style.current_zhung_icon,
1102+
m_customIconEnabled);
1103+
LoadCustomIconIfNecessary(m_current_ascii_icon,
1104+
m_style.current_ascii_icon, m_customIconAlpha);
1105+
LoadCustomIconIfNecessary(m_current_half_icon, m_style.current_half_icon,
1106+
m_customIconHalf);
1107+
LoadCustomIconIfNecessary(m_current_full_icon, m_style.current_full_icon,
1108+
m_customIconFull);
10921109
CRect iconRect(m_layout->GetStatusIconRect());
10931110
if (m_istorepos && !m_ctx.aux.str.empty())
10941111
iconRect.OffsetRect(0, m_offsety_aux);
10951112
else if (m_istorepos && !m_layout->IsInlinePreedit() &&
10961113
!m_ctx.preedit.str.empty())
10971114
iconRect.OffsetRect(0, m_offsety_preedit);
10981115

1099-
CIcon& icon(
1100-
m_status.disabled ? m_iconDisabled
1101-
: m_status.ascii_mode
1102-
? m_iconAlpha
1103-
: (m_status.type == SCHEMA
1104-
? m_iconEnabled
1105-
: (m_status.full_shape ? m_iconFull : m_iconHalf)));
1116+
HICON icon = m_status.disabled ? m_iconDisabled.m_hIcon
1117+
: m_status.ascii_mode
1118+
? GetCustomIconOrBuiltIn(m_current_ascii_icon,
1119+
m_customIconAlpha, m_iconAlpha)
1120+
: (m_status.type == SCHEMA
1121+
? GetCustomIconOrBuiltIn(m_current_zhung_icon,
1122+
m_customIconEnabled,
1123+
m_iconEnabled)
1124+
: (m_status.full_shape
1125+
? GetCustomIconOrBuiltIn(
1126+
m_current_full_icon,
1127+
m_customIconFull, m_iconFull)
1128+
: GetCustomIconOrBuiltIn(
1129+
m_current_half_icon,
1130+
m_customIconHalf, m_iconHalf)));
11061131
memDC.DrawIconEx(iconRect.left, iconRect.top, icon, 0, 0);
11071132
drawn = true;
11081133
}

WeaselUI/WeaselPanel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ class WeaselPanel
124124
CIcon m_iconAlpha;
125125
CIcon m_iconFull;
126126
CIcon m_iconHalf;
127+
CIcon m_customIconEnabled;
128+
CIcon m_customIconAlpha;
129+
CIcon m_customIconFull;
130+
CIcon m_customIconHalf;
127131
std::wstring m_current_zhung_icon;
128132
std::wstring m_current_ascii_icon;
129133
std::wstring m_current_half_icon;

0 commit comments

Comments
 (0)