From 0a97d7aafcbb564b7bc9f4e754f39055fd38ae4f Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 10 Aug 2022 19:24:45 -0500 Subject: Allow wixstdba special controls to have declarative text. Fixes 6855 --- src/api/burn/balutil/inc/BAFunctions.h | 2 +- src/api/burn/balutil/inc/BalBaseBAFunctions.h | 2 +- src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h | 2 +- src/api/burn/balutil/inc/IBAFunctions.h | 2 +- .../WixStandardBootstrapperApplication.cpp | 53 +++---- src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | 25 ++- src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 167 +++++++++++---------- .../Manual/BafThmutilTesting/BafThmUtilTesting.cpp | 2 +- 8 files changed, 141 insertions(+), 114 deletions(-) diff --git a/src/api/burn/balutil/inc/BAFunctions.h b/src/api/burn/balutil/inc/BAFunctions.h index 8ecc04ff..4a0b8599 100644 --- a/src/api/burn/balutil/inc/BAFunctions.h +++ b/src/api/burn/balutil/inc/BAFunctions.h @@ -164,7 +164,7 @@ struct BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS DWORD cbSize; BOOL fProcessed; WORD wId; - BOOL fDisableAutomaticFunctionality; + DWORD dwAutomaticBehaviorType; }; struct BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h index 49e97815..3f99673d 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h @@ -947,7 +947,7 @@ public: // IBAFunctions __in LPCWSTR /*wzName*/, __inout BOOL* /*pfProcessed*/, __inout WORD* /*pwId*/, - __inout BOOL* /*pfDisableAutomaticFunctionality*/ + __inout DWORD* /*pdwAutomaticBehaviorType*/ ) { return S_OK; diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h index e10decfc..728bd2b5 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h @@ -30,7 +30,7 @@ static HRESULT BalBaseBAFunctionsProcOnThemeControlLoading( __inout BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS* pResults ) { - return pBAFunctions->OnThemeControlLoading(pArgs->wzName, &pResults->fProcessed, &pResults->wId, &pResults->fDisableAutomaticFunctionality); + return pBAFunctions->OnThemeControlLoading(pArgs->wzName, &pResults->fProcessed, &pResults->wId, &pResults->dwAutomaticBehaviorType); } static HRESULT BalBaseBAFunctionsProcOnThemeControlWmCommand( diff --git a/src/api/burn/balutil/inc/IBAFunctions.h b/src/api/burn/balutil/inc/IBAFunctions.h index ea6c116b..bb911040 100644 --- a/src/api/burn/balutil/inc/IBAFunctions.h +++ b/src/api/burn/balutil/inc/IBAFunctions.h @@ -36,7 +36,7 @@ DECLARE_INTERFACE_IID_(IBAFunctions, IBootstrapperApplication, "0FB445ED-17BD-49 __in LPCWSTR wzName, __inout BOOL* pfProcessed, __inout WORD* pwId, - __inout BOOL* pfDisableAutomaticFunctionality + __inout DWORD* pdwAutomaticBehaviorType ) = 0; // OnThemeControlWmCommand - Called when WM_COMMAND is received for a control. diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 8544ff0e..0f1a9f49 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp @@ -3409,7 +3409,7 @@ private: fProcessed = TRUE; pResults->wId = pAssignControl->wId; - pResults->fDisableAutomaticFunctionality = pAssignControl->fDisableAutomaticFunctionality; + pResults->dwAutomaticBehaviorType = pAssignControl->dwAutomaticBehaviorType; ExitFunction(); } } @@ -3421,7 +3421,7 @@ private: themeControlLoadingResults.cbSize = sizeof(themeControlLoadingResults); themeControlLoadingResults.wId = pResults->wId; - themeControlLoadingResults.fDisableAutomaticFunctionality = pResults->fDisableAutomaticFunctionality; + themeControlLoadingResults.dwAutomaticBehaviorType = pResults->dwAutomaticBehaviorType; hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING, &themeControlLoadingArgs, &themeControlLoadingResults, m_pvBAFunctionsProcContext); @@ -3437,7 +3437,7 @@ private: { fProcessed = TRUE; pResults->wId = themeControlLoadingResults.wId; - pResults->fDisableAutomaticFunctionality = themeControlLoadingResults.fDisableAutomaticFunctionality; + pResults->dwAutomaticBehaviorType = themeControlLoadingResults.dwAutomaticBehaviorType; } } } @@ -4594,6 +4594,7 @@ public: ) : CBalBaseBootstrapperApplication(pEngine, 3, 3000) { THEME_ASSIGN_CONTROL_ID* pAssignControl = NULL; + DWORD dwAutomaticBehaviorType = THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ENABLED | THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VISIBLE | THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ACTION | THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VALUE; m_hModule = hModule; m_command = { }; @@ -4674,161 +4675,161 @@ public: pAssignControl->wId = WIXSTDBA_CONTROL_INSTALL_BUTTON; pAssignControl->wzName = L"InstallButton"; pAssignControl->ppControl = &m_pControlInstallButton; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlInstallButton = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_EULA_RICHEDIT; pAssignControl->wzName = L"EulaRichedit"; pAssignControl->ppControl = &m_pControlEulaRichedit; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlEulaRichedit = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_EULA_LINK; pAssignControl->wzName = L"EulaHyperlink"; pAssignControl->ppControl = &m_pControlEulaHyperlink; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlEulaHyperlink = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX; pAssignControl->wzName = L"EulaAcceptCheckbox"; pAssignControl->ppControl = &m_pControlEulaAcceptCheckbox; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlEulaAcceptCheckbox = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_REPAIR_BUTTON; pAssignControl->wzName = L"RepairButton"; pAssignControl->ppControl = &m_pControlRepairButton; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlRepairButton = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_UNINSTALL_BUTTON; pAssignControl->wzName = L"UninstallButton"; pAssignControl->ppControl = &m_pControlUninstallButton; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlUninstallButton = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT; pAssignControl->wzName = L"CacheProgressPackageText"; pAssignControl->ppControl = &m_pControlCacheProgressPackageText; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlCacheProgressPackageText = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR; pAssignControl->wzName = L"CacheProgressbar"; pAssignControl->ppControl = &m_pControlCacheProgressbar; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlCacheProgressbar = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT; pAssignControl->wzName = L"CacheProgressText"; pAssignControl->ppControl = &m_pControlCacheProgressText; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlCacheProgressText = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT; pAssignControl->wzName = L"ExecuteProgressPackageText"; pAssignControl->ppControl = &m_pControlExecuteProgressPackageText; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlExecuteProgressPackageText = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR; pAssignControl->wzName = L"ExecuteProgressbar"; pAssignControl->ppControl = &m_pControlExecuteProgressbar; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlExecuteProgressbar = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT; pAssignControl->wzName = L"ExecuteProgressText"; pAssignControl->ppControl = &m_pControlExecuteProgressText; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlExecuteProgressText = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT; pAssignControl->wzName = L"ExecuteProgressActionDataText"; pAssignControl->ppControl = &m_pControlExecuteProgressActionDataText; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlExecuteProgressActionDataText = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT; pAssignControl->wzName = L"OverallProgressPackageText"; pAssignControl->ppControl = &m_pControlOverallProgressPackageText; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlOverallProgressPackageText = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR; pAssignControl->wzName = L"OverallProgressbar"; pAssignControl->ppControl = &m_pControlOverallProgressbar; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlOverallProgressbar = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR; pAssignControl->wzName = L"OverallCalculatedProgressbar"; pAssignControl->ppControl = &m_pControlOverallCalculatedProgressbar; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlOverallCalculatedProgressbar = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT; pAssignControl->wzName = L"OverallProgressText"; pAssignControl->ppControl = &m_pControlOverallProgressText; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlOverallProgressText = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON; pAssignControl->wzName = L"ProgressCancelButton"; pAssignControl->ppControl = &m_pControlProgressCancelButton; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlProgressCancelButton = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_LAUNCH_BUTTON; pAssignControl->wzName = L"LaunchButton"; pAssignControl->ppControl = &m_pControlLaunchButton; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlLaunchButton = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON; pAssignControl->wzName = L"SuccessRestartButton"; pAssignControl->ppControl = &m_pControlSuccessRestartButton; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlSuccessRestartButton = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK; pAssignControl->wzName = L"FailureLogFileLink"; pAssignControl->ppControl = &m_pControlFailureLogFileLink; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlFailureLogFileLink = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT; pAssignControl->wzName = L"FailureMessageText"; pAssignControl->ppControl = &m_pControlFailureMessageText; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlFailureMessageText = NULL; ++pAssignControl; pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON; pAssignControl->wzName = L"FailureRestartButton"; pAssignControl->ppControl = &m_pControlFailureRestartButton; - pAssignControl->fDisableAutomaticFunctionality = TRUE; + pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType; m_pControlFailureRestartButton = NULL; C_ASSERT(LAST_WIXSTDBA_CONTROL == WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON + 1); diff --git a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h index 8cf7dc92..45e4fc51 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h @@ -57,6 +57,20 @@ typedef enum THEME_CONTROL_DATA THEME_CONTROL_DATA_HOVER = 1, } THEME_CONTROL_DATA; +typedef enum THEME_CONTROL_AUTOMATIC_BEHAVIOR_TYPE +{ + THEME_CONTROL_AUTOMATIC_BEHAVIOR_ALL = 0x0, + THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ENABLED = 0x1, + THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VISIBLE = 0x2, + THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ACTION = 0x4, + // For form controls like editboxes and checkboxes, + // the value will not be automatically persisted to a variable and + // the control's value will only be changed by the user. + THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VALUE = 0x8, + // This has no effect on editboxes since their text is their value. + THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_TEXT = 0x10, +} THEME_CONTROL_AUTOMATIC_BEHAVIOR_TYPE; + typedef enum THEME_CONTROL_TYPE { THEME_CONTROL_TYPE_UNKNOWN, @@ -196,7 +210,7 @@ struct THEME_ASSIGN_CONTROL_ID WORD wId; // id to apply to control LPCWSTR wzName; // name of control to match const THEME_CONTROL** ppControl; - BOOL fDisableAutomaticFunctionality; // prevent declarative functionality from interfering with the application's imperative code + DWORD dwAutomaticBehaviorType; // prevent declarative functionality from interfering with the application's imperative code }; const WORD THEME_FIRST_ASSIGN_CONTROL_ID = 0x4000; // Recommended first control id to be assigned. @@ -224,7 +238,12 @@ typedef struct _THEME_CONTROL LPWSTR sczEnableCondition; LPWSTR sczVisibleCondition; - BOOL fDisableAutomaticFunctionality; + + BOOL fAutomaticEnabled; + BOOL fAutomaticVisible; + BOOL fAutomaticAction; + BOOL fAutomaticValue; + BOOL fAutomaticText; union { @@ -472,7 +491,7 @@ typedef struct _THEME_LOADINGCONTROL_RESULTS // Due to this value being packed into 16 bits for many system window messages, this is restricted to a WORD. WORD wId; // Used to prevent declarative functionality from interfering with the application's imperative code. - BOOL fDisableAutomaticFunctionality; + DWORD dwAutomaticBehaviorType; } THEME_LOADINGCONTROL_RESULTS; diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp index f7f7c5b6..c3dbe3e9 100644 --- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp @@ -296,7 +296,7 @@ static HRESULT OnLoadingControl( __in THEME* pTheme, __in const THEME_CONTROL* pControl, __inout WORD* pwId, - __inout BOOL* pfDisableAutomaticFunctionality + __inout DWORD* pdwAutomaticBehaviorType ); static HRESULT LoadControls( __in THEME* pTheme, @@ -5016,7 +5016,7 @@ static void OnBrowseDirectory( } // Since editbox changes aren't immediately saved off, we have to treat them differently. - if (pTargetControl && !pTargetControl->fDisableAutomaticFunctionality && (!fSetVariable || THEME_CONTROL_TYPE_EDITBOX == pTargetControl->type)) + if (pTargetControl && pTargetControl->fAutomaticValue && THEME_CONTROL_TYPE_EDITBOX == pTargetControl->type) { fSetVariable = FALSE; hr = ThemeSetTextControl(pTargetControl, sczPath); @@ -5045,7 +5045,7 @@ static BOOL OnButtonClicked( if (THEME_CONTROL_TYPE_BUTTON == pControl->type || THEME_CONTROL_TYPE_COMMANDLINK == pControl->type) { - if (!pControl->fDisableAutomaticFunctionality && pControl->cActions) + if (pControl->fAutomaticAction && pControl->cActions) { fHandled = TRUE; THEME_ACTION* pChosenAction = pControl->pDefaultAction; @@ -5103,7 +5103,7 @@ static BOOL OnButtonClicked( } } } - else if (!pControl->fDisableAutomaticFunctionality && (pTheme->pfnSetNumericVariable || pTheme->pfnSetStringVariable)) + else if (pControl->fAutomaticValue && (pTheme->pfnSetNumericVariable || pTheme->pfnSetStringVariable)) { BOOL fRefresh = FALSE; @@ -5558,7 +5558,7 @@ static HRESULT ShowControl( THEME_PAGE* pPage = ThemeGetPage(pTheme, dwPageId); // Save the editbox value if necessary (other control types save their values immediately). - if (pTheme->pfnSetStringVariable && !pControl->fDisableAutomaticFunctionality && + if (pTheme->pfnSetStringVariable && pControl->fAutomaticValue && fSaveEditboxes && THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName) { hr = ThemeGetTextControl(pControl, &sczText); @@ -5585,102 +5585,102 @@ static HRESULT ShowControl( BOOL fEnabled = !(pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_DISABLED); BOOL fVisible = !(pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_HIDDEN); - if (!pControl->fDisableAutomaticFunctionality) + if (pTheme->pfnEvaluateCondition) { - if (pTheme->pfnEvaluateCondition) + // If the control has a VisibleCondition, check if it's true. + if (pControl->sczVisibleCondition && pControl->fAutomaticVisible) { - // If the control has a VisibleCondition, check if it's true. - if (pControl->sczVisibleCondition) - { - hr = pTheme->pfnEvaluateCondition(pControl->sczVisibleCondition, &fVisible, pTheme->pvVariableContext); - ThmExitOnFailure(hr, "Failed to evaluate VisibleCondition: %ls", pControl->sczVisibleCondition); - } - - // If the control has an EnableCondition, check if it's true. - if (pControl->sczEnableCondition) - { - hr = pTheme->pfnEvaluateCondition(pControl->sczEnableCondition, &fEnabled, pTheme->pvVariableContext); - ThmExitOnFailure(hr, "Failed to evaluate EnableCondition: %ls", pControl->sczEnableCondition); - } + hr = pTheme->pfnEvaluateCondition(pControl->sczVisibleCondition, &fVisible, pTheme->pvVariableContext); + ThmExitOnFailure(hr, "Failed to evaluate VisibleCondition: %ls", pControl->sczVisibleCondition); } - // Try to format each control's text based on context, except for editboxes since their text comes from the user. - if (pTheme->pfnFormatString && ((pControl->sczText && *pControl->sczText) || pControl->cConditionalText) && THEME_CONTROL_TYPE_EDITBOX != pControl->type) + // If the control has an EnableCondition, check if it's true. + if (pControl->sczEnableCondition && pControl->fAutomaticEnabled) { - LPCWSTR wzText = pControl->sczText; - LPCWSTR wzNote = pControl->sczNote; + hr = pTheme->pfnEvaluateCondition(pControl->sczEnableCondition, &fEnabled, pTheme->pvVariableContext); + ThmExitOnFailure(hr, "Failed to evaluate EnableCondition: %ls", pControl->sczEnableCondition); + } + } - if (pTheme->pfnEvaluateCondition) + // Try to format each control's text based on context, except for editboxes since their text comes from the user. + if (pTheme->pfnFormatString && pControl->fAutomaticText && ((pControl->sczText && *pControl->sczText) || pControl->cConditionalText) && THEME_CONTROL_TYPE_EDITBOX != pControl->type) + { + LPCWSTR wzText = pControl->sczText; + LPCWSTR wzNote = pControl->sczNote; + + if (pTheme->pfnEvaluateCondition) + { + // As documented in the xsd, if there are multiple conditions that are true at the same time then the behavior is undefined. + // This is the current implementation and can change at any time. + for (DWORD j = 0; j < pControl->cConditionalText; ++j) { - // As documented in the xsd, if there are multiple conditions that are true at the same time then the behavior is undefined. - // This is the current implementation and can change at any time. - for (DWORD j = 0; j < pControl->cConditionalText; ++j) - { - THEME_CONDITIONAL_TEXT* pConditionalText = pControl->rgConditionalText + j; + THEME_CONDITIONAL_TEXT* pConditionalText = pControl->rgConditionalText + j; - if (pConditionalText->sczCondition) - { - BOOL fCondition = FALSE; + if (pConditionalText->sczCondition) + { + BOOL fCondition = FALSE; - hr = pTheme->pfnEvaluateCondition(pConditionalText->sczCondition, &fCondition, pTheme->pvVariableContext); - ThmExitOnFailure(hr, "Failed to evaluate condition: %ls", pConditionalText->sczCondition); + hr = pTheme->pfnEvaluateCondition(pConditionalText->sczCondition, &fCondition, pTheme->pvVariableContext); + ThmExitOnFailure(hr, "Failed to evaluate condition: %ls", pConditionalText->sczCondition); - if (fCondition) - { - wzText = pConditionalText->sczText; - break; - } + if (fCondition) + { + wzText = pConditionalText->sczText; + break; } } + } - if (THEME_CONTROL_TYPE_COMMANDLINK == pControl->type) + if (THEME_CONTROL_TYPE_COMMANDLINK == pControl->type) + { + for (DWORD j = 0; j < pControl->CommandLink.cConditionalNotes; ++j) { - for (DWORD j = 0; j < pControl->CommandLink.cConditionalNotes; ++j) - { - THEME_CONDITIONAL_TEXT* pConditionalNote = pControl->CommandLink.rgConditionalNotes + j; + THEME_CONDITIONAL_TEXT* pConditionalNote = pControl->CommandLink.rgConditionalNotes + j; - if (pConditionalNote->sczCondition) - { - BOOL fCondition = FALSE; + if (pConditionalNote->sczCondition) + { + BOOL fCondition = FALSE; - hr = pTheme->pfnEvaluateCondition(pConditionalNote->sczCondition, &fCondition, pTheme->pvVariableContext); - ThmExitOnFailure(hr, "Failed to evaluate note condition: %ls", pConditionalNote->sczCondition); + hr = pTheme->pfnEvaluateCondition(pConditionalNote->sczCondition, &fCondition, pTheme->pvVariableContext); + ThmExitOnFailure(hr, "Failed to evaluate note condition: %ls", pConditionalNote->sczCondition); - if (fCondition) - { - wzNote = pConditionalNote->sczText; - break; - } + if (fCondition) + { + wzNote = pConditionalNote->sczText; + break; } } } } + } - if (wzText && *wzText) - { - hr = pTheme->pfnFormatString(wzText, &sczText, pTheme->pvVariableContext); - ThmExitOnFailure(hr, "Failed to format string: %ls", wzText); - } - else - { - ReleaseNullStr(sczText); - } - - ThemeSetTextControl(pControl, sczText); + if (wzText && *wzText) + { + hr = pTheme->pfnFormatString(wzText, &sczText, pTheme->pvVariableContext); + ThmExitOnFailure(hr, "Failed to format string: %ls", wzText); + } + else + { + ReleaseNullStr(sczText); + } - if (wzNote && *wzNote) - { - hr = pTheme->pfnFormatString(wzNote, &sczText, pTheme->pvVariableContext); - ThmExitOnFailure(hr, "Failed to format note: %ls", wzNote); - } - else - { - ReleaseNullStr(sczText); - } + ThemeSetTextControl(pControl, sczText); - ::SendMessageW(pControl->hWnd, BCM_SETNOTE, 0, reinterpret_cast(sczText)); + if (wzNote && *wzNote) + { + hr = pTheme->pfnFormatString(wzNote, &sczText, pTheme->pvVariableContext); + ThmExitOnFailure(hr, "Failed to format note: %ls", wzNote); + } + else + { + ReleaseNullStr(sczText); } + ::SendMessageW(pControl->hWnd, BCM_SETNOTE, 0, reinterpret_cast(sczText)); + } + + if (pControl->fAutomaticValue) + { // If this is a named control, do variable magic. if (pControl->sczName && *pControl->sczName) { @@ -6010,7 +6010,7 @@ static HRESULT OnLoadingControl( __in THEME* pTheme, __in const THEME_CONTROL* pControl, __inout WORD* pwId, - __inout BOOL* pfDisableAutomaticFunctionality + __inout DWORD* pdwAutomaticBehaviorType ) { HRESULT hr = S_OK; @@ -6030,7 +6030,7 @@ static HRESULT OnLoadingControl( if (SUCCEEDED(hr)) { *pwId = loadingControlResults.wId; - *pfDisableAutomaticFunctionality = loadingControlResults.fDisableAutomaticFunctionality; + *pdwAutomaticBehaviorType = loadingControlResults.dwAutomaticBehaviorType; } } @@ -6232,9 +6232,16 @@ static HRESULT LoadControls( // Default control ids to the next id, unless there is a specific id to assign to a control. WORD wControlId = THEME_FIRST_AUTO_ASSIGN_CONTROL_ID; - hr = OnLoadingControl(pTheme, pControl, &wControlId, &pControl->fDisableAutomaticFunctionality); + DWORD dwAutomaticBehaviorType = THEME_CONTROL_AUTOMATIC_BEHAVIOR_ALL; + hr = OnLoadingControl(pTheme, pControl, &wControlId, &dwAutomaticBehaviorType); ThmExitOnFailure(hr, "ThmLoadingControl failed."); + pControl->fAutomaticEnabled = THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ENABLED != (THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ENABLED & dwAutomaticBehaviorType); + pControl->fAutomaticVisible = THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VISIBLE != (THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VISIBLE & dwAutomaticBehaviorType); + pControl->fAutomaticAction = THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ACTION != (THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ACTION & dwAutomaticBehaviorType); + pControl->fAutomaticText = THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_TEXT != (THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_TEXT & dwAutomaticBehaviorType); + pControl->fAutomaticValue = THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VALUE != (THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VALUE & dwAutomaticBehaviorType); + // This range is reserved for thmutil. The process will run out of available window handles before reaching the end of the range. if (THEME_FIRST_AUTO_ASSIGN_CONTROL_ID <= wControlId && THEME_FIRST_ASSIGN_CONTROL_ID > wControlId) { @@ -6250,7 +6257,7 @@ static HRESULT LoadControls( BOOL fDisabled = pControl->dwStyle & WS_DISABLED; // If the control is supposed to be initially visible and it has a VisibleCondition, check if it's true. - if (fVisible && pControl->sczVisibleCondition && pTheme->pfnEvaluateCondition && !pControl->fDisableAutomaticFunctionality) + if (fVisible && pControl->sczVisibleCondition && pTheme->pfnEvaluateCondition && pControl->fAutomaticVisible) { hr = pTheme->pfnEvaluateCondition(pControl->sczVisibleCondition, &fVisible, pTheme->pvVariableContext); ThmExitOnFailure(hr, "Failed to evaluate VisibleCondition: %ls", pControl->sczVisibleCondition); @@ -6269,7 +6276,7 @@ static HRESULT LoadControls( } // If the control is supposed to be initially enabled and it has an EnableCondition, check if it's true. - if (!fDisabled && pControl->sczEnableCondition && pTheme->pfnEvaluateCondition && !pControl->fDisableAutomaticFunctionality) + if (!fDisabled && pControl->sczEnableCondition && pTheme->pfnEvaluateCondition && pControl->fAutomaticEnabled) { BOOL fEnable = TRUE; diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp index bc942dc8..ce74534d 100644 --- a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp +++ b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp @@ -48,7 +48,7 @@ public: // IBAFunctions __in LPCWSTR wzName, __inout BOOL* pfProcessed, __inout WORD* pwId, - __inout BOOL* /*pfDisableAutomaticFunctionality*/ + __inout DWORD* /*pdwAutomaticBehaviorType*/ ) { if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzName, -1, L"InstallTestButton", -1)) -- cgit v1.2.3-55-g6feb