Avoid using control ids inside of thmutil.
Sean Hall committed
Oct 31, 2021 at 14:20 UTC
7e60078d4a7fe748a39c135def9e84a2421ab474
14 files changed
+845
-551
src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+241
-73
@@ -80,7 +80,7 @@ static LPCWSTR vrgwzPageNames[] = {
80
// The range [0, 100) is unused to avoid collisions with system ids,
81
// the range [100, 0x4000) is unused to avoid collisions with thmutil,
82
// the range [0x4000, 0x8000) is unused to avoid collisions with BAFunctions.
83
-const WORD WIXSTDBA_FIRST_ASSIGN_CONTROL_ID = 0x8000;
83
+const WORD WIXSTDBA_FIRST_ASSIGN_CONTROL_ID = 0x8000;
84
85
enum WIXSTDBA_CONTROL
86
{
@@ -119,36 +119,8 @@ enum WIXSTDBA_CONTROL
119
WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK,
120
WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT,
121
WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON,
122
-};
122
124
-static THEME_ASSIGN_CONTROL_ID vrgInitControls[] = {
125
- { WIXSTDBA_CONTROL_INSTALL_BUTTON, L"InstallButton" },
126
- { WIXSTDBA_CONTROL_EULA_RICHEDIT, L"EulaRichedit" },
127
- { WIXSTDBA_CONTROL_EULA_LINK, L"EulaHyperlink" },
128
- { WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, L"EulaAcceptCheckbox" },
129
-
130
- { WIXSTDBA_CONTROL_REPAIR_BUTTON, L"RepairButton" },
131
- { WIXSTDBA_CONTROL_UNINSTALL_BUTTON, L"UninstallButton" },
132
-
133
- { WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, L"CacheProgressPackageText" },
134
- { WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR, L"CacheProgressbar" },
135
- { WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT, L"CacheProgressText" },
136
- { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, L"ExecuteProgressPackageText" },
137
- { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR, L"ExecuteProgressbar" },
138
- { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT, L"ExecuteProgressText" },
139
- { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"ExecuteProgressActionDataText"},
140
- { WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, L"OverallProgressPackageText" },
141
- { WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR, L"OverallProgressbar" },
142
- { WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, L"OverallCalculatedProgressbar" },
143
- { WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT, L"OverallProgressText" },
144
- { WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, L"ProgressCancelButton" },
145
-
146
- { WIXSTDBA_CONTROL_LAUNCH_BUTTON, L"LaunchButton" },
147
- { WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON, L"SuccessRestartButton" },
148
-
149
- { WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK, L"FailureLogFileLink" },
150
- { WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, L"FailureMessageText" },
151
- { WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON, L"FailureRestartButton" },
123
+ LAST_WIXSTDBA_CONTROL,
124
};
125
126
typedef struct _WIXSTDBA_PACKAGE_INFO
@@ -589,7 +561,7 @@ public: // IBootstrapperApplication
561
562
wz = sczFormattedString ? sczFormattedString : L"Pausing Windows automatic updates";
563
592
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
564
+ ThemeSetTextControl(m_pControlOverallProgressPackageText, wz);
565
566
ReleaseStr(sczFormattedString);
567
return hr;
@@ -615,7 +587,7 @@ public: // IBootstrapperApplication
587
588
wz = sczFormattedString ? sczFormattedString : L"Creating system restore point";
589
618
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
590
+ ThemeSetTextControl(m_pControlOverallProgressPackageText, wz);
591
592
ReleaseStr(sczFormattedString);
593
return hr;
@@ -635,12 +607,12 @@ public: // IBootstrapperApplication
607
HRESULT hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
608
LPCWSTR wz = (SUCCEEDED(hr) && pPackage->sczDisplayName) ? pPackage->sczDisplayName : wzPackageId;
609
638
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, wz);
610
+ ThemeSetTextControl(m_pControlCacheProgressPackageText, wz);
611
612
// If something started executing, leave it in the overall progress text.
613
if (!m_fStartedExecution)
614
{
643
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
615
+ ThemeSetTextControl(m_pControlOverallProgressPackageText, wz);
616
}
617
}
618
@@ -778,7 +750,7 @@ public: // IBootstrapperApplication
750
)
751
{
752
UpdateCacheProgress(SUCCEEDED(hrStatus) ? 100 : 0);
781
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, L"");
753
+ ThemeSetTextControl(m_pControlCacheProgressPackageText, L"");
754
SetState(WIXSTDBA_STATE_CACHED, S_OK); // we always return success here and let OnApplyComplete() deal with the error.
755
return __super::OnCacheComplete(hrStatus);
756
}
@@ -891,7 +863,7 @@ public: // IBootstrapperApplication
863
864
if (INSTALLMESSAGE_ACTIONSTART == messageType)
865
{
894
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, wzMessage);
866
+ ThemeSetTextControl(m_pControlExecuteProgressActionDataText, wzMessage);
867
}
868
869
return __super::OnExecuteMsiMessage(wzPackageId, messageType, dwUIHint, wzMessage, cData, rgwzData, nRecommendation, pResult);
@@ -911,9 +883,9 @@ public: // IBootstrapperApplication
883
#endif
884
885
::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage);
914
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT, wzProgress);
886
+ ThemeSetTextControl(m_pControlOverallProgressText, wzProgress);
887
916
- ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR, dwOverallProgressPercentage);
888
+ ThemeSetProgressControl(m_pControlOverallProgressbar, dwOverallProgressPercentage);
889
SetTaskbarButtonProgress(dwOverallProgressPercentage);
890
891
return __super::OnProgress(dwProgressPercentage, dwOverallProgressPercentage, pfCancel);
@@ -972,8 +944,8 @@ public: // IBootstrapperApplication
944
945
fShowingInternalUiThisPackage = INSTALLUILEVEL_NONE != (INSTALLUILEVEL_NONE & uiLevel);
946
975
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, wz);
976
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
947
+ ThemeSetTextControl(m_pControlExecuteProgressPackageText, wz);
948
+ ThemeSetTextControl(m_pControlOverallProgressPackageText, wz);
949
}
950
951
::EnterCriticalSection(&m_csShowingInternalUiThisPackage);
@@ -1000,12 +972,12 @@ public: // IBootstrapperApplication
972
#endif
973
974
::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage);
1003
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT, wzProgress);
975
+ ThemeSetTextControl(m_pControlExecuteProgressText, wzProgress);
976
1005
- ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR, dwOverallProgressPercentage);
977
+ ThemeSetProgressControl(m_pControlExecuteProgressbar, dwOverallProgressPercentage);
978
979
m_dwCalculatedExecuteProgress = dwOverallProgressPercentage * (100 - WIXSTDBA_ACQUIRE_PERCENTAGE) / 100;
1008
- ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
980
+ ThemeSetProgressControl(m_pControlOverallCalculatedProgressbar, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
981
982
SetTaskbarButtonProgress(m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
983
@@ -1051,10 +1023,10 @@ public: // IBootstrapperApplication
1023
{
1024
HRESULT hr = S_OK;
1025
1054
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, L"");
1055
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"");
1056
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, L"");
1057
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, FALSE); // no more cancel.
1026
+ ThemeSetTextControl(m_pControlExecuteProgressPackageText, L"");
1027
+ ThemeSetTextControl(m_pControlExecuteProgressActionDataText, L"");
1028
+ ThemeSetTextControl(m_pControlOverallProgressPackageText, L"");
1029
+ ThemeControlEnable(m_pControlProgressCancelButton, FALSE); // no more cancel.
1030
m_fShowingInternalUiThisPackage = FALSE;
1031
1032
SetState(WIXSTDBA_STATE_EXECUTED, S_OK); // we always return success here and let OnApplyComplete() deal with the error.
@@ -2933,12 +2905,27 @@ private:
2905
BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS themeControlLoadingArgs = { };
2906
BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS themeControlLoadingResults = { };
2907
2936
- for (DWORD iAssignControl = 0; iAssignControl < countof(vrgInitControls); ++iAssignControl)
2908
+ for (DWORD iAssignControl = 0; iAssignControl < countof(m_rgInitControls); ++iAssignControl)
2909
{
2938
- if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, vrgInitControls[iAssignControl].wzName, -1))
2910
+ THEME_ASSIGN_CONTROL_ID* pAssignControl = m_rgInitControls + iAssignControl;
2911
+ if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, pAssignControl->wzName, -1))
2912
{
2913
+ if (!pAssignControl->ppControl)
2914
+ {
2915
+ BalExitWithRootFailure(hr, E_INVALIDSTATE, "Control '%ls' has no member variable", pAssignControl->wzName);
2916
+ }
2917
+
2918
+ if (*pAssignControl->ppControl)
2919
+ {
2920
+ BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Duplicate control name: %ls", pAssignControl->wzName);
2921
+ }
2922
+ else
2923
+ {
2924
+ *pAssignControl->ppControl = pArgs->pThemeControl;
2925
+ }
2926
+
2927
fProcessed = TRUE;
2941
- pResults->wId = vrgInitControls[iAssignControl].wId;
2928
+ pResults->wId = pAssignControl->wId;
2929
ExitFunction();
2930
}
2931
}
@@ -3059,7 +3046,7 @@ private:
3046
hr = LocProbeForFile(sczLicenseDirectory, sczLicenseFilename, m_sczLanguage, &sczLicensePath);
3047
ExitOnFailure(hr, "Failed to probe for localized license file.");
3048
3062
- hr = ThemeLoadRichEditFromFile(m_pTheme, pThemeControl->wId, sczLicensePath, m_hModule);
3049
+ hr = ThemeLoadRichEditFromFile(pThemeControl, sczLicensePath, m_hModule);
3050
ExitOnFailure(hr, "Failed to load license file into richedit control.");
3051
3052
LExit:
@@ -3178,7 +3165,7 @@ private:
3165
hr = m_pEngine->Apply(m_hWnd);
3166
BalExitOnFailure(hr, "Failed to start applying packages.");
3167
3181
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, TRUE); // ensure the cancel button is enabled before starting.
3168
+ ThemeControlEnable(m_pControlProgressCancelButton, TRUE); // ensure the cancel button is enabled before starting.
3169
3170
LExit:
3171
if (FAILED(hr))
@@ -3229,22 +3216,22 @@ private:
3216
{
3217
BalGetNumericVariable(WIXBUNDLE_VARIABLE_ELEVATED, &llElevated);
3218
}
3232
- ThemeControlElevates(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, (m_Bundle.fPerMachine && !llElevated));
3219
+ ThemeControlElevates(m_pControlInstallButton, (m_Bundle.fPerMachine && !llElevated));
3220
3221
// If the EULA control exists, show it only if a license URL is provided as well.
3235
- if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK))
3222
+ if (m_pControlEulaHyperlink)
3223
{
3224
BOOL fEulaLink = (m_sczLicenseUrl && *m_sczLicenseUrl);
3238
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK, fEulaLink);
3239
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, fEulaLink);
3225
+ ThemeControlEnable(m_pControlEulaHyperlink, fEulaLink);
3226
+ ThemeControlEnable(m_pControlEulaAcceptCheckbox, fEulaLink);
3227
}
3228
3242
- BOOL fAcceptedLicense = !ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX) || !ThemeControlEnabled(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX) || ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX);
3243
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense);
3229
+ BOOL fAcceptedLicense = !m_pControlEulaAcceptCheckbox || !ThemeControlEnabled(m_pControlEulaAcceptCheckbox) || ThemeIsControlChecked(m_pControlEulaAcceptCheckbox);
3230
+ ThemeControlEnable(m_pControlInstallButton, fAcceptedLicense);
3231
}
3232
else if (m_rgdwPageIds[WIXSTDBA_PAGE_MODIFY] == dwNewPageId)
3233
{
3247
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_REPAIR_BUTTON, !m_fSuppressRepair);
3234
+ ThemeControlEnable(m_pControlRepairButton, !m_fSuppressRepair);
3235
}
3236
else if (m_rgdwPageIds[WIXSTDBA_PAGE_SUCCESS] == dwNewPageId) // on the "Success" page, check if the restart or launch button should be enabled.
3237
{
@@ -3257,13 +3244,13 @@ private:
3244
fEnableRestartButton = TRUE;
3245
}
3246
}
3260
- else if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_LAUNCH_BUTTON))
3247
+ else if (m_pControlLaunchButton)
3248
{
3249
fLaunchTargetExists = BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH);
3250
}
3251
3265
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_LAUNCH_BUTTON, fLaunchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < m_plannedAction);
3266
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON, fEnableRestartButton);
3252
+ ThemeControlEnable(m_pControlLaunchButton, fLaunchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < m_plannedAction);
3253
+ ThemeControlEnable(m_pControlSuccessRestartButton, fEnableRestartButton);
3254
}
3255
else if (m_rgdwPageIds[WIXSTDBA_PAGE_FAILURE] == dwNewPageId) // on the "Failure" page, show error message and check if the restart button should be enabled.
3256
{
@@ -3347,7 +3334,7 @@ private:
3334
StrAllocFormatted(&sczText, L"0x%08x - %ls", m_hrFinal, sczUnformattedText);
3335
}
3336
3350
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, sczText);
3337
+ ThemeSetTextControl(m_pControlFailureMessageText, sczText);
3338
fShowErrorMessage = TRUE;
3339
}
3340
@@ -3359,9 +3346,9 @@ private:
3346
}
3347
}
3348
3362
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK, fShowLogLink);
3363
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, fShowErrorMessage);
3364
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON, fEnableRestartButton);
3349
+ ThemeControlEnable(m_pControlFailureLogFileLink, fShowLogLink);
3350
+ ThemeControlEnable(m_pControlFailureMessageText, fShowErrorMessage);
3351
+ ThemeControlEnable(m_pControlFailureRestartButton, fEnableRestartButton);
3352
}
3353
3354
HRESULT hr = ThemeShowPage(m_pTheme, dwOldPageId, SW_HIDE);
@@ -3379,7 +3366,7 @@ private:
3366
// On the install page set the focus to the install button or the next enabled control if install is disabled.
3367
if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId)
3368
{
3382
- ThemeSetFocus(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON);
3369
+ ThemeSetFocus(m_pControlInstallButton);
3370
}
3371
}
3372
}
@@ -3423,7 +3410,7 @@ private:
3410
// If we canceled, disable cancel button since clicking it again is silly.
3411
if (fClose)
3412
{
3426
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, FALSE);
3413
+ ThemeControlEnable(m_pControlProgressCancelButton, FALSE);
3414
}
3415
3416
fClose = FALSE;
@@ -3447,8 +3434,8 @@ private:
3434
//
3435
void OnClickAcceptCheckbox()
3436
{
3450
- BOOL fAcceptedLicense = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX);
3451
- ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense);
3437
+ BOOL fAcceptedLicense = ThemeIsControlChecked(m_pControlEulaAcceptCheckbox);
3438
+ ThemeControlEnable(m_pControlInstallButton, fAcceptedLicense);
3439
}
3440
3441
@@ -3954,12 +3941,12 @@ LExit:
3941
WCHAR wzProgress[5] = { };
3942
3943
::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallPercentage);
3957
- ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT, wzProgress);
3944
+ ThemeSetTextControl(m_pControlCacheProgressText, wzProgress);
3945
3959
- ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR, dwOverallPercentage);
3946
+ ThemeSetProgressControl(m_pControlCacheProgressbar, dwOverallPercentage);
3947
3948
m_dwCalculatedCacheProgress = dwOverallPercentage * WIXSTDBA_ACQUIRE_PERCENTAGE / 100;
3962
- ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
3949
+ ThemeSetProgressControl(m_pControlOverallCalculatedProgressbar, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
3950
3951
SetTaskbarButtonProgress(m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
3952
}
@@ -4088,6 +4075,8 @@ public:
4075
__in IBootstrapperEngine* pEngine
4076
) : CBalBaseBootstrapperApplication(pEngine, 3, 3000)
4077
{
4078
+ THEME_ASSIGN_CONTROL_ID* pAssignControl = NULL;
4079
+
4080
m_hModule = hModule;
4081
m_command = { };
4082
m_createArgs = { };
@@ -4141,6 +4130,148 @@ public:
4130
m_hBAFModule = NULL;
4131
m_pfnBAFunctionsProc = NULL;
4132
m_pvBAFunctionsProcContext = NULL;
4133
+
4134
+ C_ASSERT(0 == WIXSTDBA_CONTROL_INSTALL_BUTTON - WIXSTDBA_FIRST_ASSIGN_CONTROL_ID);
4135
+ pAssignControl = m_rgInitControls;
4136
+
4137
+ pAssignControl->wId = WIXSTDBA_CONTROL_INSTALL_BUTTON;
4138
+ pAssignControl->wzName = L"InstallButton";
4139
+ pAssignControl->ppControl = &m_pControlInstallButton;
4140
+ m_pControlInstallButton = NULL;
4141
+ ++pAssignControl;
4142
+
4143
+ pAssignControl->wId = WIXSTDBA_CONTROL_EULA_RICHEDIT;
4144
+ pAssignControl->wzName = L"EulaRichedit";
4145
+ pAssignControl->ppControl = &m_pControlEulaRichedit;
4146
+ m_pControlEulaRichedit = NULL;
4147
+ ++pAssignControl;
4148
+
4149
+ pAssignControl->wId = WIXSTDBA_CONTROL_EULA_LINK;
4150
+ pAssignControl->wzName = L"EulaHyperlink";
4151
+ pAssignControl->ppControl = &m_pControlEulaHyperlink;
4152
+ m_pControlEulaHyperlink = NULL;
4153
+ ++pAssignControl;
4154
+
4155
+ pAssignControl->wId = WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX;
4156
+ pAssignControl->wzName = L"EulaAcceptCheckbox";
4157
+ pAssignControl->ppControl = &m_pControlEulaAcceptCheckbox;
4158
+ m_pControlEulaAcceptCheckbox = NULL;
4159
+ ++pAssignControl;
4160
+
4161
+ pAssignControl->wId = WIXSTDBA_CONTROL_REPAIR_BUTTON;
4162
+ pAssignControl->wzName = L"RepairButton";
4163
+ pAssignControl->ppControl = &m_pControlRepairButton;
4164
+ m_pControlRepairButton = NULL;
4165
+ ++pAssignControl;
4166
+
4167
+ pAssignControl->wId = WIXSTDBA_CONTROL_UNINSTALL_BUTTON;
4168
+ pAssignControl->wzName = L"UninstallButton";
4169
+ pAssignControl->ppControl = &m_pControlUninstallButton;
4170
+ m_pControlUninstallButton = NULL;
4171
+ ++pAssignControl;
4172
+
4173
+ pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT;
4174
+ pAssignControl->wzName = L"CacheProgressPackageText";
4175
+ pAssignControl->ppControl = &m_pControlCacheProgressPackageText;
4176
+ m_pControlCacheProgressPackageText = NULL;
4177
+ ++pAssignControl;
4178
+
4179
+ pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR;
4180
+ pAssignControl->wzName = L"CacheProgressbar";
4181
+ pAssignControl->ppControl = &m_pControlCacheProgressbar;
4182
+ m_pControlCacheProgressbar = NULL;
4183
+ ++pAssignControl;
4184
+
4185
+ pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT;
4186
+ pAssignControl->wzName = L"CacheProgressText";
4187
+ pAssignControl->ppControl = &m_pControlCacheProgressText;
4188
+ m_pControlCacheProgressText = NULL;
4189
+ ++pAssignControl;
4190
+
4191
+ pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT;
4192
+ pAssignControl->wzName = L"ExecuteProgressPackageText";
4193
+ pAssignControl->ppControl = &m_pControlExecuteProgressPackageText;
4194
+ m_pControlExecuteProgressPackageText = NULL;
4195
+ ++pAssignControl;
4196
+
4197
+ pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR;
4198
+ pAssignControl->wzName = L"ExecuteProgressbar";
4199
+ pAssignControl->ppControl = &m_pControlExecuteProgressbar;
4200
+ m_pControlExecuteProgressbar = NULL;
4201
+ ++pAssignControl;
4202
+
4203
+ pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT;
4204
+ pAssignControl->wzName = L"ExecuteProgressText";
4205
+ pAssignControl->ppControl = &m_pControlExecuteProgressText;
4206
+ m_pControlExecuteProgressText = NULL;
4207
+ ++pAssignControl;
4208
+
4209
+ pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT;
4210
+ pAssignControl->wzName = L"ExecuteProgressActionDataText";
4211
+ pAssignControl->ppControl = &m_pControlExecuteProgressActionDataText;
4212
+ m_pControlExecuteProgressActionDataText = NULL;
4213
+ ++pAssignControl;
4214
+
4215
+ pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT;
4216
+ pAssignControl->wzName = L"OverallProgressPackageText";
4217
+ pAssignControl->ppControl = &m_pControlOverallProgressPackageText;
4218
+ m_pControlOverallProgressPackageText = NULL;
4219
+ ++pAssignControl;
4220
+
4221
+ pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR;
4222
+ pAssignControl->wzName = L"OverallProgressbar";
4223
+ pAssignControl->ppControl = &m_pControlOverallProgressbar;
4224
+ m_pControlOverallProgressbar = NULL;
4225
+ ++pAssignControl;
4226
+
4227
+ pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR;
4228
+ pAssignControl->wzName = L"OverallCalculatedProgressbar";
4229
+ pAssignControl->ppControl = &m_pControlOverallCalculatedProgressbar;
4230
+ m_pControlOverallCalculatedProgressbar = NULL;
4231
+ ++pAssignControl;
4232
+
4233
+ pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT;
4234
+ pAssignControl->wzName = L"OverallProgressText";
4235
+ pAssignControl->ppControl = &m_pControlOverallProgressText;
4236
+ m_pControlOverallProgressText = NULL;
4237
+ ++pAssignControl;
4238
+
4239
+ pAssignControl->wId = WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON;
4240
+ pAssignControl->wzName = L"ProgressCancelButton";
4241
+ pAssignControl->ppControl = &m_pControlProgressCancelButton;
4242
+ m_pControlProgressCancelButton = NULL;
4243
+ ++pAssignControl;
4244
+
4245
+ pAssignControl->wId = WIXSTDBA_CONTROL_LAUNCH_BUTTON;
4246
+ pAssignControl->wzName = L"LaunchButton";
4247
+ pAssignControl->ppControl = &m_pControlLaunchButton;
4248
+ m_pControlLaunchButton = NULL;
4249
+ ++pAssignControl;
4250
+
4251
+ pAssignControl->wId = WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON;
4252
+ pAssignControl->wzName = L"SuccessRestartButton";
4253
+ pAssignControl->ppControl = &m_pControlSuccessRestartButton;
4254
+ m_pControlSuccessRestartButton = NULL;
4255
+ ++pAssignControl;
4256
+
4257
+ pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK;
4258
+ pAssignControl->wzName = L"FailureLogFileLink";
4259
+ pAssignControl->ppControl = &m_pControlFailureLogFileLink;
4260
+ m_pControlFailureLogFileLink = NULL;
4261
+ ++pAssignControl;
4262
+
4263
+ pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT;
4264
+ pAssignControl->wzName = L"FailureMessageText";
4265
+ pAssignControl->ppControl = &m_pControlFailureMessageText;
4266
+ m_pControlFailureMessageText = NULL;
4267
+ ++pAssignControl;
4268
+
4269
+ pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON;
4270
+ pAssignControl->wzName = L"FailureRestartButton";
4271
+ pAssignControl->ppControl = &m_pControlFailureRestartButton;
4272
+ m_pControlFailureRestartButton = NULL;
4273
+
4274
+ C_ASSERT(LAST_WIXSTDBA_CONTROL == WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON + 1);
4275
}
4276
4277
@@ -4201,11 +4332,48 @@ private:
4332
4333
LPWSTR m_sczLanguage;
4334
THEME* m_pTheme;
4335
+ THEME_ASSIGN_CONTROL_ID m_rgInitControls[LAST_WIXSTDBA_CONTROL - WIXSTDBA_FIRST_ASSIGN_CONTROL_ID];
4336
DWORD m_rgdwPageIds[countof(vrgwzPageNames)];
4337
HANDLE m_hUiThread;
4338
BOOL m_fRegistered;
4339
HWND m_hWnd;
4340
4341
+ // Welcome page
4342
+ const THEME_CONTROL* m_pControlInstallButton;
4343
+ const THEME_CONTROL* m_pControlEulaRichedit;
4344
+ const THEME_CONTROL* m_pControlEulaHyperlink;
4345
+ const THEME_CONTROL* m_pControlEulaAcceptCheckbox;
4346
+
4347
+ // Modify page
4348
+ const THEME_CONTROL* m_pControlRepairButton;
4349
+ const THEME_CONTROL* m_pControlUninstallButton;
4350
+
4351
+ // Progress page
4352
+ const THEME_CONTROL* m_pControlCacheProgressPackageText;
4353
+ const THEME_CONTROL* m_pControlCacheProgressbar;
4354
+ const THEME_CONTROL* m_pControlCacheProgressText;
4355
+
4356
+ const THEME_CONTROL* m_pControlExecuteProgressPackageText;
4357
+ const THEME_CONTROL* m_pControlExecuteProgressbar;
4358
+ const THEME_CONTROL* m_pControlExecuteProgressText;
4359
+ const THEME_CONTROL* m_pControlExecuteProgressActionDataText;
4360
+
4361
+ const THEME_CONTROL* m_pControlOverallProgressPackageText;
4362
+ const THEME_CONTROL* m_pControlOverallProgressbar;
4363
+ const THEME_CONTROL* m_pControlOverallCalculatedProgressbar;
4364
+ const THEME_CONTROL* m_pControlOverallProgressText;
4365
+
4366
+ const THEME_CONTROL* m_pControlProgressCancelButton;
4367
+
4368
+ // Success page
4369
+ const THEME_CONTROL* m_pControlLaunchButton;
4370
+ const THEME_CONTROL* m_pControlSuccessRestartButton;
4371
+
4372
+ // Failure page
4373
+ const THEME_CONTROL* m_pControlFailureLogFileLink;
4374
+ const THEME_CONTROL* m_pControlFailureMessageText;
4375
+ const THEME_CONTROL* m_pControlFailureRestartButton;
4376
+
4377
WIXSTDBA_STATE m_state;
4378
HRESULT m_hrFinal;
4379
src/ext/Bal/wixstdba/precomp.h
+1
@@ -29,6 +29,7 @@
29
#include "resrutil.h"
30
#include "shelutil.h"
31
#include "strutil.h"
32
+#include "wndutil.h"
33
#include "thmutil.h"
34
#include "verutil.h"
35
#include "uriutil.h"
src/libs/dutil/WixToolset.DUtil/dutil.vcxproj
+2
@@ -107,6 +107,7 @@
107
<ClCompile Include="userutil.cpp" />
108
<ClCompile Include="verutil.cpp" />
109
<ClCompile Include="wiutil.cpp" />
110
+ <ClCompile Include="wndutil.cpp" />
111
<ClCompile Include="wuautil.cpp" />
112
<ClCompile Include="xmlutil.cpp" />
113
</ItemGroup>
@@ -164,6 +165,7 @@
165
<ClInclude Include="inc\userutil.h" />
166
<ClInclude Include="inc\verutil.h" />
167
<ClInclude Include="inc\wiutil.h" />
168
+ <ClInclude Include="inc\wndutil.h" />
169
<ClInclude Include="inc\wuautil.h" />
170
<ClInclude Include="inc\xmlutil.h" />
171
<ClInclude Include="precomp.h" />
src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters
+6
@@ -165,6 +165,9 @@
165
<ClCompile Include="wiutil.cpp">
166
<Filter>Source Files</Filter>
167
</ClCompile>
168
+ <ClCompile Include="wndutil.cpp">
169
+ <Filter>Source Files</Filter>
170
+ </ClCompile>
171
<ClCompile Include="xmlutil.cpp">
172
<Filter>Source Files</Filter>
173
</ClCompile>
@@ -338,6 +341,9 @@
341
<ClInclude Include="inc\wiutil.h">
342
<Filter>Header Files</Filter>
343
</ClInclude>
344
+ <ClInclude Include="inc\wndutil.h">
345
+ <Filter>Header Files</Filter>
346
+ </ClInclude>
347
<ClInclude Include="inc\xmlutil.h">
348
<Filter>Header Files</Filter>
349
</ClInclude>
src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h
+1
@@ -61,6 +61,7 @@ typedef enum DUTIL_SOURCE
61
DUTIL_SOURCE_WUAUTIL,
62
DUTIL_SOURCE_XMLUTIL,
63
DUTIL_SOURCE_VERUTIL,
64
+ DUTIL_SOURCE_WNDUTIL,
65
66
DUTIL_SOURCE_EXTERNAL = 256,
67
} DUTIL_SOURCE;
src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
+33
-84
@@ -8,6 +8,7 @@ extern "C" {
8
9
// forward declare
10
11
+typedef struct _THEME_CONTROL THEME_CONTROL;
12
typedef struct _THEME THEME;
13
14
#define ReleaseTheme(p) if (p) { ThemeFree(p); p = NULL; }
@@ -194,11 +195,12 @@ struct THEME_ASSIGN_CONTROL_ID
195
{
196
WORD wId; // id to apply to control
197
LPCWSTR wzName; // name of control to match
198
+ const THEME_CONTROL** ppControl;
199
};
200
201
const WORD THEME_FIRST_ASSIGN_CONTROL_ID = 0x4000; // Recommended first control id to be assigned.
202
201
-struct THEME_CONTROL
203
+typedef struct _THEME_CONTROL
204
{
205
THEME_CONTROL_TYPE type;
206
@@ -296,7 +298,7 @@ struct THEME_CONTROL
298
HWND hWnd;
299
DWORD dwData; // type specific data
300
THEME* pTheme;
299
-};
301
+} THEME_CONTROL;
302
303
304
struct THEME_IMAGELIST
@@ -580,8 +582,7 @@ HRESULT DAPI ThemeLoadStrings(
582
583
*******************************************************************/
584
HRESULT DAPI ThemeLoadRichEditFromFile(
583
- __in THEME* pTheme,
584
- __in DWORD dwControl,
585
+ __in const THEME_CONTROL* pThemeControl,
586
__in_z LPCWSTR wzFileName,
587
__in HMODULE hModule
588
);
@@ -591,19 +592,7 @@ HRESULT DAPI ThemeLoadRichEditFromFile(
592
593
*******************************************************************/
594
HRESULT DAPI ThemeLoadRichEditFromResource(
594
- __in THEME* pTheme,
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,
595
+ __in const THEME_CONTROL* pThemeControl,
596
__in_z LPCSTR szResourceName,
597
__in HMODULE hModule
598
);
@@ -682,18 +671,28 @@ ThemeShowChild - shows a control's specified child control, hiding the rest.
671
672
*******************************************************************/
673
void DAPI ThemeShowChild(
685
- __in THEME* pTheme,
674
__in THEME_CONTROL* pParentControl,
675
__in DWORD dwIndex
676
);
677
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.
690
691
*******************************************************************/
694
-BOOL DAPI ThemeControlExists(
692
+BOOL DAPI ThemeControlExistsById(
693
__in const THEME* pTheme,
696
- __in DWORD dwControl
694
+ __in WORD wId,
695
+ __out_opt const THEME_CONTROL** ppThemeControl
696
);
697
698
/********************************************************************
@@ -701,8 +700,7 @@ BOOL DAPI ThemeControlExists(
700
701
*******************************************************************/
702
void DAPI ThemeControlEnable(
704
- __in THEME* pTheme,
705
- __in DWORD dwControl,
703
+ __in const THEME_CONTROL* pThemeControl,
704
__in BOOL fEnable
705
);
706
@@ -711,8 +709,7 @@ void DAPI ThemeControlEnable(
709
710
*******************************************************************/
711
BOOL DAPI ThemeControlEnabled(
714
- __in THEME* pTheme,
715
- __in DWORD dwControl
712
+ __in const THEME_CONTROL* pThemeControl
713
);
714
715
/********************************************************************
@@ -720,8 +717,7 @@ BOOL DAPI ThemeControlEnabled(
717
718
*******************************************************************/
719
void DAPI ThemeControlElevates(
723
- __in THEME* pTheme,
724
- __in DWORD dwControl,
720
+ __in const THEME_CONTROL* pThemeControl,
721
__in BOOL fElevates
722
);
723
@@ -730,8 +726,7 @@ void DAPI ThemeControlElevates(
726
727
*******************************************************************/
728
void DAPI ThemeShowControl(
733
- __in THEME* pTheme,
734
- __in DWORD dwControl,
729
+ __in const THEME_CONTROL* pThemeControl,
730
__in int nCmdShow
731
);
732
@@ -741,8 +736,7 @@ conditional text and notes.
736
737
*******************************************************************/
738
void DAPI ThemeShowControlEx(
744
- __in THEME* pTheme,
745
- __in DWORD dwControl,
739
+ __in const THEME_CONTROL* pThemeControl,
740
__in int nCmdShow
741
);
742
@@ -751,24 +745,7 @@ void DAPI ThemeShowControlEx(
745
746
*******************************************************************/
747
BOOL DAPI ThemeControlVisible(
754
- __in THEME* pTheme,
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
748
+ __in const THEME_CONTROL* pThemeControl
749
);
750
751
/********************************************************************
@@ -789,35 +766,13 @@ HRESULT DAPI ThemeDrawControl(
766
__in DRAWITEMSTRUCT* pdis
767
);
768
792
-/********************************************************************
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
-
769
/********************************************************************
770
ThemeIsControlChecked - gets whether a control is checked. Only
771
really useful for checkbox controls.
772
773
*******************************************************************/
774
BOOL DAPI ThemeIsControlChecked(
808
- __in THEME* pTheme,
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
775
+ __in const THEME_CONTROL* pThemeControl
776
);
777
778
/********************************************************************
@@ -826,8 +781,7 @@ BOOL DAPI ThemeSetControlColor(
781
782
*******************************************************************/
783
HRESULT DAPI ThemeSetProgressControl(
829
- __in THEME* pTheme,
830
- __in DWORD dwControl,
784
+ __in const THEME_CONTROL* pThemeControl,
785
__in DWORD dwProgressPercentage
786
);
787
@@ -837,8 +791,7 @@ HRESULT DAPI ThemeSetProgressControl(
791
792
*******************************************************************/
793
HRESULT DAPI ThemeSetProgressControlColor(
840
- __in THEME* pTheme,
841
- __in DWORD dwControl,
794
+ __in const THEME_CONTROL* pThemeControl,
795
__in DWORD dwColorIndex
796
);
797
@@ -847,8 +800,7 @@ HRESULT DAPI ThemeSetProgressControlColor(
800
801
*******************************************************************/
802
HRESULT DAPI ThemeSetTextControl(
850
- __in const THEME* pTheme,
851
- __in DWORD dwControl,
803
+ __in const THEME_CONTROL* pThemeControl,
804
__in_z_opt LPCWSTR wzText
805
);
806
@@ -858,8 +810,7 @@ ThemeSetTextControl - sets the text of a control and optionally
810
811
*******************************************************************/
812
HRESULT DAPI ThemeSetTextControlEx(
861
- __in const THEME* pTheme,
862
- __in DWORD dwControl,
813
+ __in const THEME_CONTROL* pThemeControl,
814
__in BOOL fUpdate,
815
__in_z_opt LPCWSTR wzText
816
);
@@ -869,8 +820,7 @@ HRESULT DAPI ThemeSetTextControlEx(
820
821
*******************************************************************/
822
HRESULT DAPI ThemeGetTextControl(
872
- __in const THEME* pTheme,
873
- __in DWORD dwControl,
823
+ __in const THEME_CONTROL* pThemeControl,
824
__inout_z LPWSTR* psczText
825
);
826
@@ -889,8 +839,7 @@ HRESULT DAPI ThemeUpdateCaption(
839
840
*******************************************************************/
841
void DAPI ThemeSetFocus(
892
- __in THEME* pTheme,
893
- __in DWORD dwControl
842
+ __in const THEME_CONTROL* pThemeControl
843
);
844
845
#ifdef __cplusplus
src/libs/dutil/WixToolset.DUtil/inc/wndutil.h
new
+41
@@ -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
+
src/libs/dutil/WixToolset.DUtil/precomp.h
+1
@@ -87,6 +87,7 @@
87
#include "strutil.h"
88
#include "timeutil.h"
89
#include "timeutil.h"
90
+#include "wndutil.h"
91
#include "thmutil.h"
92
#include "uncutil.h"
93
#include "uriutil.h"
src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+275
-375
@@ -44,7 +44,6 @@ const DWORD THEME_INVALID_ID = 0xFFFFFFFF;
44
const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF;
45
const DWORD GROW_FONT_INSTANCES = 3;
46
const DWORD GROW_IMAGE_INSTANCES = 5;
47
-const DWORD GROW_WINDOW_TEXT = 250;
47
48
static Gdiplus::GdiplusStartupInput vgsi;
49
static Gdiplus::GdiplusStartupOutput vgso = { };
@@ -70,16 +69,29 @@ enum INTERNAL_CONTROL_STYLE
69
INTERNAL_CONTROL_STYLE_OWNER_DRAW = 0x0010,
70
};
71
73
-struct MEMBUFFER_FOR_RICHEDIT
74
-{
75
- BYTE* rgbData;
76
- DWORD cbData;
72
78
- DWORD iData;
79
-};
73
+// prototypes
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
+ );
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
+ );
94
82
-// prototypes
95
static HRESULT RegisterWindowClasses(
96
__in_opt HMODULE hModule
97
);
@@ -258,11 +270,11 @@ static HRESULT ParseNotes(
270
);
271
static HRESULT StopBillboard(
272
__in THEME* pTheme,
261
- __in DWORD dwControl
273
+ __in THEME_CONTROL* pControl
274
);
275
static HRESULT StartBillboard(
276
__in THEME* pTheme,
265
- __in DWORD dwControl
277
+ __in THEME_CONTROL* pControl
278
);
279
static HRESULT EnsureFontInstance(
280
__in THEME* pTheme,
@@ -290,7 +302,6 @@ static HRESULT LoadControls(
302
__in_opt THEME_CONTROL* pParentControl
303
);
304
static HRESULT ShowControl(
293
- __in THEME* pTheme,
305
__in THEME_CONTROL* pControl,
306
__in int nCmdShow,
307
__in BOOL fSaveEditboxes,
@@ -376,18 +387,6 @@ static BOOL DrawHoverControl(
387
__in THEME* pTheme,
388
__in BOOL fHover
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
- );
390
static void FreeFontInstance(
391
__in THEME_FONT_INSTANCE* pFontInstance
392
);
@@ -475,6 +474,11 @@ static BOOL OnWmNotify(
474
__in const THEME_CONTROL* pThemeControl,
475
__inout LRESULT* plResult
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
+ );
482
static const THEME_CONTROL* FindControlFromHWnd(
483
__in const THEME* pTheme,
484
__in HWND hWnd,
@@ -974,83 +978,39 @@ LExit:
978
979
980
DAPI_(HRESULT) ThemeLoadRichEditFromFile(
977
- __in THEME* pTheme,
978
- __in DWORD dwControl,
981
+ __in const THEME_CONTROL* pThemeControl,
982
__in_z LPCWSTR wzFileName,
983
__in HMODULE hModule
984
)
985
{
983
- HRESULT hr = S_OK;
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.");
986
+ HRESULT hr = E_INVALIDARG;
987
991
- hFile = ::CreateFileW(sczFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
992
- if (INVALID_HANDLE_VALUE == hFile)
988
+ if (pThemeControl)
989
{
994
- ThmExitWithLastError(hr, "Failed to open RTF file.");
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);
990
+ AssertSz(THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type, "ThemeLoadRichEditFromFile called for non-RichEdit control.");
991
1009
- ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast<LPARAM>(&es));
1010
- hr = es.dwError;
1011
- ThmExitOnFailure(hr, "Failed to update RTF stream.");
992
+ hr = WnduLoadRichEditFromFile(pThemeControl->hWnd, wzFileName, hModule);
993
}
994
1014
-LExit:
1015
- ReleaseStr(sczFile);
1016
- ReleaseFile(hFile);
1017
-
995
return hr;
996
}
997
998
999
DAPI_(HRESULT) ThemeLoadRichEditFromResource(
1023
- __in THEME* pTheme,
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,
1000
+ __in const THEME_CONTROL* pThemeControl,
1001
__in_z LPCSTR szResourceName,
1002
__in HMODULE hModule
1003
)
1004
{
1039
- HRESULT hr = S_OK;
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.");
1005
+ HRESULT hr = E_INVALIDARG;
1006
1046
- es.pfnCallback = RichEditStreamFromMemoryCallback;
1047
- es.dwCookie = reinterpret_cast<DWORD_PTR>(&buffer);
1007
+ if (pThemeControl)
1008
+ {
1009
+ AssertSz(THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type, "ThemeLoadRichEditFromResource called for non-RichEdit control.");
1010
1049
- ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast<LPARAM>(&es));
1050
- hr = es.dwError;
1051
- ThmExitOnFailure(hr, "Failed to update RTF stream.");
1011
+ hr = WnduLoadRichEditFromResource(pThemeControl->hWnd, szResourceName, hModule);
1012
+ }
1013
1053
-LExit:
1014
return hr;
1015
}
1016
@@ -1293,141 +1253,127 @@ LExit:
1253
}
1254
1255
1296
-DAPI_(BOOL) ThemeControlExists(
1256
+DAPI_(BOOL) ThemeControlExistsByHWnd(
1257
__in const THEME* pTheme,
1298
- __in DWORD dwControl
1258
+ __in HWND hWnd,
1259
+ __out_opt const THEME_CONTROL** ppThemeControl
1260
)
1261
{
1301
- BOOL fExists = FALSE;
1302
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1303
- if (hWnd)
1262
+ const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd);
1263
+
1264
+ if (ppThemeControl)
1265
{
1305
- const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd);
1306
- fExists = (pControl && hWnd == pControl->hWnd);
1266
+ *ppThemeControl = pControl;
1267
}
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;
1287
}
1288
1289
1290
DAPI_(void) ThemeControlEnable(
1314
- __in THEME* pTheme,
1315
- __in DWORD dwControl,
1291
+ __in const THEME_CONTROL* pThemeControl,
1292
__in BOOL fEnable
1293
)
1294
{
1319
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1320
- THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd));
1321
- if (pControl)
1295
+ if (pThemeControl)
1296
{
1297
+ THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl);
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);
1300
1301
if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_HIDE_WHEN_DISABLED)
1302
{
1328
- ::ShowWindow(hWnd, fEnable ? SW_SHOW : SW_HIDE);
1303
+ ::ShowWindow(pControl->hWnd, fEnable ? SW_SHOW : SW_HIDE);
1304
}
1305
}
1306
}
1307
1308
1309
DAPI_(BOOL) ThemeControlEnabled(
1335
- __in THEME* pTheme,
1336
- __in DWORD dwControl
1310
+ __in const THEME_CONTROL* pThemeControl
1311
)
1312
{
1339
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1340
- const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd);
1341
- return pControl && !(pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_DISABLED);
1313
+ BOOL fEnabled = FALSE;
1314
+
1315
+ if (pThemeControl)
1316
+ {
1317
+ fEnabled = !(pThemeControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_DISABLED);
1318
+ }
1319
+
1320
+ return fEnabled;
1321
}
1322
1323
1324
DAPI_(void) ThemeControlElevates(
1346
- __in THEME* pTheme,
1347
- __in DWORD dwControl,
1325
+ __in const THEME_CONTROL* pThemeControl,
1326
__in BOOL fElevates
1327
)
1328
{
1351
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1352
- ::SendMessageW(hWnd, BCM_SETSHIELD, 0, fElevates);
1329
+ if (pThemeControl)
1330
+ {
1331
+ ::SendMessageW(pThemeControl->hWnd, BCM_SETSHIELD, 0, fElevates);
1332
+ }
1333
}
1334
1335
1336
DAPI_(void) ThemeShowControl(
1357
- __in THEME* pTheme,
1358
- __in DWORD dwControl,
1337
+ __in const THEME_CONTROL* pThemeControl,
1338
__in int nCmdShow
1339
)
1340
{
1362
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
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)
1341
+ if (pThemeControl)
1342
{
1343
+ THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl);
1344
+ ::ShowWindow(pControl->hWnd, nCmdShow);
1345
+
1346
+ // Save the control's visible state.
1347
pControl->dwInternalStyle = (SW_HIDE == nCmdShow) ? (pControl->dwInternalStyle | INTERNAL_CONTROL_STYLE_HIDDEN) : (pControl->dwInternalStyle & ~INTERNAL_CONTROL_STYLE_HIDDEN);
1348
}
1349
}
1350
1351
1352
DAPI_(void) ThemeShowControlEx(
1375
- __in THEME* pTheme,
1376
- __in DWORD dwControl,
1353
+ __in const THEME_CONTROL* pThemeControl,
1354
__in int nCmdShow
1355
)
1356
{
1380
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1381
- THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd));
1382
- if (pControl)
1357
+ if (pThemeControl)
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);
1361
}
1362
}
1363
1364
1365
DAPI_(BOOL) ThemeControlVisible(
1390
- __in THEME* pTheme,
1391
- __in DWORD dwControl
1366
+ __in const THEME_CONTROL* pThemeControl
1367
)
1368
{
1394
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1395
- return ::IsWindowVisible(hWnd);
1396
-}
1397
-
1369
+ BOOL fVisible = FALSE;
1370
1399
-DAPI_(BOOL) ThemePostControlMessage(
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))
1371
+ if (pThemeControl)
1372
{
1413
- er = ::GetLastError();
1414
- hr = HRESULT_FROM_WIN32(er);
1373
+ fVisible = ::IsWindowVisible(pThemeControl->hWnd);
1374
}
1375
1417
- return SUCCEEDED(hr);
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);
1376
+ return fVisible;
1377
}
1378
1379
@@ -1453,9 +1399,15 @@ DAPI_(HRESULT) ThemeDrawControl(
1399
)
1400
{
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
+ }
1410
1458
- AssertSz(pControl, "Expected control window from owner draw window.");
1411
AssertSz(pControl->hWnd == pdis->hwndItem, "Expected control window to match owner draw window.");
1412
AssertSz(pControl->nWidth < 1 || pControl->nWidth == pdis->rcItem.right - pdis->rcItem.left, "Expected control window width to match owner draw window width.");
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:
1444
}
1445
1446
1495
-DAPI_(BOOL) ThemeHoverControl(
1447
+static BOOL ThemeHoverControl(
1448
__in THEME* pTheme,
1449
__in HWND hwndParent,
1450
__in HWND hwndControl
@@ -1519,16 +1471,21 @@ DAPI_(BOOL) ThemeHoverControl(
1471
1472
1473
DAPI_(BOOL) ThemeIsControlChecked(
1522
- __in THEME* pTheme,
1523
- __in DWORD dwControl
1474
+ __in const THEME_CONTROL* pThemeControl
1475
)
1476
{
1526
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1527
- return BST_CHECKED == ::SendMessageW(hWnd, BM_GETCHECK, 0, 0);
1477
+ BOOL fChecked = FALSE;
1478
+
1479
+ if (pThemeControl)
1480
+ {
1481
+ fChecked = BST_CHECKED == ::SendMessageW(pThemeControl->hWnd, BM_GETCHECK, 0, 0);
1482
+ }
1483
+
1484
+ return fChecked;
1485
}
1486
1487
1531
-DAPI_(BOOL) ThemeSetControlColor(
1488
+static BOOL ThemeSetControlColor(
1489
__in THEME* pTheme,
1490
__in HDC hdc,
1491
__in HWND hWnd,
@@ -1537,6 +1494,7 @@ DAPI_(BOOL) ThemeSetControlColor(
1494
{
1495
THEME_FONT* pFont = NULL;
1496
BOOL fHasBackground = FALSE;
1497
+ const THEME_CONTROL* pControl = NULL;
1498
1499
*phBackgroundBrush = NULL;
1500
@@ -1544,10 +1502,9 @@ DAPI_(BOOL) ThemeSetControlColor(
1502
{
1503
pFont = (THEME_INVALID_ID == pTheme->dwFontId) ? NULL : pTheme->rgFonts + pTheme->dwFontId;
1504
}
1547
- else
1505
+ else if (ThemeControlExistsByHWnd(pTheme, hWnd, &pControl))
1506
{
1549
- const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd);
1550
- pFont = (!pControl || THEME_INVALID_ID == pControl->dwFontId) ? NULL : pTheme->rgFonts + pControl->dwFontId;
1507
+ pFont = THEME_INVALID_ID == pControl->dwFontId ? NULL : pTheme->rgFonts + pControl->dwFontId;
1508
}
1509
1510
if (pFont)
@@ -1577,44 +1534,40 @@ DAPI_(BOOL) ThemeSetControlColor(
1534
1535
1536
DAPI_(HRESULT) ThemeSetProgressControl(
1580
- __in THEME* pTheme,
1581
- __in DWORD dwControl,
1537
+ __in const THEME_CONTROL* pThemeControl,
1538
__in DWORD dwProgressPercentage
1539
)
1540
{
1585
- HRESULT hr = E_NOTFOUND;
1586
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1541
+ HRESULT hr = E_INVALIDARG;
1542
1588
- if (hWnd)
1543
+ if (pThemeControl && THEME_CONTROL_TYPE_PROGRESSBAR == pThemeControl->type)
1544
{
1590
- THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd));
1591
- if (pControl && THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type)
1545
+ THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl);
1546
+
1547
+ DWORD dwCurrentProgress = LOWORD(pControl->dwData);
1548
+
1549
+ if (dwCurrentProgress != dwProgressPercentage)
1550
{
1593
- DWORD dwCurrentProgress = LOWORD(pControl->dwData);
1551
+ DWORD dwColor = HIWORD(pControl->dwData);
1552
+ pControl->dwData = MAKEDWORD(dwProgressPercentage, dwColor);
1553
1595
- if (dwCurrentProgress != dwProgressPercentage)
1554
+ if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW)
1555
{
1597
- DWORD dwColor = HIWORD(pControl->dwData);
1598
- pControl->dwData = MAKEDWORD(dwProgressPercentage, dwColor);
1599
-
1600
- if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW)
1556
+ if (!::InvalidateRect(pControl->hWnd, NULL, FALSE))
1557
{
1602
- if (!::InvalidateRect(hWnd, NULL, FALSE))
1603
- {
1604
- ThmExitWithLastError(hr, "Failed to invalidate progress bar window.");
1605
- }
1606
- }
1607
- else
1608
- {
1609
- ::SendMessageW(hWnd, PBM_SETPOS, dwProgressPercentage, 0);
1558
+ ThmExitWithLastError(hr, "Failed to invalidate progress bar window.");
1559
}
1611
-
1612
- hr = S_OK;
1560
}
1561
else
1562
{
1616
- hr = S_FALSE;
1563
+ ::SendMessageW(pControl->hWnd, PBM_SETPOS, dwProgressPercentage, 0);
1564
}
1565
+
1566
+ hr = S_OK;
1567
+ }
1568
+ else
1569
+ {
1570
+ hr = S_FALSE;
1571
}
1572
}
1573
@@ -1624,37 +1577,37 @@ LExit:
1577
1578
1579
DAPI_(HRESULT) ThemeSetProgressControlColor(
1627
- __in THEME* pTheme,
1628
- __in DWORD dwControl,
1580
+ __in const THEME_CONTROL* pThemeControl,
1581
__in DWORD dwColorIndex
1582
)
1583
{
1632
- HRESULT hr = S_FALSE;
1633
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1634
- if (hWnd)
1584
+ HRESULT hr = E_INVALIDARG;
1585
+
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))
1588
{
1636
- THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd));
1589
+ THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(pThemeControl);
1590
1638
- // Only set color on owner draw progress bars.
1639
- if (pControl && (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW) && THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type)
1591
+ if (pControl->ProgressBar.cImageRef <= dwColorIndex)
1592
{
1641
- if (pControl->ProgressBar.cImageRef <= dwColorIndex)
1642
- {
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);
1593
+ ThmExitWithRootFailure(hr, E_INVALIDARG, "Invalid progress bar color index: %u", dwColorIndex);
1594
+ }
1595
1651
- if (!::InvalidateRect(hWnd, NULL, FALSE))
1652
- {
1653
- ThmExitWithLastError(hr, "Failed to invalidate progress bar window.");
1654
- }
1596
+ if (HIWORD(pControl->dwData) != dwColorIndex)
1597
+ {
1598
+ DWORD dwCurrentProgress = LOWORD(pControl->dwData);
1599
+ pControl->dwData = MAKEDWORD(dwCurrentProgress, dwColorIndex);
1600
1656
- hr = S_OK;
1601
+ if (!::InvalidateRect(pControl->hWnd, NULL, FALSE))
1602
+ {
1603
+ ThmExitWithLastError(hr, "Failed to invalidate progress bar window.");
1604
}
1605
+
1606
+ hr = S_OK;
1607
+ }
1608
+ else
1609
+ {
1610
+ hr = S_FALSE;
1611
}
1612
}
1613
@@ -1664,41 +1617,40 @@ LExit:
1617
1618
1619
DAPI_(HRESULT) ThemeSetTextControl(
1667
- __in const THEME* pTheme,
1668
- __in DWORD dwControl,
1620
+ __in const THEME_CONTROL* pThemeControl,
1621
__in_z_opt LPCWSTR wzText
1622
)
1623
{
1672
- return ThemeSetTextControlEx(pTheme, dwControl, FALSE, wzText);
1624
+ return ThemeSetTextControlEx(pThemeControl, FALSE, wzText);
1625
}
1626
1627
1628
DAPI_(HRESULT) ThemeSetTextControlEx(
1677
- __in const THEME* pTheme,
1678
- __in DWORD dwControl,
1629
+ __in const THEME_CONTROL* pThemeControl,
1630
__in BOOL fUpdate,
1631
__in_z_opt LPCWSTR wzText
1632
)
1633
{
1683
- HRESULT hr = S_OK;
1684
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
1634
+ HRESULT hr = E_INVALIDARG;
1635
1686
- if (hWnd)
1636
+ if (pThemeControl)
1637
{
1638
if (fUpdate)
1639
{
1690
- ::ShowWindow(hWnd, SW_HIDE);
1640
+ ::ShowWindow(pThemeControl->hWnd, SW_HIDE);
1641
}
1642
1693
- if (!::SetWindowTextW(hWnd, wzText))
1643
+ if (!::SetWindowTextW(pThemeControl->hWnd, wzText))
1644
{
1645
ThmExitWithLastError(hr, "Failed to set control text.");
1646
}
1647
1648
if (fUpdate)
1649
{
1700
- ::ShowWindow(hWnd, SW_SHOW);
1650
+ ::ShowWindow(pThemeControl->hWnd, SW_SHOW);
1651
}
1652
+
1653
+ hr = S_OK;
1654
}
1655
1656
LExit:
@@ -1707,50 +1659,17 @@ LExit:
1659
1660
1661
DAPI_(HRESULT) ThemeGetTextControl(
1710
- __in const THEME* pTheme,
1711
- __in DWORD dwControl,
1662
+ __in const THEME_CONTROL* pThemeControl,
1663
__inout_z LPWSTR* psczText
1664
)
1665
{
1715
- HRESULT hr = S_OK;
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.");
1666
+ HRESULT hr = E_INVALIDARG;
1667
1725
- cchText = (DWORD)min(DWORD_MAX, cbSize);
1726
-
1727
- if (!cchText)
1668
+ if (pThemeControl)
1669
{
1729
- cchText = GROW_WINDOW_TEXT;
1730
-
1731
- hr = StrAlloc(psczText, cchText);
1732
- ThmExitOnFailure(hr, "Failed to grow text buffer.");
1670
+ hr = WnduGetControlText(pThemeControl->hWnd, psczText);
1671
}
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:
1673
return hr;
1674
}
1675
@@ -1771,25 +1690,26 @@ LExit:
1690
1691
1692
DAPI_(void) ThemeSetFocus(
1774
- __in THEME* pTheme,
1775
- __in DWORD dwControl
1693
+ __in const THEME_CONTROL* pThemeControl
1694
)
1695
{
1778
- HWND hwndFocus = ::GetDlgItem(pTheme->hwndParent, dwControl);
1779
- if (hwndFocus && !ThemeControlEnabled(pTheme, dwControl))
1780
- {
1781
- hwndFocus = ::GetNextDlgTabItem(pTheme->hwndParent, hwndFocus, FALSE);
1782
- }
1696
+ if (pThemeControl)
1697
+ {
1698
+ HWND hwndFocus = pThemeControl->hWnd;
1699
+ if (hwndFocus && !ThemeControlEnabled(pThemeControl))
1700
+ {
1701
+ hwndFocus = ::GetNextDlgTabItem(pThemeControl->pTheme->hwndParent, hwndFocus, FALSE);
1702
+ }
1703
1784
- if (hwndFocus)
1785
- {
1786
- ::SetFocus(hwndFocus);
1704
+ if (hwndFocus)
1705
+ {
1706
+ ::SetFocus(hwndFocus);
1707
+ }
1708
}
1709
}
1710
1711
1712
DAPI_(void) ThemeShowChild(
1792
- __in THEME* pTheme,
1713
__in THEME_CONTROL* pParentControl,
1714
__in DWORD dwIndex
1715
)
@@ -1798,7 +1718,7 @@ DAPI_(void) ThemeShowChild(
1718
for (DWORD i = 0; i < pParentControl->cControls; ++i)
1719
{
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);
1722
}
1723
}
1724
@@ -4322,28 +4242,24 @@ LExit:
4242
4243
static HRESULT StartBillboard(
4244
__in THEME* pTheme,
4325
- __in DWORD dwControl
4245
+ __in THEME_CONTROL* pControl
4246
)
4247
{
4248
HRESULT hr = E_NOTFOUND;
4329
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
4249
+ UINT_PTR idEvent = reinterpret_cast<UINT_PTR>(pControl);
4250
4331
- if (hWnd)
4251
+ if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type)
4252
{
4333
- THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hWnd));
4334
- if (pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type)
4335
- {
4336
- // kick off
4337
- pControl->dwData = 0;
4338
- OnBillboardTimer(pTheme, pTheme->hwndParent, dwControl);
4253
+ // kick off
4254
+ pControl->dwData = 0;
4255
+ OnBillboardTimer(pTheme, pTheme->hwndParent, idEvent);
4256
4340
- if (!::SetTimer(pTheme->hwndParent, pControl->wId, pControl->wBillboardInterval, NULL))
4341
- {
4342
- ThmExitWithLastError(hr, "Failed to start billboard.");
4343
- }
4344
-
4345
- hr = S_OK;
4257
+ if (!::SetTimer(pTheme->hwndParent, idEvent, pControl->wBillboardInterval, NULL))
4258
+ {
4259
+ ThmExitWithLastError(hr, "Failed to start billboard.");
4260
}
4261
+
4262
+ hr = S_OK;
4263
}
4264
4265
LExit:
@@ -4353,23 +4269,19 @@ LExit:
4269
4270
static HRESULT StopBillboard(
4271
__in THEME* pTheme,
4356
- __in DWORD dwControl
4272
+ __in THEME_CONTROL* pControl
4273
)
4274
{
4275
HRESULT hr = E_NOTFOUND;
4360
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
4276
+ UINT_PTR idEvent = reinterpret_cast<UINT_PTR>(pControl);
4277
4362
- if (hWnd)
4278
+ if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type)
4279
{
4364
- const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd);
4365
- if (pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type)
4366
- {
4367
- ThemeControlEnable(pTheme, dwControl, FALSE);
4280
+ ThemeControlEnable(pControl, FALSE);
4281
4369
- if (::KillTimer(pTheme->hwndParent, pControl->wId))
4370
- {
4371
- hr = S_OK;
4372
- }
4282
+ if (::KillTimer(pTheme->hwndParent, idEvent))
4283
+ {
4284
+ hr = S_OK;
4285
}
4286
}
4287
@@ -5039,81 +4951,33 @@ static void FreeImageInstance(
4951
}
4952
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
-
4954
static void CALLBACK OnBillboardTimer(
5088
- __in THEME* pTheme,
4955
+ __in THEME* /*pTheme*/,
4956
__in HWND hwnd,
4957
__in UINT_PTR idEvent
4958
)
4959
{
5093
- HWND hwndControl = ::GetDlgItem(hwnd, static_cast<int>(idEvent));
5094
- if (hwndControl)
4960
+ THEME_CONTROL* pControl = reinterpret_cast<THEME_CONTROL*>(idEvent);
4961
+
4962
+ if (pControl)
4963
{
5096
- THEME_CONTROL* pControl = const_cast<THEME_CONTROL*>(FindControlFromHWnd(pTheme, hwndControl));
5097
- AssertSz(pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type, "Only billboard controls should get billboard timer messages.");
4964
+ AssertSz(THEME_CONTROL_TYPE_BILLBOARD == pControl->type, "Only billboard controls should get billboard timer messages.");
4965
5099
- if (pControl)
4966
+ if (pControl->dwData < pControl->cControls)
4967
{
5101
- if (pControl->dwData < pControl->cControls)
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;
4968
+ ThemeShowChild(pControl, pControl->dwData);
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;
4981
}
4982
}
4983
@@ -5151,7 +5015,7 @@ static void OnBrowseDirectory(
5015
5016
if (pTargetControl && THEME_CONTROL_TYPE_EDITBOX == pTargetControl->type && !pTargetControl->fDisableVariableFunctionality)
5017
{
5154
- hr = ThemeSetTextControl(pTheme, pTargetControl->wId, wzPath);
5018
+ hr = ThemeSetTextControl(pTargetControl, wzPath);
5019
ThmExitOnFailure(hr, "Failed to set text on editbox: %ls", pTargetControl->sczName);
5020
}
5021
else if (pTheme->pfnSetStringVariable)
@@ -5161,7 +5025,7 @@ static void OnBrowseDirectory(
5025
}
5026
else if (pTargetControl)
5027
{
5164
- hr = ThemeSetTextControl(pTheme, pTargetControl->wId, wzPath);
5028
+ hr = ThemeSetTextControl(pTargetControl, wzPath);
5029
ThmExitOnFailure(hr, "Failed to set text on control: %ls", pTargetControl->sczName);
5030
}
5031
@@ -5252,13 +5116,13 @@ static BOOL OnButtonClicked(
5116
case THEME_CONTROL_TYPE_CHECKBOX:
5117
if (pTheme->pfnSetNumericVariable && pControl->sczName && *pControl->sczName)
5118
{
5255
- BOOL fChecked = ThemeIsControlChecked(pTheme, pControl->wId);
5119
+ BOOL fChecked = ThemeIsControlChecked(pControl);
5120
pTheme->pfnSetNumericVariable(pControl->sczName, fChecked ? 1 : 0, pTheme->pvVariableContext);
5121
fRefresh = TRUE;
5122
}
5123
break;
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))
5126
{
5127
pTheme->pfnSetStringVariable(pControl->sczVariable, pControl->sczValue, FALSE, pTheme->pvVariableContext);
5128
fRefresh = TRUE;
@@ -5386,6 +5250,42 @@ LExit:
5250
return fProcessed;
5251
}
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
+
5289
static BOOL OnNotifyEnMsgFilter(
5290
__in THEME* pTheme,
5291
__in const THEME_CONTROL* pThemeControl,
@@ -5638,7 +5538,6 @@ LExit:
5538
5539
5540
static HRESULT ShowControl(
5641
- __in THEME* pTheme,
5541
__in THEME_CONTROL* pControl,
5542
__in int nCmdShow,
5543
__in BOOL fSaveEditboxes,
@@ -5654,13 +5553,14 @@ static HRESULT ShowControl(
5553
LPWSTR sczText = NULL;
5554
THEME_SAVEDVARIABLE* pSavedVariable = NULL;
5555
BOOL fHide = SW_HIDE == nCmdShow;
5556
+ THEME* pTheme = pControl->pTheme;
5557
THEME_PAGE* pPage = ThemeGetPage(pTheme, dwPageId);
5558
5559
// Save the editbox value if necessary (other control types save their values immediately).
5560
if (pTheme->pfnSetStringVariable && !pControl->fDisableVariableFunctionality &&
5561
fSaveEditboxes && THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName)
5562
{
5663
- hr = ThemeGetTextControl(pTheme, pControl->wId, &sczText);
5563
+ hr = ThemeGetTextControl(pControl, &sczText);
5564
ThmExitOnFailure(hr, "Failed to get the text for control: %ls", pControl->sczName);
5565
5566
hr = pTheme->pfnSetStringVariable(pControl->sczName, sczText, FALSE, pTheme->pvVariableContext);
@@ -5675,7 +5575,7 @@ static HRESULT ShowControl(
5575
5576
if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type)
5577
{
5678
- StopBillboard(pTheme, pControl->wId);
5578
+ StopBillboard(pTheme, pControl);
5579
}
5580
5581
ExitFunction();
@@ -5767,7 +5667,7 @@ static HRESULT ShowControl(
5667
ReleaseNullStr(sczText);
5668
}
5669
5770
- ThemeSetTextControl(pTheme, pControl->wId, sczText);
5670
+ ThemeSetTextControl(pControl, sczText);
5671
5672
if (wzNote && *wzNote)
5673
{
@@ -5811,7 +5711,7 @@ static HRESULT ShowControl(
5711
++iPageControl;
5712
}
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);
5715
}
5716
5717
// If this is an editbox control,
@@ -5838,7 +5738,7 @@ static HRESULT ShowControl(
5738
++iPageControl;
5739
}
5740
5841
- ThemeSetTextControl(pTheme, pControl->wId, sczText);
5741
+ ThemeSetTextControl(pControl, sczText);
5742
}
5743
}
5744
@@ -5901,11 +5801,11 @@ static HRESULT ShowControl(
5801
{
5802
if (fEnabled)
5803
{
5904
- StartBillboard(pTheme, pControl->wId);
5804
+ StartBillboard(pTheme, pControl);
5805
}
5806
else
5807
{
5908
- StopBillboard(pTheme, pControl->wId);
5808
+ StopBillboard(pTheme, pControl);
5809
}
5810
}
5811
@@ -5944,7 +5844,7 @@ static HRESULT ShowControls(
5844
// Only look at non-page controls and the specified page's controls.
5845
if (!pControl->wPageId || pControl->wPageId == dwPageId)
5846
{
5947
- hr = ShowControl(pTheme, pControl, nCmdShow, fSaveEditboxes, reason, dwPageId, &hwndFocus);
5847
+ hr = ShowControl(pControl, nCmdShow, fSaveEditboxes, reason, dwPageId, &hwndFocus);
5848
ThmExitOnFailure(hr, "Failed to show control '%ls' at index %d.", pControl->sczName, i);
5849
}
5850
}
@@ -6509,7 +6409,7 @@ static HRESULT LoadControls(
6409
HRESULT hrFormat = pTheme->pfnFormatString(pControl->sczText, &sczText, pTheme->pvVariableContext);
6410
if (SUCCEEDED(hrFormat))
6411
{
6512
- ThemeSetTextControl(pTheme, pControl->wId, sczText);
6412
+ ThemeSetTextControl(pControl, sczText);
6413
}
6414
}
6415
src/libs/dutil/WixToolset.DUtil/wndutil.cpp
new
+206
@@ -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
+}
src/samples/thmviewer/display.cpp
+4
-4
@@ -188,7 +188,7 @@ static DWORD WINAPI DisplayThreadProc(
188
THEME_CONTROL* pControl = pCurrentHandle->pTheme->rgControls + i;
189
if (!pControl->wPageId)
190
{
191
- ThemeShowControl(pCurrentHandle->pTheme, pControl->wId, nCmdShow);
191
+ ThemeShowControl(pControl, nCmdShow);
192
}
193
}
194
@@ -264,7 +264,7 @@ static LRESULT CALLBACK DisplayWndProc(
264
break;
265
266
case WM_TIMER:
267
- if (!lParam && SUCCEEDED(ThemeSetProgressControl(pHandleTheme->pTheme, wParam, dwProgress)))
267
+ if (!lParam && SUCCEEDED(ThemeSetProgressControl(reinterpret_cast<THEME_CONTROL*>(wParam), dwProgress)))
268
{
269
dwProgress += rand() % 10 + 1;
270
if (dwProgress > 100)
@@ -322,12 +322,12 @@ static BOOL DisplayOnThmLoadedControl(
322
// Pre-populate some control types with data.
323
if (THEME_CONTROL_TYPE_RICHEDIT == pControl->type)
324
{
325
- hr = ThemeLoadRichEditFromResource(pTheme, pControl->wId, MAKEINTRESOURCEA(THMVWR_RES_RICHEDIT_FILE), ::GetModuleHandleW(NULL));
325
+ hr = WnduLoadRichEditFromResource(pControl->hWnd, MAKEINTRESOURCEA(THMVWR_RES_RICHEDIT_FILE), ::GetModuleHandleW(NULL));
326
ExitOnFailure(hr, "Failed to load richedit text.");
327
}
328
else if (THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type)
329
{
330
- DWORD dwId = ::SetTimer(pTheme->hwndParent, pControl->wId, 500, NULL);
330
+ DWORD dwId = ::SetTimer(pTheme->hwndParent, reinterpret_cast<UINT_PTR>(pControl), 500, NULL);
331
dwId = dwId; // prevents warning in "ship" build.
332
Assert(dwId == pControl->wId);
333
}
src/samples/thmviewer/precomp.h
+1
@@ -28,6 +28,7 @@
28
#include "shelutil.h"
29
#include "strutil.h"
30
#include "thmutil.h"
31
+#include "wndutil.h"
32
33
#include "resource.h"
34
src/samples/thmviewer/thmviewer.cpp
+25
-12
@@ -390,6 +390,12 @@ static void OnThemeLoadError(
390
LPWSTR* psczErrors = NULL;
391
UINT cErrors = 0;
392
TVINSERTSTRUCTW tvi = { };
393
+ const THEME_CONTROL* pTreeControl = NULL;
394
+
395
+ if (!ThemeControlExistsById(pTheme, THMVWR_CONTROL_TREE, &pTreeControl))
396
+ {
397
+ ExitWithRootFailure(hr, E_INVALIDSTATE, "THMVWR_CONTROL_TREE control doesn't exist.");
398
+ }
399
400
// Add the application node.
401
tvi.hParent = NULL;
@@ -397,7 +403,7 @@ static void OnThemeLoadError(
403
tvi.item.mask = TVIF_TEXT | TVIF_PARAM;
404
tvi.item.lParam = 0;
405
tvi.item.pszText = L"Failed to load theme.";
400
- tvi.hParent = reinterpret_cast<HTREEITEM>(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)));
406
+ tvi.hParent = reinterpret_cast<HTREEITEM>(::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)));
407
408
if (!vsczThemeLoadErrors)
409
{
@@ -405,13 +411,13 @@ static void OnThemeLoadError(
411
ExitOnFailure(hr, "Failed to format error message.");
412
413
tvi.item.pszText = sczMessage;
408
- ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi));
414
+ ::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi));
415
416
hr = StrAllocFromError(&sczMessage, hrFailure, NULL);
417
ExitOnFailure(hr, "Failed to format error message text.");
418
419
tvi.item.pszText = sczMessage;
414
- ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi));
420
+ ::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi));
421
}
422
else
423
{
@@ -421,11 +427,11 @@ static void OnThemeLoadError(
427
for (DWORD i = 0; i < cErrors; ++i)
428
{
429
tvi.item.pszText = psczErrors[i];
424
- ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi));
430
+ ::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi));
431
}
432
}
433
428
- ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_EXPAND, TVE_EXPAND, reinterpret_cast<LPARAM>(tvi.hParent));
434
+ ::SendMessage(pTreeControl->hWnd, TVM_EXPAND, TVE_EXPAND, reinterpret_cast<LPARAM>(tvi.hParent));
435
436
LExit:
437
ReleaseStr(sczMessage);
@@ -439,6 +445,7 @@ static void OnNewTheme(
445
__in HANDLE_THEME* pHandle
446
)
447
{
448
+ const THEME_CONTROL* pTreeControl = NULL;
449
HANDLE_THEME* pOldHandle = reinterpret_cast<HANDLE_THEME*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA));
450
THEME* pNewTheme = pHandle->pTheme;
451
@@ -460,17 +467,23 @@ static void OnNewTheme(
467
468
::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pHandle));
469
470
+ if (!ThemeControlExistsById(pTheme, THMVWR_CONTROL_TREE, &pTreeControl))
471
+ {
472
+ TraceError(E_INVALIDSTATE, "Tree control doesn't exist.");
473
+ return;
474
+ }
475
+
476
// Remember the currently selected item by name so we can try to automatically select it later.
477
// Otherwise, the user would see their window destroyed after every save of their theme file and
478
// have to click to get the window back.
479
item.mask = TVIF_TEXT;
480
item.pszText = wzSelectedPage;
481
item.cchTextMax = countof(wzSelectedPage);
469
- item.hItem = reinterpret_cast<HTREEITEM>(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_GETNEXTITEM, TVGN_CARET, NULL));
470
- ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_GETITEM, 0, reinterpret_cast<LPARAM>(&item));
482
+ item.hItem = reinterpret_cast<HTREEITEM>(::SendMessage(pTreeControl->hWnd, TVM_GETNEXTITEM, TVGN_CARET, NULL));
483
+ ::SendMessage(pTreeControl->hWnd, TVM_GETITEM, 0, reinterpret_cast<LPARAM>(&item));
484
485
// Remove the previous items in the tree.
473
- ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_DELETEITEM, 0, reinterpret_cast<LPARAM>(TVI_ROOT));
486
+ ::SendMessage(pTreeControl->hWnd, TVM_DELETEITEM, 0, reinterpret_cast<LPARAM>(TVI_ROOT));
487
488
// Add the application node.
489
tvi.hParent = NULL;
@@ -480,7 +493,7 @@ static void OnNewTheme(
493
tvi.item.pszText = pHandle && pHandle->pTheme && pHandle->pTheme->sczCaption ? pHandle->pTheme->sczCaption : L"Window";
494
495
// Add the pages.
483
- tvi.hParent = reinterpret_cast<HTREEITEM>(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)));
496
+ tvi.hParent = reinterpret_cast<HTREEITEM>(::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)));
497
tvi.hInsertAfter = TVI_SORT;
498
for (DWORD i = 0; i < pNewTheme->cPages; ++i)
499
{
@@ -490,7 +503,7 @@ static void OnNewTheme(
503
tvi.item.pszText = pPage->sczName;
504
tvi.item.lParam = i + 1; //prgdwPageIds[i]; - TODO: do the right thing here by calling ThemeGetPageIds(), should not assume we know how the page ids will be calculated.
505
493
- HTREEITEM hti = reinterpret_cast<HTREEITEM>(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)));
506
+ HTREEITEM hti = reinterpret_cast<HTREEITEM>(::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)));
507
if (*wzSelectedPage && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pPage->sczName, -1, wzSelectedPage, -1))
508
{
509
htiSelected = hti;
@@ -503,10 +516,10 @@ static void OnNewTheme(
516
htiSelected = tvi.hParent;
517
}
518
506
- ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_EXPAND, TVE_EXPAND, reinterpret_cast<LPARAM>(tvi.hParent));
519
+ ::SendMessage(pTreeControl->hWnd, TVM_EXPAND, TVE_EXPAND, reinterpret_cast<LPARAM>(tvi.hParent));
520
if (htiSelected)
521
{
509
- ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_SELECTITEM, TVGN_CARET, reinterpret_cast<LPARAM>(htiSelected));
522
+ ::SendMessage(pTreeControl->hWnd, TVM_SELECTITEM, TVGN_CARET, reinterpret_cast<LPARAM>(htiSelected));
523
}
524
}
525
src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
+8
-3
@@ -365,18 +365,23 @@ private:
365
366
void UpdateProgressBarProgress()
367
{
368
+ const THEME_CONTROL* pControlProgressbarImage = NULL;
369
+ const THEME_CONTROL* pControlProgressbarStandard = NULL;
370
static DWORD dwProgress = 0;
371
DWORD dwCurrent = dwProgress < 100 ? dwProgress : 200 - dwProgress;
372
373
+ ThemeControlExistsById(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, &pControlProgressbarImage);
374
+ ThemeControlExistsById(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_STANDARD, &pControlProgressbarStandard);
375
+
376
if (0 == dwProgress || 100 == dwProgress)
377
{
373
- ThemeSetProgressControlColor(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, 100 == dwProgress ? 1 : 0);
378
+ ThemeSetProgressControlColor(pControlProgressbarImage, 100 == dwProgress ? 1 : 0);
379
}
380
381
dwProgress = (dwProgress + 10) % 200;
382
378
- ThemeSetProgressControl(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, dwCurrent);
379
- ThemeSetProgressControl(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_STANDARD, dwCurrent);
383
+ ThemeSetProgressControl(pControlProgressbarImage, dwCurrent);
384
+ ThemeSetProgressControl(pControlProgressbarStandard, dwCurrent);
385
}
386
387
public: