diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-06-04 13:15:28 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-06-04 14:57:11 -0500 |
commit | b22a62fd6eed5bb7a2c04d51828438daa621db6c (patch) | |
tree | 45c53dd44c2b9534f00f4bfdda5b1fa8c798ac94 | |
parent | c661b773f8ae37bbdea6da25a57d3626e7113920 (diff) | |
download | wix-b22a62fd6eed5bb7a2c04d51828438daa621db6c.tar.gz wix-b22a62fd6eed5bb7a2c04d51828438daa621db6c.tar.bz2 wix-b22a62fd6eed5bb7a2c04d51828438daa621db6c.zip |
Add THEME_IMAGE_REFERENCE to thmutil.
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | 35 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 328 |
2 files changed, 293 insertions, 70 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h index 32382793..2a7cabb9 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | |||
@@ -75,6 +75,13 @@ typedef enum THEME_CONTROL_TYPE | |||
75 | THEME_CONTROL_TYPE_TAB, | 75 | THEME_CONTROL_TYPE_TAB, |
76 | } THEME_CONTROL_TYPE; | 76 | } THEME_CONTROL_TYPE; |
77 | 77 | ||
78 | typedef enum THEME_IMAGE_REFERENCE_TYPE | ||
79 | { | ||
80 | THEME_IMAGE_REFERENCE_TYPE_NONE, | ||
81 | THEME_IMAGE_REFERENCE_TYPE_PARTIAL, | ||
82 | THEME_IMAGE_REFERENCE_TYPE_COMPLETE, | ||
83 | } THEME_IMAGE_REFERENCE_TYPE; | ||
84 | |||
78 | typedef enum THEME_SHOW_PAGE_REASON | 85 | typedef enum THEME_SHOW_PAGE_REASON |
79 | { | 86 | { |
80 | THEME_SHOW_PAGE_REASON_DEFAULT, | 87 | THEME_SHOW_PAGE_REASON_DEFAULT, |
@@ -100,6 +107,22 @@ struct THEME_COLUMN | |||
100 | }; | 107 | }; |
101 | 108 | ||
102 | 109 | ||
110 | struct THEME_IMAGE_REFERENCE | ||
111 | { | ||
112 | THEME_IMAGE_REFERENCE_TYPE type; | ||
113 | DWORD dwImageInstanceIndex; | ||
114 | int nX; | ||
115 | int nY; | ||
116 | int nHeight; | ||
117 | int nWidth; | ||
118 | }; | ||
119 | |||
120 | struct THEME_IMAGE_INSTANCE | ||
121 | { | ||
122 | Gdiplus::Bitmap* pBitmap; | ||
123 | }; | ||
124 | |||
125 | |||
103 | struct THEME_TAB | 126 | struct THEME_TAB |
104 | { | 127 | { |
105 | LPWSTR pszName; | 128 | LPWSTR pszName; |
@@ -159,15 +182,13 @@ struct THEME_CONTROL | |||
159 | int nY; | 182 | int nY; |
160 | int nHeight; | 183 | int nHeight; |
161 | int nWidth; | 184 | int nWidth; |
162 | int nSourceX; | ||
163 | int nSourceY; | ||
164 | UINT uStringId; | 185 | UINT uStringId; |
165 | 186 | ||
166 | LPWSTR sczEnableCondition; | 187 | LPWSTR sczEnableCondition; |
167 | LPWSTR sczVisibleCondition; | 188 | LPWSTR sczVisibleCondition; |
168 | BOOL fDisableVariableFunctionality; | 189 | BOOL fDisableVariableFunctionality; |
169 | 190 | ||
170 | Gdiplus::Bitmap* pBitmap; | 191 | THEME_IMAGE_REFERENCE imageRef; |
171 | HBITMAP hImage; | 192 | HBITMAP hImage; |
172 | HICON hIcon; | 193 | HICON hIcon; |
173 | 194 | ||
@@ -293,15 +314,17 @@ struct THEME | |||
293 | int nMinimumWidth; | 314 | int nMinimumWidth; |
294 | int nWindowHeight; | 315 | int nWindowHeight; |
295 | int nWindowWidth; | 316 | int nWindowWidth; |
296 | int nSourceX; | ||
297 | int nSourceY; | ||
298 | UINT uStringId; | 317 | UINT uStringId; |
299 | 318 | ||
300 | Gdiplus::Bitmap* pBitmap; | 319 | DWORD dwSourceImageInstanceIndex; |
320 | THEME_IMAGE_REFERENCE windowImageRef; | ||
301 | 321 | ||
302 | DWORD cFonts; | 322 | DWORD cFonts; |
303 | THEME_FONT* rgFonts; | 323 | THEME_FONT* rgFonts; |
304 | 324 | ||
325 | DWORD cStandaloneImages; | ||
326 | THEME_IMAGE_INSTANCE* rgStandaloneImages; | ||
327 | |||
305 | DWORD cPages; | 328 | DWORD cPages; |
306 | THEME_PAGE* rgPages; | 329 | THEME_PAGE* rgPages; |
307 | 330 | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp index 21460ad1..363c3be1 100644 --- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp | |||
@@ -42,6 +42,7 @@ | |||
42 | const DWORD THEME_INVALID_ID = 0xFFFFFFFF; | 42 | const DWORD THEME_INVALID_ID = 0xFFFFFFFF; |
43 | const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF; | 43 | const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF; |
44 | const DWORD GROW_FONT_INSTANCES = 3; | 44 | const DWORD GROW_FONT_INSTANCES = 3; |
45 | const DWORD GROW_IMAGE_INSTANCES = 5; | ||
45 | const DWORD GROW_WINDOW_TEXT = 250; | 46 | const DWORD GROW_WINDOW_TEXT = 250; |
46 | const LPCWSTR THEME_WC_HYPERLINK = L"ThemeHyperLink"; | 47 | const LPCWSTR THEME_WC_HYPERLINK = L"ThemeHyperLink"; |
47 | const LPCWSTR THEME_WC_PANEL = L"ThemePanel"; | 48 | const LPCWSTR THEME_WC_PANEL = L"ThemePanel"; |
@@ -87,6 +88,11 @@ static HRESULT ParseTheme( | |||
87 | __in IXMLDOMDocument* pixd, | 88 | __in IXMLDOMDocument* pixd, |
88 | __out THEME** ppTheme | 89 | __out THEME** ppTheme |
89 | ); | 90 | ); |
91 | static HRESULT AddStandaloneImage( | ||
92 | __in THEME* pTheme, | ||
93 | __in Gdiplus::Bitmap** ppBitmap, | ||
94 | __out DWORD* pdwIndex | ||
95 | ); | ||
90 | static HRESULT GetAttributeImageFileOrResource( | 96 | static HRESULT GetAttributeImageFileOrResource( |
91 | __in_opt HMODULE hModule, | 97 | __in_opt HMODULE hModule, |
92 | __in_z_opt LPCWSTR wzRelativePath, | 98 | __in_z_opt LPCWSTR wzRelativePath, |
@@ -118,9 +124,10 @@ static HRESULT GetAttributeFontId( | |||
118 | ); | 124 | ); |
119 | static HRESULT ParseSourceXY( | 125 | static HRESULT ParseSourceXY( |
120 | __in IXMLDOMNode* pixn, | 126 | __in IXMLDOMNode* pixn, |
121 | __in BOOL fAllowed, | 127 | __in THEME* pTheme, |
122 | __inout int* pnX, | 128 | __in int nWidth, |
123 | __inout int* pnY | 129 | __in int nHeight, |
130 | __inout THEME_IMAGE_REFERENCE* pReference | ||
124 | ); | 131 | ); |
125 | static HRESULT ParseWindow( | 132 | static HRESULT ParseWindow( |
126 | __in_opt HMODULE hModule, | 133 | __in_opt HMODULE hModule, |
@@ -281,6 +288,20 @@ static HRESULT DrawImage( | |||
281 | __in DRAWITEMSTRUCT* pdis, | 288 | __in DRAWITEMSTRUCT* pdis, |
282 | __in const THEME_CONTROL* pControl | 289 | __in const THEME_CONTROL* pControl |
283 | ); | 290 | ); |
291 | static void GetImageInstance( | ||
292 | __in THEME* pTheme, | ||
293 | __in const THEME_IMAGE_REFERENCE* pReference, | ||
294 | __out const THEME_IMAGE_INSTANCE** ppInstance | ||
295 | ); | ||
296 | static HRESULT DrawImageReference( | ||
297 | __in THEME* pTheme, | ||
298 | __in const THEME_IMAGE_REFERENCE* pReference, | ||
299 | __in HDC hdc, | ||
300 | __in int destX, | ||
301 | __in int destY, | ||
302 | __in int destWidth, | ||
303 | __in int destHeight | ||
304 | ); | ||
284 | static HRESULT DrawGdipBitmap( | 305 | static HRESULT DrawGdipBitmap( |
285 | __in HDC hdc, | 306 | __in HDC hdc, |
286 | __in int destX, | 307 | __in int destX, |
@@ -300,7 +321,7 @@ static HRESULT DrawProgressBar( | |||
300 | ); | 321 | ); |
301 | static HRESULT DrawProgressBarImage( | 322 | static HRESULT DrawProgressBarImage( |
302 | __in THEME* pTheme, | 323 | __in THEME* pTheme, |
303 | __in Gdiplus::Bitmap* pBitmap, | 324 | __in const THEME_IMAGE_INSTANCE* pImageInstance, |
304 | __in int srcX, | 325 | __in int srcX, |
305 | __in int srcY, | 326 | __in int srcY, |
306 | __in int srcWidth, | 327 | __in int srcWidth, |
@@ -333,6 +354,9 @@ static void FreeFontInstance( | |||
333 | static void FreeFont( | 354 | static void FreeFont( |
334 | __in THEME_FONT* pFont | 355 | __in THEME_FONT* pFont |
335 | ); | 356 | ); |
357 | static void FreeImageInstance( | ||
358 | __in THEME_IMAGE_INSTANCE* pImageInstance | ||
359 | ); | ||
336 | static void FreePage( | 360 | static void FreePage( |
337 | __in THEME_PAGE* pPage | 361 | __in THEME_PAGE* pPage |
338 | ); | 362 | ); |
@@ -644,6 +668,11 @@ DAPI_(void) ThemeFree( | |||
644 | FreeFont(pTheme->rgFonts + i); | 668 | FreeFont(pTheme->rgFonts + i); |
645 | } | 669 | } |
646 | 670 | ||
671 | for (DWORD i = 0; i < pTheme->cStandaloneImages; ++i) | ||
672 | { | ||
673 | FreeImageInstance(pTheme->rgStandaloneImages + i); | ||
674 | } | ||
675 | |||
647 | for (DWORD i = 0; i < pTheme->cPages; ++i) | 676 | for (DWORD i = 0; i < pTheme->cPages; ++i) |
648 | { | 677 | { |
649 | FreePage(pTheme->rgPages + i); | 678 | FreePage(pTheme->rgPages + i); |
@@ -661,13 +690,9 @@ DAPI_(void) ThemeFree( | |||
661 | 690 | ||
662 | ReleaseMem(pTheme->rgControls); | 691 | ReleaseMem(pTheme->rgControls); |
663 | ReleaseMem(pTheme->rgPages); | 692 | ReleaseMem(pTheme->rgPages); |
693 | ReleaseMem(pTheme->rgStandaloneImages); | ||
664 | ReleaseMem(pTheme->rgFonts); | 694 | ReleaseMem(pTheme->rgFonts); |
665 | 695 | ||
666 | if (pTheme->pBitmap) | ||
667 | { | ||
668 | delete pTheme->pBitmap; | ||
669 | } | ||
670 | |||
671 | ReleaseStr(pTheme->sczCaption); | 696 | ReleaseStr(pTheme->sczCaption); |
672 | ReleaseMem(pTheme); | 697 | ReleaseMem(pTheme); |
673 | } | 698 | } |
@@ -1305,9 +1330,9 @@ DAPI_(HRESULT) ThemeDrawBackground( | |||
1305 | { | 1330 | { |
1306 | HRESULT hr = S_FALSE; | 1331 | HRESULT hr = S_FALSE; |
1307 | 1332 | ||
1308 | if (pTheme->pBitmap && 0 <= pTheme->nSourceX && 0 <= pTheme->nSourceY && pps->fErase) | 1333 | if (pps->fErase && THEME_IMAGE_REFERENCE_TYPE_NONE != pTheme->windowImageRef.type) |
1309 | { | 1334 | { |
1310 | hr = DrawGdipBitmap(pps->hdc, 0, 0, pTheme->nWidth, pTheme->nHeight, pTheme->pBitmap, pTheme->nSourceX, pTheme->nSourceY, pTheme->nDefaultDpiWidth, pTheme->nDefaultDpiHeight); | 1335 | hr = DrawImageReference(pTheme, &pTheme->windowImageRef, pps->hdc, 0, 0, pTheme->nWidth, pTheme->nHeight); |
1311 | } | 1336 | } |
1312 | 1337 | ||
1313 | return hr; | 1338 | return hr; |
@@ -1743,6 +1768,7 @@ static HRESULT ParseTheme( | |||
1743 | HRESULT hr = S_OK; | 1768 | HRESULT hr = S_OK; |
1744 | THEME* pTheme = NULL; | 1769 | THEME* pTheme = NULL; |
1745 | IXMLDOMElement *pThemeElement = NULL; | 1770 | IXMLDOMElement *pThemeElement = NULL; |
1771 | Gdiplus::Bitmap* pBitmap = NULL; | ||
1746 | BOOL fXmlFound = FALSE; | 1772 | BOOL fXmlFound = FALSE; |
1747 | 1773 | ||
1748 | hr = pixd->get_documentElement(&pThemeElement); | 1774 | hr = pixd->get_documentElement(&pThemeElement); |
@@ -1755,9 +1781,19 @@ static HRESULT ParseTheme( | |||
1755 | pTheme->nDpi = USER_DEFAULT_SCREEN_DPI; | 1781 | pTheme->nDpi = USER_DEFAULT_SCREEN_DPI; |
1756 | 1782 | ||
1757 | // Parse the optional background resource image. | 1783 | // Parse the optional background resource image. |
1758 | hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pThemeElement, &pTheme->pBitmap); | 1784 | hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pThemeElement, &pBitmap); |
1759 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed while parsing theme image."); | 1785 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed while parsing theme image."); |
1760 | 1786 | ||
1787 | if (fXmlFound) | ||
1788 | { | ||
1789 | hr = AddStandaloneImage(pTheme, &pBitmap, &pTheme->dwSourceImageInstanceIndex); | ||
1790 | ThmExitOnFailure(hr, "Failed to store theme image."); | ||
1791 | } | ||
1792 | else | ||
1793 | { | ||
1794 | pTheme->dwSourceImageInstanceIndex = THEME_INVALID_ID; | ||
1795 | } | ||
1796 | |||
1761 | // Parse the fonts. | 1797 | // Parse the fonts. |
1762 | hr = ParseFonts(pThemeElement, pTheme); | 1798 | hr = ParseFonts(pThemeElement, pTheme); |
1763 | ThmExitOnFailure(hr, "Failed to parse theme fonts."); | 1799 | ThmExitOnFailure(hr, "Failed to parse theme fonts."); |
@@ -1772,6 +1808,11 @@ static HRESULT ParseTheme( | |||
1772 | LExit: | 1808 | LExit: |
1773 | ReleaseObject(pThemeElement); | 1809 | ReleaseObject(pThemeElement); |
1774 | 1810 | ||
1811 | if (pBitmap) | ||
1812 | { | ||
1813 | delete pBitmap; | ||
1814 | } | ||
1815 | |||
1775 | if (pTheme) | 1816 | if (pTheme) |
1776 | { | 1817 | { |
1777 | ThemeFree(pTheme); | 1818 | ThemeFree(pTheme); |
@@ -1780,6 +1821,30 @@ LExit: | |||
1780 | return hr; | 1821 | return hr; |
1781 | } | 1822 | } |
1782 | 1823 | ||
1824 | static HRESULT AddStandaloneImage( | ||
1825 | __in THEME* pTheme, | ||
1826 | __in Gdiplus::Bitmap** ppBitmap, | ||
1827 | __out DWORD* pdwIndex | ||
1828 | ) | ||
1829 | { | ||
1830 | HRESULT hr = S_OK; | ||
1831 | THEME_IMAGE_INSTANCE* pInstance = NULL; | ||
1832 | |||
1833 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pTheme->rgStandaloneImages), pTheme->cStandaloneImages, 1, sizeof(THEME_IMAGE_INSTANCE), GROW_IMAGE_INSTANCES); | ||
1834 | ThmExitOnFailure(hr, "Failed to allocate memory for image instances."); | ||
1835 | |||
1836 | *pdwIndex = pTheme->cStandaloneImages; | ||
1837 | ++pTheme->cStandaloneImages; | ||
1838 | |||
1839 | pInstance = pTheme->rgStandaloneImages + *pdwIndex; | ||
1840 | |||
1841 | pInstance->pBitmap = *ppBitmap; | ||
1842 | *ppBitmap = NULL; | ||
1843 | |||
1844 | LExit: | ||
1845 | return hr; | ||
1846 | } | ||
1847 | |||
1783 | static HRESULT GetAttributeImageFileOrResource( | 1848 | static HRESULT GetAttributeImageFileOrResource( |
1784 | __in_opt HMODULE hModule, | 1849 | __in_opt HMODULE hModule, |
1785 | __in_z_opt LPCWSTR wzRelativePath, | 1850 | __in_z_opt LPCWSTR wzRelativePath, |
@@ -1864,17 +1929,23 @@ static HRESULT ParseOwnerDrawImage( | |||
1864 | HRESULT hr = S_OK; | 1929 | HRESULT hr = S_OK; |
1865 | BOOL fXmlFound = FALSE; | 1930 | BOOL fXmlFound = FALSE; |
1866 | BOOL fFoundImage = FALSE; | 1931 | BOOL fFoundImage = FALSE; |
1932 | Gdiplus::Bitmap* pBitmap = NULL; | ||
1867 | 1933 | ||
1868 | // Parse the optional background resource image. | 1934 | // Parse the optional background resource image. |
1869 | hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pElement, &pControl->pBitmap); | 1935 | hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pElement, &pBitmap); |
1870 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed while parsing control image."); | 1936 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed while parsing control image."); |
1871 | 1937 | ||
1872 | if (fXmlFound) | 1938 | if (fXmlFound) |
1873 | { | 1939 | { |
1940 | hr = AddStandaloneImage(pTheme, &pBitmap, &pControl->imageRef.dwImageInstanceIndex); | ||
1941 | ThmExitOnFailure(hr, "Failed to store owner draw image."); | ||
1942 | |||
1943 | pControl->imageRef.type = THEME_IMAGE_REFERENCE_TYPE_COMPLETE; | ||
1944 | |||
1874 | fFoundImage = TRUE; | 1945 | fFoundImage = TRUE; |
1875 | } | 1946 | } |
1876 | 1947 | ||
1877 | hr = ParseSourceXY(pElement, NULL != pTheme->pBitmap, &pControl->nSourceX, &pControl->nSourceY); | 1948 | hr = ParseSourceXY(pElement, pTheme, pControl->nWidth, pControl->nHeight, &pControl->imageRef); |
1878 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get control SourceX and SourceY attributes."); | 1949 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get control SourceX and SourceY attributes."); |
1879 | 1950 | ||
1880 | if (fXmlFound) | 1951 | if (fXmlFound) |
@@ -1897,6 +1968,11 @@ static HRESULT ParseOwnerDrawImage( | |||
1897 | } | 1968 | } |
1898 | 1969 | ||
1899 | LExit: | 1970 | LExit: |
1971 | if (pBitmap) | ||
1972 | { | ||
1973 | delete pBitmap; | ||
1974 | } | ||
1975 | |||
1900 | return hr; | 1976 | return hr; |
1901 | } | 1977 | } |
1902 | 1978 | ||
@@ -2042,35 +2118,50 @@ LExit: | |||
2042 | 2118 | ||
2043 | static HRESULT ParseSourceXY( | 2119 | static HRESULT ParseSourceXY( |
2044 | __in IXMLDOMNode* pixn, | 2120 | __in IXMLDOMNode* pixn, |
2045 | __in BOOL fAllowed, | 2121 | __in THEME* pTheme, |
2046 | __inout int* pnX, | 2122 | __in int nWidth, |
2047 | __inout int* pnY | 2123 | __in int nHeight, |
2124 | __inout THEME_IMAGE_REFERENCE* pReference | ||
2048 | ) | 2125 | ) |
2049 | { | 2126 | { |
2050 | HRESULT hr = S_OK; | 2127 | HRESULT hr = S_OK; |
2051 | BOOL fXFound = FALSE; | 2128 | BOOL fXFound = FALSE; |
2052 | BOOL fYFound = FALSE; | 2129 | BOOL fYFound = FALSE; |
2053 | 2130 | int nX = 0; | |
2054 | hr = GetAttributeCoordinateOrDimension(pixn, L"SourceX", pnX); | 2131 | int nY = 0; |
2132 | DWORD dwImageInstanceIndex = pTheme->dwSourceImageInstanceIndex; | ||
2133 | THEME_IMAGE_INSTANCE* pInstance = THEME_INVALID_ID != dwImageInstanceIndex ? pTheme->rgStandaloneImages + dwImageInstanceIndex : NULL; | ||
2134 | int nSourceWidth = pInstance ? pInstance->pBitmap->GetWidth() : 0; | ||
2135 | int nSourceHeight = pInstance ? pInstance->pBitmap->GetHeight() : 0; | ||
2136 | |||
2137 | hr = GetAttributeCoordinateOrDimension(pixn, L"SourceX", &nX); | ||
2055 | ThmExitOnOptionalXmlQueryFailure(hr, fXFound, "Failed to get SourceX attribute."); | 2138 | ThmExitOnOptionalXmlQueryFailure(hr, fXFound, "Failed to get SourceX attribute."); |
2056 | 2139 | ||
2057 | if (!fXFound) | 2140 | if (!fXFound) |
2058 | { | 2141 | { |
2059 | *pnX = -1; | 2142 | nX = -1; |
2060 | } | 2143 | } |
2061 | else | 2144 | else |
2062 | { | 2145 | { |
2063 | if (!fAllowed) | 2146 | if (!pInstance) |
2064 | { | 2147 | { |
2065 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceX cannot be specified without an image specified on Theme."); | 2148 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceX cannot be specified without an image specified on Theme."); |
2066 | } | 2149 | } |
2067 | else if (0 > *pnX) | 2150 | else if (0 > nX) |
2068 | { | 2151 | { |
2069 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceX must be non-negative."); | 2152 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceX must be non-negative."); |
2070 | } | 2153 | } |
2154 | else if (nSourceWidth <= nX) | ||
2155 | { | ||
2156 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceX (%i) must be less than the image width: %i.", nX, nSourceWidth); | ||
2157 | } | ||
2158 | else if (nSourceWidth <= (nX + nWidth)) | ||
2159 | { | ||
2160 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceX (%i) with width %i must be less than the image width: %i.", nX, nWidth, nSourceWidth); | ||
2161 | } | ||
2071 | } | 2162 | } |
2072 | 2163 | ||
2073 | hr = GetAttributeCoordinateOrDimension(pixn, L"SourceY", pnY); | 2164 | hr = GetAttributeCoordinateOrDimension(pixn, L"SourceY", &nY); |
2074 | ThmExitOnOptionalXmlQueryFailure(hr, fYFound, "Failed to get SourceY attribute."); | 2165 | ThmExitOnOptionalXmlQueryFailure(hr, fYFound, "Failed to get SourceY attribute."); |
2075 | 2166 | ||
2076 | if (!fYFound) | 2167 | if (!fYFound) |
@@ -2080,12 +2171,11 @@ static HRESULT ParseSourceXY( | |||
2080 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be specified with SourceX."); | 2171 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be specified with SourceX."); |
2081 | } | 2172 | } |
2082 | 2173 | ||
2083 | *pnY = -1; | 2174 | ExitFunction1(hr = E_NOTFOUND); |
2084 | hr = E_NOTFOUND; | ||
2085 | } | 2175 | } |
2086 | else | 2176 | else |
2087 | { | 2177 | { |
2088 | if (!fAllowed) | 2178 | if (!pInstance) |
2089 | { | 2179 | { |
2090 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY cannot be specified without an image specified on Theme."); | 2180 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY cannot be specified without an image specified on Theme."); |
2091 | } | 2181 | } |
@@ -2093,12 +2183,27 @@ static HRESULT ParseSourceXY( | |||
2093 | { | 2183 | { |
2094 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be specified with SourceX."); | 2184 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be specified with SourceX."); |
2095 | } | 2185 | } |
2096 | else if (0 > *pnY) | 2186 | else if (0 > nY) |
2097 | { | 2187 | { |
2098 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be non-negative."); | 2188 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be non-negative."); |
2099 | } | 2189 | } |
2190 | else if (nSourceHeight <= nY) | ||
2191 | { | ||
2192 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY (%i) must be less than the image height: %i.", nY, nSourceHeight); | ||
2193 | } | ||
2194 | else if (nSourceHeight <= (nY + nHeight)) | ||
2195 | { | ||
2196 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY (%i) with height %i must be less than the image height: %i.", nY, nHeight, nSourceHeight); | ||
2197 | } | ||
2100 | } | 2198 | } |
2101 | 2199 | ||
2200 | pReference->type = THEME_IMAGE_REFERENCE_TYPE_PARTIAL; | ||
2201 | pReference->dwImageInstanceIndex = dwImageInstanceIndex; | ||
2202 | pReference->nX = nX; | ||
2203 | pReference->nY = nY; | ||
2204 | pReference->nWidth = nWidth; | ||
2205 | pReference->nHeight = nHeight; | ||
2206 | |||
2102 | LExit: | 2207 | LExit: |
2103 | return hr; | 2208 | return hr; |
2104 | } | 2209 | } |
@@ -2220,7 +2325,7 @@ static HRESULT ParseWindow( | |||
2220 | ReleaseNullBSTR(bstr); | 2325 | ReleaseNullBSTR(bstr); |
2221 | } | 2326 | } |
2222 | 2327 | ||
2223 | hr = ParseSourceXY(pixn, NULL != pTheme->pBitmap, &pTheme->nSourceX, &pTheme->nSourceY); | 2328 | hr = ParseSourceXY(pixn, pTheme, pTheme->nDefaultDpiWidth, pTheme->nDefaultDpiHeight, &pTheme->windowImageRef); |
2224 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window SourceX and SourceY attributes."); | 2329 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window SourceX and SourceY attributes."); |
2225 | 2330 | ||
2226 | // Parse the optional window style. | 2331 | // Parse the optional window style. |
@@ -2230,7 +2335,7 @@ static HRESULT ParseWindow( | |||
2230 | if (!fXmlFound) | 2335 | if (!fXmlFound) |
2231 | { | 2336 | { |
2232 | pTheme->dwStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION; | 2337 | pTheme->dwStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION; |
2233 | pTheme->dwStyle |= (0 <= pTheme->nSourceX && 0 <= pTheme->nSourceY) ? WS_POPUP : WS_OVERLAPPED; | 2338 | pTheme->dwStyle |= (THEME_IMAGE_REFERENCE_TYPE_NONE != pTheme->windowImageRef.type) ? WS_POPUP : WS_OVERLAPPED; |
2234 | } | 2339 | } |
2235 | 2340 | ||
2236 | hr = XmlGetAttributeUInt32(pixn, L"StringId", reinterpret_cast<DWORD*>(&pTheme->uStringId)); | 2341 | hr = XmlGetAttributeUInt32(pixn, L"StringId", reinterpret_cast<DWORD*>(&pTheme->uStringId)); |
@@ -3171,8 +3276,6 @@ static void InitializeThemeControl( | |||
3171 | pControl->dwFontHoverId = THEME_INVALID_ID; | 3276 | pControl->dwFontHoverId = THEME_INVALID_ID; |
3172 | pControl->dwFontId = THEME_INVALID_ID; | 3277 | pControl->dwFontId = THEME_INVALID_ID; |
3173 | pControl->dwFontSelectedId = THEME_INVALID_ID; | 3278 | pControl->dwFontSelectedId = THEME_INVALID_ID; |
3174 | pControl->nSourceX = -1; | ||
3175 | pControl->nSourceY = -1; | ||
3176 | pControl->uStringId = UINT_MAX; | 3279 | pControl->uStringId = UINT_MAX; |
3177 | } | 3280 | } |
3178 | 3281 | ||
@@ -3889,35 +3992,57 @@ static HRESULT DrawButton( | |||
3889 | ) | 3992 | ) |
3890 | { | 3993 | { |
3891 | HRESULT hr = S_OK; | 3994 | HRESULT hr = S_OK; |
3892 | int nSourceX = pControl->pBitmap ? 0 : pControl->nSourceX; | 3995 | THEME_IMAGE_REFERENCE buttonImageRef = { }; |
3893 | int nSourceY = pControl->pBitmap ? 0 : pControl->nSourceY; | 3996 | const THEME_IMAGE_INSTANCE* pInstance = NULL; |
3894 | int nSourceWidth = pControl->pBitmap ? pControl->pBitmap->GetWidth() : pControl->nDefaultDpiWidth; | ||
3895 | int nSourceHeight = pControl->pBitmap ? pControl->pBitmap->GetHeight() / 4 : pControl->nDefaultDpiHeight; | ||
3896 | Gdiplus::Bitmap* pBitmap = pControl->pBitmap ? pControl->pBitmap : pTheme->pBitmap; | ||
3897 | int nHeight = pdis->rcItem.bottom - pdis->rcItem.top; | 3997 | int nHeight = pdis->rcItem.bottom - pdis->rcItem.top; |
3898 | int nWidth = pdis->rcItem.right - pdis->rcItem.left; | 3998 | int nWidth = pdis->rcItem.right - pdis->rcItem.left; |
3899 | 3999 | ||
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 | |||
3900 | DWORD_PTR dwStyle = ::GetWindowLongPtrW(pdis->hwndItem, GWL_STYLE); | 4024 | DWORD_PTR dwStyle = ::GetWindowLongPtrW(pdis->hwndItem, GWL_STYLE); |
3901 | // "clicked" gets priority | 4025 | // "clicked" gets priority |
3902 | if (ODS_SELECTED & pdis->itemState) | 4026 | if (ODS_SELECTED & pdis->itemState) |
3903 | { | 4027 | { |
3904 | nSourceY += nSourceHeight * 2; | 4028 | buttonImageRef.nY += buttonImageRef.nHeight * 2; |
3905 | } | 4029 | } |
3906 | // then hover | 4030 | // then hover |
3907 | else if (pControl->dwData & THEME_CONTROL_DATA_HOVER) | 4031 | else if (pControl->dwData & THEME_CONTROL_DATA_HOVER) |
3908 | { | 4032 | { |
3909 | nSourceY += nSourceHeight; | 4033 | buttonImageRef.nY += buttonImageRef.nHeight; |
3910 | } | 4034 | } |
3911 | // then focused | 4035 | // then focused |
3912 | else if ((WS_TABSTOP & dwStyle) && (ODS_FOCUS & pdis->itemState)) | 4036 | else if ((WS_TABSTOP & dwStyle) && (ODS_FOCUS & pdis->itemState)) |
3913 | { | 4037 | { |
3914 | nSourceY += nSourceHeight * 3; | 4038 | buttonImageRef.nY += buttonImageRef.nHeight * 3; |
3915 | } | 4039 | } |
3916 | 4040 | ||
3917 | hr = DrawGdipBitmap(pdis->hDC, 0, 0, nWidth, nHeight, pBitmap, nSourceX, nSourceY, nSourceWidth, nSourceHeight); | 4041 | hr = DrawImageReference(pTheme, &buttonImageRef, pdis->hDC, 0, 0, nWidth, nHeight); |
3918 | 4042 | ||
3919 | DrawControlText(pTheme, pdis, pControl, TRUE, FALSE); | 4043 | DrawControlText(pTheme, pdis, pControl, TRUE, FALSE); |
3920 | 4044 | ||
4045 | LExit: | ||
3921 | return hr; | 4046 | return hr; |
3922 | } | 4047 | } |
3923 | 4048 | ||
@@ -3996,17 +4121,65 @@ static HRESULT DrawImage( | |||
3996 | HRESULT hr = S_OK; | 4121 | HRESULT hr = S_OK; |
3997 | int nHeight = pdis->rcItem.bottom - pdis->rcItem.top; | 4122 | int nHeight = pdis->rcItem.bottom - pdis->rcItem.top; |
3998 | int nWidth = pdis->rcItem.right - pdis->rcItem.left; | 4123 | int nWidth = pdis->rcItem.right - pdis->rcItem.left; |
3999 | int nSourceX = pControl->pBitmap ? 0 : pControl->nSourceX; | ||
4000 | int nSourceY = pControl->pBitmap ? 0 : pControl->nSourceY; | ||
4001 | int nSourceWidth = pControl->pBitmap ? pControl->pBitmap->GetWidth() : pControl->nDefaultDpiWidth; | ||
4002 | int nSourceHeight = pControl->pBitmap ? pControl->pBitmap->GetHeight() : pControl->nDefaultDpiHeight; | ||
4003 | Gdiplus::Bitmap* pBitmap = pControl->pBitmap ? pControl->pBitmap : pTheme->pBitmap; | ||
4004 | 4124 | ||
4005 | hr = DrawGdipBitmap(pdis->hDC, 0, 0, nWidth, nHeight, pBitmap, nSourceX, nSourceY, nSourceWidth, nSourceHeight); | 4125 | hr = DrawImageReference(pTheme, &pControl->imageRef, pdis->hDC, 0, 0, nWidth, nHeight); |
4006 | 4126 | ||
4007 | return hr; | 4127 | return hr; |
4008 | } | 4128 | } |
4009 | 4129 | ||
4130 | static void GetImageInstance( | ||
4131 | __in THEME* pTheme, | ||
4132 | __in const THEME_IMAGE_REFERENCE* pReference, | ||
4133 | __out const THEME_IMAGE_INSTANCE** ppInstance | ||
4134 | ) | ||
4135 | { | ||
4136 | *ppInstance = pTheme->rgStandaloneImages + pReference->dwImageInstanceIndex; | ||
4137 | } | ||
4138 | |||
4139 | static HRESULT DrawImageReference( | ||
4140 | __in THEME* pTheme, | ||
4141 | __in const THEME_IMAGE_REFERENCE* pReference, | ||
4142 | __in HDC hdc, | ||
4143 | __in int destX, | ||
4144 | __in int destY, | ||
4145 | __in int destWidth, | ||
4146 | __in int destHeight | ||
4147 | ) | ||
4148 | { | ||
4149 | HRESULT hr = S_OK; | ||
4150 | const THEME_IMAGE_INSTANCE* pImageInstance = NULL; | ||
4151 | int nX = 0; | ||
4152 | int nY = 0; | ||
4153 | int nWidth = 0; | ||
4154 | int nHeight = 0; | ||
4155 | |||
4156 | GetImageInstance(pTheme, pReference, &pImageInstance); | ||
4157 | if (THEME_IMAGE_REFERENCE_TYPE_PARTIAL == pReference->type) | ||
4158 | { | ||
4159 | nX = pReference->nX; | ||
4160 | nY = pReference->nY; | ||
4161 | nWidth = pReference->nWidth; | ||
4162 | nHeight = pReference->nHeight; | ||
4163 | } | ||
4164 | else if (THEME_IMAGE_REFERENCE_TYPE_COMPLETE == pReference->type) | ||
4165 | { | ||
4166 | nX = 0; | ||
4167 | nY = 0; | ||
4168 | nWidth = pImageInstance->pBitmap->GetWidth(); | ||
4169 | nHeight = pImageInstance->pBitmap->GetHeight(); | ||
4170 | } | ||
4171 | else | ||
4172 | { | ||
4173 | AssertSz(FALSE, "Invalid image reference type for drawing"); | ||
4174 | ExitFunction1(hr = E_INVALIDARG); | ||
4175 | } | ||
4176 | |||
4177 | hr = DrawGdipBitmap(hdc, destX, destY, destWidth, destHeight, pImageInstance->pBitmap, nX, nY, nWidth, nHeight); | ||
4178 | |||
4179 | LExit: | ||
4180 | return hr; | ||
4181 | } | ||
4182 | |||
4010 | static HRESULT DrawGdipBitmap( | 4183 | static HRESULT DrawGdipBitmap( |
4011 | __in HDC hdc, | 4184 | __in HDC hdc, |
4012 | __in int destX, | 4185 | __in int destX, |
@@ -4069,36 +4242,56 @@ static HRESULT DrawProgressBar( | |||
4069 | HRESULT hr = S_OK; | 4242 | HRESULT hr = S_OK; |
4070 | WORD wProgressColor = HIWORD(pControl->dwData); | 4243 | WORD wProgressColor = HIWORD(pControl->dwData); |
4071 | WORD wProgressPercentage = LOWORD(pControl->dwData); | 4244 | WORD wProgressPercentage = LOWORD(pControl->dwData); |
4245 | const THEME_IMAGE_INSTANCE* pInstance = NULL; | ||
4072 | int nHeight = pdis->rcItem.bottom - pdis->rcItem.top; | 4246 | int nHeight = pdis->rcItem.bottom - pdis->rcItem.top; |
4073 | int nSourceHeight = pControl->nDefaultDpiHeight; | 4247 | int nSourceHeight = 0; |
4074 | int nSourceX = pControl->pBitmap ? 0 : pControl->nSourceX; | 4248 | int nSourceX = 0; |
4075 | int nSourceY = (pControl->pBitmap ? 0 : pControl->nSourceY) + (wProgressColor * nSourceHeight); | 4249 | int nSourceY = 0; |
4076 | int nFillableWidth = pdis->rcItem.right - 2 * nSideWidth; | 4250 | int nFillableWidth = pdis->rcItem.right - 2 * nSideWidth; |
4077 | int nCenter = nFillableWidth > 0 ? nFillableWidth * wProgressPercentage / 100 : 0; | 4251 | int nCenter = nFillableWidth > 0 ? nFillableWidth * wProgressPercentage / 100 : 0; |
4078 | Gdiplus::Bitmap* pBitmap = pControl->pBitmap ? pControl->pBitmap : pTheme->pBitmap; | ||
4079 | 4252 | ||
4080 | if (0 > nFillableWidth) | 4253 | if (0 > nFillableWidth) |
4081 | { | 4254 | { |
4082 | ExitFunction1(hr = S_FALSE); | 4255 | ExitFunction1(hr = S_FALSE); |
4083 | } | 4256 | } |
4084 | 4257 | ||
4258 | GetImageInstance(pTheme, &pControl->imageRef, &pInstance); | ||
4259 | |||
4260 | if (THEME_IMAGE_REFERENCE_TYPE_PARTIAL == pControl->imageRef.type) | ||
4261 | { | ||
4262 | nSourceHeight = pControl->imageRef.nHeight; | ||
4263 | nSourceX = pControl->imageRef.nX; | ||
4264 | nSourceY = pControl->imageRef.nY + (wProgressColor * nSourceHeight); | ||
4265 | } | ||
4266 | else if (THEME_IMAGE_REFERENCE_TYPE_COMPLETE == pControl->imageRef.type) | ||
4267 | { | ||
4268 | nSourceHeight = pControl->nDefaultDpiHeight; | ||
4269 | nSourceX = 0; | ||
4270 | nSourceY = wProgressColor * nSourceHeight; | ||
4271 | } | ||
4272 | else | ||
4273 | { | ||
4274 | AssertSz(FALSE, "Invalid image reference type for drawing"); | ||
4275 | ExitFunction1(hr = E_INVALIDARG); | ||
4276 | } | ||
4277 | |||
4085 | // Draw the left side of the progress bar. | 4278 | // Draw the left side of the progress bar. |
4086 | hr = DrawProgressBarImage(pTheme, pBitmap, nSourceX, nSourceY, 1, nSourceHeight, pdis->hDC, 0, 0, nSideWidth, nHeight); | 4279 | hr = DrawProgressBarImage(pTheme, pInstance, nSourceX, nSourceY, 1, nSourceHeight, pdis->hDC, 0, 0, nSideWidth, nHeight); |
4087 | 4280 | ||
4088 | // Draw the filled side of the progress bar, if there is any. | 4281 | // Draw the filled side of the progress bar, if there is any. |
4089 | if (0 < nCenter) | 4282 | if (0 < nCenter) |
4090 | { | 4283 | { |
4091 | hr = DrawProgressBarImage(pTheme, pBitmap, nSourceX + 1, nSourceY, 1, nSourceHeight, pdis->hDC, nSideWidth, 0, nCenter, nHeight); | 4284 | hr = DrawProgressBarImage(pTheme, pInstance, nSourceX + 1, nSourceY, 1, nSourceHeight, pdis->hDC, nSideWidth, 0, nCenter, nHeight); |
4092 | } | 4285 | } |
4093 | 4286 | ||
4094 | // Draw the unfilled side of the progress bar, if there is any. | 4287 | // Draw the unfilled side of the progress bar, if there is any. |
4095 | if (nCenter < nFillableWidth) | 4288 | if (nCenter < nFillableWidth) |
4096 | { | 4289 | { |
4097 | hr = DrawProgressBarImage(pTheme, pBitmap, nSourceX + 2, nSourceY, 1, nSourceHeight, pdis->hDC, nSideWidth + nCenter, 0, pdis->rcItem.right - nCenter - nSideWidth, nHeight); | 4290 | hr = DrawProgressBarImage(pTheme, pInstance, nSourceX + 2, nSourceY, 1, nSourceHeight, pdis->hDC, nSideWidth + nCenter, 0, pdis->rcItem.right - nCenter - nSideWidth, nHeight); |
4098 | } | 4291 | } |
4099 | 4292 | ||
4100 | // Draw the right side of the progress bar. | 4293 | // Draw the right side of the progress bar. |
4101 | hr = DrawProgressBarImage(pTheme, pBitmap, nSourceX + 3, nSourceY, 1, nSourceHeight, pdis->hDC, pdis->rcItem.right - nSideWidth, 0, nSideWidth, nHeight); | 4294 | hr = DrawProgressBarImage(pTheme, pInstance, nSourceX + 3, nSourceY, 1, nSourceHeight, pdis->hDC, pdis->rcItem.right - nSideWidth, 0, nSideWidth, nHeight); |
4102 | 4295 | ||
4103 | LExit: | 4296 | LExit: |
4104 | return hr; | 4297 | return hr; |
@@ -4106,7 +4299,7 @@ LExit: | |||
4106 | 4299 | ||
4107 | static HRESULT DrawProgressBarImage( | 4300 | static HRESULT DrawProgressBarImage( |
4108 | __in THEME* /*pTheme*/, | 4301 | __in THEME* /*pTheme*/, |
4109 | __in Gdiplus::Bitmap* pBitmap, | 4302 | __in const THEME_IMAGE_INSTANCE* pImageInstance, |
4110 | __in int srcX, | 4303 | __in int srcX, |
4111 | __in int srcY, | 4304 | __in int srcY, |
4112 | __in int srcWidth, | 4305 | __in int srcWidth, |
@@ -4125,7 +4318,7 @@ static HRESULT DrawProgressBarImage( | |||
4125 | graphics.SetCompositingMode(Gdiplus::CompositingMode::CompositingModeSourceCopy); | 4318 | graphics.SetCompositingMode(Gdiplus::CompositingMode::CompositingModeSourceCopy); |
4126 | 4319 | ||
4127 | // Isolate the source rectangle into a temporary bitmap because otherwise GDI+ would use pixels outside of that rectangle when stretching. | 4320 | // Isolate the source rectangle into a temporary bitmap because otherwise GDI+ would use pixels outside of that rectangle when stretching. |
4128 | Gdiplus::Status gs = graphics.DrawImage(pBitmap, dest, srcX, srcY, srcWidth, srcHeight, Gdiplus::Unit::UnitPixel); | 4321 | Gdiplus::Status gs = graphics.DrawImage(pImageInstance->pBitmap, dest, srcX, srcY, srcWidth, srcHeight, Gdiplus::Unit::UnitPixel); |
4129 | hr = GdipHresultFromStatus(gs); | 4322 | hr = GdipHresultFromStatus(gs); |
4130 | if (SUCCEEDED(hr)) | 4323 | if (SUCCEEDED(hr)) |
4131 | { | 4324 | { |
@@ -4218,11 +4411,6 @@ static void FreeControl( | |||
4218 | ReleaseStr(pControl->sczValue); | 4411 | ReleaseStr(pControl->sczValue); |
4219 | ReleaseStr(pControl->sczVariable); | 4412 | ReleaseStr(pControl->sczVariable); |
4220 | 4413 | ||
4221 | if (pControl->pBitmap) | ||
4222 | { | ||
4223 | delete pControl->pBitmap; | ||
4224 | } | ||
4225 | |||
4226 | if (pControl->hImage) | 4414 | if (pControl->hImage) |
4227 | { | 4415 | { |
4228 | ::DeleteBitmap(pControl->hImage); | 4416 | ::DeleteBitmap(pControl->hImage); |
@@ -4351,6 +4539,17 @@ static void FreeFont( | |||
4351 | } | 4539 | } |
4352 | 4540 | ||
4353 | 4541 | ||
4542 | static void FreeImageInstance( | ||
4543 | __in THEME_IMAGE_INSTANCE* pImageInstance | ||
4544 | ) | ||
4545 | { | ||
4546 | if (pImageInstance->pBitmap) | ||
4547 | { | ||
4548 | delete pImageInstance->pBitmap; | ||
4549 | } | ||
4550 | } | ||
4551 | |||
4552 | |||
4354 | static DWORD CALLBACK RichEditStreamFromFileHandleCallback( | 4553 | static DWORD CALLBACK RichEditStreamFromFileHandleCallback( |
4355 | __in DWORD_PTR dwCookie, | 4554 | __in DWORD_PTR dwCookie, |
4356 | __in_bcount(cb) LPBYTE pbBuff, | 4555 | __in_bcount(cb) LPBYTE pbBuff, |
@@ -5298,6 +5497,7 @@ static HRESULT LoadControls( | |||
5298 | LPCWSTR wzWindowClass = NULL; | 5497 | LPCWSTR wzWindowClass = NULL; |
5299 | DWORD dwWindowBits = WS_CHILD; | 5498 | DWORD dwWindowBits = WS_CHILD; |
5300 | DWORD dwWindowExBits = 0; | 5499 | DWORD dwWindowExBits = 0; |
5500 | BOOL fOwnerDrawImage = THEME_IMAGE_REFERENCE_TYPE_NONE != pControl->imageRef.type; | ||
5301 | 5501 | ||
5302 | if (fStartNewGroup) | 5502 | if (fStartNewGroup) |
5303 | { | 5503 | { |
@@ -5322,7 +5522,7 @@ static HRESULT LoadControls( | |||
5322 | __fallthrough; | 5522 | __fallthrough; |
5323 | case THEME_CONTROL_TYPE_BUTTON: | 5523 | case THEME_CONTROL_TYPE_BUTTON: |
5324 | wzWindowClass = WC_BUTTONW; | 5524 | wzWindowClass = WC_BUTTONW; |
5325 | if (pControl->pBitmap || (pTheme->pBitmap && 0 <= pControl->nSourceX && 0 <= pControl->nSourceY)) | 5525 | if (fOwnerDrawImage) |
5326 | { | 5526 | { |
5327 | dwWindowBits |= BS_OWNERDRAW; | 5527 | dwWindowBits |= BS_OWNERDRAW; |
5328 | pControl->dwInternalStyle |= INTERNAL_CONTROL_STYLE_OWNER_DRAW; | 5528 | pControl->dwInternalStyle |= INTERNAL_CONTROL_STYLE_OWNER_DRAW; |
@@ -5356,7 +5556,7 @@ static HRESULT LoadControls( | |||
5356 | break; | 5556 | break; |
5357 | 5557 | ||
5358 | case THEME_CONTROL_TYPE_IMAGE: // images are basically just owner drawn static controls (so we can draw .jpgs and .pngs instead of just bitmaps). | 5558 | case THEME_CONTROL_TYPE_IMAGE: // images are basically just owner drawn static controls (so we can draw .jpgs and .pngs instead of just bitmaps). |
5359 | if (pControl->pBitmap || (pTheme->pBitmap && 0 <= pControl->nSourceX && 0 <= pControl->nSourceY)) | 5559 | if (fOwnerDrawImage) |
5360 | { | 5560 | { |
5361 | wzWindowClass = THEME_WC_STATICOWNERDRAW; | 5561 | wzWindowClass = THEME_WC_STATICOWNERDRAW; |
5362 | dwWindowBits |= SS_OWNERDRAW; | 5562 | dwWindowBits |= SS_OWNERDRAW; |
@@ -5383,7 +5583,7 @@ static HRESULT LoadControls( | |||
5383 | break; | 5583 | break; |
5384 | 5584 | ||
5385 | case THEME_CONTROL_TYPE_PROGRESSBAR: | 5585 | case THEME_CONTROL_TYPE_PROGRESSBAR: |
5386 | if (pControl->pBitmap || (pTheme->pBitmap && 0 <= pControl->nSourceX && 0 <= pControl->nSourceY)) | 5586 | if (fOwnerDrawImage) |
5387 | { | 5587 | { |
5388 | wzWindowClass = THEME_WC_STATICOWNERDRAW; // no such thing as an owner drawn progress bar so we'll make our own out of a static control. | 5588 | wzWindowClass = THEME_WC_STATICOWNERDRAW; // no such thing as an owner drawn progress bar so we'll make our own out of a static control. |
5389 | dwWindowBits |= SS_OWNERDRAW; | 5589 | dwWindowBits |= SS_OWNERDRAW; |