diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-06-03 16:24:25 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-06-04 14:57:11 -0500 |
| commit | 089295bf2eb1274da2326e5864afc905070a2832 (patch) | |
| tree | 1b55fd5a24497acd01705b83f78e8f911dff4871 /src/libs/dutil/WixToolset.DUtil/thmutil.cpp | |
| parent | 13482e726fd148eaa58eb95e358e13e390d63148 (diff) | |
| download | wix-089295bf2eb1274da2326e5864afc905070a2832.tar.gz wix-089295bf2eb1274da2326e5864afc905070a2832.tar.bz2 wix-089295bf2eb1274da2326e5864afc905070a2832.zip | |
Enforce schema restrictions for numeric and image thmutil attributes.
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, |
