diff options
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/thmutil.cpp')
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 993 |
1 files changed, 562 insertions, 431 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp index 599021bf..1e7fa01a 100644 --- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp | |||
@@ -20,6 +20,7 @@ | |||
20 | #define ThmExitOnRequiredXmlQueryFailure(x, s, ...) ExitOnRequiredXmlQueryFailureSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__) | 20 | #define ThmExitOnRequiredXmlQueryFailure(x, s, ...) ExitOnRequiredXmlQueryFailureSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__) |
21 | #define ThmExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_THMUTIL, g, x, s, __VA_ARGS__) | 21 | #define ThmExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_THMUTIL, g, x, s, __VA_ARGS__) |
22 | 22 | ||
23 | #define ThmExitOnUnexpectedAttribute(x, n, e, a) { x = ParseUnexpectedAttribute(n, e, a); if (FAILED(x)) { ExitFunction(); } } | ||
23 | 24 | ||
24 | // from CommCtrl.h | 25 | // from CommCtrl.h |
25 | #ifndef BS_COMMANDLINK | 26 | #ifndef BS_COMMANDLINK |
@@ -86,17 +87,33 @@ static HRESULT ParseTheme( | |||
86 | __in IXMLDOMDocument* pixd, | 87 | __in IXMLDOMDocument* pixd, |
87 | __out THEME** ppTheme | 88 | __out THEME** ppTheme |
88 | ); | 89 | ); |
89 | static HRESULT ParseImage( | 90 | static HRESULT GetAttributeImageFileOrResource( |
90 | __in_opt HMODULE hModule, | 91 | __in_opt HMODULE hModule, |
91 | __in_z_opt LPCWSTR wzRelativePath, | 92 | __in_z_opt LPCWSTR wzRelativePath, |
92 | __in IXMLDOMNode* pElement, | 93 | __in IXMLDOMNode* pElement, |
93 | __out HBITMAP* phImage | 94 | __out HBITMAP* phImage |
94 | ); | 95 | ); |
95 | static HRESULT ParseIcon( | 96 | static HRESULT ParseCommandLinkImage( |
96 | __in_opt HMODULE hModule, | 97 | __in_opt HMODULE hModule, |
97 | __in_z_opt LPCWSTR wzRelativePath, | 98 | __in_z_opt LPCWSTR wzRelativePath, |
98 | __in IXMLDOMNode* pElement, | 99 | __in IXMLDOMNode* pElement, |
99 | __out HICON* phIcon | 100 | __in THEME_CONTROL* pControl |
101 | ); | ||
102 | static HRESULT GetAttributeCoordinateOrDimension( | ||
103 | __in IXMLDOMNode* pixn, | ||
104 | __in LPCWSTR wzAttribute, | ||
105 | __inout int* pnValue | ||
106 | ); | ||
107 | static HRESULT GetAttributeFontId( | ||
108 | __in IXMLDOMNode* pixn, | ||
109 | __in LPCWSTR wzAttribute, | ||
110 | __inout DWORD* pdwValue | ||
111 | ); | ||
112 | static HRESULT ParseSourceXY( | ||
113 | __in IXMLDOMNode* pixn, | ||
114 | __in BOOL fAllowed, | ||
115 | __inout int* pnX, | ||
116 | __inout int* pnY | ||
100 | ); | 117 | ); |
101 | static HRESULT ParseWindow( | 118 | static HRESULT ParseWindow( |
102 | __in_opt HMODULE hModule, | 119 | __in_opt HMODULE hModule, |
@@ -138,6 +155,7 @@ static HRESULT ParseControl( | |||
138 | __in_opt HMODULE hModule, | 155 | __in_opt HMODULE hModule, |
139 | __in_opt LPCWSTR wzRelativePath, | 156 | __in_opt LPCWSTR wzRelativePath, |
140 | __in IXMLDOMNode* pixn, | 157 | __in IXMLDOMNode* pixn, |
158 | __in_z LPCWSTR wzElementName, | ||
141 | __in THEME* pTheme, | 159 | __in THEME* pTheme, |
142 | __in THEME_CONTROL* pControl, | 160 | __in THEME_CONTROL* pControl, |
143 | __in_opt THEME_PAGE* pPage | 161 | __in_opt THEME_PAGE* pPage |
@@ -183,6 +201,11 @@ static HRESULT ParseTooltips( | |||
183 | __in THEME_CONTROL* pControl, | 201 | __in THEME_CONTROL* pControl, |
184 | __inout BOOL* pfAnyChildren | 202 | __inout BOOL* pfAnyChildren |
185 | ); | 203 | ); |
204 | static HRESULT ParseUnexpectedAttribute( | ||
205 | __in IXMLDOMNode* pixn, | ||
206 | __in_z LPCWSTR wzElementName, | ||
207 | __in_z LPCWSTR wzAttribute | ||
208 | ); | ||
186 | static HRESULT ParseNotes( | 209 | static HRESULT ParseNotes( |
187 | __in IXMLDOMNode* pixn, | 210 | __in IXMLDOMNode* pixn, |
188 | __in THEME_CONTROL* pControl, | 211 | __in THEME_CONTROL* pControl, |
@@ -1698,6 +1721,7 @@ static HRESULT ParseTheme( | |||
1698 | HRESULT hr = S_OK; | 1721 | HRESULT hr = S_OK; |
1699 | THEME* pTheme = NULL; | 1722 | THEME* pTheme = NULL; |
1700 | IXMLDOMElement *pThemeElement = NULL; | 1723 | IXMLDOMElement *pThemeElement = NULL; |
1724 | BOOL fXmlFound = FALSE; | ||
1701 | 1725 | ||
1702 | hr = pixd->get_documentElement(&pThemeElement); | 1726 | hr = pixd->get_documentElement(&pThemeElement); |
1703 | ThmExitOnFailure(hr, "Failed to get theme element."); | 1727 | ThmExitOnFailure(hr, "Failed to get theme element."); |
@@ -1709,8 +1733,8 @@ static HRESULT ParseTheme( | |||
1709 | pTheme->nDpi = USER_DEFAULT_SCREEN_DPI; | 1733 | pTheme->nDpi = USER_DEFAULT_SCREEN_DPI; |
1710 | 1734 | ||
1711 | // Parse the optional background resource image. | 1735 | // Parse the optional background resource image. |
1712 | hr = ParseImage(hModule, wzRelativePath, pThemeElement, &pTheme->hImage); | 1736 | hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pThemeElement, &pTheme->hImage); |
1713 | ThmExitOnFailure(hr, "Failed while parsing theme image."); | 1737 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed while parsing theme image."); |
1714 | 1738 | ||
1715 | // Parse the fonts. | 1739 | // Parse the fonts. |
1716 | hr = ParseFonts(pThemeElement, pTheme); | 1740 | hr = ParseFonts(pThemeElement, pTheme); |
@@ -1734,7 +1758,7 @@ LExit: | |||
1734 | return hr; | 1758 | return hr; |
1735 | } | 1759 | } |
1736 | 1760 | ||
1737 | static HRESULT ParseImage( | 1761 | static HRESULT GetAttributeImageFileOrResource( |
1738 | __in_opt HMODULE hModule, | 1762 | __in_opt HMODULE hModule, |
1739 | __in_z_opt LPCWSTR wzRelativePath, | 1763 | __in_z_opt LPCWSTR wzRelativePath, |
1740 | __in IXMLDOMNode* pElement, | 1764 | __in IXMLDOMNode* pElement, |
@@ -1744,45 +1768,44 @@ static HRESULT ParseImage( | |||
1744 | HRESULT hr = S_OK; | 1768 | HRESULT hr = S_OK; |
1745 | BSTR bstr = NULL; | 1769 | BSTR bstr = NULL; |
1746 | LPWSTR sczImageFile = NULL; | 1770 | LPWSTR sczImageFile = NULL; |
1747 | int iResourceId = 0; | 1771 | WORD wResourceId = 0; |
1772 | BOOL fFound = FALSE; | ||
1748 | Gdiplus::Bitmap* pBitmap = NULL; | 1773 | Gdiplus::Bitmap* pBitmap = NULL; |
1749 | *phImage = NULL; | 1774 | *phImage = NULL; |
1750 | 1775 | ||
1751 | hr = XmlGetAttribute(pElement, L"ImageResource", &bstr); | 1776 | hr = XmlGetAttributeUInt16(pElement, L"ImageResource", &wResourceId); |
1752 | ThmExitOnFailure(hr, "Failed to get image resource attribute."); | 1777 | ThmExitOnOptionalXmlQueryFailure(hr, fFound, "Failed to get image resource attribute."); |
1753 | 1778 | ||
1754 | if (S_OK == hr) | 1779 | if (fFound) |
1755 | { | 1780 | { |
1756 | iResourceId = wcstol(bstr, NULL, 10); | 1781 | hr = GdipBitmapFromResource(hModule, MAKEINTRESOURCE(wResourceId), &pBitmap); |
1757 | 1782 | ThmExitOnFailure(hr, "Failed to load image from resource: %hu", wResourceId); | |
1758 | hr = GdipBitmapFromResource(hModule, MAKEINTRESOURCE(iResourceId), &pBitmap); | ||
1759 | // Don't fail. | ||
1760 | } | 1783 | } |
1761 | 1784 | ||
1762 | ReleaseNullBSTR(bstr); | 1785 | hr = XmlGetAttribute(pElement, L"ImageFile", &bstr); |
1786 | ThmExitOnOptionalXmlQueryFailure(hr, fFound, "Failed to get image file attribute."); | ||
1763 | 1787 | ||
1764 | // Parse the optional background image from a given file. | 1788 | if (fFound) |
1765 | if (!pBitmap) | ||
1766 | { | 1789 | { |
1767 | hr = XmlGetAttribute(pElement, L"ImageFile", &bstr); | 1790 | if (pBitmap) |
1768 | ThmExitOnFailure(hr, "Failed to get image file attribute."); | ||
1769 | |||
1770 | if (S_OK == hr) | ||
1771 | { | 1791 | { |
1772 | if (wzRelativePath) | 1792 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "ImageFile attribute can't be specified with ImageResource attribute."); |
1773 | { | 1793 | } |
1774 | hr = PathConcat(wzRelativePath, bstr, &sczImageFile); | ||
1775 | ThmExitOnFailure(hr, "Failed to combine image file path."); | ||
1776 | } | ||
1777 | else | ||
1778 | { | ||
1779 | hr = PathRelativeToModule(&sczImageFile, bstr, hModule); | ||
1780 | ThmExitOnFailure(hr, "Failed to get image filename."); | ||
1781 | } | ||
1782 | 1794 | ||
1783 | hr = GdipBitmapFromFile(sczImageFile, &pBitmap); | 1795 | // Parse the optional background image from a given file. |
1784 | // Don't fail. | 1796 | if (wzRelativePath) |
1797 | { | ||
1798 | hr = PathConcat(wzRelativePath, bstr, &sczImageFile); | ||
1799 | ThmExitOnFailure(hr, "Failed to combine image file path."); | ||
1800 | } | ||
1801 | else | ||
1802 | { | ||
1803 | hr = PathRelativeToModule(&sczImageFile, bstr, hModule); | ||
1804 | ThmExitOnFailure(hr, "Failed to get image filename."); | ||
1785 | } | 1805 | } |
1806 | |||
1807 | hr = GdipBitmapFromFile(sczImageFile, &pBitmap); | ||
1808 | ThmExitOnFailure(hr, "Failed to load image from file: %ls", sczImageFile); | ||
1786 | } | 1809 | } |
1787 | 1810 | ||
1788 | // If there is an image, convert it into a bitmap handle. | 1811 | // If there is an image, convert it into a bitmap handle. |
@@ -1792,8 +1815,10 @@ static HRESULT ParseImage( | |||
1792 | Gdiplus::Status gs = pBitmap->GetHBITMAP(black, phImage); | 1815 | Gdiplus::Status gs = pBitmap->GetHBITMAP(black, phImage); |
1793 | ThmExitOnGdipFailure(gs, hr, "Failed to convert GDI+ bitmap into HBITMAP."); | 1816 | ThmExitOnGdipFailure(gs, hr, "Failed to convert GDI+ bitmap into HBITMAP."); |
1794 | } | 1817 | } |
1795 | 1818 | else | |
1796 | hr = S_OK; | 1819 | { |
1820 | hr = E_NOTFOUND; | ||
1821 | } | ||
1797 | 1822 | ||
1798 | LExit: | 1823 | LExit: |
1799 | if (pBitmap) | 1824 | if (pBitmap) |
@@ -1808,62 +1833,244 @@ LExit: | |||
1808 | } | 1833 | } |
1809 | 1834 | ||
1810 | 1835 | ||
1811 | static HRESULT ParseIcon( | 1836 | static HRESULT ParseOwnerDrawImage( |
1812 | __in_opt HMODULE hModule, | 1837 | __in_opt HMODULE hModule, |
1813 | __in_z_opt LPCWSTR wzRelativePath, | 1838 | __in_z_opt LPCWSTR wzRelativePath, |
1839 | __in THEME* pTheme, | ||
1814 | __in IXMLDOMNode* pElement, | 1840 | __in IXMLDOMNode* pElement, |
1815 | __out HICON* phIcon | 1841 | __in THEME_CONTROL* pControl |
1816 | ) | 1842 | ) |
1817 | { | 1843 | { |
1818 | HRESULT hr = S_OK; | 1844 | HRESULT hr = S_OK; |
1819 | BSTR bstr = NULL; | 1845 | BOOL fXmlFound = FALSE; |
1820 | LPWSTR sczImageFile = NULL; | 1846 | BOOL fFoundImage = FALSE; |
1821 | int iResourceId = 0; | ||
1822 | *phIcon = NULL; | ||
1823 | 1847 | ||
1824 | hr = XmlGetAttribute(pElement, L"IconResource", &bstr); | 1848 | // Parse the optional background resource image. |
1825 | ThmExitOnFailure(hr, "Failed to get icon resource attribute."); | 1849 | hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pElement, &pControl->hImage); |
1850 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed while parsing control image."); | ||
1826 | 1851 | ||
1827 | if (S_OK == hr) | 1852 | if (fXmlFound) |
1853 | { | ||
1854 | fFoundImage = TRUE; | ||
1855 | } | ||
1856 | |||
1857 | hr = ParseSourceXY(pElement, NULL != pTheme->hImage, &pControl->nSourceX, &pControl->nSourceY); | ||
1858 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get control SourceX and SourceY attributes."); | ||
1859 | |||
1860 | if (fXmlFound) | ||
1828 | { | 1861 | { |
1829 | iResourceId = wcstol(bstr, NULL, 10); | 1862 | if (fFoundImage) |
1863 | { | ||
1864 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Unexpected SourceX attribute with image attribute."); | ||
1865 | } | ||
1866 | else if (1 > pControl->nWidth || 1 > pControl->nHeight) | ||
1867 | { | ||
1868 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Control Width and Height must be positive when using SourceX and SourceY."); | ||
1869 | } | ||
1830 | 1870 | ||
1831 | *phIcon = reinterpret_cast<HICON>(::LoadImageW(hModule, MAKEINTRESOURCEW(iResourceId), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE)); | 1871 | fFoundImage = TRUE; |
1832 | ThmExitOnNullWithLastError(*phIcon, hr, "Failed to load icon."); | ||
1833 | } | 1872 | } |
1834 | else | 1873 | |
1874 | if (THEME_CONTROL_TYPE_IMAGE == pControl->type && !fFoundImage) | ||
1835 | { | 1875 | { |
1836 | ReleaseNullBSTR(bstr); | 1876 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Image control didn't specify an image."); |
1877 | } | ||
1837 | 1878 | ||
1838 | hr = XmlGetAttribute(pElement, L"IconFile", &bstr); | 1879 | LExit: |
1839 | ThmExitOnFailure(hr, "Failed to get icon file attribute."); | 1880 | return hr; |
1881 | } | ||
1840 | 1882 | ||
1841 | if (S_OK == hr) | 1883 | |
1884 | static HRESULT ParseCommandLinkImage( | ||
1885 | __in_opt HMODULE hModule, | ||
1886 | __in_z_opt LPCWSTR wzRelativePath, | ||
1887 | __in IXMLDOMNode* pElement, | ||
1888 | __in THEME_CONTROL* pControl | ||
1889 | ) | ||
1890 | { | ||
1891 | HRESULT hr = S_OK; | ||
1892 | BSTR bstr = NULL; | ||
1893 | BOOL fImageFound = FALSE; | ||
1894 | BOOL fXmlFound = FALSE; | ||
1895 | LPWSTR sczIconFile = NULL; | ||
1896 | WORD wResourceId = 0; | ||
1897 | |||
1898 | hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pElement, &pControl->hImage); | ||
1899 | ThmExitOnOptionalXmlQueryFailure(hr, fImageFound, "Failed to parse image attributes for CommandLink."); | ||
1900 | |||
1901 | hr = XmlGetAttributeUInt16(pElement, L"IconResource", &wResourceId); | ||
1902 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get icon resource attribute."); | ||
1903 | |||
1904 | if (fXmlFound) | ||
1905 | { | ||
1906 | if (fImageFound) | ||
1842 | { | 1907 | { |
1843 | if (wzRelativePath) | 1908 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Unexpected IconResource attribute with image attribute."); |
1844 | { | 1909 | } |
1845 | hr = PathConcat(wzRelativePath, bstr, &sczImageFile); | 1910 | |
1846 | ThmExitOnFailure(hr, "Failed to combine image file path."); | 1911 | pControl->hIcon = reinterpret_cast<HICON>(::LoadImageW(hModule, MAKEINTRESOURCEW(wResourceId), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE)); |
1847 | } | 1912 | ThmExitOnNullWithLastError(pControl->hIcon, hr, "Failed to load icon."); |
1848 | else | 1913 | } |
1849 | { | 1914 | |
1850 | hr = PathRelativeToModule(&sczImageFile, bstr, hModule); | 1915 | hr = XmlGetAttribute(pElement, L"IconFile", &bstr); |
1851 | ThmExitOnFailure(hr, "Failed to get image filename."); | 1916 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get icon file attribute."); |
1852 | } | 1917 | |
1918 | if (fXmlFound) | ||
1919 | { | ||
1920 | if (fImageFound) | ||
1921 | { | ||
1922 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Unexpected IconFile attribute with image attribute."); | ||
1923 | } | ||
1924 | else if (pControl->hIcon) | ||
1925 | { | ||
1926 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "IconFile attribute can't be specified with IconResource attribute."); | ||
1927 | } | ||
1853 | 1928 | ||
1854 | *phIcon = reinterpret_cast<HICON>(::LoadImageW(NULL, sczImageFile, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE)); | 1929 | if (wzRelativePath) |
1855 | ThmExitOnNullWithLastError(*phIcon, hr, "Failed to load icon: %ls.", sczImageFile); | 1930 | { |
1931 | hr = PathConcat(wzRelativePath, bstr, &sczIconFile); | ||
1932 | ThmExitOnFailure(hr, "Failed to combine image file path."); | ||
1856 | } | 1933 | } |
1934 | else | ||
1935 | { | ||
1936 | hr = PathRelativeToModule(&sczIconFile, bstr, hModule); | ||
1937 | ThmExitOnFailure(hr, "Failed to get image filename."); | ||
1938 | } | ||
1939 | |||
1940 | pControl->hIcon = reinterpret_cast<HICON>(::LoadImageW(NULL, sczIconFile, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE)); | ||
1941 | ThmExitOnNullWithLastError(pControl->hIcon, hr, "Failed to load icon: %ls.", sczIconFile); | ||
1857 | } | 1942 | } |
1858 | 1943 | ||
1944 | ThmExitOnUnexpectedAttribute(hr, pElement, L"CommandLink", L"SourceX"); | ||
1945 | ThmExitOnUnexpectedAttribute(hr, pElement, L"CommandLink", L"SourceY"); | ||
1946 | |||
1859 | LExit: | 1947 | LExit: |
1860 | ReleaseStr(sczImageFile); | 1948 | ReleaseStr(sczIconFile); |
1861 | ReleaseBSTR(bstr); | 1949 | ReleaseBSTR(bstr); |
1862 | 1950 | ||
1863 | return hr; | 1951 | return hr; |
1864 | } | 1952 | } |
1865 | 1953 | ||
1866 | 1954 | ||
1955 | static HRESULT GetAttributeCoordinateOrDimension( | ||
1956 | __in IXMLDOMNode* pixn, | ||
1957 | __in LPCWSTR wzAttribute, | ||
1958 | __inout int* pnValue | ||
1959 | ) | ||
1960 | { | ||
1961 | HRESULT hr = S_OK; | ||
1962 | int nValue = 0; | ||
1963 | BOOL fXmlFound = FALSE; | ||
1964 | |||
1965 | hr = XmlGetAttributeInt32(pixn, wzAttribute, &nValue); | ||
1966 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get coordinate or dimension attribute."); | ||
1967 | |||
1968 | if (!fXmlFound) | ||
1969 | { | ||
1970 | ExitFunction1(hr = E_NOTFOUND); | ||
1971 | } | ||
1972 | else if (abs(nValue) > SHORT_MAX) | ||
1973 | { | ||
1974 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Invalid coordinate or dimension attribute value: %i", nValue); | ||
1975 | } | ||
1976 | |||
1977 | *pnValue = nValue; | ||
1978 | |||
1979 | LExit: | ||
1980 | return hr; | ||
1981 | } | ||
1982 | |||
1983 | static HRESULT GetAttributeFontId( | ||
1984 | __in IXMLDOMNode* pixn, | ||
1985 | __in LPCWSTR wzAttribute, | ||
1986 | __inout DWORD* pdwValue | ||
1987 | ) | ||
1988 | { | ||
1989 | HRESULT hr = S_OK; | ||
1990 | DWORD dwValue = 0; | ||
1991 | BOOL fXmlFound = FALSE; | ||
1992 | |||
1993 | hr = XmlGetAttributeUInt32(pixn, wzAttribute, &dwValue); | ||
1994 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get font id attribute."); | ||
1995 | |||
1996 | if (!fXmlFound) | ||
1997 | { | ||
1998 | ExitFunction1(hr = E_NOTFOUND); | ||
1999 | } | ||
2000 | else if (THEME_INVALID_ID == dwValue) | ||
2001 | { | ||
2002 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Invalid font id value: %u", dwValue); | ||
2003 | } | ||
2004 | |||
2005 | *pdwValue = dwValue; | ||
2006 | |||
2007 | LExit: | ||
2008 | return hr; | ||
2009 | } | ||
2010 | |||
2011 | static HRESULT ParseSourceXY( | ||
2012 | __in IXMLDOMNode* pixn, | ||
2013 | __in BOOL fAllowed, | ||
2014 | __inout int* pnX, | ||
2015 | __inout int* pnY | ||
2016 | ) | ||
2017 | { | ||
2018 | HRESULT hr = S_OK; | ||
2019 | BOOL fXFound = FALSE; | ||
2020 | BOOL fYFound = FALSE; | ||
2021 | |||
2022 | hr = GetAttributeCoordinateOrDimension(pixn, L"SourceX", pnX); | ||
2023 | ThmExitOnOptionalXmlQueryFailure(hr, fXFound, "Failed to get SourceX attribute."); | ||
2024 | |||
2025 | if (!fXFound) | ||
2026 | { | ||
2027 | *pnX = -1; | ||
2028 | } | ||
2029 | else | ||
2030 | { | ||
2031 | if (!fAllowed) | ||
2032 | { | ||
2033 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceX cannot be specified without an image specified on Theme."); | ||
2034 | } | ||
2035 | else if (0 > *pnX) | ||
2036 | { | ||
2037 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceX must be non-negative."); | ||
2038 | } | ||
2039 | } | ||
2040 | |||
2041 | hr = GetAttributeCoordinateOrDimension(pixn, L"SourceY", pnY); | ||
2042 | ThmExitOnOptionalXmlQueryFailure(hr, fYFound, "Failed to get SourceY attribute."); | ||
2043 | |||
2044 | if (!fYFound) | ||
2045 | { | ||
2046 | if (fXFound) | ||
2047 | { | ||
2048 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be specified with SourceX."); | ||
2049 | } | ||
2050 | |||
2051 | *pnY = -1; | ||
2052 | hr = E_NOTFOUND; | ||
2053 | } | ||
2054 | else | ||
2055 | { | ||
2056 | if (!fAllowed) | ||
2057 | { | ||
2058 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY cannot be specified without an image specified on Theme."); | ||
2059 | } | ||
2060 | else if (!fXFound) | ||
2061 | { | ||
2062 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be specified with SourceX."); | ||
2063 | } | ||
2064 | else if (0 > *pnY) | ||
2065 | { | ||
2066 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "SourceY must be non-negative."); | ||
2067 | } | ||
2068 | } | ||
2069 | |||
2070 | LExit: | ||
2071 | return hr; | ||
2072 | } | ||
2073 | |||
1867 | static HRESULT ParseWindow( | 2074 | static HRESULT ParseWindow( |
1868 | __in_opt HMODULE hModule, | 2075 | __in_opt HMODULE hModule, |
1869 | __in_opt LPCWSTR wzRelativePath, | 2076 | __in_opt LPCWSTR wzRelativePath, |
@@ -1873,77 +2080,79 @@ static HRESULT ParseWindow( | |||
1873 | { | 2080 | { |
1874 | HRESULT hr = S_OK; | 2081 | HRESULT hr = S_OK; |
1875 | IXMLDOMNode* pixn = NULL; | 2082 | IXMLDOMNode* pixn = NULL; |
1876 | DWORD dwValue = 0; | 2083 | BOOL fXmlFound = FALSE; |
2084 | int nValue = 0; | ||
1877 | BSTR bstr = NULL; | 2085 | BSTR bstr = NULL; |
1878 | LPWSTR sczIconFile = NULL; | 2086 | LPWSTR sczIconFile = NULL; |
1879 | 2087 | ||
1880 | hr = XmlSelectSingleNode(pElement, L"Window", &pixn); | 2088 | hr = XmlSelectSingleNode(pElement, L"Window", &pixn); |
1881 | if (S_FALSE == hr) | 2089 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find window element."); |
1882 | { | ||
1883 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
1884 | } | ||
1885 | ThmExitOnFailure(hr, "Failed to find window element."); | ||
1886 | 2090 | ||
1887 | hr = XmlGetYesNoAttribute(pixn, L"AutoResize", &pTheme->fAutoResize); | 2091 | hr = XmlGetYesNoAttribute(pixn, L"AutoResize", &pTheme->fAutoResize); |
1888 | if (E_NOTFOUND == hr) | 2092 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window AutoResize attribute."); |
1889 | { | ||
1890 | hr = S_OK; | ||
1891 | } | ||
1892 | ThmExitOnFailure(hr, "Failed to get window AutoResize attribute."); | ||
1893 | |||
1894 | hr = XmlGetAttributeNumber(pixn, L"Width", &dwValue); | ||
1895 | if (S_FALSE == hr) | ||
1896 | { | ||
1897 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
1898 | ThmExitOnRootFailure(hr, "Failed to find window Width attribute."); | ||
1899 | } | ||
1900 | ThmExitOnFailure(hr, "Failed to get window Width attribute."); | ||
1901 | 2093 | ||
1902 | pTheme->nWidth = pTheme->nDefaultDpiWidth = pTheme->nWindowWidth = dwValue; | 2094 | hr = GetAttributeCoordinateOrDimension(pixn, L"Width", &nValue); |
2095 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to get window Width attribute."); | ||
1903 | 2096 | ||
1904 | hr = XmlGetAttributeNumber(pixn, L"Height", &dwValue); | 2097 | if (1 > nValue) |
1905 | if (S_FALSE == hr) | ||
1906 | { | 2098 | { |
1907 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2099 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Window/@Width must be positive: %i", nValue); |
1908 | ThmExitOnRootFailure(hr, "Failed to find window Height attribute."); | ||
1909 | } | 2100 | } |
1910 | ThmExitOnFailure(hr, "Failed to get window Height attribute."); | ||
1911 | 2101 | ||
1912 | pTheme->nHeight = pTheme->nDefaultDpiHeight = pTheme->nWindowHeight = dwValue; | 2102 | pTheme->nWidth = pTheme->nDefaultDpiWidth = pTheme->nWindowWidth = nValue; |
1913 | 2103 | ||
1914 | hr = XmlGetAttributeNumber(pixn, L"MinimumWidth", &dwValue); | 2104 | hr = GetAttributeCoordinateOrDimension(pixn, L"Height", &nValue); |
1915 | if (S_FALSE == hr) | 2105 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to get window Height attribute."); |
2106 | |||
2107 | if (1 > nValue) | ||
1916 | { | 2108 | { |
1917 | dwValue = 0; | 2109 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Window/@Height must be positive: %i", nValue); |
1918 | hr = S_OK; | ||
1919 | } | 2110 | } |
1920 | ThmExitOnFailure(hr, "Failed to get window MinimumWidth attribute."); | ||
1921 | 2111 | ||
1922 | pTheme->nMinimumWidth = pTheme->nDefaultDpiMinimumWidth = dwValue; | 2112 | pTheme->nHeight = pTheme->nDefaultDpiHeight = pTheme->nWindowHeight = nValue; |
1923 | 2113 | ||
1924 | hr = XmlGetAttributeNumber(pixn, L"MinimumHeight", &dwValue); | 2114 | hr = GetAttributeCoordinateOrDimension(pixn, L"MinimumWidth", &nValue); |
1925 | if (S_FALSE == hr) | 2115 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window MinimumWidth attribute."); |
2116 | |||
2117 | if (fXmlFound) | ||
1926 | { | 2118 | { |
1927 | dwValue = 0; | 2119 | if (!pTheme->fAutoResize) |
1928 | hr = S_OK; | 2120 | { |
2121 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Window/@MinimumWidth can't be specified unless AutoResize is enabled."); | ||
2122 | } | ||
2123 | else if (1 > nValue || pTheme->nWidth < nValue) | ||
2124 | { | ||
2125 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Window/@MinimumWidth must be positive and not greater than Window/@Width: %i", nValue); | ||
2126 | } | ||
2127 | |||
2128 | pTheme->nMinimumWidth = pTheme->nDefaultDpiMinimumWidth = nValue; | ||
1929 | } | 2129 | } |
1930 | ThmExitOnFailure(hr, "Failed to get window MinimumHeight attribute."); | ||
1931 | 2130 | ||
1932 | pTheme->nMinimumHeight = pTheme->nDefaultDpiMinimumHeight = dwValue; | 2131 | hr = GetAttributeCoordinateOrDimension(pixn, L"MinimumHeight", &nValue); |
2132 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window MinimumHeight attribute."); | ||
1933 | 2133 | ||
1934 | hr = XmlGetAttributeNumber(pixn, L"FontId", &pTheme->dwFontId); | 2134 | if (fXmlFound) |
1935 | if (S_FALSE == hr) | ||
1936 | { | 2135 | { |
1937 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2136 | if (!pTheme->fAutoResize) |
1938 | ThmExitOnRootFailure(hr, "Failed to find window FontId attribute."); | 2137 | { |
2138 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Window/@MinimumHeight can't be specified unless AutoResize is enabled."); | ||
2139 | } | ||
2140 | else if (1 > nValue || pTheme->nHeight < nValue) | ||
2141 | { | ||
2142 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Window/@MinimumHeight must be positive and not greater than Window/@Height: %i", nValue); | ||
2143 | } | ||
2144 | |||
2145 | pTheme->nMinimumHeight = pTheme->nDefaultDpiMinimumHeight = nValue; | ||
1939 | } | 2146 | } |
1940 | ThmExitOnFailure(hr, "Failed to get window FontId attribute."); | 2147 | |
2148 | hr = GetAttributeFontId(pixn, L"FontId", &pTheme->dwFontId); | ||
2149 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to get window FontId attribute."); | ||
1941 | 2150 | ||
1942 | // Get the optional window icon from a resource. | 2151 | // Get the optional window icon from a resource. |
1943 | hr = XmlGetAttribute(pixn, L"IconResource", &bstr); | 2152 | hr = XmlGetAttribute(pixn, L"IconResource", &bstr); |
1944 | ThmExitOnFailure(hr, "Failed to get window IconResource attribute."); | 2153 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window IconResource attribute."); |
1945 | 2154 | ||
1946 | if (S_OK == hr) | 2155 | if (fXmlFound) |
1947 | { | 2156 | { |
1948 | pTheme->hIcon = ::LoadIconW(hModule, bstr); | 2157 | pTheme->hIcon = ::LoadIconW(hModule, bstr); |
1949 | ThmExitOnNullWithLastError(pTheme->hIcon, hr, "Failed to load window icon from IconResource."); | 2158 | ThmExitOnNullWithLastError(pTheme->hIcon, hr, "Failed to load window icon from IconResource."); |
@@ -1953,10 +2162,15 @@ static HRESULT ParseWindow( | |||
1953 | 2162 | ||
1954 | // Get the optional window icon from a file. | 2163 | // Get the optional window icon from a file. |
1955 | hr = XmlGetAttribute(pixn, L"IconFile", &bstr); | 2164 | hr = XmlGetAttribute(pixn, L"IconFile", &bstr); |
1956 | ThmExitOnFailure(hr, "Failed to get window IconFile attribute."); | 2165 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window IconFile attribute."); |
1957 | 2166 | ||
1958 | if (S_OK == hr) | 2167 | if (fXmlFound) |
1959 | { | 2168 | { |
2169 | if (pTheme->hIcon) | ||
2170 | { | ||
2171 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Window/@IconFile can't be specified with IconResource."); | ||
2172 | } | ||
2173 | |||
1960 | if (wzRelativePath) | 2174 | if (wzRelativePath) |
1961 | { | 2175 | { |
1962 | hr = PathConcat(wzRelativePath, bstr, &sczIconFile); | 2176 | hr = PathConcat(wzRelativePath, bstr, &sczIconFile); |
@@ -1974,48 +2188,37 @@ static HRESULT ParseWindow( | |||
1974 | ReleaseNullBSTR(bstr); | 2188 | ReleaseNullBSTR(bstr); |
1975 | } | 2189 | } |
1976 | 2190 | ||
1977 | hr = XmlGetAttributeNumber(pixn, L"SourceX", reinterpret_cast<DWORD*>(&pTheme->nSourceX)); | 2191 | hr = ParseSourceXY(pixn, NULL != pTheme->hImage, &pTheme->nSourceX, &pTheme->nSourceY); |
1978 | if (S_FALSE == hr) | 2192 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window SourceX and SourceY attributes."); |
1979 | { | ||
1980 | pTheme->nSourceX = -1; | ||
1981 | } | ||
1982 | ThmExitOnFailure(hr, "Failed to get window SourceX attribute."); | ||
1983 | |||
1984 | hr = XmlGetAttributeNumber(pixn, L"SourceY", reinterpret_cast<DWORD*>(&pTheme->nSourceY)); | ||
1985 | if (S_FALSE == hr) | ||
1986 | { | ||
1987 | pTheme->nSourceY = -1; | ||
1988 | } | ||
1989 | ThmExitOnFailure(hr, "Failed to get window SourceY attribute."); | ||
1990 | 2193 | ||
1991 | // Parse the optional window style. | 2194 | // Parse the optional window style. |
1992 | hr = XmlGetAttributeNumberBase(pixn, L"HexStyle", 16, &pTheme->dwStyle); | 2195 | hr = XmlGetAttributeNumberBase(pixn, L"HexStyle", 16, &pTheme->dwStyle); |
1993 | ThmExitOnFailure(hr, "Failed to get theme window style (Window@HexStyle) attribute."); | 2196 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get theme window style (Window@HexStyle) attribute."); |
1994 | 2197 | ||
1995 | if (S_FALSE == hr) | 2198 | if (!fXmlFound) |
1996 | { | 2199 | { |
1997 | pTheme->dwStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU; | 2200 | pTheme->dwStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION; |
1998 | pTheme->dwStyle |= (0 <= pTheme->nSourceX && 0 <= pTheme->nSourceY) ? WS_POPUP : WS_OVERLAPPED; | 2201 | pTheme->dwStyle |= (0 <= pTheme->nSourceX && 0 <= pTheme->nSourceY) ? WS_POPUP : WS_OVERLAPPED; |
1999 | } | 2202 | } |
2000 | 2203 | ||
2001 | hr = XmlGetAttributeNumber(pixn, L"StringId", reinterpret_cast<DWORD*>(&pTheme->uStringId)); | 2204 | hr = XmlGetAttributeUInt32(pixn, L"StringId", reinterpret_cast<DWORD*>(&pTheme->uStringId)); |
2002 | ThmExitOnFailure(hr, "Failed to get window StringId attribute."); | 2205 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window StringId attribute."); |
2003 | 2206 | ||
2004 | if (S_FALSE == hr) | 2207 | if (!fXmlFound) |
2005 | { | 2208 | { |
2006 | pTheme->uStringId = UINT_MAX; | 2209 | pTheme->uStringId = UINT_MAX; |
2210 | } | ||
2211 | else if (UINT_MAX == pTheme->uStringId) | ||
2212 | { | ||
2213 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Invalid StringId: %u", pTheme->uStringId); | ||
2214 | } | ||
2007 | 2215 | ||
2008 | hr = XmlGetAttribute(pixn, L"Caption", &bstr); | 2216 | hr = XmlGetAttributeEx(pixn, L"Caption", &pTheme->sczCaption); |
2009 | ThmExitOnFailure(hr, "Failed to get window Caption attribute."); | 2217 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get window Caption attribute."); |
2010 | |||
2011 | if (S_FALSE == hr) | ||
2012 | { | ||
2013 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
2014 | ThmExitOnRootFailure(hr, "Window elements must contain the Caption or StringId attribute."); | ||
2015 | } | ||
2016 | 2218 | ||
2017 | hr = StrAllocString(&pTheme->sczCaption, bstr, 0); | 2219 | if (fXmlFound && UINT_MAX != pTheme->uStringId || !fXmlFound && UINT_MAX == pTheme->uStringId) |
2018 | ThmExitOnFailure(hr, "Failed to copy window Caption attribute."); | 2220 | { |
2221 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Window elements must contain either the Caption or StringId attribute."); | ||
2019 | } | 2222 | } |
2020 | 2223 | ||
2021 | // Parse any image lists. | 2224 | // Parse any image lists. |
@@ -2049,6 +2252,7 @@ static HRESULT ParseFonts( | |||
2049 | IXMLDOMNode* pixn = NULL; | 2252 | IXMLDOMNode* pixn = NULL; |
2050 | BSTR bstrName = NULL; | 2253 | BSTR bstrName = NULL; |
2051 | DWORD dwId = 0; | 2254 | DWORD dwId = 0; |
2255 | BOOL fXmlFound = FALSE; | ||
2052 | COLORREF crForeground = THEME_INVISIBLE_COLORREF; | 2256 | COLORREF crForeground = THEME_INVISIBLE_COLORREF; |
2053 | COLORREF crBackground = THEME_INVISIBLE_COLORREF; | 2257 | COLORREF crBackground = THEME_INVISIBLE_COLORREF; |
2054 | DWORD dwSystemForegroundColor = FALSE; | 2258 | DWORD dwSystemForegroundColor = FALSE; |
@@ -2062,7 +2266,7 @@ static HRESULT ParseFonts( | |||
2062 | 2266 | ||
2063 | if (!pTheme->cFonts) | 2267 | if (!pTheme->cFonts) |
2064 | { | 2268 | { |
2065 | ExitFunction1(hr = S_OK); | 2269 | ThmExitOnRootFailure(hr = E_INVALIDDATA, "No font elements found."); |
2066 | } | 2270 | } |
2067 | 2271 | ||
2068 | pTheme->rgFonts = static_cast<THEME_FONT*>(MemAlloc(sizeof(THEME_FONT) * pTheme->cFonts, TRUE)); | 2272 | pTheme->rgFonts = static_cast<THEME_FONT*>(MemAlloc(sizeof(THEME_FONT) * pTheme->cFonts, TRUE)); |
@@ -2070,66 +2274,52 @@ static HRESULT ParseFonts( | |||
2070 | 2274 | ||
2071 | while (S_OK == (hr = XmlNextElement(pixnl, &pixn, NULL))) | 2275 | while (S_OK == (hr = XmlNextElement(pixnl, &pixn, NULL))) |
2072 | { | 2276 | { |
2073 | hr = XmlGetAttributeNumber(pixn, L"Id", &dwId); | 2277 | hr = GetAttributeFontId(pixn, L"Id", &dwId); |
2074 | if (S_FALSE == hr) | 2278 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find font id."); |
2075 | { | ||
2076 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
2077 | } | ||
2078 | ThmExitOnFailure(hr, "Failed to find font id."); | ||
2079 | 2279 | ||
2080 | if (pTheme->cFonts <= dwId) | 2280 | if (pTheme->cFonts <= dwId) |
2081 | { | 2281 | { |
2082 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2282 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Invalid theme font id: %u.", dwId); |
2083 | ThmExitOnRootFailure(hr, "Invalid theme font id."); | ||
2084 | } | 2283 | } |
2085 | 2284 | ||
2086 | THEME_FONT* pFont = pTheme->rgFonts + dwId; | 2285 | THEME_FONT* pFont = pTheme->rgFonts + dwId; |
2087 | if (pFont->cFontInstances) | 2286 | if (pFont->cFontInstances) |
2088 | { | 2287 | { |
2089 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2288 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Theme font id duplicated."); |
2090 | ThmExitOnRootFailure(hr, "Theme font id duplicated."); | ||
2091 | } | 2289 | } |
2092 | 2290 | ||
2093 | pFont->lfQuality = CLEARTYPE_QUALITY; | 2291 | pFont->lfQuality = CLEARTYPE_QUALITY; |
2094 | 2292 | ||
2095 | hr = XmlGetText(pixn, &bstrName); | 2293 | hr = XmlGetText(pixn, &bstrName); |
2096 | if (S_FALSE == hr) | 2294 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to get font name."); |
2097 | { | ||
2098 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
2099 | } | ||
2100 | ThmExitOnFailure(hr, "Failed to get font name."); | ||
2101 | 2295 | ||
2102 | hr = StrAllocString(&pFont->sczFaceName, bstrName, 0); | 2296 | hr = StrAllocString(&pFont->sczFaceName, bstrName, 0); |
2103 | ThmExitOnFailure(hr, "Failed to copy font name."); | 2297 | ThmExitOnFailure(hr, "Failed to copy font name."); |
2104 | 2298 | ||
2105 | hr = XmlGetAttributeNumber(pixn, L"Height", reinterpret_cast<DWORD*>(&pFont->lfHeight)); | 2299 | hr = XmlGetAttributeInt32(pixn, L"Height", reinterpret_cast<int*>(&pFont->lfHeight)); |
2106 | if (S_FALSE == hr) | 2300 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find font height attribute."); |
2107 | { | 2301 | |
2108 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2302 | hr = XmlGetAttributeInt32(pixn, L"Weight", reinterpret_cast<int*>(&pFont->lfWeight)); |
2109 | } | 2303 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find font weight attribute."); |
2110 | ThmExitOnFailure(hr, "Failed to find font height attribute."); | ||
2111 | 2304 | ||
2112 | hr = XmlGetAttributeNumber(pixn, L"Weight", reinterpret_cast<DWORD*>(&pFont->lfWeight)); | 2305 | if (!fXmlFound) |
2113 | if (S_FALSE == hr) | ||
2114 | { | 2306 | { |
2115 | pFont->lfWeight = FW_DONTCARE; | 2307 | pFont->lfWeight = FW_DONTCARE; |
2116 | hr = S_OK; | ||
2117 | } | 2308 | } |
2118 | ThmExitOnFailure(hr, "Failed to find font weight attribute."); | ||
2119 | 2309 | ||
2120 | hr = XmlGetYesNoAttribute(pixn, L"Underline", reinterpret_cast<BOOL*>(&pFont->lfUnderline)); | 2310 | hr = XmlGetYesNoAttribute(pixn, L"Underline", reinterpret_cast<BOOL*>(&pFont->lfUnderline)); |
2121 | if (E_NOTFOUND == hr) | 2311 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find font underline attribute."); |
2312 | |||
2313 | if (!fXmlFound) | ||
2122 | { | 2314 | { |
2123 | pFont->lfUnderline = FALSE; | 2315 | pFont->lfUnderline = FALSE; |
2124 | hr = S_OK; | ||
2125 | } | 2316 | } |
2126 | ThmExitOnFailure(hr, "Failed to find font underline attribute."); | ||
2127 | 2317 | ||
2128 | hr = GetFontColor(pixn, L"Foreground", &crForeground, &dwSystemForegroundColor); | 2318 | hr = GetFontColor(pixn, L"Foreground", &crForeground, &dwSystemForegroundColor); |
2129 | ThmExitOnFailure(hr, "Failed to find font foreground color."); | 2319 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find font foreground color."); |
2130 | 2320 | ||
2131 | hr = GetFontColor(pixn, L"Background", &crBackground, &dwSystemBackgroundColor); | 2321 | hr = GetFontColor(pixn, L"Background", &crBackground, &dwSystemBackgroundColor); |
2132 | ThmExitOnFailure(hr, "Failed to find font background color."); | 2322 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find font background color."); |
2133 | 2323 | ||
2134 | pFont->crForeground = crForeground; | 2324 | pFont->crForeground = crForeground; |
2135 | if (THEME_INVISIBLE_COLORREF != pFont->crForeground) | 2325 | if (THEME_INVISIBLE_COLORREF != pFont->crForeground) |
@@ -2173,16 +2363,18 @@ static HRESULT GetFontColor( | |||
2173 | { | 2363 | { |
2174 | HRESULT hr = S_OK; | 2364 | HRESULT hr = S_OK; |
2175 | BSTR bstr = NULL; | 2365 | BSTR bstr = NULL; |
2366 | BOOL fXmlFound = FALSE; | ||
2176 | 2367 | ||
2177 | *pdwSystemColor = 0; | 2368 | *pdwSystemColor = 0; |
2178 | 2369 | ||
2179 | hr = XmlGetAttribute(pixn, wzAttributeName, &bstr); | 2370 | hr = XmlGetAttribute(pixn, wzAttributeName, &bstr); |
2180 | if (S_FALSE == hr) | 2371 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find font %ls color.", wzAttributeName); |
2372 | |||
2373 | if (!fXmlFound) | ||
2181 | { | 2374 | { |
2182 | *pColorRef = THEME_INVISIBLE_COLORREF; | 2375 | *pColorRef = THEME_INVISIBLE_COLORREF; |
2183 | ExitFunction1(hr = S_OK); | 2376 | ExitFunction1(hr = E_NOTFOUND); |
2184 | } | 2377 | } |
2185 | ThmExitOnFailure(hr, "Failed to find font %ls color.", wzAttributeName); | ||
2186 | 2378 | ||
2187 | if (pdwSystemColor) | 2379 | if (pdwSystemColor) |
2188 | { | 2380 | { |
@@ -2220,7 +2412,12 @@ static HRESULT GetFontColor( | |||
2220 | } | 2412 | } |
2221 | else | 2413 | else |
2222 | { | 2414 | { |
2223 | *pColorRef = wcstoul(bstr, NULL, 16); | 2415 | *pColorRef = ::wcstoul(bstr, NULL, 16); |
2416 | |||
2417 | if (THEME_INVISIBLE_COLORREF == *pColorRef) | ||
2418 | { | ||
2419 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Invalid %ls value: %ls.", wzAttributeName, bstr); | ||
2420 | } | ||
2224 | } | 2421 | } |
2225 | 2422 | ||
2226 | if (*pdwSystemColor) | 2423 | if (*pdwSystemColor) |
@@ -2248,6 +2445,7 @@ static HRESULT ParsePages( | |||
2248 | BSTR bstrType = NULL; | 2445 | BSTR bstrType = NULL; |
2249 | THEME_PAGE* pPage = NULL; | 2446 | THEME_PAGE* pPage = NULL; |
2250 | DWORD iPage = 0; | 2447 | DWORD iPage = 0; |
2448 | BOOL fXmlFound = FALSE; | ||
2251 | 2449 | ||
2252 | hr = XmlSelectNodes(pElement, L"Page", &pixnl); | 2450 | hr = XmlSelectNodes(pElement, L"Page", &pixnl); |
2253 | ThmExitOnFailure(hr, "Failed to find page elements."); | 2451 | ThmExitOnFailure(hr, "Failed to find page elements."); |
@@ -2270,11 +2468,7 @@ static HRESULT ParsePages( | |||
2270 | pPage->wId = static_cast<WORD>(iPage + 1); | 2468 | pPage->wId = static_cast<WORD>(iPage + 1); |
2271 | 2469 | ||
2272 | hr = XmlGetAttributeEx(pixn, L"Name", &pPage->sczName); | 2470 | hr = XmlGetAttributeEx(pixn, L"Name", &pPage->sczName); |
2273 | if (E_NOTFOUND == hr) | 2471 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying page Name."); |
2274 | { | ||
2275 | hr = S_OK; | ||
2276 | } | ||
2277 | ThmExitOnFailure(hr, "Failed when querying page Name."); | ||
2278 | 2472 | ||
2279 | hr = ParseControls(hModule, wzRelativePath, pixn, pTheme, NULL, pPage); | 2473 | hr = ParseControls(hModule, wzRelativePath, pixn, pTheme, NULL, pPage); |
2280 | ThmExitOnFailure(hr, "Failed to parse page controls."); | 2474 | ThmExitOnFailure(hr, "Failed to parse page controls."); |
@@ -2314,9 +2508,10 @@ static HRESULT ParseImageLists( | |||
2314 | IXMLDOMNode* pixnImage = NULL; | 2508 | IXMLDOMNode* pixnImage = NULL; |
2315 | DWORD dwImageListIndex = 0; | 2509 | DWORD dwImageListIndex = 0; |
2316 | DWORD dwImageCount = 0; | 2510 | DWORD dwImageCount = 0; |
2511 | THEME_IMAGELIST* pThemeImageList = NULL; | ||
2512 | BOOL fXmlFound = FALSE; | ||
2317 | HBITMAP hBitmap = NULL; | 2513 | HBITMAP hBitmap = NULL; |
2318 | BITMAP bm = { }; | 2514 | BITMAP bm = { }; |
2319 | BSTR bstr = NULL; | ||
2320 | DWORD i = 0; | 2515 | DWORD i = 0; |
2321 | int iRetVal = 0; | 2516 | int iRetVal = 0; |
2322 | 2517 | ||
@@ -2336,15 +2531,12 @@ static HRESULT ParseImageLists( | |||
2336 | 2531 | ||
2337 | while (S_OK == (hr = XmlNextElement(pixnlImageLists, &pixnImageList, NULL))) | 2532 | while (S_OK == (hr = XmlNextElement(pixnlImageLists, &pixnImageList, NULL))) |
2338 | { | 2533 | { |
2339 | hr = XmlGetAttribute(pixnImageList, L"Name", &bstr); | 2534 | pThemeImageList = pTheme->rgImageLists + dwImageListIndex; |
2340 | if (S_FALSE == hr) | 2535 | ++dwImageListIndex; |
2341 | { | 2536 | i = 0; |
2342 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
2343 | } | ||
2344 | ThmExitOnFailure(hr, "Failed to find ImageList/@Name attribute."); | ||
2345 | 2537 | ||
2346 | hr = StrAllocString(&pTheme->rgImageLists[dwImageListIndex].sczName, bstr, 0); | 2538 | hr = XmlGetAttributeEx(pixnImageList, L"Name", &pThemeImageList->sczName); |
2347 | ThmExitOnFailure(hr, "Failed to make copy of ImageList name."); | 2539 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find ImageList/@Name attribute."); |
2348 | 2540 | ||
2349 | hr = XmlSelectNodes(pixnImageList, L"Image", &pixnlImages); | 2541 | hr = XmlSelectNodes(pixnImageList, L"Image", &pixnlImages); |
2350 | ThmExitOnFailure(hr, "Failed to select child Image nodes."); | 2542 | ThmExitOnFailure(hr, "Failed to select child Image nodes."); |
@@ -2352,38 +2544,44 @@ static HRESULT ParseImageLists( | |||
2352 | hr = pixnlImages->get_length(reinterpret_cast<long*>(&dwImageCount)); | 2544 | hr = pixnlImages->get_length(reinterpret_cast<long*>(&dwImageCount)); |
2353 | ThmExitOnFailure(hr, "Failed to count the number of images in list."); | 2545 | ThmExitOnFailure(hr, "Failed to count the number of images in list."); |
2354 | 2546 | ||
2355 | if (0 < dwImageCount) | 2547 | if (!dwImageCount) |
2356 | { | 2548 | { |
2357 | i = 0; | 2549 | ThmExitOnRootFailure(hr = E_INVALIDDATA, "ImageList '%ls' has no images.", pThemeImageList->sczName); |
2358 | while (S_OK == (hr = XmlNextElement(pixnlImages, &pixnImage, NULL))) | 2550 | } |
2551 | |||
2552 | while (S_OK == (hr = XmlNextElement(pixnlImages, &pixnImage, NULL))) | ||
2553 | { | ||
2554 | if (hBitmap) | ||
2359 | { | 2555 | { |
2360 | if (hBitmap) | 2556 | ::DeleteObject(hBitmap); |
2361 | { | 2557 | hBitmap = NULL; |
2362 | ::DeleteObject(hBitmap); | 2558 | } |
2363 | hBitmap = NULL; | ||
2364 | } | ||
2365 | hr = ParseImage(hModule, wzRelativePath, pixnImage, &hBitmap); | ||
2366 | ThmExitOnFailure(hr, "Failed to parse image: %u", i); | ||
2367 | 2559 | ||
2368 | if (0 == i) | 2560 | hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pixnImage, &hBitmap); |
2369 | { | 2561 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to parse image list: '%ls', item: %u", pThemeImageList->sczName, i); |
2370 | ::GetObjectW(hBitmap, sizeof(BITMAP), &bm); | ||
2371 | 2562 | ||
2372 | pTheme->rgImageLists[dwImageListIndex].hImageList = ImageList_Create(bm.bmWidth, bm.bmHeight, ILC_COLOR24, dwImageCount, 0); | 2563 | if (!fXmlFound) |
2373 | ThmExitOnNullWithLastError(pTheme->rgImageLists[dwImageListIndex].hImageList, hr, "Failed to create image list."); | 2564 | { |
2374 | } | 2565 | ThmExitWithRootFailure(hr, E_INVALIDDATA, "Image list: '%ls', item %u didn't specify an image.", pThemeImageList->sczName, i); |
2566 | } | ||
2375 | 2567 | ||
2376 | iRetVal = ImageList_Add(pTheme->rgImageLists[dwImageListIndex].hImageList, hBitmap, NULL); | 2568 | if (0 == i) |
2377 | if (-1 == iRetVal) | 2569 | { |
2378 | { | 2570 | ::GetObjectW(hBitmap, sizeof(BITMAP), &bm); |
2379 | ThmExitWithLastError(hr, "Failed to add image %u to image list.", i); | ||
2380 | } | ||
2381 | 2571 | ||
2382 | ++i; | 2572 | pThemeImageList->hImageList = ImageList_Create(bm.bmWidth, bm.bmHeight, ILC_COLOR24, dwImageCount, 0); |
2383 | ReleaseNullObject(pixnImage); | 2573 | ThmExitOnNullWithLastError(pThemeImageList->hImageList, hr, "Failed to create image list."); |
2384 | } | 2574 | } |
2575 | |||
2576 | iRetVal = ImageList_Add(pThemeImageList->hImageList, hBitmap, NULL); | ||
2577 | if (-1 == iRetVal) | ||
2578 | { | ||
2579 | ThmExitWithLastError(hr, "Failed to add image %u to image list.", i); | ||
2580 | } | ||
2581 | |||
2582 | ++i; | ||
2583 | ReleaseNullObject(pixnImage); | ||
2385 | } | 2584 | } |
2386 | ++dwImageListIndex; | ||
2387 | 2585 | ||
2388 | ReleaseNullObject(pixnlImages); | 2586 | ReleaseNullObject(pixnlImages); |
2389 | ReleaseNullObject(pixnImageList); | 2587 | ReleaseNullObject(pixnImageList); |
@@ -2394,7 +2592,6 @@ LExit: | |||
2394 | { | 2592 | { |
2395 | ::DeleteObject(hBitmap); | 2593 | ::DeleteObject(hBitmap); |
2396 | } | 2594 | } |
2397 | ReleaseBSTR(bstr); | ||
2398 | ReleaseObject(pixnlImageLists); | 2595 | ReleaseObject(pixnlImageLists); |
2399 | ReleaseObject(pixnImageList); | 2596 | ReleaseObject(pixnImageList); |
2400 | ReleaseObject(pixnlImages); | 2597 | ReleaseObject(pixnlImages); |
@@ -2572,7 +2769,7 @@ static HRESULT ParseControls( | |||
2572 | THEME_CONTROL* pControl = *prgControls + iControl; | 2769 | THEME_CONTROL* pControl = *prgControls + iControl; |
2573 | pControl->type = type; | 2770 | pControl->type = type; |
2574 | 2771 | ||
2575 | hr = ParseControl(hModule, wzRelativePath, pixn, pTheme, pControl, pPage); | 2772 | hr = ParseControl(hModule, wzRelativePath, pixn, bstrType, pTheme, pControl, pPage); |
2576 | ThmExitOnFailure(hr, "Failed to parse control."); | 2773 | ThmExitOnFailure(hr, "Failed to parse control."); |
2577 | 2774 | ||
2578 | if (pPage) | 2775 | if (pPage) |
@@ -2608,154 +2805,108 @@ static HRESULT ParseControl( | |||
2608 | __in_opt HMODULE hModule, | 2805 | __in_opt HMODULE hModule, |
2609 | __in_opt LPCWSTR wzRelativePath, | 2806 | __in_opt LPCWSTR wzRelativePath, |
2610 | __in IXMLDOMNode* pixn, | 2807 | __in IXMLDOMNode* pixn, |
2808 | __in_z LPCWSTR wzElementName, | ||
2611 | __in THEME* pTheme, | 2809 | __in THEME* pTheme, |
2612 | __in THEME_CONTROL* pControl, | 2810 | __in THEME_CONTROL* pControl, |
2613 | __in_opt THEME_PAGE* pPage | 2811 | __in_opt THEME_PAGE* pPage |
2614 | ) | 2812 | ) |
2615 | { | 2813 | { |
2616 | HRESULT hr = S_OK; | 2814 | HRESULT hr = S_OK; |
2617 | BOOL fFound = FALSE; | 2815 | BOOL fXmlFound = FALSE; |
2618 | DWORD dwValue = 0; | 2816 | DWORD dwValue = 0; |
2817 | int nValue = 0; | ||
2619 | BOOL fValue = FALSE; | 2818 | BOOL fValue = FALSE; |
2620 | BSTR bstrText = NULL; | 2819 | BSTR bstrText = NULL; |
2621 | BOOL fAnyTextChildren = FALSE; | 2820 | BOOL fAnyTextChildren = FALSE; |
2622 | BOOL fAnyNoteChildren = FALSE; | 2821 | BOOL fAnyNoteChildren = FALSE; |
2623 | BOOL fSkipDimensions = FALSE; | ||
2624 | 2822 | ||
2625 | InitializeThemeControl(pControl); | 2823 | InitializeThemeControl(pControl); |
2626 | 2824 | ||
2627 | hr = XmlGetAttributeEx(pixn, L"Name", &pControl->sczName); | 2825 | hr = XmlGetAttributeEx(pixn, L"Name", &pControl->sczName); |
2628 | if (E_NOTFOUND == hr) | 2826 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control Name attribute."); |
2629 | { | ||
2630 | hr = S_OK; | ||
2631 | } | ||
2632 | ThmExitOnFailure(hr, "Failed when querying control Name attribute."); | ||
2633 | 2827 | ||
2634 | hr = XmlGetAttributeEx(pixn, L"EnableCondition", &pControl->sczEnableCondition); | 2828 | hr = XmlGetAttributeEx(pixn, L"EnableCondition", &pControl->sczEnableCondition); |
2635 | if (E_NOTFOUND == hr) | 2829 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control EnableCondition attribute."); |
2636 | { | ||
2637 | hr = S_OK; | ||
2638 | } | ||
2639 | ThmExitOnFailure(hr, "Failed when querying control EnableCondition attribute."); | ||
2640 | 2830 | ||
2641 | hr = XmlGetAttributeEx(pixn, L"VisibleCondition", &pControl->sczVisibleCondition); | 2831 | hr = XmlGetAttributeEx(pixn, L"VisibleCondition", &pControl->sczVisibleCondition); |
2642 | if (E_NOTFOUND == hr) | 2832 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control VisibleCondition attribute."); |
2643 | { | ||
2644 | hr = S_OK; | ||
2645 | } | ||
2646 | ThmExitOnFailure(hr, "Failed when querying control VisibleCondition attribute."); | ||
2647 | |||
2648 | if (!fSkipDimensions) | ||
2649 | { | ||
2650 | hr = XmlGetAttributeNumber(pixn, L"X", &dwValue); | ||
2651 | if (S_FALSE == hr) | ||
2652 | { | ||
2653 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
2654 | } | ||
2655 | ThmExitOnFailure(hr, "Failed to find control X attribute."); | ||
2656 | 2833 | ||
2657 | pControl->nX = pControl->nDefaultDpiX = dwValue; | 2834 | hr = GetAttributeCoordinateOrDimension(pixn, L"X", &nValue); |
2835 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find control X attribute."); | ||
2658 | 2836 | ||
2659 | hr = XmlGetAttributeNumber(pixn, L"Y", &dwValue); | 2837 | pControl->nX = pControl->nDefaultDpiX = nValue; |
2660 | if (S_FALSE == hr) | ||
2661 | { | ||
2662 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
2663 | } | ||
2664 | ThmExitOnFailure(hr, "Failed to find control Y attribute."); | ||
2665 | 2838 | ||
2666 | pControl->nY = pControl->nDefaultDpiY = dwValue; | 2839 | hr = GetAttributeCoordinateOrDimension(pixn, L"Y", &nValue); |
2840 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find control Y attribute."); | ||
2667 | 2841 | ||
2668 | hr = XmlGetAttributeNumber(pixn, L"Height", &dwValue); | 2842 | pControl->nY = pControl->nDefaultDpiY = nValue; |
2669 | if (S_FALSE == hr) | ||
2670 | { | ||
2671 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
2672 | } | ||
2673 | ThmExitOnFailure(hr, "Failed to find control Height attribute."); | ||
2674 | 2843 | ||
2675 | pControl->nHeight = pControl->nDefaultDpiHeight = dwValue; | 2844 | hr = GetAttributeCoordinateOrDimension(pixn, L"Height", &nValue); |
2845 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find control Height attribute."); | ||
2676 | 2846 | ||
2677 | hr = XmlGetAttributeNumber(pixn, L"Width", &dwValue); | 2847 | pControl->nHeight = pControl->nDefaultDpiHeight = nValue; |
2678 | if (S_FALSE == hr) | ||
2679 | { | ||
2680 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | ||
2681 | } | ||
2682 | ThmExitOnFailure(hr, "Failed to find control Width attribute."); | ||
2683 | 2848 | ||
2684 | pControl->nWidth = pControl->nDefaultDpiWidth = dwValue; | 2849 | hr = GetAttributeCoordinateOrDimension(pixn, L"Width", &nValue); |
2685 | } | 2850 | ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find control Width attribute."); |
2686 | 2851 | ||
2687 | // Parse the optional background resource image. | 2852 | pControl->nWidth = pControl->nDefaultDpiWidth = nValue; |
2688 | hr = ParseImage(hModule, wzRelativePath, pixn, &pControl->hImage); | ||
2689 | ThmExitOnFailure(hr, "Failed while parsing control image."); | ||
2690 | 2853 | ||
2691 | hr = XmlGetAttributeNumber(pixn, L"SourceX", reinterpret_cast<DWORD*>(&pControl->nSourceX)); | 2854 | switch (pControl->type) |
2692 | ThmExitOnFailure(hr, "Failed when querying control SourceX attribute."); | 2855 | { |
2856 | case THEME_CONTROL_TYPE_COMMANDLINK: | ||
2857 | hr = ParseCommandLinkImage(hModule, wzRelativePath, pixn, pControl); | ||
2858 | ThmExitOnFailure(hr, "Failed while parsing CommandLink image."); | ||
2859 | break; | ||
2860 | case THEME_CONTROL_TYPE_BUTTON: | ||
2861 | case THEME_CONTROL_TYPE_IMAGE: | ||
2862 | case THEME_CONTROL_TYPE_PROGRESSBAR: | ||
2863 | hr = ParseOwnerDrawImage(hModule, wzRelativePath, pTheme, pixn, pControl); | ||
2864 | ThmExitOnFailure(hr, "Failed while parsing OwnerDraw image."); | ||
2865 | break; | ||
2866 | default: | ||
2867 | ThmExitOnUnexpectedAttribute(hr, pixn, wzElementName, L"ImageId"); | ||
2868 | ThmExitOnUnexpectedAttribute(hr, pixn, wzElementName, L"ImageFile"); | ||
2869 | ThmExitOnUnexpectedAttribute(hr, pixn, wzElementName, L"ImageResource"); | ||
2870 | ThmExitOnUnexpectedAttribute(hr, pixn, wzElementName, L"SourceX"); | ||
2871 | ThmExitOnUnexpectedAttribute(hr, pixn, wzElementName, L"SourceY"); | ||
2872 | break; | ||
2873 | } | ||
2693 | 2874 | ||
2694 | hr = XmlGetAttributeNumber(pixn, L"SourceY", reinterpret_cast<DWORD*>(&pControl->nSourceY)); | ||
2695 | ThmExitOnFailure(hr, "Failed when querying control SourceY attribute."); | ||
2696 | 2875 | ||
2697 | hr = XmlGetAttributeNumber(pixn, L"FontId", &pControl->dwFontId); | 2876 | hr = GetAttributeFontId(pixn, L"FontId", &pControl->dwFontId); |
2698 | ThmExitOnFailure(hr, "Failed when querying control FontId attribute."); | 2877 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control FontId attribute."); |
2699 | 2878 | ||
2700 | // Parse the optional window style. | 2879 | // Parse the optional window style. |
2701 | hr = XmlGetAttributeNumberBase(pixn, L"HexStyle", 16, &pControl->dwStyle); | 2880 | hr = XmlGetAttributeNumberBase(pixn, L"HexStyle", 16, &pControl->dwStyle); |
2702 | ThmExitOnFailure(hr, "Failed when querying control HexStyle attribute."); | 2881 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control HexStyle attribute."); |
2703 | 2882 | ||
2704 | // Parse the tabstop bit "shortcut nomenclature", this could have been set with the style above. | 2883 | // Parse the tabstop bit "shortcut nomenclature", this could have been set with the style above. |
2705 | hr = XmlGetYesNoAttribute(pixn, L"TabStop", &fValue); | 2884 | hr = XmlGetYesNoAttribute(pixn, L"TabStop", &fValue); |
2706 | if (E_NOTFOUND == hr) | 2885 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control TabStop attribute."); |
2707 | { | ||
2708 | hr = S_OK; | ||
2709 | } | ||
2710 | else | ||
2711 | { | ||
2712 | ThmExitOnFailure(hr, "Failed when querying control TabStop attribute."); | ||
2713 | 2886 | ||
2714 | if (fValue) | 2887 | if (fXmlFound && fValue) |
2715 | { | 2888 | { |
2716 | pControl->dwStyle |= WS_TABSTOP; | 2889 | pControl->dwStyle |= WS_TABSTOP; |
2717 | } | ||
2718 | } | 2890 | } |
2719 | 2891 | ||
2720 | hr = XmlGetYesNoAttribute(pixn, L"Visible", &fValue); | 2892 | hr = XmlGetYesNoAttribute(pixn, L"Visible", &fValue); |
2721 | if (E_NOTFOUND == hr) | 2893 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control Visible attribute."); |
2722 | { | ||
2723 | hr = S_OK; | ||
2724 | } | ||
2725 | else | ||
2726 | { | ||
2727 | ThmExitOnFailure(hr, "Failed when querying control Visible attribute."); | ||
2728 | 2894 | ||
2729 | if (fValue) | 2895 | if (fXmlFound && fValue) |
2730 | { | 2896 | { |
2731 | pControl->dwStyle |= WS_VISIBLE; | 2897 | pControl->dwStyle |= WS_VISIBLE; |
2732 | } | ||
2733 | } | 2898 | } |
2734 | 2899 | ||
2735 | hr = XmlGetYesNoAttribute(pixn, L"HideWhenDisabled", &fValue); | 2900 | hr = XmlGetYesNoAttribute(pixn, L"HideWhenDisabled", &fValue); |
2736 | if (E_NOTFOUND == hr) | 2901 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control HideWhenDisabled attribute."); |
2737 | { | ||
2738 | hr = S_OK; | ||
2739 | } | ||
2740 | else | ||
2741 | { | ||
2742 | ThmExitOnFailure(hr, "Failed when querying control HideWhenDisabled attribute."); | ||
2743 | 2902 | ||
2744 | if (fValue) | 2903 | if (fXmlFound && fValue) |
2745 | { | 2904 | { |
2746 | pControl->dwInternalStyle |= INTERNAL_CONTROL_STYLE_HIDE_WHEN_DISABLED; | 2905 | pControl->dwInternalStyle |= INTERNAL_CONTROL_STYLE_HIDE_WHEN_DISABLED; |
2747 | } | ||
2748 | } | 2906 | } |
2749 | 2907 | ||
2750 | hr = XmlGetYesNoAttribute(pixn, L"DisableAutomaticBehavior", &pControl->fDisableVariableFunctionality); | 2908 | hr = XmlGetYesNoAttribute(pixn, L"DisableAutomaticBehavior", &pControl->fDisableVariableFunctionality); |
2751 | if (E_NOTFOUND == hr) | 2909 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control DisableAutomaticBehavior attribute."); |
2752 | { | ||
2753 | hr = S_OK; | ||
2754 | } | ||
2755 | else | ||
2756 | { | ||
2757 | ThmExitOnFailure(hr, "Failed when querying control DisableAutomaticBehavior attribute."); | ||
2758 | } | ||
2759 | 2910 | ||
2760 | hr = ParseActions(pixn, pControl); | 2911 | hr = ParseActions(pixn, pControl); |
2761 | ThmExitOnFailure(hr, "Failed to parse action nodes of the control."); | 2912 | ThmExitOnFailure(hr, "Failed to parse action nodes of the control."); |
@@ -2774,10 +2925,10 @@ static HRESULT ParseControl( | |||
2774 | 2925 | ||
2775 | if (!fAnyTextChildren && !fAnyNoteChildren) | 2926 | if (!fAnyTextChildren && !fAnyNoteChildren) |
2776 | { | 2927 | { |
2777 | hr = XmlGetAttributeNumber(pixn, L"StringId", &dwValue); | 2928 | hr = XmlGetAttributeUInt32(pixn, L"StringId", &dwValue); |
2778 | ThmExitOnOptionalXmlQueryFailure(hr, fFound, "Failed when querying control StringId attribute."); | 2929 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control StringId attribute."); |
2779 | 2930 | ||
2780 | if (fFound) | 2931 | if (fXmlFound) |
2781 | { | 2932 | { |
2782 | pControl->uStringId = dwValue; | 2933 | pControl->uStringId = dwValue; |
2783 | } | 2934 | } |
@@ -2787,9 +2938,9 @@ static HRESULT ParseControl( | |||
2787 | if (THEME_CONTROL_TYPE_BILLBOARD != pControl->type && THEME_CONTROL_TYPE_PANEL != pControl->type) | 2938 | if (THEME_CONTROL_TYPE_BILLBOARD != pControl->type && THEME_CONTROL_TYPE_PANEL != pControl->type) |
2788 | { | 2939 | { |
2789 | hr = XmlGetText(pixn, &bstrText); | 2940 | hr = XmlGetText(pixn, &bstrText); |
2790 | ThmExitOnOptionalXmlQueryFailure(hr, fFound, "Failed to get control inner text."); | 2941 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get control inner text."); |
2791 | 2942 | ||
2792 | if (fFound) | 2943 | if (fXmlFound) |
2793 | { | 2944 | { |
2794 | hr = StrAllocString(&pControl->sczText, bstrText, 0); | 2945 | hr = StrAllocString(&pControl->sczText, bstrText, 0); |
2795 | ThmExitOnFailure(hr, "Failed to copy control text."); | 2946 | ThmExitOnFailure(hr, "Failed to copy control text."); |
@@ -2803,115 +2954,93 @@ static HRESULT ParseControl( | |||
2803 | if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) | 2954 | if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) |
2804 | { | 2955 | { |
2805 | hr = XmlGetYesNoAttribute(pixn, L"Loop", &pControl->fBillboardLoops); | 2956 | hr = XmlGetYesNoAttribute(pixn, L"Loop", &pControl->fBillboardLoops); |
2806 | if (E_NOTFOUND == hr) | 2957 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying Billboard/@Loop attribute."); |
2807 | { | ||
2808 | hr = S_OK; | ||
2809 | } | ||
2810 | ThmExitOnFailure(hr, "Failed when querying Billboard/@Loop attribute."); | ||
2811 | 2958 | ||
2812 | pControl->wBillboardInterval = 5000; | 2959 | hr = XmlGetAttributeUInt16(pixn, L"Interval", &pControl->wBillboardInterval); |
2813 | hr = XmlGetAttributeNumber(pixn, L"Interval", &dwValue); | 2960 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying Billboard/@Interval attribute."); |
2814 | if (S_OK == hr && dwValue) | 2961 | |
2962 | if (!pControl->wBillboardInterval) | ||
2815 | { | 2963 | { |
2816 | pControl->wBillboardInterval = static_cast<WORD>(dwValue & 0xFFFF); | 2964 | pControl->wBillboardInterval = 5000; |
2817 | } | 2965 | } |
2818 | ThmExitOnFailure(hr, "Failed when querying Billboard/@Interval attribute."); | ||
2819 | 2966 | ||
2820 | hr = ParseBillboardPanels(hModule, wzRelativePath, pixn, pTheme, pControl, pPage); | 2967 | hr = ParseBillboardPanels(hModule, wzRelativePath, pixn, pTheme, pControl, pPage); |
2821 | ThmExitOnFailure(hr, "Failed to parse billboard children."); | 2968 | ThmExitOnFailure(hr, "Failed to parse billboard children."); |
2822 | } | 2969 | } |
2823 | else if (THEME_CONTROL_TYPE_COMMANDLINK == pControl->type) | ||
2824 | { | ||
2825 | hr = ParseIcon(hModule, wzRelativePath, pixn, &pControl->hIcon); | ||
2826 | ThmExitOnFailure(hr, "Failed while parsing control icon."); | ||
2827 | } | ||
2828 | else if (THEME_CONTROL_TYPE_EDITBOX == pControl->type) | 2970 | else if (THEME_CONTROL_TYPE_EDITBOX == pControl->type) |
2829 | { | 2971 | { |
2830 | hr = XmlGetYesNoAttribute(pixn, L"FileSystemAutoComplete", &fValue); | 2972 | hr = XmlGetYesNoAttribute(pixn, L"FileSystemAutoComplete", &fValue); |
2831 | if (E_NOTFOUND == hr) | 2973 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying Editbox/@FileSystemAutoComplete attribute."); |
2832 | { | ||
2833 | hr = S_OK; | ||
2834 | } | ||
2835 | else | ||
2836 | { | ||
2837 | ThmExitOnFailure(hr, "Failed when querying Editbox/@FileSystemAutoComplete attribute."); | ||
2838 | 2974 | ||
2839 | if (fValue) | 2975 | if (fXmlFound && fValue) |
2840 | { | 2976 | { |
2841 | pControl->dwInternalStyle |= INTERNAL_CONTROL_STYLE_FILESYSTEM_AUTOCOMPLETE; | 2977 | pControl->dwInternalStyle |= INTERNAL_CONTROL_STYLE_FILESYSTEM_AUTOCOMPLETE; |
2842 | } | ||
2843 | } | 2978 | } |
2844 | } | 2979 | } |
2845 | else if (THEME_CONTROL_TYPE_HYPERLINK == pControl->type || THEME_CONTROL_TYPE_BUTTON == pControl->type) | 2980 | else if (THEME_CONTROL_TYPE_HYPERLINK == pControl->type || THEME_CONTROL_TYPE_BUTTON == pControl->type) |
2846 | { | 2981 | { |
2847 | hr = XmlGetAttributeNumber(pixn, L"HoverFontId", &pControl->dwFontHoverId); | 2982 | hr = GetAttributeFontId(pixn, L"HoverFontId", &pControl->dwFontHoverId); |
2848 | ThmExitOnFailure(hr, "Failed when querying control HoverFontId attribute."); | 2983 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control HoverFontId attribute."); |
2849 | 2984 | ||
2850 | hr = XmlGetAttributeNumber(pixn, L"SelectedFontId", &pControl->dwFontSelectedId); | 2985 | hr = GetAttributeFontId(pixn, L"SelectedFontId", &pControl->dwFontSelectedId); |
2851 | ThmExitOnFailure(hr, "Failed when querying control SelectedFontId attribute."); | 2986 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control SelectedFontId attribute."); |
2852 | } | 2987 | } |
2853 | else if (THEME_CONTROL_TYPE_LABEL == pControl->type) | 2988 | else if (THEME_CONTROL_TYPE_LABEL == pControl->type) |
2854 | { | 2989 | { |
2855 | hr = XmlGetYesNoAttribute(pixn, L"Center", &fValue); | 2990 | hr = XmlGetYesNoAttribute(pixn, L"Center", &fValue); |
2856 | if (E_NOTFOUND == hr) | 2991 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying Label/@Center attribute."); |
2857 | { | 2992 | |
2858 | hr = S_OK; | 2993 | if (fXmlFound && fValue) |
2859 | } | ||
2860 | else if (fValue) | ||
2861 | { | 2994 | { |
2862 | pControl->dwStyle |= SS_CENTER; | 2995 | pControl->dwStyle |= SS_CENTER; |
2863 | } | 2996 | } |
2864 | ThmExitOnFailure(hr, "Failed when querying Label/@Center attribute."); | ||
2865 | 2997 | ||
2866 | hr = XmlGetYesNoAttribute(pixn, L"DisablePrefix", &fValue); | 2998 | hr = XmlGetYesNoAttribute(pixn, L"DisablePrefix", &fValue); |
2867 | if (E_NOTFOUND == hr) | 2999 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying Label/@DisablePrefix attribute."); |
2868 | { | 3000 | |
2869 | hr = S_OK; | 3001 | if (fXmlFound && fValue) |
2870 | } | ||
2871 | else if (fValue) | ||
2872 | { | 3002 | { |
2873 | pControl->dwStyle |= SS_NOPREFIX; | 3003 | pControl->dwStyle |= SS_NOPREFIX; |
2874 | } | 3004 | } |
2875 | ThmExitOnFailure(hr, "Failed when querying Label/@DisablePrefix attribute."); | ||
2876 | } | 3005 | } |
2877 | else if (THEME_CONTROL_TYPE_LISTVIEW == pControl->type) | 3006 | else if (THEME_CONTROL_TYPE_LISTVIEW == pControl->type) |
2878 | { | 3007 | { |
2879 | // Parse the optional extended window style. | 3008 | // Parse the optional extended window style. |
2880 | hr = XmlGetAttributeNumberBase(pixn, L"HexExtendedStyle", 16, &pControl->dwExtendedStyle); | 3009 | hr = XmlGetAttributeNumberBase(pixn, L"HexExtendedStyle", 16, &pControl->dwExtendedStyle); |
2881 | ThmExitOnFailure(hr, "Failed when querying ListView/@HexExtendedStyle attribute."); | 3010 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying ListView/@HexExtendedStyle attribute."); |
2882 | 3011 | ||
2883 | hr = XmlGetAttribute(pixn, L"ImageList", &bstrText); | 3012 | hr = XmlGetAttribute(pixn, L"ImageList", &bstrText); |
2884 | if (S_FALSE != hr) | 3013 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying ListView/@ImageList attribute."); |
2885 | { | ||
2886 | ThmExitOnFailure(hr, "Failed when querying ListView/@ImageList attribute."); | ||
2887 | 3014 | ||
3015 | if (fXmlFound) | ||
3016 | { | ||
2888 | hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[0]); | 3017 | hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[0]); |
2889 | ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageList for ListView.", bstrText); | 3018 | ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageList for ListView.", bstrText); |
2890 | } | 3019 | } |
2891 | 3020 | ||
2892 | hr = XmlGetAttribute(pixn, L"ImageListSmall", &bstrText); | 3021 | hr = XmlGetAttribute(pixn, L"ImageListSmall", &bstrText); |
2893 | if (S_FALSE != hr) | 3022 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying ListView/@ImageListSmall attribute."); |
2894 | { | ||
2895 | ThmExitOnFailure(hr, "Failed when querying ListView/@ImageListSmall attribute."); | ||
2896 | 3023 | ||
3024 | if (fXmlFound) | ||
3025 | { | ||
2897 | hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[1]); | 3026 | hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[1]); |
2898 | ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListSmall for ListView.", bstrText); | 3027 | ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListSmall for ListView.", bstrText); |
2899 | } | 3028 | } |
2900 | 3029 | ||
2901 | hr = XmlGetAttribute(pixn, L"ImageListState", &bstrText); | 3030 | hr = XmlGetAttribute(pixn, L"ImageListState", &bstrText); |
2902 | if (S_FALSE != hr) | 3031 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying ListView/@ImageListState attribute."); |
2903 | { | ||
2904 | ThmExitOnFailure(hr, "Failed when querying ListView/@ImageListState attribute."); | ||
2905 | 3032 | ||
3033 | if (fXmlFound) | ||
3034 | { | ||
2906 | hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[2]); | 3035 | hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[2]); |
2907 | ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListState for ListView.", bstrText); | 3036 | ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListState for ListView.", bstrText); |
2908 | } | 3037 | } |
2909 | 3038 | ||
2910 | hr = XmlGetAttribute(pixn, L"ImageListGroupHeader", &bstrText); | 3039 | hr = XmlGetAttribute(pixn, L"ImageListGroupHeader", &bstrText); |
2911 | if (S_FALSE != hr) | 3040 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying ListView/@ImageListGroupHeader attribute."); |
2912 | { | ||
2913 | ThmExitOnFailure(hr, "Failed when querying ListView/@ImageListGroupHeader attribute."); | ||
2914 | 3041 | ||
3042 | if (fXmlFound) | ||
3043 | { | ||
2915 | hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[3]); | 3044 | hr = FindImageList(pTheme, bstrText, &pControl->rghImageList[3]); |
2916 | ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListGroupHeader for ListView.", bstrText); | 3045 | ThmExitOnFailure(hr, "Failed to find image list %ls while setting ImageListGroupHeader for ListView.", bstrText); |
2917 | } | 3046 | } |
@@ -2927,11 +3056,7 @@ static HRESULT ParseControl( | |||
2927 | else if (THEME_CONTROL_TYPE_RADIOBUTTON == pControl->type) | 3056 | else if (THEME_CONTROL_TYPE_RADIOBUTTON == pControl->type) |
2928 | { | 3057 | { |
2929 | hr = XmlGetAttributeEx(pixn, L"Value", &pControl->sczValue); | 3058 | hr = XmlGetAttributeEx(pixn, L"Value", &pControl->sczValue); |
2930 | if (E_NOTFOUND == hr) | 3059 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying RadioButton/@Value attribute."); |
2931 | { | ||
2932 | hr = S_OK; | ||
2933 | } | ||
2934 | ThmExitOnFailure(hr, "Failed when querying RadioButton/@Value attribute."); | ||
2935 | } | 3060 | } |
2936 | else if (THEME_CONTROL_TYPE_TAB == pControl->type) | 3061 | else if (THEME_CONTROL_TYPE_TAB == pControl->type) |
2937 | { | 3062 | { |
@@ -2943,70 +3068,52 @@ static HRESULT ParseControl( | |||
2943 | pControl->dwStyle |= TVS_DISABLEDRAGDROP; | 3068 | pControl->dwStyle |= TVS_DISABLEDRAGDROP; |
2944 | 3069 | ||
2945 | hr = XmlGetYesNoAttribute(pixn, L"EnableDragDrop", &fValue); | 3070 | hr = XmlGetYesNoAttribute(pixn, L"EnableDragDrop", &fValue); |
2946 | if (E_NOTFOUND == hr) | 3071 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying TreeView/@EnableDragDrop attribute."); |
2947 | { | 3072 | |
2948 | hr = S_OK; | 3073 | if (fXmlFound && fValue) |
2949 | } | ||
2950 | else if (fValue) | ||
2951 | { | 3074 | { |
2952 | pControl->dwStyle &= ~TVS_DISABLEDRAGDROP; | 3075 | pControl->dwStyle &= ~TVS_DISABLEDRAGDROP; |
2953 | } | 3076 | } |
2954 | ThmExitOnFailure(hr, "Failed when querying TreeView/@EnableDragDrop attribute."); | ||
2955 | 3077 | ||
2956 | hr = XmlGetYesNoAttribute(pixn, L"FullRowSelect", &fValue); | 3078 | hr = XmlGetYesNoAttribute(pixn, L"FullRowSelect", &fValue); |
2957 | if (E_NOTFOUND == hr) | 3079 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying TreeView/@FullRowSelect attribute."); |
2958 | { | 3080 | |
2959 | hr = S_OK; | 3081 | if (fXmlFound && fValue) |
2960 | } | ||
2961 | else if (fValue) | ||
2962 | { | 3082 | { |
2963 | pControl->dwStyle |= TVS_FULLROWSELECT; | 3083 | pControl->dwStyle |= TVS_FULLROWSELECT; |
2964 | } | 3084 | } |
2965 | ThmExitOnFailure(hr, "Failed when querying TreeView/@FullRowSelect attribute."); | ||
2966 | 3085 | ||
2967 | hr = XmlGetYesNoAttribute(pixn, L"HasButtons", &fValue); | 3086 | hr = XmlGetYesNoAttribute(pixn, L"HasButtons", &fValue); |
2968 | if (E_NOTFOUND == hr) | 3087 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying TreeView/@HasButtons attribute."); |
2969 | { | 3088 | |
2970 | hr = S_OK; | 3089 | if (fXmlFound && fValue) |
2971 | } | ||
2972 | else if (fValue) | ||
2973 | { | 3090 | { |
2974 | pControl->dwStyle |= TVS_HASBUTTONS; | 3091 | pControl->dwStyle |= TVS_HASBUTTONS; |
2975 | } | 3092 | } |
2976 | ThmExitOnFailure(hr, "Failed when querying TreeView/@HasButtons attribute."); | ||
2977 | 3093 | ||
2978 | hr = XmlGetYesNoAttribute(pixn, L"AlwaysShowSelect", &fValue); | 3094 | hr = XmlGetYesNoAttribute(pixn, L"AlwaysShowSelect", &fValue); |
2979 | if (E_NOTFOUND == hr) | 3095 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying TreeView/@AlwaysShowSelect attribute."); |
2980 | { | 3096 | |
2981 | hr = S_OK; | 3097 | if (fXmlFound && fValue) |
2982 | } | ||
2983 | else if (fValue) | ||
2984 | { | 3098 | { |
2985 | pControl->dwStyle |= TVS_SHOWSELALWAYS; | 3099 | pControl->dwStyle |= TVS_SHOWSELALWAYS; |
2986 | } | 3100 | } |
2987 | ThmExitOnFailure(hr, "Failed when querying TreeView/@AlwaysShowSelect attribute."); | ||
2988 | 3101 | ||
2989 | hr = XmlGetYesNoAttribute(pixn, L"LinesAtRoot", &fValue); | 3102 | hr = XmlGetYesNoAttribute(pixn, L"LinesAtRoot", &fValue); |
2990 | if (E_NOTFOUND == hr) | 3103 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying TreeView/@LinesAtRoot attribute."); |
2991 | { | 3104 | |
2992 | hr = S_OK; | 3105 | if (fXmlFound && fValue) |
2993 | } | ||
2994 | else if (fValue) | ||
2995 | { | 3106 | { |
2996 | pControl->dwStyle |= TVS_LINESATROOT; | 3107 | pControl->dwStyle |= TVS_LINESATROOT; |
2997 | } | 3108 | } |
2998 | ThmExitOnFailure(hr, "Failed when querying TreeView/@LinesAtRoot attribute."); | ||
2999 | 3109 | ||
3000 | hr = XmlGetYesNoAttribute(pixn, L"HasLines", &fValue); | 3110 | hr = XmlGetYesNoAttribute(pixn, L"HasLines", &fValue); |
3001 | if (E_NOTFOUND == hr) | 3111 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying TreeView/@HasLines attribute."); |
3002 | { | 3112 | |
3003 | hr = S_OK; | 3113 | if (fXmlFound && fValue) |
3004 | } | ||
3005 | else if (fValue) | ||
3006 | { | 3114 | { |
3007 | pControl->dwStyle |= TVS_HASLINES; | 3115 | pControl->dwStyle |= TVS_HASLINES; |
3008 | } | 3116 | } |
3009 | ThmExitOnFailure(hr, "Failed when querying TreeView/@HasLines attribute."); | ||
3010 | } | 3117 | } |
3011 | 3118 | ||
3012 | LExit: | 3119 | LExit: |
@@ -3188,7 +3295,8 @@ static HRESULT ParseColumns( | |||
3188 | IXMLDOMNodeList* pixnl = NULL; | 3295 | IXMLDOMNodeList* pixnl = NULL; |
3189 | IXMLDOMNode* pixnChild = NULL; | 3296 | IXMLDOMNode* pixnChild = NULL; |
3190 | BSTR bstrText = NULL; | 3297 | BSTR bstrText = NULL; |
3191 | DWORD dwValue = 0; | 3298 | int nValue = 0; |
3299 | BOOL fXmlFound = FALSE; | ||
3192 | 3300 | ||
3193 | hr = XmlSelectNodes(pixn, L"Column", &pixnl); | 3301 | hr = XmlSelectNodes(pixn, L"Column", &pixnl); |
3194 | ThmExitOnFailure(hr, "Failed to select child column nodes."); | 3302 | ThmExitOnFailure(hr, "Failed to select child column nodes."); |
@@ -3209,21 +3317,18 @@ static HRESULT ParseColumns( | |||
3209 | hr = XmlGetText(pixnChild, &bstrText); | 3317 | hr = XmlGetText(pixnChild, &bstrText); |
3210 | ThmExitOnFailure(hr, "Failed to get inner text of column element."); | 3318 | ThmExitOnFailure(hr, "Failed to get inner text of column element."); |
3211 | 3319 | ||
3212 | hr = XmlGetAttributeNumber(pixnChild, L"Width", &dwValue); | 3320 | hr = GetAttributeCoordinateOrDimension(pixnChild, L"Width", &nValue); |
3213 | if (S_FALSE == hr) | 3321 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get column width attribute."); |
3322 | |||
3323 | if (!fXmlFound) | ||
3214 | { | 3324 | { |
3215 | dwValue = 100; | 3325 | nValue = 100; |
3216 | } | 3326 | } |
3217 | ThmExitOnFailure(hr, "Failed to get column width attribute."); | ||
3218 | 3327 | ||
3219 | pColumn->nBaseWidth = pColumn->nDefaultDpiBaseWidth = dwValue; | 3328 | pColumn->nBaseWidth = pColumn->nDefaultDpiBaseWidth = nValue; |
3220 | 3329 | ||
3221 | hr = XmlGetYesNoAttribute(pixnChild, L"Expands", reinterpret_cast<BOOL*>(&pColumn->fExpands)); | 3330 | hr = XmlGetYesNoAttribute(pixnChild, L"Expands", &pColumn->fExpands); |
3222 | if (E_NOTFOUND == hr) | 3331 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get expands attribute."); |
3223 | { | ||
3224 | hr = S_OK; | ||
3225 | } | ||
3226 | ThmExitOnFailure(hr, "Failed to get expands attribute."); | ||
3227 | 3332 | ||
3228 | hr = StrAllocString(&pColumn->pszName, bstrText, 0); | 3333 | hr = StrAllocString(&pColumn->pszName, bstrText, 0); |
3229 | ThmExitOnFailure(hr, "Failed to copy column name."); | 3334 | ThmExitOnFailure(hr, "Failed to copy column name."); |
@@ -3305,7 +3410,7 @@ static HRESULT ParseRadioButtons( | |||
3305 | pControl->type = THEME_CONTROL_TYPE_RADIOBUTTON; | 3410 | pControl->type = THEME_CONTROL_TYPE_RADIOBUTTON; |
3306 | *pcControls += 1; | 3411 | *pcControls += 1; |
3307 | 3412 | ||
3308 | hr = ParseControl(hModule, wzRelativePath, pixnChild, pTheme, pControl, pPage); | 3413 | hr = ParseControl(hModule, wzRelativePath, pixnChild, L"RadioButton", pTheme, pControl, pPage); |
3309 | ThmExitOnFailure(hr, "Failed to parse control."); | 3414 | ThmExitOnFailure(hr, "Failed to parse control."); |
3310 | 3415 | ||
3311 | if (fFirst) | 3416 | if (fFirst) |
@@ -3472,7 +3577,7 @@ static HRESULT ParseTooltips( | |||
3472 | __in IXMLDOMNode* pixn, | 3577 | __in IXMLDOMNode* pixn, |
3473 | __in THEME_CONTROL* pControl, | 3578 | __in THEME_CONTROL* pControl, |
3474 | __inout BOOL* pfAnyChildren | 3579 | __inout BOOL* pfAnyChildren |
3475 | ) | 3580 | ) |
3476 | { | 3581 | { |
3477 | HRESULT hr = S_OK; | 3582 | HRESULT hr = S_OK; |
3478 | IXMLDOMNode* pixnChild = NULL; | 3583 | IXMLDOMNode* pixnChild = NULL; |
@@ -3503,6 +3608,32 @@ LExit: | |||
3503 | } | 3608 | } |
3504 | 3609 | ||
3505 | 3610 | ||
3611 | static HRESULT ParseUnexpectedAttribute( | ||
3612 | __in IXMLDOMNode* pixn, | ||
3613 | __in_z LPCWSTR wzElementName, | ||
3614 | __in_z LPCWSTR wzAttribute | ||
3615 | ) | ||
3616 | { | ||
3617 | HRESULT hr = S_OK; | ||
3618 | BSTR bstr = NULL; | ||
3619 | |||
3620 | hr = XmlGetAttribute(pixn, wzAttribute, &bstr); | ||
3621 | ThmExitOnFailure(hr, "Failed to get attribute %ls/@%ls", wzElementName, wzAttribute); | ||
3622 | |||
3623 | if (S_OK == hr) | ||
3624 | { | ||
3625 | ThmExitOnRootFailure(hr = E_INVALIDDATA, "Element '%ls' has unexpected attribute '%ls', value: %ls.", wzElementName, wzAttribute, bstr); | ||
3626 | } | ||
3627 | |||
3628 | hr = S_OK; | ||
3629 | |||
3630 | LExit: | ||
3631 | ReleaseBSTR(bstr); | ||
3632 | |||
3633 | return hr; | ||
3634 | } | ||
3635 | |||
3636 | |||
3506 | static HRESULT ParseNotes( | 3637 | static HRESULT ParseNotes( |
3507 | __in IXMLDOMNode* pixn, | 3638 | __in IXMLDOMNode* pixn, |
3508 | __in THEME_CONTROL* pControl, | 3639 | __in THEME_CONTROL* pControl, |