diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-10-31 14:20:44 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-11-01 16:34:09 -0500 |
| commit | 7e60078d4a7fe748a39c135def9e84a2421ab474 (patch) | |
| tree | 51dbe5067ca9596f99107719734c4946e4c080b4 /src/libs | |
| parent | c092722a147940532b08f62403e182ef279f2c74 (diff) | |
| download | wix-7e60078d4a7fe748a39c135def9e84a2421ab474.tar.gz wix-7e60078d4a7fe748a39c135def9e84a2421ab474.tar.bz2 wix-7e60078d4a7fe748a39c135def9e84a2421ab474.zip | |
Avoid using control ids inside of thmutil.
Diffstat (limited to 'src/libs')
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/dutil.vcxproj | 2 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters | 6 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h | 1 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | 117 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/wndutil.h | 41 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/precomp.h | 1 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 650 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/wndutil.cpp | 206 |
8 files changed, 565 insertions, 459 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj index a02e638a..3ab8285f 100644 --- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj +++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj | |||
| @@ -107,6 +107,7 @@ | |||
| 107 | <ClCompile Include="userutil.cpp" /> | 107 | <ClCompile Include="userutil.cpp" /> |
| 108 | <ClCompile Include="verutil.cpp" /> | 108 | <ClCompile Include="verutil.cpp" /> |
| 109 | <ClCompile Include="wiutil.cpp" /> | 109 | <ClCompile Include="wiutil.cpp" /> |
| 110 | <ClCompile Include="wndutil.cpp" /> | ||
| 110 | <ClCompile Include="wuautil.cpp" /> | 111 | <ClCompile Include="wuautil.cpp" /> |
| 111 | <ClCompile Include="xmlutil.cpp" /> | 112 | <ClCompile Include="xmlutil.cpp" /> |
| 112 | </ItemGroup> | 113 | </ItemGroup> |
| @@ -164,6 +165,7 @@ | |||
| 164 | <ClInclude Include="inc\userutil.h" /> | 165 | <ClInclude Include="inc\userutil.h" /> |
| 165 | <ClInclude Include="inc\verutil.h" /> | 166 | <ClInclude Include="inc\verutil.h" /> |
| 166 | <ClInclude Include="inc\wiutil.h" /> | 167 | <ClInclude Include="inc\wiutil.h" /> |
| 168 | <ClInclude Include="inc\wndutil.h" /> | ||
| 167 | <ClInclude Include="inc\wuautil.h" /> | 169 | <ClInclude Include="inc\wuautil.h" /> |
| 168 | <ClInclude Include="inc\xmlutil.h" /> | 170 | <ClInclude Include="inc\xmlutil.h" /> |
| 169 | <ClInclude Include="precomp.h" /> | 171 | <ClInclude Include="precomp.h" /> |
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters index b93d166b..6444b19c 100644 --- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters +++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters | |||
| @@ -165,6 +165,9 @@ | |||
| 165 | <ClCompile Include="wiutil.cpp"> | 165 | <ClCompile Include="wiutil.cpp"> |
| 166 | <Filter>Source Files</Filter> | 166 | <Filter>Source Files</Filter> |
| 167 | </ClCompile> | 167 | </ClCompile> |
| 168 | <ClCompile Include="wndutil.cpp"> | ||
| 169 | <Filter>Source Files</Filter> | ||
| 170 | </ClCompile> | ||
| 168 | <ClCompile Include="xmlutil.cpp"> | 171 | <ClCompile Include="xmlutil.cpp"> |
| 169 | <Filter>Source Files</Filter> | 172 | <Filter>Source Files</Filter> |
| 170 | </ClCompile> | 173 | </ClCompile> |
| @@ -338,6 +341,9 @@ | |||
| 338 | <ClInclude Include="inc\wiutil.h"> | 341 | <ClInclude Include="inc\wiutil.h"> |
| 339 | <Filter>Header Files</Filter> | 342 | <Filter>Header Files</Filter> |
| 340 | </ClInclude> | 343 | </ClInclude> |
| 344 | <ClInclude Include="inc\wndutil.h"> | ||
| 345 | <Filter>Header Files</Filter> | ||
| 346 | </ClInclude> | ||
| 341 | <ClInclude Include="inc\xmlutil.h"> | 347 | <ClInclude Include="inc\xmlutil.h"> |
| 342 | <Filter>Header Files</Filter> | 348 | <Filter>Header Files</Filter> |
| 343 | </ClInclude> | 349 | </ClInclude> |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h b/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h index 7d512cb3..6affb392 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h | |||
| @@ -61,6 +61,7 @@ typedef enum DUTIL_SOURCE | |||
| 61 | DUTIL_SOURCE_WUAUTIL, | 61 | DUTIL_SOURCE_WUAUTIL, |
| 62 | DUTIL_SOURCE_XMLUTIL, | 62 | DUTIL_SOURCE_XMLUTIL, |
| 63 | DUTIL_SOURCE_VERUTIL, | 63 | DUTIL_SOURCE_VERUTIL, |
| 64 | DUTIL_SOURCE_WNDUTIL, | ||
| 64 | 65 | ||
| 65 | DUTIL_SOURCE_EXTERNAL = 256, | 66 | DUTIL_SOURCE_EXTERNAL = 256, |
| 66 | } DUTIL_SOURCE; | 67 | } DUTIL_SOURCE; |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h index cd286854..2f0bfeac 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | |||
| @@ -8,6 +8,7 @@ extern "C" { | |||
| 8 | 8 | ||
| 9 | // forward declare | 9 | // forward declare |
| 10 | 10 | ||
| 11 | typedef struct _THEME_CONTROL THEME_CONTROL; | ||
| 11 | typedef struct _THEME THEME; | 12 | typedef struct _THEME THEME; |
| 12 | 13 | ||
| 13 | #define ReleaseTheme(p) if (p) { ThemeFree(p); p = NULL; } | 14 | #define ReleaseTheme(p) if (p) { ThemeFree(p); p = NULL; } |
| @@ -194,11 +195,12 @@ struct THEME_ASSIGN_CONTROL_ID | |||
| 194 | { | 195 | { |
| 195 | WORD wId; // id to apply to control | 196 | WORD wId; // id to apply to control |
| 196 | LPCWSTR wzName; // name of control to match | 197 | LPCWSTR wzName; // name of control to match |
| 198 | const THEME_CONTROL** ppControl; | ||
| 197 | }; | 199 | }; |
| 198 | 200 | ||
| 199 | const WORD THEME_FIRST_ASSIGN_CONTROL_ID = 0x4000; // Recommended first control id to be assigned. | 201 | const WORD THEME_FIRST_ASSIGN_CONTROL_ID = 0x4000; // Recommended first control id to be assigned. |
| 200 | 202 | ||
| 201 | struct THEME_CONTROL | 203 | typedef struct _THEME_CONTROL |
| 202 | { | 204 | { |
| 203 | THEME_CONTROL_TYPE type; | 205 | THEME_CONTROL_TYPE type; |
| 204 | 206 | ||
| @@ -296,7 +298,7 @@ struct THEME_CONTROL | |||
| 296 | HWND hWnd; | 298 | HWND hWnd; |
| 297 | DWORD dwData; // type specific data | 299 | DWORD dwData; // type specific data |
| 298 | THEME* pTheme; | 300 | THEME* pTheme; |
| 299 | }; | 301 | } THEME_CONTROL; |
| 300 | 302 | ||
| 301 | 303 | ||
| 302 | struct THEME_IMAGELIST | 304 | struct THEME_IMAGELIST |
| @@ -580,8 +582,7 @@ HRESULT DAPI ThemeLoadStrings( | |||
| 580 | 582 | ||
| 581 | *******************************************************************/ | 583 | *******************************************************************/ |
| 582 | HRESULT DAPI ThemeLoadRichEditFromFile( | 584 | HRESULT DAPI ThemeLoadRichEditFromFile( |
| 583 | __in THEME* pTheme, | 585 | __in const THEME_CONTROL* pThemeControl, |
| 584 | __in DWORD dwControl, | ||
| 585 | __in_z LPCWSTR wzFileName, | 586 | __in_z LPCWSTR wzFileName, |
| 586 | __in HMODULE hModule | 587 | __in HMODULE hModule |
| 587 | ); | 588 | ); |
| @@ -591,19 +592,7 @@ HRESULT DAPI ThemeLoadRichEditFromFile( | |||
| 591 | 592 | ||
| 592 | *******************************************************************/ | 593 | *******************************************************************/ |
| 593 | HRESULT DAPI ThemeLoadRichEditFromResource( | 594 | HRESULT DAPI ThemeLoadRichEditFromResource( |
| 594 | __in THEME* pTheme, | 595 | __in const THEME_CONTROL* pThemeControl, |
| 595 | __in DWORD dwControl, | ||
| 596 | __in_z LPCSTR szResourceName, | ||
| 597 | __in HMODULE hModule | ||
| 598 | ); | ||
| 599 | |||
| 600 | /******************************************************************** | ||
| 601 | ThemeLoadRichEditFromResourceToHWnd - Attach a richedit control (by | ||
| 602 | HWND) to resource data. | ||
| 603 | |||
| 604 | *******************************************************************/ | ||
| 605 | HRESULT DAPI ThemeLoadRichEditFromResourceToHWnd( | ||
| 606 | __in HWND hWnd, | ||
| 607 | __in_z LPCSTR szResourceName, | 596 | __in_z LPCSTR szResourceName, |
| 608 | __in HMODULE hModule | 597 | __in HMODULE hModule |
| 609 | ); | 598 | ); |
| @@ -682,18 +671,28 @@ ThemeShowChild - shows a control's specified child control, hiding the rest. | |||
| 682 | 671 | ||
| 683 | *******************************************************************/ | 672 | *******************************************************************/ |
| 684 | void DAPI ThemeShowChild( | 673 | void DAPI ThemeShowChild( |
| 685 | __in THEME* pTheme, | ||
| 686 | __in THEME_CONTROL* pParentControl, | 674 | __in THEME_CONTROL* pParentControl, |
| 687 | __in DWORD dwIndex | 675 | __in DWORD dwIndex |
| 688 | ); | 676 | ); |
| 689 | 677 | ||
| 690 | /******************************************************************** | 678 | /******************************************************************** |
| 691 | ThemeControlExists - check if a control with the specified id exists. | 679 | ThemeControlExistsByHwnd - check if a control with the specified hWnd exists. |
| 680 | |||
| 681 | *******************************************************************/ | ||
| 682 | BOOL DAPI ThemeControlExistsByHWnd( | ||
| 683 | __in const THEME* pTheme, | ||
| 684 | __in HWND hWnd, | ||
| 685 | __out_opt const THEME_CONTROL** ppThemeControl | ||
| 686 | ); | ||
| 687 | |||
| 688 | /******************************************************************** | ||
| 689 | ThemeControlExistsById - check if a control with the specified id exists. | ||
| 692 | 690 | ||
| 693 | *******************************************************************/ | 691 | *******************************************************************/ |
| 694 | BOOL DAPI ThemeControlExists( | 692 | BOOL DAPI ThemeControlExistsById( |
| 695 | __in const THEME* pTheme, | 693 | __in const THEME* pTheme, |
| 696 | __in DWORD dwControl | 694 | __in WORD wId, |
| 695 | __out_opt const THEME_CONTROL** ppThemeControl | ||
| 697 | ); | 696 | ); |
| 698 | 697 | ||
| 699 | /******************************************************************** | 698 | /******************************************************************** |
| @@ -701,8 +700,7 @@ BOOL DAPI ThemeControlExists( | |||
| 701 | 700 | ||
| 702 | *******************************************************************/ | 701 | *******************************************************************/ |
| 703 | void DAPI ThemeControlEnable( | 702 | void DAPI ThemeControlEnable( |
| 704 | __in THEME* pTheme, | 703 | __in const THEME_CONTROL* pThemeControl, |
| 705 | __in DWORD dwControl, | ||
| 706 | __in BOOL fEnable | 704 | __in BOOL fEnable |
| 707 | ); | 705 | ); |
| 708 | 706 | ||
| @@ -711,8 +709,7 @@ void DAPI ThemeControlEnable( | |||
| 711 | 709 | ||
| 712 | *******************************************************************/ | 710 | *******************************************************************/ |
| 713 | BOOL DAPI ThemeControlEnabled( | 711 | BOOL DAPI ThemeControlEnabled( |
| 714 | __in THEME* pTheme, | 712 | __in const THEME_CONTROL* pThemeControl |
| 715 | __in DWORD dwControl | ||
| 716 | ); | 713 | ); |
| 717 | 714 | ||
| 718 | /******************************************************************** | 715 | /******************************************************************** |
| @@ -720,8 +717,7 @@ BOOL DAPI ThemeControlEnabled( | |||
| 720 | 717 | ||
| 721 | *******************************************************************/ | 718 | *******************************************************************/ |
| 722 | void DAPI ThemeControlElevates( | 719 | void DAPI ThemeControlElevates( |
| 723 | __in THEME* pTheme, | 720 | __in const THEME_CONTROL* pThemeControl, |
| 724 | __in DWORD dwControl, | ||
| 725 | __in BOOL fElevates | 721 | __in BOOL fElevates |
| 726 | ); | 722 | ); |
| 727 | 723 | ||
| @@ -730,8 +726,7 @@ void DAPI ThemeControlElevates( | |||
| 730 | 726 | ||
| 731 | *******************************************************************/ | 727 | *******************************************************************/ |
| 732 | void DAPI ThemeShowControl( | 728 | void DAPI ThemeShowControl( |
| 733 | __in THEME* pTheme, | 729 | __in const THEME_CONTROL* pThemeControl, |
| 734 | __in DWORD dwControl, | ||
| 735 | __in int nCmdShow | 730 | __in int nCmdShow |
| 736 | ); | 731 | ); |
| 737 | 732 | ||
| @@ -741,8 +736,7 @@ conditional text and notes. | |||
| 741 | 736 | ||
| 742 | *******************************************************************/ | 737 | *******************************************************************/ |
| 743 | void DAPI ThemeShowControlEx( | 738 | void DAPI ThemeShowControlEx( |
| 744 | __in THEME* pTheme, | 739 | __in const THEME_CONTROL* pThemeControl, |
| 745 | __in DWORD dwControl, | ||
| 746 | __in int nCmdShow | 740 | __in int nCmdShow |
| 747 | ); | 741 | ); |
| 748 | 742 | ||
| @@ -751,24 +745,7 @@ void DAPI ThemeShowControlEx( | |||
| 751 | 745 | ||
| 752 | *******************************************************************/ | 746 | *******************************************************************/ |
| 753 | BOOL DAPI ThemeControlVisible( | 747 | BOOL DAPI ThemeControlVisible( |
| 754 | __in THEME* pTheme, | 748 | __in const THEME_CONTROL* pThemeControl |
| 755 | __in DWORD dwControl | ||
| 756 | ); | ||
| 757 | |||
| 758 | BOOL DAPI ThemePostControlMessage( | ||
| 759 | __in THEME* pTheme, | ||
| 760 | __in DWORD dwControl, | ||
| 761 | __in UINT Msg, | ||
| 762 | __in WPARAM wParam, | ||
| 763 | __in LPARAM lParam | ||
| 764 | ); | ||
| 765 | |||
| 766 | LRESULT DAPI ThemeSendControlMessage( | ||
| 767 | __in const THEME* pTheme, | ||
| 768 | __in DWORD dwControl, | ||
| 769 | __in UINT Msg, | ||
| 770 | __in WPARAM wParam, | ||
| 771 | __in LPARAM lParam | ||
| 772 | ); | 749 | ); |
| 773 | 750 | ||
| 774 | /******************************************************************** | 751 | /******************************************************************** |
| @@ -790,34 +767,12 @@ HRESULT DAPI ThemeDrawControl( | |||
| 790 | ); | 767 | ); |
| 791 | 768 | ||
| 792 | /******************************************************************** | 769 | /******************************************************************** |
| 793 | ThemeHoverControl - mark a control as hover. | ||
| 794 | |||
| 795 | *******************************************************************/ | ||
| 796 | BOOL DAPI ThemeHoverControl( | ||
| 797 | __in THEME* pTheme, | ||
| 798 | __in HWND hwndParent, | ||
| 799 | __in HWND hwndControl | ||
| 800 | ); | ||
| 801 | |||
| 802 | /******************************************************************** | ||
| 803 | ThemeIsControlChecked - gets whether a control is checked. Only | 770 | ThemeIsControlChecked - gets whether a control is checked. Only |
| 804 | really useful for checkbox controls. | 771 | really useful for checkbox controls. |
| 805 | 772 | ||
| 806 | *******************************************************************/ | 773 | *******************************************************************/ |
| 807 | BOOL DAPI ThemeIsControlChecked( | 774 | BOOL DAPI ThemeIsControlChecked( |
| 808 | __in THEME* pTheme, | 775 | __in const THEME_CONTROL* pThemeControl |
| 809 | __in DWORD dwControl | ||
| 810 | ); | ||
| 811 | |||
| 812 | /******************************************************************** | ||
| 813 | ThemeSetControlColor - sets the color of text for a control. | ||
| 814 | |||
| 815 | *******************************************************************/ | ||
| 816 | BOOL DAPI ThemeSetControlColor( | ||
| 817 | __in THEME* pTheme, | ||
| 818 | __in HDC hdc, | ||
| 819 | __in HWND hWnd, | ||
| 820 | __out HBRUSH* phBackgroundBrush | ||
| 821 | ); | 776 | ); |
| 822 | 777 | ||
| 823 | /******************************************************************** | 778 | /******************************************************************** |
| @@ -826,8 +781,7 @@ BOOL DAPI ThemeSetControlColor( | |||
| 826 | 781 | ||
| 827 | *******************************************************************/ | 782 | *******************************************************************/ |
| 828 | HRESULT DAPI ThemeSetProgressControl( | 783 | HRESULT DAPI ThemeSetProgressControl( |
| 829 | __in THEME* pTheme, | 784 | __in const THEME_CONTROL* pThemeControl, |
| 830 | __in DWORD dwControl, | ||
| 831 | __in DWORD dwProgressPercentage | 785 | __in DWORD dwProgressPercentage |
| 832 | ); | 786 | ); |
| 833 | 787 | ||
| @@ -837,8 +791,7 @@ HRESULT DAPI ThemeSetProgressControl( | |||
| 837 | 791 | ||
| 838 | *******************************************************************/ | 792 | *******************************************************************/ |
| 839 | HRESULT DAPI ThemeSetProgressControlColor( | 793 | HRESULT DAPI ThemeSetProgressControlColor( |
| 840 | __in THEME* pTheme, | 794 | __in const THEME_CONTROL* pThemeControl, |
| 841 | __in DWORD dwControl, | ||
| 842 | __in DWORD dwColorIndex | 795 | __in DWORD dwColorIndex |
| 843 | ); | 796 | ); |
| 844 | 797 | ||
| @@ -847,8 +800,7 @@ HRESULT DAPI ThemeSetProgressControlColor( | |||
| 847 | 800 | ||
| 848 | *******************************************************************/ | 801 | *******************************************************************/ |
| 849 | HRESULT DAPI ThemeSetTextControl( | 802 | HRESULT DAPI ThemeSetTextControl( |
| 850 | __in const THEME* pTheme, | 803 | __in const THEME_CONTROL* pThemeControl, |
| 851 | __in DWORD dwControl, | ||
| 852 | __in_z_opt LPCWSTR wzText | 804 | __in_z_opt LPCWSTR wzText |
| 853 | ); | 805 | ); |
| 854 | 806 | ||
| @@ -858,8 +810,7 @@ ThemeSetTextControl - sets the text of a control and optionally | |||
| 858 | 810 | ||
| 859 | *******************************************************************/ | 811 | *******************************************************************/ |
| 860 | HRESULT DAPI ThemeSetTextControlEx( | 812 | HRESULT DAPI ThemeSetTextControlEx( |
| 861 | __in const THEME* pTheme, | 813 | __in const THEME_CONTROL* pThemeControl, |
| 862 | __in DWORD dwControl, | ||
| 863 | __in BOOL fUpdate, | 814 | __in BOOL fUpdate, |
| 864 | __in_z_opt LPCWSTR wzText | 815 | __in_z_opt LPCWSTR wzText |
| 865 | ); | 816 | ); |
| @@ -869,8 +820,7 @@ HRESULT DAPI ThemeSetTextControlEx( | |||
| 869 | 820 | ||
| 870 | *******************************************************************/ | 821 | *******************************************************************/ |
| 871 | HRESULT DAPI ThemeGetTextControl( | 822 | HRESULT DAPI ThemeGetTextControl( |
| 872 | __in const THEME* pTheme, | 823 | __in const THEME_CONTROL* pThemeControl, |
| 873 | __in DWORD dwControl, | ||
| 874 | __inout_z LPWSTR* psczText | 824 | __inout_z LPWSTR* psczText |
| 875 | ); | 825 | ); |
| 876 | 826 | ||
| @@ -889,8 +839,7 @@ HRESULT DAPI ThemeUpdateCaption( | |||
| 889 | 839 | ||
| 890 | *******************************************************************/ | 840 | *******************************************************************/ |
| 891 | void DAPI ThemeSetFocus( | 841 | void DAPI ThemeSetFocus( |
| 892 | __in THEME* pTheme, | 842 | __in const THEME_CONTROL* pThemeControl |
| 893 | __in DWORD dwControl | ||
| 894 | ); | 843 | ); |
| 895 | 844 | ||
| 896 | #ifdef __cplusplus | 845 | #ifdef __cplusplus |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/wndutil.h b/src/libs/dutil/WixToolset.DUtil/inc/wndutil.h new file mode 100644 index 00000000..8de77f6e --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/inc/wndutil.h | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | #pragma once | ||
| 2 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 3 | |||
| 4 | |||
| 5 | #ifdef __cplusplus | ||
| 6 | extern "C" { | ||
| 7 | #endif | ||
| 8 | |||
| 9 | /******************************************************************** | ||
| 10 | WnduLoadRichEditFromFile - Attach a richedit control to a RTF file. | ||
| 11 | |||
| 12 | *******************************************************************/ | ||
| 13 | HRESULT DAPI WnduLoadRichEditFromFile( | ||
| 14 | __in HWND hWnd, | ||
| 15 | __in_z LPCWSTR wzFileName, | ||
| 16 | __in HMODULE hModule | ||
| 17 | ); | ||
| 18 | |||
| 19 | /******************************************************************** | ||
| 20 | WnduLoadRichEditFromResource - Attach a richedit control to resource data. | ||
| 21 | |||
| 22 | *******************************************************************/ | ||
| 23 | HRESULT DAPI WnduLoadRichEditFromResource( | ||
| 24 | __in HWND hWnd, | ||
| 25 | __in_z LPCSTR szResourceName, | ||
| 26 | __in HMODULE hModule | ||
| 27 | ); | ||
| 28 | |||
| 29 | /******************************************************************** | ||
| 30 | WnduGetControlText - gets the text of a control. | ||
| 31 | |||
| 32 | *******************************************************************/ | ||
| 33 | HRESULT DAPI WnduGetControlText( | ||
| 34 | __in HWND hWnd, | ||
| 35 | __inout_z LPWSTR* psczText | ||
| 36 | ); | ||
| 37 | |||
| 38 | #ifdef __cplusplus | ||
| 39 | } | ||
| 40 | #endif | ||
| 41 | |||
diff --git a/src/libs/dutil/WixToolset.DUtil/precomp.h b/src/libs/dutil/WixToolset.DUtil/precomp.h index 46d29f21..093c16a2 100644 --- a/src/libs/dutil/WixToolset.DUtil/precomp.h +++ b/src/libs/dutil/WixToolset.DUtil/precomp.h | |||
| @@ -87,6 +87,7 @@ | |||
| 87 | #include "strutil.h" | 87 | #include "strutil.h" |
| 88 | #include "timeutil.h" | 88 | #include "timeutil.h" |
| 89 | #include "timeutil.h" | 89 | #include "timeutil.h" |
| 90 | #include "wndutil.h" | ||
| 90 | #include "thmutil.h" | 91 | #include "thmutil.h" |
| 91 | #include "uncutil.h" | 92 | #include "uncutil.h" |
| 92 | #include "uriutil.h" | 93 | #include "uriutil.h" |
diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp index e8c23b6c..9adc2ddd 100644 --- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp | |||
| @@ -44,7 +44,6 @@ const DWORD THEME_INVALID_ID = 0xFFFFFFFF; | |||
| 44 | const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF; | 44 | const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF; |
| 45 | const DWORD GROW_FONT_INSTANCES = 3; | 45 | const DWORD GROW_FONT_INSTANCES = 3; |
| 46 | const DWORD GROW_IMAGE_INSTANCES = 5; | 46 | const DWORD GROW_IMAGE_INSTANCES = 5; |
| 47 | const DWORD GROW_WINDOW_TEXT = 250; | ||
| 48 | 47 | ||
| 49 | static Gdiplus::GdiplusStartupInput vgsi; | 48 | static Gdiplus::GdiplusStartupInput vgsi; |
| 50 | static Gdiplus::GdiplusStartupOutput vgso = { }; | 49 | static Gdiplus::GdiplusStartupOutput vgso = { }; |
| @@ -70,16 +69,29 @@ enum INTERNAL_CONTROL_STYLE | |||
| 70 | INTERNAL_CONTROL_STYLE_OWNER_DRAW = 0x0010, | 69 | INTERNAL_CONTROL_STYLE_OWNER_DRAW = 0x0010, |
| 71 | }; | 70 | }; |
| 72 | 71 | ||
| 73 | struct MEMBUFFER_FOR_RICHEDIT | ||
| 74 | { | ||
| 75 | BYTE* rgbData; | ||
| 76 | DWORD cbData; | ||
| 77 | 72 | ||
| 78 | DWORD iData; | 73 | // prototypes |
| 79 | }; | 74 | /******************************************************************** |
| 75 | ThemeHoverControl - mark a control as hover. | ||
| 76 | |||
| 77 | *******************************************************************/ | ||
| 78 | static BOOL ThemeHoverControl( | ||
| 79 | __in THEME* pTheme, | ||
| 80 | __in HWND hwndParent, | ||
| 81 | __in HWND hwndControl | ||
| 82 | ); | ||
| 80 | 83 | ||
| 84 | /******************************************************************** | ||
| 85 | ThemeSetControlColor - sets the color of text for a control. | ||
| 86 | |||
| 87 | *******************************************************************/ | ||
| 88 | static BOOL ThemeSetControlColor( | ||
| 89 | __in THEME* pTheme, | ||
| 90 | __in HDC hdc, | ||
| 91 | __in HWND hWnd, | ||
| 92 | __out HBRUSH* phBackgroundBrush | ||
| 93 | ); | ||
| 81 | 94 | ||
| 82 | // prototypes | ||
| 83 | static HRESULT RegisterWindowClasses( | 95 | static HRESULT RegisterWindowClasses( |
| 84 | __in_opt HMODULE hModule | 96 | __in_opt HMODULE hModule |
| 85 | ); | 97 | ); |
| @@ -258,11 +270,11 @@ static HRESULT ParseNotes( | |||
| 258 | ); | 270 | ); |
| 259 | static HRESULT StopBillboard( | 271 | static HRESULT StopBillboard( |
| 260 | __in THEME* pTheme, | 272 | __in THEME* pTheme, |
| 261 | __in DWORD dwControl | 273 | __in THEME_CONTROL* pControl |
| 262 | ); | 274 | ); |
| 263 | static HRESULT StartBillboard( | 275 | static HRESULT StartBillboard( |
| 264 | __in THEME* pTheme, | 276 | __in THEME* pTheme, |
| 265 | __in DWORD dwControl | 277 | __in THEME_CONTROL* pControl |
| 266 | ); | 278 | ); |
| 267 | static HRESULT EnsureFontInstance( | 279 | static HRESULT EnsureFontInstance( |
| 268 | __in THEME* pTheme, | 280 | __in THEME* pTheme, |
| @@ -290,7 +302,6 @@ static HRESULT LoadControls( | |||
| 290 | __in_opt THEME_CONTROL* pParentControl | 302 | __in_opt THEME_CONTROL* pParentControl |
| 291 | ); | 303 | ); |
| 292 | static HRESULT ShowControl( | 304 | static HRESULT ShowControl( |
| 293 | __in THEME* pTheme, | ||
| 294 | __in THEME_CONTROL* pControl, | 305 | __in THEME_CONTROL* pControl, |
| 295 | __in int nCmdShow, | 306 | __in int nCmdShow, |
| 296 | __in BOOL fSaveEditboxes, | 307 | __in BOOL fSaveEditboxes, |
| @@ -376,18 +387,6 @@ static BOOL DrawHoverControl( | |||
| 376 | __in THEME* pTheme, | 387 | __in THEME* pTheme, |
| 377 | __in BOOL fHover | 388 | __in BOOL fHover |
| 378 | ); | 389 | ); |
| 379 | static DWORD CALLBACK RichEditStreamFromFileHandleCallback( | ||
| 380 | __in DWORD_PTR dwCookie, | ||
| 381 | __in_bcount(cb) LPBYTE pbBuff, | ||
| 382 | __in LONG cb, | ||
| 383 | __in LONG *pcb | ||
| 384 | ); | ||
| 385 | static DWORD CALLBACK RichEditStreamFromMemoryCallback( | ||
| 386 | __in DWORD_PTR dwCookie, | ||
| 387 | __in_bcount(cb) LPBYTE pbBuff, | ||
| 388 | __in LONG cb, | ||
| 389 | __in LONG *pcb | ||
| 390 | ); | ||
| 391 | static void FreeFontInstance( | 390 | static void FreeFontInstance( |
| 392 | __in THEME_FONT_INSTANCE* pFontInstance | 391 | __in THEME_FONT_INSTANCE* pFontInstance |
| 393 | ); | 392 | ); |
| @@ -475,6 +474,11 @@ static BOOL OnWmNotify( | |||
| 475 | __in const THEME_CONTROL* pThemeControl, | 474 | __in const THEME_CONTROL* pThemeControl, |
| 476 | __inout LRESULT* plResult | 475 | __inout LRESULT* plResult |
| 477 | ); | 476 | ); |
| 477 | static const THEME_CONTROL* FindControlFromId( | ||
| 478 | __in const THEME* pTheme, | ||
| 479 | __in WORD wId, | ||
| 480 | __in_opt const THEME_CONTROL* pParentControl = NULL | ||
| 481 | ); | ||
| 478 | static const THEME_CONTROL* FindControlFromHWnd( | 482 | static const THEME_CONTROL* FindControlFromHWnd( |
| 479 | __in const THEME* pTheme, | 483 | __in const THEME* pTheme, |
| 480 | __in HWND hWnd, | 484 | __in HWND hWnd, |
| @@ -974,83 +978,39 @@ LExit: | |||
| 974 | 978 | ||
| 975 | 979 | ||
| 976 | DAPI_(HRESULT) ThemeLoadRichEditFromFile( | 980 | DAPI_(HRESULT) ThemeLoadRichEditFromFile( |
| 977 | __in THEME* pTheme, | 981 | __in const THEME_CONTROL* pThemeControl, |
| 978 | __in DWORD dwControl, | ||
| 979 | __in_z LPCWSTR wzFileName, | 982 | __in_z LPCWSTR wzFileName, |
| 980 | __in HMODULE hModule | 983 | __in HMODULE hModule |
| 981 | ) | 984 | ) |
| 982 | { | 985 | { |
| 983 | HRESULT hr = S_OK; | 986 | HRESULT hr = E_INVALIDARG; |
| 984 | LPWSTR sczFile = NULL; | ||
| 985 | HANDLE hFile = INVALID_HANDLE_VALUE; | ||
| 986 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | ||
| 987 | |||
| 988 | hr = PathRelativeToModule(&sczFile, wzFileName, hModule); | ||
| 989 | ThmExitOnFailure(hr, "Failed to read resource data."); | ||
| 990 | 987 | ||
| 991 | hFile = ::CreateFileW(sczFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); | 988 | if (pThemeControl) |
| 992 | if (INVALID_HANDLE_VALUE == hFile) | ||
| 993 | { | 989 | { |
| 994 | ThmExitWithLastError(hr, "Failed to open RTF file."); | 990 | AssertSz(THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type, "ThemeLoadRichEditFromFile called for non-RichEdit control."); |
| 995 | } | ||
| 996 | else | ||
| 997 | { | ||
| 998 | LONGLONG llRtfSize; | ||
| 999 | hr = FileSizeByHandle(hFile, &llRtfSize); | ||
| 1000 | if (SUCCEEDED(hr)) | ||
| 1001 | { | ||
| 1002 | ::SendMessageW(hWnd, EM_EXLIMITTEXT, 0, static_cast<LPARAM>(llRtfSize)); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | EDITSTREAM es = { }; | ||
| 1006 | es.pfnCallback = RichEditStreamFromFileHandleCallback; | ||
| 1007 | es.dwCookie = reinterpret_cast<DWORD_PTR>(hFile); | ||
| 1008 | 991 | ||
| 1009 | ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast<LPARAM>(&es)); | 992 | hr = WnduLoadRichEditFromFile(pThemeControl->hWnd, wzFileName, hModule); |
| 1010 | hr = es.dwError; | ||
| 1011 | ThmExitOnFailure(hr, "Failed to update RTF stream."); | ||
| 1012 | } | 993 | } |
| 1013 | 994 | ||
| 1014 | LExit: | ||
| 1015 | ReleaseStr(sczFile); | ||
| 1016 | ReleaseFile(hFile); | ||
| 1017 | |||
| 1018 | return hr; | 995 | return hr; |
| 1019 | } | 996 | } |
| 1020 | 997 | ||
| 1021 | 998 | ||
| 1022 | DAPI_(HRESULT) ThemeLoadRichEditFromResource( | 999 | DAPI_(HRESULT) ThemeLoadRichEditFromResource( |
| 1023 | __in THEME* pTheme, | 1000 | __in const THEME_CONTROL* pThemeControl, |
| 1024 | __in DWORD dwControl, | ||
| 1025 | __in_z LPCSTR szResourceName, | ||
| 1026 | __in HMODULE hModule | ||
| 1027 | ) | ||
| 1028 | { | ||
| 1029 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | ||
| 1030 | return ThemeLoadRichEditFromResourceToHWnd(hWnd, szResourceName, hModule); | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | DAPI_(HRESULT) ThemeLoadRichEditFromResourceToHWnd( | ||
| 1034 | __in HWND hWnd, | ||
| 1035 | __in_z LPCSTR szResourceName, | 1001 | __in_z LPCSTR szResourceName, |
| 1036 | __in HMODULE hModule | 1002 | __in HMODULE hModule |
| 1037 | ) | 1003 | ) |
| 1038 | { | 1004 | { |
| 1039 | HRESULT hr = S_OK; | 1005 | HRESULT hr = E_INVALIDARG; |
| 1040 | MEMBUFFER_FOR_RICHEDIT buffer = { }; | ||
| 1041 | EDITSTREAM es = { }; | ||
| 1042 | |||
| 1043 | hr = ResReadData(hModule, szResourceName, reinterpret_cast<LPVOID*>(&buffer.rgbData), &buffer.cbData); | ||
| 1044 | ThmExitOnFailure(hr, "Failed to read resource data."); | ||
| 1045 | 1006 | ||
| 1046 | es.pfnCallback = RichEditStreamFromMemoryCallback; | 1007 | if (pThemeControl) |
| 1047 | es.dwCookie = reinterpret_cast<DWORD_PTR>(&buffer); | 1008 | { |
| 1009 | AssertSz(THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type, "ThemeLoadRichEditFromResource called for non-RichEdit control."); | ||
| 1048 | 1010 | ||
| 1049 | ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast<LPARAM>(&es)); | 1011 | hr = WnduLoadRichEditFromResource(pThemeControl->hWnd, szResourceName, hModule); |
| 1050 | hr = es.dwError; | 1012 | } |
| 1051 | ThmExitOnFailure(hr, "Failed to update RTF stream."); | ||
| 1052 | 1013 | ||
| 1053 | LExit: | ||
| 1054 | return hr; | 1014 | return hr; |
| 1055 | } | 1015 | } |
| 1056 | 1016 | ||
| @@ -1293,141 +1253,127 @@ LExit: | |||
| 1293 | } | 1253 | } |
| 1294 | 1254 | ||
| 1295 | 1255 | ||
| 1296 | DAPI_(BOOL) ThemeControlExists( | 1256 | DAPI_(BOOL) ThemeControlExistsByHWnd( |
| 1297 | __in const THEME* pTheme, | 1257 | __in const THEME* pTheme, |
| 1298 | __in DWORD dwControl | 1258 | __in HWND hWnd, |
| 1259 | __out_opt const THEME_CONTROL** ppThemeControl | ||
| 1299 | ) | 1260 | ) |
| 1300 | { | 1261 | { |
| 1301 | BOOL fExists = FALSE; | 1262 | const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); |
| 1302 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1263 | |
| 1303 | if (hWnd) | 1264 | if (ppThemeControl) |
| 1304 | { | 1265 | { |
| 1305 | const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); | 1266 | *ppThemeControl = pControl; |
| 1306 | fExists = (pControl && hWnd == pControl->hWnd); | ||
| 1307 | } | 1267 | } |
| 1308 | 1268 | ||
| 1309 | return fExists; | 1269 | return NULL != pControl; |
| 1270 | } | ||
| 1271 | |||
| 1272 | |||
| 1273 | DAPI_(BOOL) ThemeControlExistsById( | ||
| 1274 | __in const THEME* pTheme, | ||
| 1275 | __in WORD wId, | ||
| 1276 | __out_opt const THEME_CONTROL** ppThemeControl | ||
| 1277 | ) | ||
| 1278 | { | ||
| 1279 | const THEME_CONTROL* pControl = FindControlFromId(pTheme, wId); | ||
| 1280 | |||
| 1281 | if (ppThemeControl) | ||
| 1282 | { | ||
| 1283 | *ppThemeControl = pControl; | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | return NULL != pControl; | ||
| 1310 | } | 1287 | } |
| 1311 | 1288 | ||
| 1312 | 1289 | ||
| 1313 | DAPI_(void) ThemeControlEnable( | 1290 | DAPI_(void) ThemeControlEnable( |
| 1314 | __in THEME* pTheme, | 1291 | __in const THEME_CONTROL* pThemeControl, |
| 1315 | __in DWORD dwControl, | ||
| 1316 | __in BOOL fEnable | 1292 | __in BOOL fEnable |
| 1317 | ) | 1293 | ) |
| 1318 | { | 1294 | { |
| 1319 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1295 | if (pThemeControl) |
| 1320 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd)); | ||
| 1321 | if (pControl) | ||
| 1322 | { | 1296 | { |
| 1297 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl); | ||
| 1323 | pControl->dwInternalStyle = fEnable ? (pControl->dwInternalStyle & ~INTERNAL_CONTROL_STYLE_DISABLED) : (pControl->dwInternalStyle | INTERNAL_CONTROL_STYLE_DISABLED); | 1298 | pControl->dwInternalStyle = fEnable ? (pControl->dwInternalStyle & ~INTERNAL_CONTROL_STYLE_DISABLED) : (pControl->dwInternalStyle | INTERNAL_CONTROL_STYLE_DISABLED); |
| 1324 | ::EnableWindow(hWnd, fEnable); | 1299 | ::EnableWindow(pControl->hWnd, fEnable); |
| 1325 | 1300 | ||
| 1326 | if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_HIDE_WHEN_DISABLED) | 1301 | if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_HIDE_WHEN_DISABLED) |
| 1327 | { | 1302 | { |
| 1328 | ::ShowWindow(hWnd, fEnable ? SW_SHOW : SW_HIDE); | 1303 | ::ShowWindow(pControl->hWnd, fEnable ? SW_SHOW : SW_HIDE); |
| 1329 | } | 1304 | } |
| 1330 | } | 1305 | } |
| 1331 | } | 1306 | } |
| 1332 | 1307 | ||
| 1333 | 1308 | ||
| 1334 | DAPI_(BOOL) ThemeControlEnabled( | 1309 | DAPI_(BOOL) ThemeControlEnabled( |
| 1335 | __in THEME* pTheme, | 1310 | __in const THEME_CONTROL* pThemeControl |
| 1336 | __in DWORD dwControl | ||
| 1337 | ) | 1311 | ) |
| 1338 | { | 1312 | { |
| 1339 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1313 | BOOL fEnabled = FALSE; |
| 1340 | const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); | 1314 | |
| 1341 | return pControl && !(pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_DISABLED); | 1315 | if (pThemeControl) |
| 1316 | { | ||
| 1317 | fEnabled = !(pThemeControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_DISABLED); | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | return fEnabled; | ||
| 1342 | } | 1321 | } |
| 1343 | 1322 | ||
| 1344 | 1323 | ||
| 1345 | DAPI_(void) ThemeControlElevates( | 1324 | DAPI_(void) ThemeControlElevates( |
| 1346 | __in THEME* pTheme, | 1325 | __in const THEME_CONTROL* pThemeControl, |
| 1347 | __in DWORD dwControl, | ||
| 1348 | __in BOOL fElevates | 1326 | __in BOOL fElevates |
| 1349 | ) | 1327 | ) |
| 1350 | { | 1328 | { |
| 1351 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1329 | if (pThemeControl) |
| 1352 | ::SendMessageW(hWnd, BCM_SETSHIELD, 0, fElevates); | 1330 | { |
| 1331 | ::SendMessageW(pThemeControl->hWnd, BCM_SETSHIELD, 0, fElevates); | ||
| 1332 | } | ||
| 1353 | } | 1333 | } |
| 1354 | 1334 | ||
| 1355 | 1335 | ||
| 1356 | DAPI_(void) ThemeShowControl( | 1336 | DAPI_(void) ThemeShowControl( |
| 1357 | __in THEME* pTheme, | 1337 | __in const THEME_CONTROL* pThemeControl, |
| 1358 | __in DWORD dwControl, | ||
| 1359 | __in int nCmdShow | 1338 | __in int nCmdShow |
| 1360 | ) | 1339 | ) |
| 1361 | { | 1340 | { |
| 1362 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1341 | if (pThemeControl) |
| 1363 | ::ShowWindow(hWnd, nCmdShow); | ||
| 1364 | |||
| 1365 | // Save the control's visible state. | ||
| 1366 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd)); | ||
| 1367 | if (pControl) | ||
| 1368 | { | 1342 | { |
| 1343 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl); | ||
| 1344 | ::ShowWindow(pControl->hWnd, nCmdShow); | ||
| 1345 | |||
| 1346 | // Save the control's visible state. | ||
| 1369 | pControl->dwInternalStyle = (SW_HIDE == nCmdShow) ? (pControl->dwInternalStyle | INTERNAL_CONTROL_STYLE_HIDDEN) : (pControl->dwInternalStyle & ~INTERNAL_CONTROL_STYLE_HIDDEN); | 1347 | pControl->dwInternalStyle = (SW_HIDE == nCmdShow) ? (pControl->dwInternalStyle | INTERNAL_CONTROL_STYLE_HIDDEN) : (pControl->dwInternalStyle & ~INTERNAL_CONTROL_STYLE_HIDDEN); |
| 1370 | } | 1348 | } |
| 1371 | } | 1349 | } |
| 1372 | 1350 | ||
| 1373 | 1351 | ||
| 1374 | DAPI_(void) ThemeShowControlEx( | 1352 | DAPI_(void) ThemeShowControlEx( |
| 1375 | __in THEME* pTheme, | 1353 | __in const THEME_CONTROL* pThemeControl, |
| 1376 | __in DWORD dwControl, | ||
| 1377 | __in int nCmdShow | 1354 | __in int nCmdShow |
| 1378 | ) | 1355 | ) |
| 1379 | { | 1356 | { |
| 1380 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1357 | if (pThemeControl) |
| 1381 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd)); | ||
| 1382 | if (pControl) | ||
| 1383 | { | 1358 | { |
| 1384 | ShowControl(pTheme, pControl, nCmdShow, THEME_CONTROL_TYPE_EDITBOX == pControl->type, THEME_SHOW_PAGE_REASON_REFRESH, 0, NULL); | 1359 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl); |
| 1360 | ShowControl(pControl, nCmdShow, THEME_CONTROL_TYPE_EDITBOX == pControl->type, THEME_SHOW_PAGE_REASON_REFRESH, 0, NULL); | ||
| 1385 | } | 1361 | } |
| 1386 | } | 1362 | } |
| 1387 | 1363 | ||
| 1388 | 1364 | ||
| 1389 | DAPI_(BOOL) ThemeControlVisible( | 1365 | DAPI_(BOOL) ThemeControlVisible( |
| 1390 | __in THEME* pTheme, | 1366 | __in const THEME_CONTROL* pThemeControl |
| 1391 | __in DWORD dwControl | ||
| 1392 | ) | 1367 | ) |
| 1393 | { | 1368 | { |
| 1394 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1369 | BOOL fVisible = FALSE; |
| 1395 | return ::IsWindowVisible(hWnd); | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | 1370 | ||
| 1399 | DAPI_(BOOL) ThemePostControlMessage( | 1371 | if (pThemeControl) |
| 1400 | __in THEME* pTheme, | ||
| 1401 | __in DWORD dwControl, | ||
| 1402 | __in UINT Msg, | ||
| 1403 | __in WPARAM wParam, | ||
| 1404 | __in LPARAM lParam | ||
| 1405 | ) | ||
| 1406 | { | ||
| 1407 | HRESULT hr = S_OK; | ||
| 1408 | UINT er = ERROR_SUCCESS; | ||
| 1409 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | ||
| 1410 | |||
| 1411 | if (!::PostMessageW(hWnd, Msg, wParam, lParam)) | ||
| 1412 | { | 1372 | { |
| 1413 | er = ::GetLastError(); | 1373 | fVisible = ::IsWindowVisible(pThemeControl->hWnd); |
| 1414 | hr = HRESULT_FROM_WIN32(er); | ||
| 1415 | } | 1374 | } |
| 1416 | 1375 | ||
| 1417 | return SUCCEEDED(hr); | 1376 | return fVisible; |
| 1418 | } | ||
| 1419 | |||
| 1420 | |||
| 1421 | DAPI_(LRESULT) ThemeSendControlMessage( | ||
| 1422 | __in const THEME* pTheme, | ||
| 1423 | __in DWORD dwControl, | ||
| 1424 | __in UINT Msg, | ||
| 1425 | __in WPARAM wParam, | ||
| 1426 | __in LPARAM lParam | ||
| 1427 | ) | ||
| 1428 | { | ||
| 1429 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | ||
| 1430 | return ::SendMessageW(hWnd, Msg, wParam, lParam); | ||
| 1431 | } | 1377 | } |
| 1432 | 1378 | ||
| 1433 | 1379 | ||
| @@ -1453,9 +1399,15 @@ DAPI_(HRESULT) ThemeDrawControl( | |||
| 1453 | ) | 1399 | ) |
| 1454 | { | 1400 | { |
| 1455 | HRESULT hr = S_OK; | 1401 | HRESULT hr = S_OK; |
| 1456 | const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, pdis->hwndItem); | 1402 | const THEME_CONTROL* pControl = NULL; |
| 1403 | BOOL fExists = ThemeControlExistsByHWnd(pTheme, pdis->hwndItem, &pControl); | ||
| 1404 | |||
| 1405 | AssertSz(fExists, "Expected control window from owner draw window."); | ||
| 1406 | if (!fExists) | ||
| 1407 | { | ||
| 1408 | ExitFunction1(hr = E_INVALIDARG); | ||
| 1409 | } | ||
| 1457 | 1410 | ||
| 1458 | AssertSz(pControl, "Expected control window from owner draw window."); | ||
| 1459 | AssertSz(pControl->hWnd == pdis->hwndItem, "Expected control window to match owner draw window."); | 1411 | AssertSz(pControl->hWnd == pdis->hwndItem, "Expected control window to match owner draw window."); |
| 1460 | AssertSz(pControl->nWidth < 1 || pControl->nWidth == pdis->rcItem.right - pdis->rcItem.left, "Expected control window width to match owner draw window width."); | 1412 | AssertSz(pControl->nWidth < 1 || pControl->nWidth == pdis->rcItem.right - pdis->rcItem.left, "Expected control window width to match owner draw window width."); |
| 1461 | AssertSz(pControl->nHeight < 1 || pControl->nHeight == pdis->rcItem.bottom - pdis->rcItem.top, "Expected control window height to match owner draw window height."); | 1413 | AssertSz(pControl->nHeight < 1 || pControl->nHeight == pdis->rcItem.bottom - pdis->rcItem.top, "Expected control window height to match owner draw window height."); |
| @@ -1492,7 +1444,7 @@ LExit: | |||
| 1492 | } | 1444 | } |
| 1493 | 1445 | ||
| 1494 | 1446 | ||
| 1495 | DAPI_(BOOL) ThemeHoverControl( | 1447 | static BOOL ThemeHoverControl( |
| 1496 | __in THEME* pTheme, | 1448 | __in THEME* pTheme, |
| 1497 | __in HWND hwndParent, | 1449 | __in HWND hwndParent, |
| 1498 | __in HWND hwndControl | 1450 | __in HWND hwndControl |
| @@ -1519,16 +1471,21 @@ DAPI_(BOOL) ThemeHoverControl( | |||
| 1519 | 1471 | ||
| 1520 | 1472 | ||
| 1521 | DAPI_(BOOL) ThemeIsControlChecked( | 1473 | DAPI_(BOOL) ThemeIsControlChecked( |
| 1522 | __in THEME* pTheme, | 1474 | __in const THEME_CONTROL* pThemeControl |
| 1523 | __in DWORD dwControl | ||
| 1524 | ) | 1475 | ) |
| 1525 | { | 1476 | { |
| 1526 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1477 | BOOL fChecked = FALSE; |
| 1527 | return BST_CHECKED == ::SendMessageW(hWnd, BM_GETCHECK, 0, 0); | 1478 | |
| 1479 | if (pThemeControl) | ||
| 1480 | { | ||
| 1481 | fChecked = BST_CHECKED == ::SendMessageW(pThemeControl->hWnd, BM_GETCHECK, 0, 0); | ||
| 1482 | } | ||
| 1483 | |||
| 1484 | return fChecked; | ||
| 1528 | } | 1485 | } |
| 1529 | 1486 | ||
| 1530 | 1487 | ||
| 1531 | DAPI_(BOOL) ThemeSetControlColor( | 1488 | static BOOL ThemeSetControlColor( |
| 1532 | __in THEME* pTheme, | 1489 | __in THEME* pTheme, |
| 1533 | __in HDC hdc, | 1490 | __in HDC hdc, |
| 1534 | __in HWND hWnd, | 1491 | __in HWND hWnd, |
| @@ -1537,6 +1494,7 @@ DAPI_(BOOL) ThemeSetControlColor( | |||
| 1537 | { | 1494 | { |
| 1538 | THEME_FONT* pFont = NULL; | 1495 | THEME_FONT* pFont = NULL; |
| 1539 | BOOL fHasBackground = FALSE; | 1496 | BOOL fHasBackground = FALSE; |
| 1497 | const THEME_CONTROL* pControl = NULL; | ||
| 1540 | 1498 | ||
| 1541 | *phBackgroundBrush = NULL; | 1499 | *phBackgroundBrush = NULL; |
| 1542 | 1500 | ||
| @@ -1544,10 +1502,9 @@ DAPI_(BOOL) ThemeSetControlColor( | |||
| 1544 | { | 1502 | { |
| 1545 | pFont = (THEME_INVALID_ID == pTheme->dwFontId) ? NULL : pTheme->rgFonts + pTheme->dwFontId; | 1503 | pFont = (THEME_INVALID_ID == pTheme->dwFontId) ? NULL : pTheme->rgFonts + pTheme->dwFontId; |
| 1546 | } | 1504 | } |
| 1547 | else | 1505 | else if (ThemeControlExistsByHWnd(pTheme, hWnd, &pControl)) |
| 1548 | { | 1506 | { |
| 1549 | const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); | 1507 | pFont = THEME_INVALID_ID == pControl->dwFontId ? NULL : pTheme->rgFonts + pControl->dwFontId; |
| 1550 | pFont = (!pControl || THEME_INVALID_ID == pControl->dwFontId) ? NULL : pTheme->rgFonts + pControl->dwFontId; | ||
| 1551 | } | 1508 | } |
| 1552 | 1509 | ||
| 1553 | if (pFont) | 1510 | if (pFont) |
| @@ -1577,44 +1534,40 @@ DAPI_(BOOL) ThemeSetControlColor( | |||
| 1577 | 1534 | ||
| 1578 | 1535 | ||
| 1579 | DAPI_(HRESULT) ThemeSetProgressControl( | 1536 | DAPI_(HRESULT) ThemeSetProgressControl( |
| 1580 | __in THEME* pTheme, | 1537 | __in const THEME_CONTROL* pThemeControl, |
| 1581 | __in DWORD dwControl, | ||
| 1582 | __in DWORD dwProgressPercentage | 1538 | __in DWORD dwProgressPercentage |
| 1583 | ) | 1539 | ) |
| 1584 | { | 1540 | { |
| 1585 | HRESULT hr = E_NOTFOUND; | 1541 | HRESULT hr = E_INVALIDARG; |
| 1586 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | ||
| 1587 | 1542 | ||
| 1588 | if (hWnd) | 1543 | if (pThemeControl && THEME_CONTROL_TYPE_PROGRESSBAR == pThemeControl->type) |
| 1589 | { | 1544 | { |
| 1590 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd)); | 1545 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl); |
| 1591 | if (pControl && THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type) | 1546 | |
| 1547 | DWORD dwCurrentProgress = LOWORD(pControl->dwData); | ||
| 1548 | |||
| 1549 | if (dwCurrentProgress != dwProgressPercentage) | ||
| 1592 | { | 1550 | { |
| 1593 | DWORD dwCurrentProgress = LOWORD(pControl->dwData); | 1551 | DWORD dwColor = HIWORD(pControl->dwData); |
| 1552 | pControl->dwData = MAKEDWORD(dwProgressPercentage, dwColor); | ||
| 1594 | 1553 | ||
| 1595 | if (dwCurrentProgress != dwProgressPercentage) | 1554 | if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW) |
| 1596 | { | 1555 | { |
| 1597 | DWORD dwColor = HIWORD(pControl->dwData); | 1556 | if (!::InvalidateRect(pControl->hWnd, NULL, FALSE)) |
| 1598 | pControl->dwData = MAKEDWORD(dwProgressPercentage, dwColor); | ||
| 1599 | |||
| 1600 | if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW) | ||
| 1601 | { | 1557 | { |
| 1602 | if (!::InvalidateRect(hWnd, NULL, FALSE)) | 1558 | ThmExitWithLastError(hr, "Failed to invalidate progress bar window."); |
| 1603 | { | ||
| 1604 | ThmExitWithLastError(hr, "Failed to invalidate progress bar window."); | ||
| 1605 | } | ||
| 1606 | } | ||
| 1607 | else | ||
| 1608 | { | ||
| 1609 | ::SendMessageW(hWnd, PBM_SETPOS, dwProgressPercentage, 0); | ||
| 1610 | } | 1559 | } |
| 1611 | |||
| 1612 | hr = S_OK; | ||
| 1613 | } | 1560 | } |
| 1614 | else | 1561 | else |
| 1615 | { | 1562 | { |
| 1616 | hr = S_FALSE; | 1563 | ::SendMessageW(pControl->hWnd, PBM_SETPOS, dwProgressPercentage, 0); |
| 1617 | } | 1564 | } |
| 1565 | |||
| 1566 | hr = S_OK; | ||
| 1567 | } | ||
| 1568 | else | ||
| 1569 | { | ||
| 1570 | hr = S_FALSE; | ||
| 1618 | } | 1571 | } |
| 1619 | } | 1572 | } |
| 1620 | 1573 | ||
| @@ -1624,37 +1577,37 @@ LExit: | |||
| 1624 | 1577 | ||
| 1625 | 1578 | ||
| 1626 | DAPI_(HRESULT) ThemeSetProgressControlColor( | 1579 | DAPI_(HRESULT) ThemeSetProgressControlColor( |
| 1627 | __in THEME* pTheme, | 1580 | __in const THEME_CONTROL* pThemeControl, |
| 1628 | __in DWORD dwControl, | ||
| 1629 | __in DWORD dwColorIndex | 1581 | __in DWORD dwColorIndex |
| 1630 | ) | 1582 | ) |
| 1631 | { | 1583 | { |
| 1632 | HRESULT hr = S_FALSE; | 1584 | HRESULT hr = E_INVALIDARG; |
| 1633 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1585 | |
| 1634 | if (hWnd) | 1586 | // Only set color on owner draw progress bars. |
| 1587 | if (pThemeControl && THEME_CONTROL_TYPE_PROGRESSBAR == pThemeControl->type && (pThemeControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW)) | ||
| 1635 | { | 1588 | { |
| 1636 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd)); | 1589 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl); |
| 1637 | 1590 | ||
| 1638 | // Only set color on owner draw progress bars. | 1591 | if (pControl->ProgressBar.cImageRef <= dwColorIndex) |
| 1639 | if (pControl && (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW) && THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type) | ||
| 1640 | { | 1592 | { |
| 1641 | if (pControl->ProgressBar.cImageRef <= dwColorIndex) | 1593 | ThmExitWithRootFailure(hr, E_INVALIDARG, "Invalid progress bar color index: %u", dwColorIndex); |
| 1642 | { | 1594 | } |
| 1643 | ThmExitWithRootFailure(hr, E_INVALIDARG, "Invalid progress bar color index: %u", dwColorIndex); | ||
| 1644 | } | ||
| 1645 | |||
| 1646 | if (HIWORD(pControl->dwData) != dwColorIndex) | ||
| 1647 | { | ||
| 1648 | DWORD dwCurrentProgress = LOWORD(pControl->dwData); | ||
| 1649 | pControl->dwData = MAKEDWORD(dwCurrentProgress, dwColorIndex); | ||
| 1650 | 1595 | ||
| 1651 | if (!::InvalidateRect(hWnd, NULL, FALSE)) | 1596 | if (HIWORD(pControl->dwData) != dwColorIndex) |
| 1652 | { | 1597 | { |
| 1653 | ThmExitWithLastError(hr, "Failed to invalidate progress bar window."); | 1598 | DWORD dwCurrentProgress = LOWORD(pControl->dwData); |
| 1654 | } | 1599 | pControl->dwData = MAKEDWORD(dwCurrentProgress, dwColorIndex); |
| 1655 | 1600 | ||
| 1656 | hr = S_OK; | 1601 | if (!::InvalidateRect(pControl->hWnd, NULL, FALSE)) |
| 1602 | { | ||
| 1603 | ThmExitWithLastError(hr, "Failed to invalidate progress bar window."); | ||
| 1657 | } | 1604 | } |
| 1605 | |||
| 1606 | hr = S_OK; | ||
| 1607 | } | ||
| 1608 | else | ||
| 1609 | { | ||
| 1610 | hr = S_FALSE; | ||
| 1658 | } | 1611 | } |
| 1659 | } | 1612 | } |
| 1660 | 1613 | ||
| @@ -1664,41 +1617,40 @@ LExit: | |||
| 1664 | 1617 | ||
| 1665 | 1618 | ||
| 1666 | DAPI_(HRESULT) ThemeSetTextControl( | 1619 | DAPI_(HRESULT) ThemeSetTextControl( |
| 1667 | __in const THEME* pTheme, | 1620 | __in const THEME_CONTROL* pThemeControl, |
| 1668 | __in DWORD dwControl, | ||
| 1669 | __in_z_opt LPCWSTR wzText | 1621 | __in_z_opt LPCWSTR wzText |
| 1670 | ) | 1622 | ) |
| 1671 | { | 1623 | { |
| 1672 | return ThemeSetTextControlEx(pTheme, dwControl, FALSE, wzText); | 1624 | return ThemeSetTextControlEx(pThemeControl, FALSE, wzText); |
| 1673 | } | 1625 | } |
| 1674 | 1626 | ||
| 1675 | 1627 | ||
| 1676 | DAPI_(HRESULT) ThemeSetTextControlEx( | 1628 | DAPI_(HRESULT) ThemeSetTextControlEx( |
| 1677 | __in const THEME* pTheme, | 1629 | __in const THEME_CONTROL* pThemeControl, |
| 1678 | __in DWORD dwControl, | ||
| 1679 | __in BOOL fUpdate, | 1630 | __in BOOL fUpdate, |
| 1680 | __in_z_opt LPCWSTR wzText | 1631 | __in_z_opt LPCWSTR wzText |
| 1681 | ) | 1632 | ) |
| 1682 | { | 1633 | { |
| 1683 | HRESULT hr = S_OK; | 1634 | HRESULT hr = E_INVALIDARG; |
| 1684 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | ||
| 1685 | 1635 | ||
| 1686 | if (hWnd) | 1636 | if (pThemeControl) |
| 1687 | { | 1637 | { |
| 1688 | if (fUpdate) | 1638 | if (fUpdate) |
| 1689 | { | 1639 | { |
| 1690 | ::ShowWindow(hWnd, SW_HIDE); | 1640 | ::ShowWindow(pThemeControl->hWnd, SW_HIDE); |
| 1691 | } | 1641 | } |
| 1692 | 1642 | ||
| 1693 | if (!::SetWindowTextW(hWnd, wzText)) | 1643 | if (!::SetWindowTextW(pThemeControl->hWnd, wzText)) |
| 1694 | { | 1644 | { |
| 1695 | ThmExitWithLastError(hr, "Failed to set control text."); | 1645 | ThmExitWithLastError(hr, "Failed to set control text."); |
| 1696 | } | 1646 | } |
| 1697 | 1647 | ||
| 1698 | if (fUpdate) | 1648 | if (fUpdate) |
| 1699 | { | 1649 | { |
| 1700 | ::ShowWindow(hWnd, SW_SHOW); | 1650 | ::ShowWindow(pThemeControl->hWnd, SW_SHOW); |
| 1701 | } | 1651 | } |
| 1652 | |||
| 1653 | hr = S_OK; | ||
| 1702 | } | 1654 | } |
| 1703 | 1655 | ||
| 1704 | LExit: | 1656 | LExit: |
| @@ -1707,50 +1659,17 @@ LExit: | |||
| 1707 | 1659 | ||
| 1708 | 1660 | ||
| 1709 | DAPI_(HRESULT) ThemeGetTextControl( | 1661 | DAPI_(HRESULT) ThemeGetTextControl( |
| 1710 | __in const THEME* pTheme, | 1662 | __in const THEME_CONTROL* pThemeControl, |
| 1711 | __in DWORD dwControl, | ||
| 1712 | __inout_z LPWSTR* psczText | 1663 | __inout_z LPWSTR* psczText |
| 1713 | ) | 1664 | ) |
| 1714 | { | 1665 | { |
| 1715 | HRESULT hr = S_OK; | 1666 | HRESULT hr = E_INVALIDARG; |
| 1716 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | ||
| 1717 | SIZE_T cbSize = 0; | ||
| 1718 | DWORD cchText = 0; | ||
| 1719 | DWORD cchTextRead = 0; | ||
| 1720 | |||
| 1721 | // Ensure the string has room for at least one character. | ||
| 1722 | hr = StrMaxLength(*psczText, &cbSize); | ||
| 1723 | ThmExitOnFailure(hr, "Failed to get text buffer length."); | ||
| 1724 | 1667 | ||
| 1725 | cchText = (DWORD)min(DWORD_MAX, cbSize); | 1668 | if (pThemeControl) |
| 1726 | |||
| 1727 | if (!cchText) | ||
| 1728 | { | 1669 | { |
| 1729 | cchText = GROW_WINDOW_TEXT; | 1670 | hr = WnduGetControlText(pThemeControl->hWnd, psczText); |
| 1730 | |||
| 1731 | hr = StrAlloc(psczText, cchText); | ||
| 1732 | ThmExitOnFailure(hr, "Failed to grow text buffer."); | ||
| 1733 | } | 1671 | } |
| 1734 | 1672 | ||
| 1735 | // Read (and keep growing buffer) until we finally read less than there | ||
| 1736 | // is room in the buffer. | ||
| 1737 | for (;;) | ||
| 1738 | { | ||
| 1739 | cchTextRead = ::GetWindowTextW(hWnd, *psczText, cchText); | ||
| 1740 | if (cchTextRead + 1 < cchText) | ||
| 1741 | { | ||
| 1742 | break; | ||
| 1743 | } | ||
| 1744 | else | ||
| 1745 | { | ||
| 1746 | cchText = cchTextRead + GROW_WINDOW_TEXT; | ||
| 1747 | |||
| 1748 | hr = StrAlloc(psczText, cchText); | ||
| 1749 | ThmExitOnFailure(hr, "Failed to grow text buffer again."); | ||
| 1750 | } | ||
| 1751 | } | ||
| 1752 | |||
| 1753 | LExit: | ||
| 1754 | return hr; | 1673 | return hr; |
| 1755 | } | 1674 | } |
| 1756 | 1675 | ||
| @@ -1771,25 +1690,26 @@ LExit: | |||
| 1771 | 1690 | ||
| 1772 | 1691 | ||
| 1773 | DAPI_(void) ThemeSetFocus( | 1692 | DAPI_(void) ThemeSetFocus( |
| 1774 | __in THEME* pTheme, | 1693 | __in const THEME_CONTROL* pThemeControl |
| 1775 | __in DWORD dwControl | ||
| 1776 | ) | 1694 | ) |
| 1777 | { | 1695 | { |
| 1778 | HWND hwndFocus = ::GetDlgItem(pTheme->hwndParent, dwControl); | 1696 | if (pThemeControl) |
| 1779 | if (hwndFocus && !ThemeControlEnabled(pTheme, dwControl)) | 1697 | { |
| 1780 | { | 1698 | HWND hwndFocus = pThemeControl->hWnd; |
| 1781 | hwndFocus = ::GetNextDlgTabItem(pTheme->hwndParent, hwndFocus, FALSE); | 1699 | if (hwndFocus && !ThemeControlEnabled(pThemeControl)) |
| 1782 | } | 1700 | { |
| 1701 | hwndFocus = ::GetNextDlgTabItem(pThemeControl->pTheme->hwndParent, hwndFocus, FALSE); | ||
| 1702 | } | ||
| 1783 | 1703 | ||
| 1784 | if (hwndFocus) | 1704 | if (hwndFocus) |
| 1785 | { | 1705 | { |
| 1786 | ::SetFocus(hwndFocus); | 1706 | ::SetFocus(hwndFocus); |
| 1707 | } | ||
| 1787 | } | 1708 | } |
| 1788 | } | 1709 | } |
| 1789 | 1710 | ||
| 1790 | 1711 | ||
| 1791 | DAPI_(void) ThemeShowChild( | 1712 | DAPI_(void) ThemeShowChild( |
| 1792 | __in THEME* pTheme, | ||
| 1793 | __in THEME_CONTROL* pParentControl, | 1713 | __in THEME_CONTROL* pParentControl, |
| 1794 | __in DWORD dwIndex | 1714 | __in DWORD dwIndex |
| 1795 | ) | 1715 | ) |
| @@ -1798,7 +1718,7 @@ DAPI_(void) ThemeShowChild( | |||
| 1798 | for (DWORD i = 0; i < pParentControl->cControls; ++i) | 1718 | for (DWORD i = 0; i < pParentControl->cControls; ++i) |
| 1799 | { | 1719 | { |
| 1800 | THEME_CONTROL* pControl = pParentControl->rgControls + i; | 1720 | THEME_CONTROL* pControl = pParentControl->rgControls + i; |
| 1801 | ShowControl(pTheme, pControl, dwIndex == i ? SW_SHOW : SW_HIDE, FALSE, THEME_SHOW_PAGE_REASON_DEFAULT, 0, NULL); | 1721 | ShowControl(pControl, dwIndex == i ? SW_SHOW : SW_HIDE, FALSE, THEME_SHOW_PAGE_REASON_DEFAULT, 0, NULL); |
| 1802 | } | 1722 | } |
| 1803 | } | 1723 | } |
| 1804 | 1724 | ||
| @@ -4322,28 +4242,24 @@ LExit: | |||
| 4322 | 4242 | ||
| 4323 | static HRESULT StartBillboard( | 4243 | static HRESULT StartBillboard( |
| 4324 | __in THEME* pTheme, | 4244 | __in THEME* pTheme, |
| 4325 | __in DWORD dwControl | 4245 | __in THEME_CONTROL* pControl |
| 4326 | ) | 4246 | ) |
| 4327 | { | 4247 | { |
| 4328 | HRESULT hr = E_NOTFOUND; | 4248 | HRESULT hr = E_NOTFOUND; |
| 4329 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 4249 | UINT_PTR idEvent = reinterpret_cast<UINT_PTR>(pControl); |
| 4330 | 4250 | ||
| 4331 | if (hWnd) | 4251 | if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) |
| 4332 | { | 4252 | { |
| 4333 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd)); | 4253 | // kick off |
| 4334 | if (pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type) | 4254 | pControl->dwData = 0; |
| 4335 | { | 4255 | OnBillboardTimer(pTheme, pTheme->hwndParent, idEvent); |
| 4336 | // kick off | ||
| 4337 | pControl->dwData = 0; | ||
| 4338 | OnBillboardTimer(pTheme, pTheme->hwndParent, dwControl); | ||
| 4339 | 4256 | ||
| 4340 | if (!::SetTimer(pTheme->hwndParent, pControl->wId, pControl->wBillboardInterval, NULL)) | 4257 | if (!::SetTimer(pTheme->hwndParent, idEvent, pControl->wBillboardInterval, NULL)) |
| 4341 | { | 4258 | { |
| 4342 | ThmExitWithLastError(hr, "Failed to start billboard."); | 4259 | ThmExitWithLastError(hr, "Failed to start billboard."); |
| 4343 | } | ||
| 4344 | |||
| 4345 | hr = S_OK; | ||
| 4346 | } | 4260 | } |
| 4261 | |||
| 4262 | hr = S_OK; | ||
| 4347 | } | 4263 | } |
| 4348 | 4264 | ||
| 4349 | LExit: | 4265 | LExit: |
| @@ -4353,23 +4269,19 @@ LExit: | |||
| 4353 | 4269 | ||
| 4354 | static HRESULT StopBillboard( | 4270 | static HRESULT StopBillboard( |
| 4355 | __in THEME* pTheme, | 4271 | __in THEME* pTheme, |
| 4356 | __in DWORD dwControl | 4272 | __in THEME_CONTROL* pControl |
| 4357 | ) | 4273 | ) |
| 4358 | { | 4274 | { |
| 4359 | HRESULT hr = E_NOTFOUND; | 4275 | HRESULT hr = E_NOTFOUND; |
| 4360 | HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); | 4276 | UINT_PTR idEvent = reinterpret_cast<UINT_PTR>(pControl); |
| 4361 | 4277 | ||
| 4362 | if (hWnd) | 4278 | if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) |
| 4363 | { | 4279 | { |
| 4364 | const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); | 4280 | ThemeControlEnable(pControl, FALSE); |
| 4365 | if (pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type) | ||
| 4366 | { | ||
| 4367 | ThemeControlEnable(pTheme, dwControl, FALSE); | ||
| 4368 | 4281 | ||
| 4369 | if (::KillTimer(pTheme->hwndParent, pControl->wId)) | 4282 | if (::KillTimer(pTheme->hwndParent, idEvent)) |
| 4370 | { | 4283 | { |
| 4371 | hr = S_OK; | 4284 | hr = S_OK; |
| 4372 | } | ||
| 4373 | } | 4285 | } |
| 4374 | } | 4286 | } |
| 4375 | 4287 | ||
| @@ -5039,81 +4951,33 @@ static void FreeImageInstance( | |||
| 5039 | } | 4951 | } |
| 5040 | 4952 | ||
| 5041 | 4953 | ||
| 5042 | static DWORD CALLBACK RichEditStreamFromFileHandleCallback( | ||
| 5043 | __in DWORD_PTR dwCookie, | ||
| 5044 | __in_bcount(cb) LPBYTE pbBuff, | ||
| 5045 | __in LONG cb, | ||
| 5046 | __in LONG* pcb | ||
| 5047 | ) | ||
| 5048 | { | ||
| 5049 | HRESULT hr = S_OK; | ||
| 5050 | HANDLE hFile = reinterpret_cast<HANDLE>(dwCookie); | ||
| 5051 | |||
| 5052 | if (!::ReadFile(hFile, pbBuff, cb, reinterpret_cast<DWORD*>(pcb), NULL)) | ||
| 5053 | { | ||
| 5054 | ThmExitWithLastError(hr, "Failed to read file"); | ||
| 5055 | } | ||
| 5056 | |||
| 5057 | LExit: | ||
| 5058 | return hr; | ||
| 5059 | } | ||
| 5060 | |||
| 5061 | |||
| 5062 | static DWORD CALLBACK RichEditStreamFromMemoryCallback( | ||
| 5063 | __in DWORD_PTR dwCookie, | ||
| 5064 | __in_bcount(cb) LPBYTE pbBuff, | ||
| 5065 | __in LONG cb, | ||
| 5066 | __in LONG* pcb | ||
| 5067 | ) | ||
| 5068 | { | ||
| 5069 | HRESULT hr = S_OK; | ||
| 5070 | MEMBUFFER_FOR_RICHEDIT* pBuffer = reinterpret_cast<MEMBUFFER_FOR_RICHEDIT*>(dwCookie); | ||
| 5071 | DWORD cbCopy = 0; | ||
| 5072 | |||
| 5073 | if (pBuffer->iData < pBuffer->cbData) | ||
| 5074 | { | ||
| 5075 | cbCopy = min(static_cast<DWORD>(cb), pBuffer->cbData - pBuffer->iData); | ||
| 5076 | memcpy(pbBuff, pBuffer->rgbData + pBuffer->iData, cbCopy); | ||
| 5077 | |||
| 5078 | pBuffer->iData += cbCopy; | ||
| 5079 | Assert(pBuffer->iData <= pBuffer->cbData); | ||
| 5080 | } | ||
| 5081 | |||
| 5082 | *pcb = cbCopy; | ||
| 5083 | return hr; | ||
| 5084 | } | ||
| 5085 | |||
| 5086 | |||
| 5087 | static void CALLBACK OnBillboardTimer( | 4954 | static void CALLBACK OnBillboardTimer( |
| 5088 | __in THEME* pTheme, | 4955 | __in THEME* /*pTheme*/, |
| 5089 | __in HWND hwnd, | 4956 | __in HWND hwnd, |
| 5090 | __in UINT_PTR idEvent | 4957 | __in UINT_PTR idEvent |
| 5091 | ) | 4958 | ) |
| 5092 | { | 4959 | { |
| 5093 | HWND hwndControl = ::GetDlgItem(hwnd, static_cast<int>(idEvent)); | 4960 | THEME_CONTROL* pControl = reinterpret_cast<THEME_CONTROL*>(idEvent); |
| 5094 | if (hwndControl) | 4961 | |
| 4962 | if (pControl) | ||
| 5095 | { | 4963 | { |
| 5096 | THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hwndControl)); | 4964 | AssertSz(THEME_CONTROL_TYPE_BILLBOARD == pControl->type, "Only billboard controls should get billboard timer messages."); |
| 5097 | AssertSz(pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type, "Only billboard controls should get billboard timer messages."); | ||
| 5098 | 4965 | ||
| 5099 | if (pControl) | 4966 | if (pControl->dwData < pControl->cControls) |
| 5100 | { | 4967 | { |
| 5101 | if (pControl->dwData < pControl->cControls) | 4968 | ThemeShowChild(pControl, pControl->dwData); |
| 5102 | { | ||
| 5103 | ThemeShowChild(pTheme, pControl, pControl->dwData); | ||
| 5104 | } | ||
| 5105 | else if (pControl->fBillboardLoops) | ||
| 5106 | { | ||
| 5107 | pControl->dwData = 0; | ||
| 5108 | ThemeShowChild(pTheme, pControl, pControl->dwData); | ||
| 5109 | } | ||
| 5110 | else // no more looping | ||
| 5111 | { | ||
| 5112 | ::KillTimer(hwnd, idEvent); | ||
| 5113 | } | ||
| 5114 | |||
| 5115 | ++pControl->dwData; | ||
| 5116 | } | 4969 | } |
| 4970 | else if (pControl->fBillboardLoops) | ||
| 4971 | { | ||
| 4972 | pControl->dwData = 0; | ||
| 4973 | ThemeShowChild(pControl, pControl->dwData); | ||
| 4974 | } | ||
| 4975 | else // no more looping | ||
| 4976 | { | ||
| 4977 | ::KillTimer(hwnd, idEvent); | ||
| 4978 | } | ||
| 4979 | |||
| 4980 | ++pControl->dwData; | ||
| 5117 | } | 4981 | } |
| 5118 | } | 4982 | } |
| 5119 | 4983 | ||
| @@ -5151,7 +5015,7 @@ static void OnBrowseDirectory( | |||
| 5151 | 5015 | ||
| 5152 | if (pTargetControl && THEME_CONTROL_TYPE_EDITBOX == pTargetControl->type && !pTargetControl->fDisableVariableFunctionality) | 5016 | if (pTargetControl && THEME_CONTROL_TYPE_EDITBOX == pTargetControl->type && !pTargetControl->fDisableVariableFunctionality) |
| 5153 | { | 5017 | { |
| 5154 | hr = ThemeSetTextControl(pTheme, pTargetControl->wId, wzPath); | 5018 | hr = ThemeSetTextControl(pTargetControl, wzPath); |
| 5155 | ThmExitOnFailure(hr, "Failed to set text on editbox: %ls", pTargetControl->sczName); | 5019 | ThmExitOnFailure(hr, "Failed to set text on editbox: %ls", pTargetControl->sczName); |
| 5156 | } | 5020 | } |
| 5157 | else if (pTheme->pfnSetStringVariable) | 5021 | else if (pTheme->pfnSetStringVariable) |
| @@ -5161,7 +5025,7 @@ static void OnBrowseDirectory( | |||
| 5161 | } | 5025 | } |
| 5162 | else if (pTargetControl) | 5026 | else if (pTargetControl) |
| 5163 | { | 5027 | { |
| 5164 | hr = ThemeSetTextControl(pTheme, pTargetControl->wId, wzPath); | 5028 | hr = ThemeSetTextControl(pTargetControl, wzPath); |
| 5165 | ThmExitOnFailure(hr, "Failed to set text on control: %ls", pTargetControl->sczName); | 5029 | ThmExitOnFailure(hr, "Failed to set text on control: %ls", pTargetControl->sczName); |
| 5166 | } | 5030 | } |
| 5167 | 5031 | ||
| @@ -5252,13 +5116,13 @@ static BOOL OnButtonClicked( | |||
| 5252 | case THEME_CONTROL_TYPE_CHECKBOX: | 5116 | case THEME_CONTROL_TYPE_CHECKBOX: |
| 5253 | if (pTheme->pfnSetNumericVariable && pControl->sczName && *pControl->sczName) | 5117 | if (pTheme->pfnSetNumericVariable && pControl->sczName && *pControl->sczName) |
| 5254 | { | 5118 | { |
| 5255 | BOOL fChecked = ThemeIsControlChecked(pTheme, pControl->wId); | 5119 | BOOL fChecked = ThemeIsControlChecked(pControl); |
| 5256 | pTheme->pfnSetNumericVariable(pControl->sczName, fChecked ? 1 : 0, pTheme->pvVariableContext); | 5120 | pTheme->pfnSetNumericVariable(pControl->sczName, fChecked ? 1 : 0, pTheme->pvVariableContext); |
| 5257 | fRefresh = TRUE; | 5121 | fRefresh = TRUE; |
| 5258 | } | 5122 | } |
| 5259 | break; | 5123 | break; |
| 5260 | case THEME_CONTROL_TYPE_RADIOBUTTON: | 5124 | case THEME_CONTROL_TYPE_RADIOBUTTON: |
| 5261 | if (pTheme->pfnSetStringVariable && pControl->sczVariable && *pControl->sczVariable && ThemeIsControlChecked(pTheme, pControl->wId)) | 5125 | if (pTheme->pfnSetStringVariable && pControl->sczVariable && *pControl->sczVariable && ThemeIsControlChecked(pControl)) |
| 5262 | { | 5126 | { |
| 5263 | pTheme->pfnSetStringVariable(pControl->sczVariable, pControl->sczValue, FALSE, pTheme->pvVariableContext); | 5127 | pTheme->pfnSetStringVariable(pControl->sczVariable, pControl->sczValue, FALSE, pTheme->pvVariableContext); |
| 5264 | fRefresh = TRUE; | 5128 | fRefresh = TRUE; |
| @@ -5386,6 +5250,42 @@ LExit: | |||
| 5386 | return fProcessed; | 5250 | return fProcessed; |
| 5387 | } | 5251 | } |
| 5388 | 5252 | ||
| 5253 | static const THEME_CONTROL* FindControlFromId( | ||
| 5254 | __in const THEME* pTheme, | ||
| 5255 | __in WORD wId, | ||
| 5256 | __in_opt const THEME_CONTROL* pParentControl | ||
| 5257 | ) | ||
| 5258 | { | ||
| 5259 | DWORD cControls = 0; | ||
| 5260 | THEME_CONTROL* rgControls = NULL; | ||
| 5261 | const THEME_CONTROL* pChildControl = NULL; | ||
| 5262 | |||
| 5263 | GetControls(pTheme, pParentControl, cControls, rgControls); | ||
| 5264 | |||
| 5265 | // Breadth first search since control ids are technically only valid for direct child windows of a specific parent window. | ||
| 5266 | for (DWORD i = 0; i < cControls; ++i) | ||
| 5267 | { | ||
| 5268 | if (wId == rgControls[i].wId) | ||
| 5269 | { | ||
| 5270 | return rgControls + i; | ||
| 5271 | } | ||
| 5272 | } | ||
| 5273 | |||
| 5274 | for (DWORD i = 0; i < cControls; ++i) | ||
| 5275 | { | ||
| 5276 | if (0 < rgControls[i].cControls) | ||
| 5277 | { | ||
| 5278 | pChildControl = FindControlFromId(pTheme, wId, rgControls + i); | ||
| 5279 | if (pChildControl) | ||
| 5280 | { | ||
| 5281 | return pChildControl; | ||
| 5282 | } | ||
| 5283 | } | ||
| 5284 | } | ||
| 5285 | |||
| 5286 | return NULL; | ||
| 5287 | } | ||
| 5288 | |||
| 5389 | static BOOL OnNotifyEnMsgFilter( | 5289 | static BOOL OnNotifyEnMsgFilter( |
| 5390 | __in THEME* pTheme, | 5290 | __in THEME* pTheme, |
| 5391 | __in const THEME_CONTROL* pThemeControl, | 5291 | __in const THEME_CONTROL* pThemeControl, |
| @@ -5638,7 +5538,6 @@ LExit: | |||
| 5638 | 5538 | ||
| 5639 | 5539 | ||
| 5640 | static HRESULT ShowControl( | 5540 | static HRESULT ShowControl( |
| 5641 | __in THEME* pTheme, | ||
| 5642 | __in THEME_CONTROL* pControl, | 5541 | __in THEME_CONTROL* pControl, |
| 5643 | __in int nCmdShow, | 5542 | __in int nCmdShow, |
| 5644 | __in BOOL fSaveEditboxes, | 5543 | __in BOOL fSaveEditboxes, |
| @@ -5654,13 +5553,14 @@ static HRESULT ShowControl( | |||
| 5654 | LPWSTR sczText = NULL; | 5553 | LPWSTR sczText = NULL; |
| 5655 | THEME_SAVEDVARIABLE* pSavedVariable = NULL; | 5554 | THEME_SAVEDVARIABLE* pSavedVariable = NULL; |
| 5656 | BOOL fHide = SW_HIDE == nCmdShow; | 5555 | BOOL fHide = SW_HIDE == nCmdShow; |
| 5556 | THEME* pTheme = pControl->pTheme; | ||
| 5657 | THEME_PAGE* pPage = ThemeGetPage(pTheme, dwPageId); | 5557 | THEME_PAGE* pPage = ThemeGetPage(pTheme, dwPageId); |
| 5658 | 5558 | ||
| 5659 | // Save the editbox value if necessary (other control types save their values immediately). | 5559 | // Save the editbox value if necessary (other control types save their values immediately). |
| 5660 | if (pTheme->pfnSetStringVariable && !pControl->fDisableVariableFunctionality && | 5560 | if (pTheme->pfnSetStringVariable && !pControl->fDisableVariableFunctionality && |
| 5661 | fSaveEditboxes && THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName) | 5561 | fSaveEditboxes && THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName) |
| 5662 | { | 5562 | { |
| 5663 | hr = ThemeGetTextControl(pTheme, pControl->wId, &sczText); | 5563 | hr = ThemeGetTextControl(pControl, &sczText); |
| 5664 | ThmExitOnFailure(hr, "Failed to get the text for control: %ls", pControl->sczName); | 5564 | ThmExitOnFailure(hr, "Failed to get the text for control: %ls", pControl->sczName); |
| 5665 | 5565 | ||
| 5666 | hr = pTheme->pfnSetStringVariable(pControl->sczName, sczText, FALSE, pTheme->pvVariableContext); | 5566 | hr = pTheme->pfnSetStringVariable(pControl->sczName, sczText, FALSE, pTheme->pvVariableContext); |
| @@ -5675,7 +5575,7 @@ static HRESULT ShowControl( | |||
| 5675 | 5575 | ||
| 5676 | if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) | 5576 | if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) |
| 5677 | { | 5577 | { |
| 5678 | StopBillboard(pTheme, pControl->wId); | 5578 | StopBillboard(pTheme, pControl); |
| 5679 | } | 5579 | } |
| 5680 | 5580 | ||
| 5681 | ExitFunction(); | 5581 | ExitFunction(); |
| @@ -5767,7 +5667,7 @@ static HRESULT ShowControl( | |||
| 5767 | ReleaseNullStr(sczText); | 5667 | ReleaseNullStr(sczText); |
| 5768 | } | 5668 | } |
| 5769 | 5669 | ||
| 5770 | ThemeSetTextControl(pTheme, pControl->wId, sczText); | 5670 | ThemeSetTextControl(pControl, sczText); |
| 5771 | 5671 | ||
| 5772 | if (wzNote && *wzNote) | 5672 | if (wzNote && *wzNote) |
| 5773 | { | 5673 | { |
| @@ -5811,7 +5711,7 @@ static HRESULT ShowControl( | |||
| 5811 | ++iPageControl; | 5711 | ++iPageControl; |
| 5812 | } | 5712 | } |
| 5813 | 5713 | ||
| 5814 | ThemeSendControlMessage(pTheme, pControl->wId, BM_SETCHECK, SUCCEEDED(hr) && llValue ? BST_CHECKED : BST_UNCHECKED, 0); | 5714 | ::SendMessageW(pControl->hWnd, BM_SETCHECK, SUCCEEDED(hr) && llValue ? BST_CHECKED : BST_UNCHECKED, 0); |
| 5815 | } | 5715 | } |
| 5816 | 5716 | ||
| 5817 | // If this is an editbox control, | 5717 | // If this is an editbox control, |
| @@ -5838,7 +5738,7 @@ static HRESULT ShowControl( | |||
| 5838 | ++iPageControl; | 5738 | ++iPageControl; |
| 5839 | } | 5739 | } |
| 5840 | 5740 | ||
| 5841 | ThemeSetTextControl(pTheme, pControl->wId, sczText); | 5741 | ThemeSetTextControl(pControl, sczText); |
| 5842 | } | 5742 | } |
| 5843 | } | 5743 | } |
| 5844 | 5744 | ||
| @@ -5901,11 +5801,11 @@ static HRESULT ShowControl( | |||
| 5901 | { | 5801 | { |
| 5902 | if (fEnabled) | 5802 | if (fEnabled) |
| 5903 | { | 5803 | { |
| 5904 | StartBillboard(pTheme, pControl->wId); | 5804 | StartBillboard(pTheme, pControl); |
| 5905 | } | 5805 | } |
| 5906 | else | 5806 | else |
| 5907 | { | 5807 | { |
| 5908 | StopBillboard(pTheme, pControl->wId); | 5808 | StopBillboard(pTheme, pControl); |
| 5909 | } | 5809 | } |
| 5910 | } | 5810 | } |
| 5911 | 5811 | ||
| @@ -5944,7 +5844,7 @@ static HRESULT ShowControls( | |||
| 5944 | // Only look at non-page controls and the specified page's controls. | 5844 | // Only look at non-page controls and the specified page's controls. |
| 5945 | if (!pControl->wPageId || pControl->wPageId == dwPageId) | 5845 | if (!pControl->wPageId || pControl->wPageId == dwPageId) |
| 5946 | { | 5846 | { |
| 5947 | hr = ShowControl(pTheme, pControl, nCmdShow, fSaveEditboxes, reason, dwPageId, &hwndFocus); | 5847 | hr = ShowControl(pControl, nCmdShow, fSaveEditboxes, reason, dwPageId, &hwndFocus); |
| 5948 | ThmExitOnFailure(hr, "Failed to show control '%ls' at index %d.", pControl->sczName, i); | 5848 | ThmExitOnFailure(hr, "Failed to show control '%ls' at index %d.", pControl->sczName, i); |
| 5949 | } | 5849 | } |
| 5950 | } | 5850 | } |
| @@ -6509,7 +6409,7 @@ static HRESULT LoadControls( | |||
| 6509 | HRESULT hrFormat = pTheme->pfnFormatString(pControl->sczText, &sczText, pTheme->pvVariableContext); | 6409 | HRESULT hrFormat = pTheme->pfnFormatString(pControl->sczText, &sczText, pTheme->pvVariableContext); |
| 6510 | if (SUCCEEDED(hrFormat)) | 6410 | if (SUCCEEDED(hrFormat)) |
| 6511 | { | 6411 | { |
| 6512 | ThemeSetTextControl(pTheme, pControl->wId, sczText); | 6412 | ThemeSetTextControl(pControl, sczText); |
| 6513 | } | 6413 | } |
| 6514 | } | 6414 | } |
| 6515 | 6415 | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/wndutil.cpp b/src/libs/dutil/WixToolset.DUtil/wndutil.cpp new file mode 100644 index 00000000..b75b0491 --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/wndutil.cpp | |||
| @@ -0,0 +1,206 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | |||
| 6 | // Exit macros | ||
| 7 | #define WnduExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) | ||
| 8 | #define WnduExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) | ||
| 9 | #define WnduExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) | ||
| 10 | #define WnduExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) | ||
| 11 | #define WnduExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) | ||
| 12 | #define WnduExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_WNDUTIL, x, e, s, __VA_ARGS__) | ||
| 13 | #define WnduExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) | ||
| 14 | #define WnduExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_WNDUTIL, p, x, e, s, __VA_ARGS__) | ||
| 15 | #define WnduExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_WNDUTIL, p, x, s, __VA_ARGS__) | ||
| 16 | #define WnduExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_WNDUTIL, p, x, e, s, __VA_ARGS__) | ||
| 17 | #define WnduExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_WNDUTIL, p, x, s, __VA_ARGS__) | ||
| 18 | #define WnduExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_WNDUTIL, e, x, s, __VA_ARGS__) | ||
| 19 | #define WnduExitOnOptionalXmlQueryFailure(x, b, s, ...) ExitOnOptionalXmlQueryFailureSource(DUTIL_SOURCE_WNDUTIL, x, b, s, __VA_ARGS__) | ||
| 20 | #define WnduExitOnRequiredXmlQueryFailure(x, s, ...) ExitOnRequiredXmlQueryFailureSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) | ||
| 21 | #define WnduExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_WNDUTIL, g, x, s, __VA_ARGS__) | ||
| 22 | |||
| 23 | struct MEMBUFFER_FOR_RICHEDIT | ||
| 24 | { | ||
| 25 | BYTE* rgbData; | ||
| 26 | DWORD cbData; | ||
| 27 | |||
| 28 | DWORD iData; | ||
| 29 | }; | ||
| 30 | |||
| 31 | const DWORD GROW_WINDOW_TEXT = 250; | ||
| 32 | |||
| 33 | |||
| 34 | // prototypes | ||
| 35 | static DWORD CALLBACK RichEditStreamFromFileHandleCallback( | ||
| 36 | __in DWORD_PTR dwCookie, | ||
| 37 | __in_bcount(cb) LPBYTE pbBuff, | ||
| 38 | __in LONG cb, | ||
| 39 | __in LONG *pcb | ||
| 40 | ); | ||
| 41 | static DWORD CALLBACK RichEditStreamFromMemoryCallback( | ||
| 42 | __in DWORD_PTR dwCookie, | ||
| 43 | __in_bcount(cb) LPBYTE pbBuff, | ||
| 44 | __in LONG cb, | ||
| 45 | __in LONG *pcb | ||
| 46 | ); | ||
| 47 | |||
| 48 | |||
| 49 | DAPI_(HRESULT) WnduLoadRichEditFromFile( | ||
| 50 | __in HWND hWnd, | ||
| 51 | __in_z LPCWSTR wzFileName, | ||
| 52 | __in HMODULE hModule | ||
| 53 | ) | ||
| 54 | { | ||
| 55 | HRESULT hr = S_OK; | ||
| 56 | LPWSTR sczFile = NULL; | ||
| 57 | HANDLE hFile = INVALID_HANDLE_VALUE; | ||
| 58 | |||
| 59 | hr = PathRelativeToModule(&sczFile, wzFileName, hModule); | ||
| 60 | WnduExitOnFailure(hr, "Failed to read resource data."); | ||
| 61 | |||
| 62 | hFile = ::CreateFileW(sczFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); | ||
| 63 | if (INVALID_HANDLE_VALUE == hFile) | ||
| 64 | { | ||
| 65 | WnduExitWithLastError(hr, "Failed to open RTF file."); | ||
| 66 | } | ||
| 67 | else | ||
| 68 | { | ||
| 69 | LONGLONG llRtfSize; | ||
| 70 | hr = FileSizeByHandle(hFile, &llRtfSize); | ||
| 71 | if (SUCCEEDED(hr)) | ||
| 72 | { | ||
| 73 | ::SendMessageW(hWnd, EM_EXLIMITTEXT, 0, static_cast<LPARAM>(llRtfSize)); | ||
| 74 | } | ||
| 75 | |||
| 76 | EDITSTREAM es = { }; | ||
| 77 | es.pfnCallback = RichEditStreamFromFileHandleCallback; | ||
| 78 | es.dwCookie = reinterpret_cast<DWORD_PTR>(hFile); | ||
| 79 | |||
| 80 | ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast<LPARAM>(&es)); | ||
| 81 | hr = es.dwError; | ||
| 82 | WnduExitOnFailure(hr, "Failed to update RTF stream."); | ||
| 83 | } | ||
| 84 | |||
| 85 | LExit: | ||
| 86 | ReleaseStr(sczFile); | ||
| 87 | ReleaseFile(hFile); | ||
| 88 | |||
| 89 | return hr; | ||
| 90 | } | ||
| 91 | |||
| 92 | DAPI_(HRESULT) WnduLoadRichEditFromResource( | ||
| 93 | __in HWND hWnd, | ||
| 94 | __in_z LPCSTR szResourceName, | ||
| 95 | __in HMODULE hModule | ||
| 96 | ) | ||
| 97 | { | ||
| 98 | HRESULT hr = S_OK; | ||
| 99 | MEMBUFFER_FOR_RICHEDIT buffer = { }; | ||
| 100 | EDITSTREAM es = { }; | ||
| 101 | |||
| 102 | hr = ResReadData(hModule, szResourceName, reinterpret_cast<LPVOID*>(&buffer.rgbData), &buffer.cbData); | ||
| 103 | WnduExitOnFailure(hr, "Failed to read resource data."); | ||
| 104 | |||
| 105 | es.pfnCallback = RichEditStreamFromMemoryCallback; | ||
| 106 | es.dwCookie = reinterpret_cast<DWORD_PTR>(&buffer); | ||
| 107 | |||
| 108 | ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast<LPARAM>(&es)); | ||
| 109 | hr = es.dwError; | ||
| 110 | WnduExitOnFailure(hr, "Failed to update RTF stream."); | ||
| 111 | |||
| 112 | LExit: | ||
| 113 | return hr; | ||
| 114 | } | ||
| 115 | |||
| 116 | |||
| 117 | DAPI_(HRESULT) WnduGetControlText( | ||
| 118 | __in HWND hWnd, | ||
| 119 | __inout_z LPWSTR* psczText | ||
| 120 | ) | ||
| 121 | { | ||
| 122 | HRESULT hr = S_OK; | ||
| 123 | SIZE_T cbSize = 0; | ||
| 124 | DWORD cchText = 0; | ||
| 125 | DWORD cchTextRead = 0; | ||
| 126 | |||
| 127 | // Ensure the string has room for at least one character. | ||
| 128 | hr = StrMaxLength(*psczText, &cbSize); | ||
| 129 | WnduExitOnFailure(hr, "Failed to get text buffer length."); | ||
| 130 | |||
| 131 | cchText = (DWORD)min(DWORD_MAX, cbSize); | ||
| 132 | |||
| 133 | if (!cchText) | ||
| 134 | { | ||
| 135 | cchText = GROW_WINDOW_TEXT; | ||
| 136 | |||
| 137 | hr = StrAlloc(psczText, cchText); | ||
| 138 | WnduExitOnFailure(hr, "Failed to grow text buffer."); | ||
| 139 | } | ||
| 140 | |||
| 141 | // Read (and keep growing buffer) until we finally read less than there | ||
| 142 | // is room in the buffer. | ||
| 143 | for (;;) | ||
| 144 | { | ||
| 145 | cchTextRead = ::GetWindowTextW(hWnd, *psczText, cchText); | ||
| 146 | if (cchTextRead + 1 < cchText) | ||
| 147 | { | ||
| 148 | break; | ||
| 149 | } | ||
| 150 | else | ||
| 151 | { | ||
| 152 | cchText = cchTextRead + GROW_WINDOW_TEXT; | ||
| 153 | |||
| 154 | hr = StrAlloc(psczText, cchText); | ||
| 155 | WnduExitOnFailure(hr, "Failed to grow text buffer again."); | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | LExit: | ||
| 160 | return hr; | ||
| 161 | } | ||
| 162 | |||
| 163 | |||
| 164 | static DWORD CALLBACK RichEditStreamFromFileHandleCallback( | ||
| 165 | __in DWORD_PTR dwCookie, | ||
| 166 | __in_bcount(cb) LPBYTE pbBuff, | ||
| 167 | __in LONG cb, | ||
| 168 | __in LONG* pcb | ||
| 169 | ) | ||
| 170 | { | ||
| 171 | HRESULT hr = S_OK; | ||
| 172 | HANDLE hFile = reinterpret_cast<HANDLE>(dwCookie); | ||
| 173 | |||
| 174 | if (!::ReadFile(hFile, pbBuff, cb, reinterpret_cast<DWORD*>(pcb), NULL)) | ||
| 175 | { | ||
| 176 | WnduExitWithLastError(hr, "Failed to read file"); | ||
| 177 | } | ||
| 178 | |||
| 179 | LExit: | ||
| 180 | return hr; | ||
| 181 | } | ||
| 182 | |||
| 183 | |||
| 184 | static DWORD CALLBACK RichEditStreamFromMemoryCallback( | ||
| 185 | __in DWORD_PTR dwCookie, | ||
| 186 | __in_bcount(cb) LPBYTE pbBuff, | ||
| 187 | __in LONG cb, | ||
| 188 | __in LONG* pcb | ||
| 189 | ) | ||
| 190 | { | ||
| 191 | HRESULT hr = S_OK; | ||
| 192 | MEMBUFFER_FOR_RICHEDIT* pBuffer = reinterpret_cast<MEMBUFFER_FOR_RICHEDIT*>(dwCookie); | ||
| 193 | DWORD cbCopy = 0; | ||
| 194 | |||
| 195 | if (pBuffer->iData < pBuffer->cbData) | ||
| 196 | { | ||
| 197 | cbCopy = min(static_cast<DWORD>(cb), pBuffer->cbData - pBuffer->iData); | ||
| 198 | memcpy(pbBuff, pBuffer->rgbData + pBuffer->iData, cbCopy); | ||
| 199 | |||
| 200 | pBuffer->iData += cbCopy; | ||
| 201 | Assert(pBuffer->iData <= pBuffer->cbData); | ||
| 202 | } | ||
| 203 | |||
| 204 | *pcb = cbCopy; | ||
| 205 | return hr; | ||
| 206 | } | ||
