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 /src | |
| parent | c661b773f8ae37bbdea6da25a57d3626e7113920 (diff) | |
| download | wix-b22a62fd6eed5bb7a2c04d51828438daa621db6c.tar.gz wix-b22a62fd6eed5bb7a2c04d51828438daa621db6c.tar.bz2 wix-b22a62fd6eed5bb7a2c04d51828438daa621db6c.zip | |
Add THEME_IMAGE_REFERENCE to thmutil.
Diffstat (limited to 'src')
| -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; |
