@joebigelow / wix-1 / commits / c0fa7740

Require separate images for thmutil graphic Buttons and Progressbars.

Sean Hall committed Jun 4, 2021 at 13:35 UTC c0fa77405e0cc1e231dfef357b9ca6e1645c1fe3
2 files changed +389 -187
src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
+31 -13
@@ -188,12 +188,38 @@ struct THEME_CONTROL
188 LPWSTR sczVisibleCondition;
189 BOOL fDisableVariableFunctionality;
190
191 - THEME_IMAGE_REFERENCE imageRef;
192 - HBITMAP hImage;
193 - HICON hIcon;
191 + union
192 + {
193 + struct
194 + {
195 + THEME_IMAGE_REFERENCE rgImageRef[4];
196 + } Button;
197 + struct
198 + {
199 + HBITMAP hImage;
200 + HICON hIcon;
201 +
202 + DWORD cConditionalNotes;
203 + THEME_CONDITIONAL_TEXT* rgConditionalNotes;
204 + } CommandLink;
205 + struct
206 + {
207 + THEME_IMAGE_REFERENCE imageRef;
208 + } Image;
209 + struct
210 + {
211 + // Don't free these; it's just a handle to the central image lists stored in THEME. The handle is freed once, there.
212 + HIMAGELIST rghImageList[4];
213
195 - // Don't free these; it's just a handle to the central image lists stored in THEME. The handle is freed once, there.
196 - HIMAGELIST rghImageList[4];
214 + THEME_COLUMN* ptcColumns;
215 + DWORD cColumns;
216 + } ListView;
217 + struct
218 + {
219 + DWORD cImageRef;
220 + THEME_IMAGE_REFERENCE* rgImageRef;
221 + } ProgressBar;
222 + };
223
224 DWORD dwStyle;
225 DWORD dwExtendedStyle;
@@ -218,10 +244,6 @@ struct THEME_CONTROL
244 DWORD dwFontHoverId;
245 DWORD dwFontSelectedId;
246
221 - // Used by listview controls
222 - THEME_COLUMN *ptcColumns;
223 - DWORD cColumns;
224 -
247 // Used by radio button controls
248 BOOL fLastRadioButton;
249 LPWSTR sczValue;
@@ -235,10 +257,6 @@ struct THEME_CONTROL
257 DWORD cConditionalText;
258 THEME_CONDITIONAL_TEXT* rgConditionalText;
259
238 - // Used by command link controls
239 - DWORD cConditionalNotes;
240 - THEME_CONDITIONAL_TEXT* rgConditionalNotes;
241 -
260 // state variables that should be ignored
261 HWND hWnd;
262 DWORD dwData; // type specific data
src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+358 -174
@@ -100,6 +100,15 @@ static HRESULT GetAttributeImageFileOrResource(
100 __out Gdiplus::Bitmap** ppBitmap
101 );
102 static HRESULT ParseOwnerDrawImage(
103 + __in_opt HMODULE hModule,
104 + __in_z_opt LPCWSTR wzRelativePath,
105 + __in THEME* pTheme,
106 + __in IXMLDOMNode* pElement,
107 + __in_z LPCWSTR wzElementName,
108 + __in THEME_CONTROL* pControl,
109 + __in THEME_IMAGE_REFERENCE* pImageRef
110 + );
111 +static HRESULT ParseButtonImages(
112 __in_opt HMODULE hModule,
113 __in_z_opt LPCWSTR wzRelativePath,
114 __in THEME* pTheme,
@@ -112,6 +121,13 @@ static HRESULT ParseCommandLinkImage(
121 __in IXMLDOMNode* pElement,
122 __in THEME_CONTROL* pControl
123 );
124 +static HRESULT ParseProgressBarImages(
125 + __in_opt HMODULE hModule,
126 + __in_z_opt LPCWSTR wzRelativePath,
127 + __in THEME* pTheme,
128 + __in IXMLDOMNode* pElement,
129 + __in THEME_CONTROL* pControl
130 + );
131 static HRESULT GetAttributeCoordinateOrDimension(
132 __in IXMLDOMNode* pixn,
133 __in LPCWSTR wzAttribute,
@@ -1528,11 +1544,14 @@ DAPI_(HRESULT) ThemeSetProgressControlColor(
1544 THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd));
1545
1546 // Only set color on owner draw progress bars.
1531 - if (pControl && (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW))
1547 + if (pControl && (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW) && THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type)
1548 {
1533 - DWORD dwCurrentColor = HIWORD(pControl->dwData);
1549 + if (pControl->ProgressBar.cImageRef <= dwColorIndex)
1550 + {
1551 + ThmExitWithRootFailure(hr, E_INVALIDARG, "Invalid progress bar color index: %u", dwColorIndex);
1552 + }
1553
1535 - if (dwCurrentColor != dwColorIndex)
1554 + if (HIWORD(pControl->dwData) != dwColorIndex)
1555 {
1556 DWORD dwCurrentProgress = LOWORD(pControl->dwData);
1557 pControl->dwData = MAKEDWORD(dwCurrentProgress, dwColorIndex);
@@ -1923,7 +1942,9 @@ static HRESULT ParseOwnerDrawImage(
1942 __in_z_opt LPCWSTR wzRelativePath,
1943 __in THEME* pTheme,
1944 __in IXMLDOMNode* pElement,
1926 - __in THEME_CONTROL* pControl
1945 + __in_z LPCWSTR wzElementName,
1946 + __in THEME_CONTROL* pControl,
1947 + __in THEME_IMAGE_REFERENCE* pImageRef
1948 )
1949 {
1950 HRESULT hr = S_OK;
@@ -1937,15 +1958,15 @@ static HRESULT ParseOwnerDrawImage(
1958
1959 if (fXmlFound)
1960 {
1940 - hr = AddStandaloneImage(pTheme, &pBitmap, &pControl->imageRef.dwImageInstanceIndex);
1961 + hr = AddStandaloneImage(pTheme, &pBitmap, &pImageRef->dwImageInstanceIndex);
1962 ThmExitOnFailure(hr, "Failed to store owner draw image.");
1963
1943 - pControl->imageRef.type = THEME_IMAGE_REFERENCE_TYPE_COMPLETE;
1964 + pImageRef->type = THEME_IMAGE_REFERENCE_TYPE_COMPLETE;
1965
1966 fFoundImage = TRUE;
1967 }
1968
1948 - hr = ParseSourceXY(pElement, pTheme, pControl->nWidth, pControl->nHeight, &pControl->imageRef);
1969 + hr = ParseSourceXY(pElement, pTheme, pControl->nWidth, pControl->nHeight, pImageRef);
1970 ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get control SourceX and SourceY attributes.");
1971
1972 if (fXmlFound)
@@ -1962,9 +1983,9 @@ static HRESULT ParseOwnerDrawImage(
1983 fFoundImage = TRUE;
1984 }
1985
1965 - if (THEME_CONTROL_TYPE_IMAGE == pControl->type && !fFoundImage)
1986 + if (!fFoundImage)
1987 {
1967 - ThmExitWithRootFailure(hr, E_INVALIDDATA, "Image control didn't specify an image.");
1988 + ThmExitWithRootFailure(hr, E_INVALIDDATA, "%ls didn't specify an image.", wzElementName);
1989 }
1990
1991 LExit:
@@ -1977,6 +1998,97 @@ LExit:
1998 }
1999
2000
2001 +static HRESULT ParseButtonImages(
2002 + __in_opt HMODULE hModule,
2003 + __in_z_opt LPCWSTR wzRelativePath,
2004 + __in THEME* pTheme,
2005 + __in IXMLDOMNode* pElement,
2006 + __in THEME_CONTROL* pControl
2007 + )
2008 +{
2009 + HRESULT hr = S_OK;
2010 + DWORD i = 0;
2011 + IXMLDOMNodeList* pixnl = NULL;
2012 + IXMLDOMNode* pixnChild = NULL;
2013 + BSTR bstrType = NULL;
2014 + THEME_IMAGE_REFERENCE* pImageRef = NULL;
2015 + THEME_IMAGE_REFERENCE* pDefaultImageRef = NULL;
2016 + THEME_IMAGE_REFERENCE* pFocusImageRef = NULL;
2017 + THEME_IMAGE_REFERENCE* pHoverImageRef = NULL;
2018 + THEME_IMAGE_REFERENCE* pSelectedImageRef = NULL;
2019 +
2020 + hr = XmlSelectNodes(pElement, L"ButtonImage|ButtonFocusImage|ButtonHoverImage|ButtonSelectedImage", &pixnl);
2021 + ThmExitOnFailure(hr, "Failed to select child ButtonImage nodes.");
2022 +
2023 + i = 0;
2024 + while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, &bstrType)))
2025 + {
2026 + if (!bstrType)
2027 + {
2028 + hr = E_UNEXPECTED;
2029 + ThmExitOnFailure(hr, "Null element encountered!");
2030 + }
2031 +
2032 + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ButtonFocusImage", -1))
2033 + {
2034 + if (pFocusImageRef)
2035 + {
2036 + ThmExitWithRootFailure(hr, E_INVALIDDATA, "Duplicate ButtonFocusImage element.");
2037 + }
2038 +
2039 + pImageRef = pFocusImageRef = pControl->Button.rgImageRef + 3;
2040 + }
2041 + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ButtonHoverImage", -1))
2042 + {
2043 + if (pHoverImageRef)
2044 + {
2045 + ThmExitWithRootFailure(hr, E_INVALIDDATA, "Duplicate ButtonHoverImage element.");
2046 + }
2047 +
2048 + pImageRef = pHoverImageRef = pControl->Button.rgImageRef + 1;
2049 + }
2050 + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ButtonSelectedImage", -1))
2051 + {
2052 + if (pSelectedImageRef)
2053 + {
2054 + ThmExitWithRootFailure(hr, E_INVALIDDATA, "Duplicate ButtonSelectedImage element.");
2055 + }
2056 +
2057 + pImageRef = pSelectedImageRef = pControl->Button.rgImageRef + 2;
2058 + }
2059 + else
2060 + {
2061 + if (pDefaultImageRef)
2062 + {
2063 + ThmExitWithRootFailure(hr, E_INVALIDDATA, "Duplicate ButtonImage element.");
2064 + }
2065 +
2066 + pImageRef = pDefaultImageRef = pControl->Button.rgImageRef;
2067 + }
2068 +
2069 + hr = ParseOwnerDrawImage(hModule, wzRelativePath, pTheme, pixnChild, bstrType, pControl, pImageRef);
2070 + ThmExitOnFailure(hr, "Failed when parsing %ls", bstrType);
2071 +
2072 + ReleaseBSTR(bstrType);
2073 + ReleaseNullObject(pixnChild);
2074 + ++i;
2075 + }
2076 +
2077 + if (!pDefaultImageRef && (pFocusImageRef || pHoverImageRef || pSelectedImageRef) ||
2078 + pDefaultImageRef && (!pHoverImageRef || !pSelectedImageRef))
2079 + {
2080 + ThmExitWithRootFailure(hr, E_INVALIDDATA, "Graphic buttons require ButtonImage, ButtonHoverImage, and ButtonSelectedImage.");
2081 + }
2082 +
2083 +LExit:
2084 + ReleaseObject(pixnl);
2085 + ReleaseObject(pixnChild);
2086 + ReleaseBSTR(bstrType);
2087 +
2088 + return hr;
2089 +}
2090 +
2091 +
2092 static HRESULT ParseCommandLinkImage(
2093 __in_opt HMODULE hModule,
2094 __in_z_opt LPCWSTR wzRelativePath,
@@ -1997,7 +2109,7 @@ static HRESULT ParseCommandLinkImage(
2109
2110 if (pBitmap)
2111 {
2000 - hr = GdipBitmapToGdiBitmap(pBitmap, &pControl->hImage);
2112 + hr = GdipBitmapToGdiBitmap(pBitmap, &pControl->CommandLink.hImage);
2113 ThmExitOnFailure(hr, "Failed to convert bitmap for CommandLink.");
2114 }
2115
@@ -2011,8 +2123,8 @@ static HRESULT ParseCommandLinkImage(
2123 ThmExitWithRootFailure(hr, E_INVALIDDATA, "Unexpected IconResource attribute with image attribute.");
2124 }
2125
2014 - pControl->hIcon = reinterpret_cast<HICON>(::LoadImageW(hModule, MAKEINTRESOURCEW(wResourceId), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));
2015 - ThmExitOnNullWithLastError(pControl->hIcon, hr, "Failed to load icon.");
2126 + pControl->CommandLink.hIcon = reinterpret_cast<HICON>(::LoadImageW(hModule, MAKEINTRESOURCEW(wResourceId), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));
2127 + ThmExitOnNullWithLastError(pControl->CommandLink.hIcon, hr, "Failed to load icon.");
2128 }
2129
2130 hr = XmlGetAttribute(pElement, L"IconFile", &bstr);
@@ -2024,7 +2136,7 @@ static HRESULT ParseCommandLinkImage(
2136 {
2137 ThmExitWithRootFailure(hr, E_INVALIDDATA, "Unexpected IconFile attribute with image attribute.");
2138 }
2027 - else if (pControl->hIcon)
2139 + else if (pControl->CommandLink.hIcon)
2140 {
2141 ThmExitWithRootFailure(hr, E_INVALIDDATA, "IconFile attribute can't be specified with IconResource attribute.");
2142 }
@@ -2040,8 +2152,8 @@ static HRESULT ParseCommandLinkImage(
2152 ThmExitOnFailure(hr, "Failed to get image filename.");
2153 }
2154
2043 - pControl->hIcon = reinterpret_cast<HICON>(::LoadImageW(NULL, sczIconFile, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE));
2044 - ThmExitOnNullWithLastError(pControl->hIcon, hr, "Failed to load icon: %ls.", sczIconFile);
2155 + pControl->CommandLink.hIcon = reinterpret_cast<HICON>(::LoadImageW(NULL, sczIconFile, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE));
2156 + ThmExitOnNullWithLastError(pControl->CommandLink.hIcon, hr, "Failed to load icon: %ls.", sczIconFile);
2157 }
2158
2159 ThmExitOnUnexpectedAttribute(hr, pElement, L"CommandLink", L"SourceX");
@@ -2060,6 +2172,53 @@ LExit:
2172 }
2173
2174
2175 +static HRESULT ParseProgressBarImages(
2176 + __in_opt HMODULE hModule,
2177 + __in_z_opt LPCWSTR wzRelativePath,
2178 + __in THEME* pTheme,
2179 + __in IXMLDOMNode* pElement,
2180 + __in THEME_CONTROL* pControl
2181 + )
2182 +{
2183 + HRESULT hr = S_OK;
2184 + DWORD i = 0;
2185 + IXMLDOMNodeList* pixnl = NULL;
2186 + IXMLDOMNode* pixnChild = NULL;
2187 +
2188 + hr = XmlSelectNodes(pElement, L"ProgressbarImage", &pixnl);
2189 + ThmExitOnFailure(hr, "Failed to select child ProgressbarImage nodes.");
2190 +
2191 + hr = pixnl->get_length(reinterpret_cast<long*>(&pControl->ProgressBar.cImageRef));
2192 + ThmExitOnFailure(hr, "Failed to count the number of ProgressbarImage nodes.");
2193 +
2194 + if (!pControl->ProgressBar.cImageRef)
2195 + {
2196 + ExitFunction();
2197 + }
2198 +
2199 + MemAllocArray(reinterpret_cast<LPVOID*>(&pControl->ProgressBar.rgImageRef), sizeof(THEME_IMAGE_REFERENCE), pControl->ProgressBar.cImageRef);
2200 + ThmExitOnNull(pControl->ProgressBar.rgImageRef, hr, E_OUTOFMEMORY, "Failed to allocate progress bar images.");
2201 +
2202 + i = 0;
2203 + while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, NULL)))
2204 + {
2205 + THEME_IMAGE_REFERENCE* pImageRef = pControl->ProgressBar.rgImageRef + i;
2206 +
2207 + hr = ParseOwnerDrawImage(hModule, wzRelativePath, pTheme, pixnChild, L"ProgressbarImage", pControl, pImageRef);
2208 + ThmExitOnFailure(hr, "Failed when parsing ProgressbarImage image: %u.", i);
2209 +
2210 + ReleaseNullObject(pixnChild);
2211 + ++i;
2212 + }
2213 +
2214 +LExit:
2215 + ReleaseObject(pixnl);
2216 + ReleaseObject(pixnChild);
2217 +
2218 + return hr;
2219 +}
2220 +
2221 +
2222 static HRESULT GetAttributeCoordinateOrDimension(
2223 __in IXMLDOMNode* pixn,
2224 __in LPCWSTR wzAttribute,
@@ -3005,10 +3164,16 @@ static HRESULT ParseControl(
3164 ThmExitOnFailure(hr, "Failed while parsing CommandLink image.");
3165 break;
3166 case THEME_CONTROL_TYPE_BUTTON:
3167 + hr = ParseButtonImages(hModule, wzRelativePath, pTheme, pixn, pControl);
3168 + ThmExitOnFailure(hr, "Failed while parsing Button images.");
3169 + break;
3170 case THEME_CONTROL_TYPE_IMAGE:
3171 + hr = ParseOwnerDrawImage(hModule, wzRelativePath, pTheme, pixn, wzElementName, pControl, &pControl->Image.imageRef);
3172 + ThmExitOnFailure(hr, "Failed while parsing ImageControl image.");
3173 + break;
3174 case THEME_CONTROL_TYPE_PROGRESSBAR:
3010 - hr = ParseOwnerDrawImage(hModule, wzRelativePath, pTheme, pixn, pControl);
3011 - ThmExitOnFailure(hr, "Failed while parsing OwnerDraw image.");
3175 + hr = ParseProgressBarImages(hModule, wzRelativePath, pTheme, pixn, pControl);
3176 + ThmExitOnFailure(hr, "Failed while parsing Progressbar images.");
3177 break;
3178 default:
3179 ThmExitOnUnexpectedAttribute(hr, pixn, wzElementName, L"ImageId");
@@ -3161,7 +3326,7 @@ static HRESULT ParseControl(
3326
3327 if (fXmlFound)
3328 {
3164 - hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[0]);
3329 + hr = FindImageList(pTheme, bstrText, &pControl->ListView.rghImageList[0]);
3330 ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageList for ListView.", bstrText);
3331 }
3332
@@ -3170,7 +3335,7 @@ static HRESULT ParseControl(
3335
3336 if (fXmlFound)
3337 {
3173 - hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[1]);
3338 + hr = FindImageList(pTheme, bstrText, &pControl->ListView.rghImageList[1]);
3339 ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListSmall for ListView.", bstrText);
3340 }
3341
@@ -3179,7 +3344,7 @@ static HRESULT ParseControl(
3344
3345 if (fXmlFound)
3346 {
3182 - hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[2]);
3347 + hr = FindImageList(pTheme, bstrText, &pControl->ListView.rghImageList[2]);
3348 ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListState for ListView.", bstrText);
3349 }
3350
@@ -3188,7 +3353,7 @@ static HRESULT ParseControl(
3353
3354 if (fXmlFound)
3355 {
3191 - hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[3]);
3356 + hr = FindImageList(pTheme, bstrText, &pControl->ListView.rghImageList[3]);
3357 ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListGroupHeader for ListView.", bstrText);
3358 }
3359
@@ -3446,18 +3611,18 @@ static HRESULT ParseColumns(
3611 hr = XmlSelectNodes(pixn, L"Column", &pixnl);
3612 ThmExitOnFailure(hr, "Failed to select child column nodes.");
3613
3449 - hr = pixnl->get_length(reinterpret_cast<long*>(&pControl->cColumns));
3614 + hr = pixnl->get_length(reinterpret_cast<long*>(&pControl->ListView.cColumns));
3615 ThmExitOnFailure(hr, "Failed to count the number of control columns.");
3616
3452 - if (0 < pControl->cColumns)
3617 + if (0 < pControl->ListView.cColumns)
3618 {
3454 - hr = MemAllocArray(reinterpret_cast<LPVOID*>(&pControl->ptcColumns), sizeof(THEME_COLUMN), pControl->cColumns);
3619 + hr = MemAllocArray(reinterpret_cast<LPVOID*>(&pControl->ListView.ptcColumns), sizeof(THEME_COLUMN), pControl->ListView.cColumns);
3620 ThmExitOnFailure(hr, "Failed to allocate column structs.");
3621
3622 i = 0;
3623 while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, NULL)))
3624 {
3460 - THEME_COLUMN* pColumn = pControl->ptcColumns + i;
3625 + THEME_COLUMN* pColumn = pControl->ListView.ptcColumns + i;
3626
3627 hr = XmlGetText(pixnChild, &bstrText);
3628 ThmExitOnFailure(hr, "Failed to get inner text of column element.");
@@ -3794,23 +3959,23 @@ static HRESULT ParseNotes(
3959 hr = XmlSelectNodes(pixn, L"Note", &pixnl);
3960 ThmExitOnFailure(hr, "Failed to select child Note nodes.");
3961
3797 - hr = pixnl->get_length(reinterpret_cast<long*>(&pControl->cConditionalNotes));
3962 + hr = pixnl->get_length(reinterpret_cast<long*>(&pControl->CommandLink.cConditionalNotes));
3963 ThmExitOnFailure(hr, "Failed to count the number of Note nodes.");
3964
3965 if (pfAnyChildren)
3966 {
3802 - *pfAnyChildren = 0 < pControl->cConditionalNotes;
3967 + *pfAnyChildren = 0 < pControl->CommandLink.cConditionalNotes;
3968 }
3969
3805 - if (0 < pControl->cConditionalNotes)
3970 + if (0 < pControl->CommandLink.cConditionalNotes)
3971 {
3807 - MemAllocArray(reinterpret_cast<LPVOID*>(&pControl->rgConditionalNotes), sizeof(THEME_CONDITIONAL_TEXT), pControl->cConditionalNotes);
3808 - ThmExitOnNull(pControl->rgConditionalNotes, hr, E_OUTOFMEMORY, "Failed to allocate note THEME_CONDITIONAL_TEXT structs.");
3972 + MemAllocArray(reinterpret_cast<LPVOID*>(&pControl->CommandLink.rgConditionalNotes), sizeof(THEME_CONDITIONAL_TEXT), pControl->CommandLink.cConditionalNotes);
3973 + ThmExitOnNull(pControl->CommandLink.rgConditionalNotes, hr, E_OUTOFMEMORY, "Failed to allocate note THEME_CONDITIONAL_TEXT structs.");
3974
3975 i = 0;
3976 while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, NULL)))
3977 {
3813 - THEME_CONDITIONAL_TEXT* pConditionalNote = pControl->rgConditionalNotes + i;
3978 + THEME_CONDITIONAL_TEXT* pConditionalNote = pControl->CommandLink.rgConditionalNotes + i;
3979
3980 hr = XmlGetAttributeEx(pixnChild, L"Condition", &pConditionalNote->sczCondition);
3981 if (E_NOTFOUND == hr)
@@ -3843,7 +4008,7 @@ static HRESULT ParseNotes(
4008 ThmExitOnFailure(hr, "Failed to copy text to command link control.");
4009
4010 // Unconditional note entries aren't stored in the conditional notes list.
3846 - --pControl->cConditionalNotes;
4011 + --pControl->CommandLink.cConditionalNotes;
4012 }
4013 }
4014
@@ -3992,57 +4157,43 @@ static HRESULT DrawButton(
4157 )
4158 {
4159 HRESULT hr = S_OK;
3995 - THEME_IMAGE_REFERENCE buttonImageRef = { };
3996 - const THEME_IMAGE_INSTANCE* pInstance = NULL;
4160 + const THEME_IMAGE_REFERENCE* pImageRef = NULL;
4161 + BOOL fDrawFocusRect = FALSE;
4162 int nHeight = pdis->rcItem.bottom - pdis->rcItem.top;
4163 int nWidth = pdis->rcItem.right - pdis->rcItem.left;
4164
4000 - buttonImageRef.type = THEME_IMAGE_REFERENCE_TYPE_PARTIAL;
4001 - buttonImageRef.dwImageInstanceIndex = pControl->imageRef.dwImageInstanceIndex;
4002 - GetImageInstance(pTheme, &pControl->imageRef, &pInstance);
4003 -
4004 - if (THEME_IMAGE_REFERENCE_TYPE_PARTIAL == pControl->imageRef.type)
4005 - {
4006 - buttonImageRef.nX = pControl->imageRef.nX;
4007 - buttonImageRef.nY = pControl->imageRef.nY;
4008 - buttonImageRef.nWidth = pControl->imageRef.nWidth;
4009 - buttonImageRef.nHeight = pControl->imageRef.nHeight;
4010 - }
4011 - else if (THEME_IMAGE_REFERENCE_TYPE_COMPLETE == pControl->imageRef.type)
4012 - {
4013 - buttonImageRef.nX = 0;
4014 - buttonImageRef.nY = 0;
4015 - buttonImageRef.nWidth = pInstance->pBitmap->GetWidth();
4016 - buttonImageRef.nHeight = pInstance->pBitmap->GetHeight() / 4;
4017 - }
4018 - else
4019 - {
4020 - AssertSz(FALSE, "Invalid image reference type for drawing");
4021 - ExitFunction1(hr = E_INVALIDARG);
4022 - }
4023 -
4024 - DWORD_PTR dwStyle = ::GetWindowLongPtrW(pdis->hwndItem, GWL_STYLE);
4165 // "clicked" gets priority
4166 if (ODS_SELECTED & pdis->itemState)
4167 {
4028 - buttonImageRef.nY += buttonImageRef.nHeight * 2;
4168 + pImageRef = pControl->Button.rgImageRef + 2;
4169 }
4170 // then hover
4171 else if (pControl->dwData & THEME_CONTROL_DATA_HOVER)
4172 {
4033 - buttonImageRef.nY += buttonImageRef.nHeight;
4173 + pImageRef = pControl->Button.rgImageRef + 1;
4174 }
4175 // then focused
4036 - else if ((WS_TABSTOP & dwStyle) && (ODS_FOCUS & pdis->itemState))
4176 + else if ((WS_TABSTOP & ::GetWindowLongPtrW(pdis->hwndItem, GWL_STYLE)) && (ODS_FOCUS & pdis->itemState))
4177 {
4038 - buttonImageRef.nY += buttonImageRef.nHeight * 3;
4178 + if (THEME_IMAGE_REFERENCE_TYPE_NONE != pControl->Button.rgImageRef[3].type)
4179 + {
4180 + pImageRef = pControl->Button.rgImageRef + 3;
4181 + }
4182 + else
4183 + {
4184 + fDrawFocusRect = TRUE;
4185 + pImageRef = pControl->Button.rgImageRef;
4186 + }
4187 + }
4188 + else
4189 + {
4190 + pImageRef = pControl->Button.rgImageRef;
4191 }
4192
4041 - hr = DrawImageReference(pTheme, &buttonImageRef, pdis->hDC, 0, 0, nWidth, nHeight);
4193 + hr = DrawImageReference(pTheme, pImageRef, pdis->hDC, 0, 0, nWidth, nHeight);
4194
4043 - DrawControlText(pTheme, pdis, pControl, TRUE, FALSE);
4195 + DrawControlText(pTheme, pdis, pControl, TRUE, fDrawFocusRect);
4196
4045 -LExit:
4197 return hr;
4198 }
4199
@@ -4068,47 +4219,44 @@ static void DrawControlText(
4219 {
4220 HRESULT hr = S_OK;
4221 WCHAR wzText[256] = { };
4071 - DWORD cchText = 0;
4222 THEME_FONT* pFont = NULL;
4223 THEME_FONT_INSTANCE* pFontInstance = NULL;
4224 HFONT hfPrev = NULL;
4225 + DWORD cchText = ::GetWindowTextW(pdis->hwndItem, wzText, countof(wzText));
4226
4076 - if (0 == (cchText = ::GetWindowTextW(pdis->hwndItem, wzText, countof(wzText))))
4227 + if (cchText)
4228 {
4078 - // nothing to do
4079 - return;
4080 - }
4229 + if (ODS_SELECTED & pdis->itemState)
4230 + {
4231 + pFont = pTheme->rgFonts + (THEME_INVALID_ID != pControl->dwFontSelectedId ? pControl->dwFontSelectedId : pControl->dwFontId);
4232 + }
4233 + else if (pControl->dwData & THEME_CONTROL_DATA_HOVER)
4234 + {
4235 + pFont = pTheme->rgFonts + (THEME_INVALID_ID != pControl->dwFontHoverId ? pControl->dwFontHoverId : pControl->dwFontId);
4236 + }
4237 + else
4238 + {
4239 + pFont = pTheme->rgFonts + pControl->dwFontId;
4240 + }
4241
4082 - if (ODS_SELECTED & pdis->itemState)
4083 - {
4084 - pFont = pTheme->rgFonts + (THEME_INVALID_ID != pControl->dwFontSelectedId ? pControl->dwFontSelectedId : pControl->dwFontId);
4085 - }
4086 - else if (pControl->dwData & THEME_CONTROL_DATA_HOVER)
4087 - {
4088 - pFont = pTheme->rgFonts + (THEME_INVALID_ID != pControl->dwFontHoverId ? pControl->dwFontHoverId : pControl->dwFontId);
4089 - }
4090 - else
4091 - {
4092 - pFont = pTheme->rgFonts + pControl->dwFontId;
4093 - }
4242 + hr = EnsureFontInstance(pTheme, pFont, &pFontInstance);
4243 + if (SUCCEEDED(hr))
4244 + {
4245 + hfPrev = SelectFont(pdis->hDC, pFontInstance->hFont);
4246 + }
4247
4095 - hr = EnsureFontInstance(pTheme, pFont, &pFontInstance);
4096 - if (SUCCEEDED(hr))
4097 - {
4098 - hfPrev = SelectFont(pdis->hDC, pFontInstance->hFont);
4099 - }
4248 + ::DrawTextExW(pdis->hDC, wzText, cchText, &pdis->rcItem, DT_SINGLELINE | (fCentered ? (DT_CENTER | DT_VCENTER) : 0), NULL);
4249
4101 - ::DrawTextExW(pdis->hDC, wzText, cchText, &pdis->rcItem, DT_SINGLELINE | (fCentered ? (DT_CENTER | DT_VCENTER) : 0), NULL);
4250 + if (hfPrev)
4251 + {
4252 + SelectFont(pdis->hDC, hfPrev);
4253 + }
4254 + }
4255
4256 if (fDrawFocusRect && (WS_TABSTOP & ::GetWindowLongPtrW(pdis->hwndItem, GWL_STYLE)) && (ODS_FOCUS & pdis->itemState))
4257 {
4258 ::DrawFocusRect(pdis->hDC, &pdis->rcItem);
4259 }
4107 -
4108 - if (hfPrev)
4109 - {
4110 - SelectFont(pdis->hDC, hfPrev);
4111 - }
4260 }
4261
4262
@@ -4122,7 +4270,7 @@ static HRESULT DrawImage(
4270 int nHeight = pdis->rcItem.bottom - pdis->rcItem.top;
4271 int nWidth = pdis->rcItem.right - pdis->rcItem.left;
4272
4125 - hr = DrawImageReference(pTheme, &pControl->imageRef, pdis->hDC, 0, 0, nWidth, nHeight);
4273 + hr = DrawImageReference(pTheme, &pControl->Image.imageRef, pdis->hDC, 0, 0, nWidth, nHeight);
4274
4275 return hr;
4276 }
@@ -4240,8 +4388,9 @@ static HRESULT DrawProgressBar(
4388 {
4389 const int nSideWidth = 1;
4390 HRESULT hr = S_OK;
4243 - WORD wProgressColor = HIWORD(pControl->dwData);
4391 + WORD wProgressColorIndex = HIWORD(pControl->dwData);
4392 WORD wProgressPercentage = LOWORD(pControl->dwData);
4393 + const THEME_IMAGE_REFERENCE* pImageRef = pControl->ProgressBar.rgImageRef + wProgressColorIndex;
4394 const THEME_IMAGE_INSTANCE* pInstance = NULL;
4395 int nHeight = pdis->rcItem.bottom - pdis->rcItem.top;
4396 int nSourceHeight = 0;
@@ -4255,19 +4404,19 @@ static HRESULT DrawProgressBar(
4404 ExitFunction1(hr = S_FALSE);
4405 }
4406
4258 - GetImageInstance(pTheme, &pControl->imageRef, &pInstance);
4407 + GetImageInstance(pTheme, pImageRef, &pInstance);
4408
4260 - if (THEME_IMAGE_REFERENCE_TYPE_PARTIAL == pControl->imageRef.type)
4409 + if (THEME_IMAGE_REFERENCE_TYPE_PARTIAL == pImageRef->type)
4410 {
4262 - nSourceHeight = pControl->imageRef.nHeight;
4263 - nSourceX = pControl->imageRef.nX;
4264 - nSourceY = pControl->imageRef.nY + (wProgressColor * nSourceHeight);
4411 + nSourceHeight = pImageRef->nHeight;
4412 + nSourceX = pImageRef->nX;
4413 + nSourceY = pImageRef->nY;
4414 }
4266 - else if (THEME_IMAGE_REFERENCE_TYPE_COMPLETE == pControl->imageRef.type)
4415 + else if (THEME_IMAGE_REFERENCE_TYPE_COMPLETE == pImageRef->type)
4416 {
4268 - nSourceHeight = pControl->nDefaultDpiHeight;
4417 + nSourceHeight = pInstance->pBitmap->GetHeight();
4418 nSourceX = 0;
4270 - nSourceY = wProgressColor * nSourceHeight;
4419 + nSourceY = 0;
4420 }
4421 else
4422 {
@@ -4411,9 +4560,34 @@ static void FreeControl(
4560 ReleaseStr(pControl->sczValue);
4561 ReleaseStr(pControl->sczVariable);
4562
4414 - if (pControl->hImage)
4563 + switch (pControl->type)
4564 {
4416 - ::DeleteBitmap(pControl->hImage);
4565 + case THEME_CONTROL_TYPE_COMMANDLINK:
4566 + if (pControl->CommandLink.hImage)
4567 + {
4568 + ::DeleteBitmap(pControl->CommandLink.hImage);
4569 + }
4570 +
4571 + if (pControl->CommandLink.hIcon)
4572 + {
4573 + ::DestroyIcon(pControl->CommandLink.hIcon);
4574 + }
4575 +
4576 + for (DWORD i = 0; i < pControl->CommandLink.cConditionalNotes; ++i)
4577 + {
4578 + FreeConditionalText(pControl->CommandLink.rgConditionalNotes + i);
4579 + }
4580 +
4581 + ReleaseMem(pControl->CommandLink.rgConditionalNotes);
4582 + break;
4583 + case THEME_CONTROL_TYPE_LISTVIEW:
4584 + for (DWORD i = 0; i < pControl->ListView.cColumns; ++i)
4585 + {
4586 + FreeColumn(pControl->ListView.ptcColumns + i);
4587 + }
4588 +
4589 + ReleaseMem(pControl->ListView.ptcColumns);
4590 + break;
4591 }
4592
4593 for (DWORD i = 0; i < pControl->cControls; ++i)
@@ -4426,30 +4600,18 @@ static void FreeControl(
4600 FreeAction(&(pControl->rgActions[i]));
4601 }
4602
4429 - for (DWORD i = 0; i < pControl->cColumns; ++i)
4430 - {
4431 - FreeColumn(&(pControl->ptcColumns[i]));
4432 - }
4433 -
4603 for (DWORD i = 0; i < pControl->cConditionalText; ++i)
4604 {
4605 FreeConditionalText(&(pControl->rgConditionalText[i]));
4606 }
4607
4439 - for (DWORD i = 0; i < pControl->cConditionalNotes; ++i)
4440 - {
4441 - FreeConditionalText(&(pControl->rgConditionalNotes[i]));
4442 - }
4443 -
4608 for (DWORD i = 0; i < pControl->cTabs; ++i)
4609 {
4610 FreeTab(&(pControl->pttTabs[i]));
4611 }
4612
4613 ReleaseMem(pControl->rgActions)
4450 - ReleaseMem(pControl->ptcColumns);
4614 ReleaseMem(pControl->rgConditionalText);
4452 - ReleaseMem(pControl->rgConditionalNotes);
4615 ReleaseMem(pControl->pttTabs);
4616 }
4617 }
@@ -4945,6 +5107,7 @@ static HRESULT SizeListViewColumns(
5107 RECT rcParent = { };
5108 int cNumExpandingColumns = 0;
5109 int iExtraAvailableSize;
5110 + THEME_COLUMN* pColumn = NULL;
5111
5112 if (!::GetWindowRect(pControl->hWnd, &rcParent))
5113 {
@@ -4953,31 +5116,35 @@ static HRESULT SizeListViewColumns(
5116
5117 iExtraAvailableSize = rcParent.right - rcParent.left;
5118
4956 - for (DWORD i = 0; i < pControl->cColumns; ++i)
5119 + for (DWORD i = 0; i < pControl->ListView.cColumns; ++i)
5120 {
4958 - if (pControl->ptcColumns[i].fExpands)
5121 + pColumn = pControl->ListView.ptcColumns + i;
5122 +
5123 + if (pColumn->fExpands)
5124 {
5125 ++cNumExpandingColumns;
5126 }
5127
4963 - iExtraAvailableSize -= pControl->ptcColumns[i].nBaseWidth;
5128 + iExtraAvailableSize -= pColumn->nBaseWidth;
5129 }
5130
5131 // Leave room for a vertical scroll bar just in case.
5132 iExtraAvailableSize -= ::GetSystemMetrics(SM_CXVSCROLL);
5133
4969 - for (DWORD i = 0; i < pControl->cColumns; ++i)
5134 + for (DWORD i = 0; i < pControl->ListView.cColumns; ++i)
5135 {
4971 - if (pControl->ptcColumns[i].fExpands)
5136 + pColumn = pControl->ListView.ptcColumns + i;
5137 +
5138 + if (pColumn->fExpands)
5139 {
4973 - pControl->ptcColumns[i].nWidth = pControl->ptcColumns[i].nBaseWidth + (iExtraAvailableSize / cNumExpandingColumns);
5140 + pColumn->nWidth = pColumn->nBaseWidth + (iExtraAvailableSize / cNumExpandingColumns);
5141 // In case there is any remainder, use it up the first chance we get.
4975 - pControl->ptcColumns[i].nWidth += iExtraAvailableSize % cNumExpandingColumns;
5142 + pColumn->nWidth += iExtraAvailableSize % cNumExpandingColumns;
5143 iExtraAvailableSize -= iExtraAvailableSize % cNumExpandingColumns;
5144 }
5145 else
5146 {
4980 - pControl->ptcColumns[i].nWidth = pControl->ptcColumns[i].nBaseWidth;
5147 + pColumn->nWidth = pColumn->nBaseWidth;
5148 }
5149 }
5150
@@ -5082,22 +5249,25 @@ static HRESULT ShowControl(
5249 }
5250 }
5251
5085 - for (DWORD j = 0; j < pControl->cConditionalNotes; ++j)
5252 + if (THEME_CONTROL_TYPE_COMMANDLINK == pControl->type)
5253 {
5087 - THEME_CONDITIONAL_TEXT* pConditionalNote = pControl->rgConditionalNotes + j;
5088 - wzNote = pConditionalNote->sczText;
5089 -
5090 - if (pConditionalNote->sczCondition)
5254 + for (DWORD j = 0; j < pControl->CommandLink.cConditionalNotes; ++j)
5255 {
5092 - BOOL fCondition = FALSE;
5256 + THEME_CONDITIONAL_TEXT* pConditionalNote = pControl->CommandLink.rgConditionalNotes + j;
5257 + wzNote = pConditionalNote->sczText;
5258
5094 - hr = pTheme->pfnEvaluateCondition(pConditionalNote->sczCondition, &fCondition, pTheme->pvVariableContext);
5095 - ThmExitOnFailure(hr, "Failed to evaluate note condition: %ls", pConditionalNote->sczCondition);
5096 -
5097 - if (fCondition)
5259 + if (pConditionalNote->sczCondition)
5260 {
5099 - wzNote = pConditionalNote->sczText;
5100 - break;
5261 + BOOL fCondition = FALSE;
5262 +
5263 + hr = pTheme->pfnEvaluateCondition(pConditionalNote->sczCondition, &fCondition, pTheme->pvVariableContext);
5264 + ThmExitOnFailure(hr, "Failed to evaluate note condition: %ls", pConditionalNote->sczCondition);
5265 +
5266 + if (fCondition)
5267 + {
5268 + wzNote = pConditionalNote->sczText;
5269 + break;
5270 + }
5271 }
5272 }
5273 }
@@ -5497,7 +5667,6 @@ static HRESULT LoadControls(
5667 LPCWSTR wzWindowClass = NULL;
5668 DWORD dwWindowBits = WS_CHILD;
5669 DWORD dwWindowExBits = 0;
5500 - BOOL fOwnerDrawImage = THEME_IMAGE_REFERENCE_TYPE_NONE != pControl->imageRef.type;
5670
5671 if (fStartNewGroup)
5672 {
@@ -5522,7 +5691,7 @@ static HRESULT LoadControls(
5691 __fallthrough;
5692 case THEME_CONTROL_TYPE_BUTTON:
5693 wzWindowClass = WC_BUTTONW;
5525 - if (fOwnerDrawImage)
5694 + if (THEME_IMAGE_REFERENCE_TYPE_NONE != pControl->Button.rgImageRef[0].type)
5695 {
5696 dwWindowBits |= BS_OWNERDRAW;
5697 pControl->dwInternalStyle |= INTERNAL_CONTROL_STYLE_OWNER_DRAW;
@@ -5556,7 +5725,7 @@ static HRESULT LoadControls(
5725 break;
5726
5727 case THEME_CONTROL_TYPE_IMAGE: // images are basically just owner drawn static controls (so we can draw .jpgs and .pngs instead of just bitmaps).
5559 - if (fOwnerDrawImage)
5728 + if (THEME_IMAGE_REFERENCE_TYPE_NONE != pControl->Image.imageRef.type)
5729 {
5730 wzWindowClass = THEME_WC_STATICOWNERDRAW;
5731 dwWindowBits |= SS_OWNERDRAW;
@@ -5575,7 +5744,7 @@ static HRESULT LoadControls(
5744
5745 case THEME_CONTROL_TYPE_LISTVIEW:
5746 // If thmutil is handling the image list for this listview, tell Windows not to free it when the control is destroyed.
5578 - if (pControl->rghImageList[0] || pControl->rghImageList[1] || pControl->rghImageList[2] || pControl->rghImageList[3])
5747 + if (pControl->ListView.rghImageList[0] || pControl->ListView.rghImageList[1] || pControl->ListView.rghImageList[2] || pControl->ListView.rghImageList[3])
5748 {
5749 pControl->dwStyle |= LVS_SHAREIMAGELISTS;
5750 }
@@ -5583,7 +5752,7 @@ static HRESULT LoadControls(
5752 break;
5753
5754 case THEME_CONTROL_TYPE_PROGRESSBAR:
5586 - if (fOwnerDrawImage)
5755 + if (pControl->ProgressBar.cImageRef)
5756 {
5757 wzWindowClass = THEME_WC_STATICOWNERDRAW; // no such thing as an owner drawn progress bar so we'll make our own out of a static control.
5758 dwWindowBits |= SS_OWNERDRAW;
@@ -5721,13 +5890,13 @@ static HRESULT LoadControls(
5890 ::SendMessageW(pControl->hWnd, BCM_SETNOTE, 0, reinterpret_cast<WPARAM>(pControl->sczNote));
5891 }
5892
5724 - if (pControl->hImage)
5893 + if (pControl->CommandLink.hImage)
5894 {
5726 - ::SendMessageW(pControl->hWnd, BM_SETIMAGE, IMAGE_BITMAP, reinterpret_cast<LPARAM>(pControl->hImage));
5895 + ::SendMessageW(pControl->hWnd, BM_SETIMAGE, IMAGE_BITMAP, reinterpret_cast<LPARAM>(pControl->CommandLink.hImage));
5896 }
5728 - else if (pControl->hIcon)
5897 + else if (pControl->CommandLink.hIcon)
5898 {
5730 - ::SendMessageW(pControl->hWnd, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast<LPARAM>(pControl->hIcon));
5899 + ::SendMessageW(pControl->hWnd, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast<LPARAM>(pControl->CommandLink.hIcon));
5900 }
5901 }
5902 else if (THEME_CONTROL_TYPE_EDITBOX == pControl->type)
@@ -5744,13 +5913,13 @@ static HRESULT LoadControls(
5913 hr = SizeListViewColumns(pControl);
5914 ThmExitOnFailure(hr, "Failed to get size of list view columns.");
5915
5747 - for (DWORD j = 0; j < pControl->cColumns; ++j)
5916 + for (DWORD j = 0; j < pControl->ListView.cColumns; ++j)
5917 {
5918 LVCOLUMNW lvc = { };
5919 lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
5751 - lvc.cx = pControl->ptcColumns[j].nWidth;
5920 + lvc.cx = pControl->ListView.ptcColumns[j].nWidth;
5921 lvc.iSubItem = j;
5753 - lvc.pszText = pControl->ptcColumns[j].pszName;
5922 + lvc.pszText = pControl->ListView.ptcColumns[j].pszName;
5923 lvc.fmt = LVCFMT_LEFT;
5924 lvc.cchTextMax = 4;
5925
@@ -5760,21 +5929,21 @@ static HRESULT LoadControls(
5929 }
5930
5931 // Return value tells us the old image list, we don't care.
5763 - if (pControl->rghImageList[0])
5932 + if (pControl->ListView.rghImageList[0])
5933 {
5765 - ::SendMessageW(pControl->hWnd, LVM_SETIMAGELIST, static_cast<WPARAM>(LVSIL_NORMAL), reinterpret_cast<LPARAM>(pControl->rghImageList[0]));
5934 + ::SendMessageW(pControl->hWnd, LVM_SETIMAGELIST, static_cast<WPARAM>(LVSIL_NORMAL), reinterpret_cast<LPARAM>(pControl->ListView.rghImageList[0]));
5935 }
5767 - else if (pControl->rghImageList[1])
5936 + else if (pControl->ListView.rghImageList[1])
5937 {
5769 - ::SendMessageW(pControl->hWnd, LVM_SETIMAGELIST, static_cast<WPARAM>(LVSIL_SMALL), reinterpret_cast<LPARAM>(pControl->rghImageList[1]));
5938 + ::SendMessageW(pControl->hWnd, LVM_SETIMAGELIST, static_cast<WPARAM>(LVSIL_SMALL), reinterpret_cast<LPARAM>(pControl->ListView.rghImageList[1]));
5939 }
5771 - else if (pControl->rghImageList[2])
5940 + else if (pControl->ListView.rghImageList[2])
5941 {
5773 - ::SendMessageW(pControl->hWnd, LVM_SETIMAGELIST, static_cast<WPARAM>(LVSIL_STATE), reinterpret_cast<LPARAM>(pControl->rghImageList[2]));
5942 + ::SendMessageW(pControl->hWnd, LVM_SETIMAGELIST, static_cast<WPARAM>(LVSIL_STATE), reinterpret_cast<LPARAM>(pControl->ListView.rghImageList[2]));
5943 }
5775 - else if (pControl->rghImageList[3])
5944 + else if (pControl->ListView.rghImageList[3])
5945 {
5777 - ::SendMessageW(pControl->hWnd, LVM_SETIMAGELIST, static_cast<WPARAM>(LVSIL_GROUPHEADER), reinterpret_cast<LPARAM>(pControl->rghImageList[3]));
5946 + ::SendMessageW(pControl->hWnd, LVM_SETIMAGELIST, static_cast<WPARAM>(LVSIL_GROUPHEADER), reinterpret_cast<LPARAM>(pControl->ListView.rghImageList[3]));
5947 }
5948 }
5949 }
@@ -5909,16 +6078,24 @@ static HRESULT LocalizeControl(
6078 ThmExitOnFailure(hr, "Failed to localize conditional text.");
6079 }
6080
5912 - for (DWORD j = 0; j < pControl->cConditionalNotes; ++j)
6081 + switch (pControl->type)
6082 {
5914 - hr = LocLocalizeString(pWixLoc, &pControl->rgConditionalNotes[j].sczText);
5915 - ThmExitOnFailure(hr, "Failed to localize conditional note.");
5916 - }
6083 + case THEME_CONTROL_TYPE_COMMANDLINK:
6084 + for (DWORD j = 0; j < pControl->CommandLink.cConditionalNotes; ++j)
6085 + {
6086 + hr = LocLocalizeString(pWixLoc, &pControl->CommandLink.rgConditionalNotes[j].sczText);
6087 + ThmExitOnFailure(hr, "Failed to localize conditional note.");
6088 + }
6089
5918 - for (DWORD j = 0; j < pControl->cColumns; ++j)
5919 - {
5920 - hr = LocLocalizeString(pWixLoc, &pControl->ptcColumns[j].pszName);
5921 - ThmExitOnFailure(hr, "Failed to localize column text.");
6090 + break;
6091 + case THEME_CONTROL_TYPE_LISTVIEW:
6092 + for (DWORD j = 0; j < pControl->ListView.cColumns; ++j)
6093 + {
6094 + hr = LocLocalizeString(pWixLoc, &pControl->ListView.ptcColumns[j].pszName);
6095 + ThmExitOnFailure(hr, "Failed to localize column text.");
6096 + }
6097 +
6098 + break;
6099 }
6100
6101 for (DWORD j = 0; j < pControl->cTabs; ++j)
@@ -6002,13 +6179,20 @@ static HRESULT LoadControlString(
6179 hr = ResReadString(hResModule, pControl->uStringId, &pControl->sczText);
6180 ThmExitOnFailure(hr, "Failed to load control text.");
6181
6005 - for (DWORD j = 0; j < pControl->cColumns; ++j)
6182 + switch (pControl->type)
6183 {
6007 - if (UINT_MAX != pControl->ptcColumns[j].uStringId)
6184 + case THEME_CONTROL_TYPE_LISTVIEW:
6185 + for (DWORD j = 0; j < pControl->ListView.cColumns; ++j)
6186 {
6009 - hr = ResReadString(hResModule, pControl->ptcColumns[j].uStringId, &pControl->ptcColumns[j].pszName);
6010 - ThmExitOnFailure(hr, "Failed to load column text.");
6187 + THEME_COLUMN* pColumn = pControl->ListView.ptcColumns + j;
6188 + if (UINT_MAX != pColumn->uStringId)
6189 + {
6190 + hr = ResReadString(hResModule, pColumn->uStringId, &pColumn->pszName);
6191 + ThmExitOnFailure(hr, "Failed to load column text.");
6192 + }
6193 }
6194 +
6195 + break;
6196 }
6197
6198 for (DWORD j = 0; j < pControl->cTabs; ++j)
@@ -6066,9 +6250,9 @@ static void ResizeControl(
6250 {
6251 SizeListViewColumns(pControl);
6252
6069 - for (DWORD j = 0; j < pControl->cColumns; ++j)
6253 + for (DWORD j = 0; j < pControl->ListView.cColumns; ++j)
6254 {
6071 - if (-1 == ::SendMessageW(pControl->hWnd, LVM_SETCOLUMNWIDTH, (WPARAM) (int) (j), (LPARAM) (pControl->ptcColumns[j].nWidth)))
6255 + if (-1 == ::SendMessageW(pControl->hWnd, LVM_SETCOLUMNWIDTH, (WPARAM) (int) (j), (LPARAM) (pControl->ListView.ptcColumns[j].nWidth)))
6256 {
6257 Trace(REPORT_DEBUG, "Failed to resize listview column %u with error %u", j, ::GetLastError());
6258 return;
@@ -6167,9 +6351,9 @@ static void ScaleControl(
6351
6352 if (THEME_CONTROL_TYPE_LISTVIEW == pControl->type)
6353 {
6170 - for (DWORD i = 0; i < pControl->cColumns; ++i)
6354 + for (DWORD i = 0; i < pControl->ListView.cColumns; ++i)
6355 {
6172 - THEME_COLUMN* pColumn = pControl->ptcColumns + i;
6356 + THEME_COLUMN* pColumn = pControl->ListView.ptcColumns + i;
6357
6358 pColumn->nBaseWidth = DpiuScaleValue(pColumn->nDefaultDpiBaseWidth, nDpi);
6359 }