From 7e60078d4a7fe748a39c135def9e84a2421ab474 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sun, 31 Oct 2021 14:20:44 -0500 Subject: Avoid using control ids inside of thmutil. --- .../WixStandardBootstrapperApplication.cpp | 314 +++++++--- src/ext/Bal/wixstdba/precomp.h | 1 + src/libs/dutil/WixToolset.DUtil/dutil.vcxproj | 2 + .../dutil/WixToolset.DUtil/dutil.vcxproj.filters | 6 + src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h | 1 + src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | 117 ++-- src/libs/dutil/WixToolset.DUtil/inc/wndutil.h | 41 ++ src/libs/dutil/WixToolset.DUtil/precomp.h | 1 + src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 650 +++++++++------------ src/libs/dutil/WixToolset.DUtil/wndutil.cpp | 206 +++++++ src/samples/thmviewer/display.cpp | 8 +- src/samples/thmviewer/precomp.h | 1 + src/samples/thmviewer/thmviewer.cpp | 37 +- .../Manual/BafThmutilTesting/BafThmUtilTesting.cpp | 11 +- 14 files changed, 845 insertions(+), 551 deletions(-) create mode 100644 src/libs/dutil/WixToolset.DUtil/inc/wndutil.h create mode 100644 src/libs/dutil/WixToolset.DUtil/wndutil.cpp (limited to 'src') diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 23158a1c..d1b18cb3 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp @@ -80,7 +80,7 @@ static LPCWSTR vrgwzPageNames[] = { // The range [0, 100) is unused to avoid collisions with system ids, // the range [100, 0x4000) is unused to avoid collisions with thmutil, // the range [0x4000, 0x8000) is unused to avoid collisions with BAFunctions. -const WORD WIXSTDBA_FIRST_ASSIGN_CONTROL_ID = 0x8000; +const WORD WIXSTDBA_FIRST_ASSIGN_CONTROL_ID = 0x8000; enum WIXSTDBA_CONTROL { @@ -119,36 +119,8 @@ enum WIXSTDBA_CONTROL WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK, WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON, -}; -static THEME_ASSIGN_CONTROL_ID vrgInitControls[] = { - { WIXSTDBA_CONTROL_INSTALL_BUTTON, L"InstallButton" }, - { WIXSTDBA_CONTROL_EULA_RICHEDIT, L"EulaRichedit" }, - { WIXSTDBA_CONTROL_EULA_LINK, L"EulaHyperlink" }, - { WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, L"EulaAcceptCheckbox" }, - - { WIXSTDBA_CONTROL_REPAIR_BUTTON, L"RepairButton" }, - { WIXSTDBA_CONTROL_UNINSTALL_BUTTON, L"UninstallButton" }, - - { WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, L"CacheProgressPackageText" }, - { WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR, L"CacheProgressbar" }, - { WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT, L"CacheProgressText" }, - { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, L"ExecuteProgressPackageText" }, - { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR, L"ExecuteProgressbar" }, - { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT, L"ExecuteProgressText" }, - { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"ExecuteProgressActionDataText"}, - { WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, L"OverallProgressPackageText" }, - { WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR, L"OverallProgressbar" }, - { WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, L"OverallCalculatedProgressbar" }, - { WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT, L"OverallProgressText" }, - { WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, L"ProgressCancelButton" }, - - { WIXSTDBA_CONTROL_LAUNCH_BUTTON, L"LaunchButton" }, - { WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON, L"SuccessRestartButton" }, - - { WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK, L"FailureLogFileLink" }, - { WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, L"FailureMessageText" }, - { WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON, L"FailureRestartButton" }, + LAST_WIXSTDBA_CONTROL, }; typedef struct _WIXSTDBA_PACKAGE_INFO @@ -589,7 +561,7 @@ public: // IBootstrapperApplication wz = sczFormattedString ? sczFormattedString : L"Pausing Windows automatic updates"; - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz); + ThemeSetTextControl(m_pControlOverallProgressPackageText, wz); ReleaseStr(sczFormattedString); return hr; @@ -615,7 +587,7 @@ public: // IBootstrapperApplication wz = sczFormattedString ? sczFormattedString : L"Creating system restore point"; - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz); + ThemeSetTextControl(m_pControlOverallProgressPackageText, wz); ReleaseStr(sczFormattedString); return hr; @@ -635,12 +607,12 @@ public: // IBootstrapperApplication HRESULT hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage); LPCWSTR wz = (SUCCEEDED(hr) && pPackage->sczDisplayName) ? pPackage->sczDisplayName : wzPackageId; - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, wz); + ThemeSetTextControl(m_pControlCacheProgressPackageText, wz); // If something started executing, leave it in the overall progress text. if (!m_fStartedExecution) { - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz); + ThemeSetTextControl(m_pControlOverallProgressPackageText, wz); } } @@ -778,7 +750,7 @@ public: // IBootstrapperApplication ) { UpdateCacheProgress(SUCCEEDED(hrStatus) ? 100 : 0); - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, L""); + ThemeSetTextControl(m_pControlCacheProgressPackageText, L""); SetState(WIXSTDBA_STATE_CACHED, S_OK); // we always return success here and let OnApplyComplete() deal with the error. return __super::OnCacheComplete(hrStatus); } @@ -891,7 +863,7 @@ public: // IBootstrapperApplication if (INSTALLMESSAGE_ACTIONSTART == messageType) { - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, wzMessage); + ThemeSetTextControl(m_pControlExecuteProgressActionDataText, wzMessage); } return __super::OnExecuteMsiMessage(wzPackageId, messageType, dwUIHint, wzMessage, cData, rgwzData, nRecommendation, pResult); @@ -911,9 +883,9 @@ public: // IBootstrapperApplication #endif ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage); - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT, wzProgress); + ThemeSetTextControl(m_pControlOverallProgressText, wzProgress); - ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR, dwOverallProgressPercentage); + ThemeSetProgressControl(m_pControlOverallProgressbar, dwOverallProgressPercentage); SetTaskbarButtonProgress(dwOverallProgressPercentage); return __super::OnProgress(dwProgressPercentage, dwOverallProgressPercentage, pfCancel); @@ -972,8 +944,8 @@ public: // IBootstrapperApplication fShowingInternalUiThisPackage = INSTALLUILEVEL_NONE != (INSTALLUILEVEL_NONE & uiLevel); - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, wz); - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz); + ThemeSetTextControl(m_pControlExecuteProgressPackageText, wz); + ThemeSetTextControl(m_pControlOverallProgressPackageText, wz); } ::EnterCriticalSection(&m_csShowingInternalUiThisPackage); @@ -1000,12 +972,12 @@ public: // IBootstrapperApplication #endif ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage); - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT, wzProgress); + ThemeSetTextControl(m_pControlExecuteProgressText, wzProgress); - ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR, dwOverallProgressPercentage); + ThemeSetProgressControl(m_pControlExecuteProgressbar, dwOverallProgressPercentage); m_dwCalculatedExecuteProgress = dwOverallProgressPercentage * (100 - WIXSTDBA_ACQUIRE_PERCENTAGE) / 100; - ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress); + ThemeSetProgressControl(m_pControlOverallCalculatedProgressbar, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress); SetTaskbarButtonProgress(m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress); @@ -1051,10 +1023,10 @@ public: // IBootstrapperApplication { HRESULT hr = S_OK; - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, L""); - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L""); - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, L""); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, FALSE); // no more cancel. + ThemeSetTextControl(m_pControlExecuteProgressPackageText, L""); + ThemeSetTextControl(m_pControlExecuteProgressActionDataText, L""); + ThemeSetTextControl(m_pControlOverallProgressPackageText, L""); + ThemeControlEnable(m_pControlProgressCancelButton, FALSE); // no more cancel. m_fShowingInternalUiThisPackage = FALSE; SetState(WIXSTDBA_STATE_EXECUTED, S_OK); // we always return success here and let OnApplyComplete() deal with the error. @@ -2933,12 +2905,27 @@ private: BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS themeControlLoadingArgs = { }; BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS themeControlLoadingResults = { }; - for (DWORD iAssignControl = 0; iAssignControl < countof(vrgInitControls); ++iAssignControl) + for (DWORD iAssignControl = 0; iAssignControl < countof(m_rgInitControls); ++iAssignControl) { - if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, vrgInitControls[iAssignControl].wzName, -1)) + THEME_ASSIGN_CONTROL_ID* pAssignControl = m_rgInitControls + iAssignControl; + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, pAssignControl->wzName, -1)) { + if (!pAssignControl->ppControl) + { + BalExitWithRootFailure(hr, E_INVALIDSTATE, "Control '%ls' has no member variable", pAssignControl->wzName); + } + + if (*pAssignControl->ppControl) + { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Duplicate control name: %ls", pAssignControl->wzName); + } + else + { + *pAssignControl->ppControl = pArgs->pThemeControl; + } + fProcessed = TRUE; - pResults->wId = vrgInitControls[iAssignControl].wId; + pResults->wId = pAssignControl->wId; ExitFunction(); } } @@ -3059,7 +3046,7 @@ private: hr = LocProbeForFile(sczLicenseDirectory, sczLicenseFilename, m_sczLanguage, &sczLicensePath); ExitOnFailure(hr, "Failed to probe for localized license file."); - hr = ThemeLoadRichEditFromFile(m_pTheme, pThemeControl->wId, sczLicensePath, m_hModule); + hr = ThemeLoadRichEditFromFile(pThemeControl, sczLicensePath, m_hModule); ExitOnFailure(hr, "Failed to load license file into richedit control."); LExit: @@ -3178,7 +3165,7 @@ private: hr = m_pEngine->Apply(m_hWnd); BalExitOnFailure(hr, "Failed to start applying packages."); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, TRUE); // ensure the cancel button is enabled before starting. + ThemeControlEnable(m_pControlProgressCancelButton, TRUE); // ensure the cancel button is enabled before starting. LExit: if (FAILED(hr)) @@ -3229,22 +3216,22 @@ private: { BalGetNumericVariable(WIXBUNDLE_VARIABLE_ELEVATED, &llElevated); } - ThemeControlElevates(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, (m_Bundle.fPerMachine && !llElevated)); + ThemeControlElevates(m_pControlInstallButton, (m_Bundle.fPerMachine && !llElevated)); // If the EULA control exists, show it only if a license URL is provided as well. - if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK)) + if (m_pControlEulaHyperlink) { BOOL fEulaLink = (m_sczLicenseUrl && *m_sczLicenseUrl); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK, fEulaLink); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, fEulaLink); + ThemeControlEnable(m_pControlEulaHyperlink, fEulaLink); + ThemeControlEnable(m_pControlEulaAcceptCheckbox, fEulaLink); } - 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); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense); + BOOL fAcceptedLicense = !m_pControlEulaAcceptCheckbox || !ThemeControlEnabled(m_pControlEulaAcceptCheckbox) || ThemeIsControlChecked(m_pControlEulaAcceptCheckbox); + ThemeControlEnable(m_pControlInstallButton, fAcceptedLicense); } else if (m_rgdwPageIds[WIXSTDBA_PAGE_MODIFY] == dwNewPageId) { - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_REPAIR_BUTTON, !m_fSuppressRepair); + ThemeControlEnable(m_pControlRepairButton, !m_fSuppressRepair); } else if (m_rgdwPageIds[WIXSTDBA_PAGE_SUCCESS] == dwNewPageId) // on the "Success" page, check if the restart or launch button should be enabled. { @@ -3257,13 +3244,13 @@ private: fEnableRestartButton = TRUE; } } - else if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_LAUNCH_BUTTON)) + else if (m_pControlLaunchButton) { fLaunchTargetExists = BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH); } - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_LAUNCH_BUTTON, fLaunchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < m_plannedAction); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON, fEnableRestartButton); + ThemeControlEnable(m_pControlLaunchButton, fLaunchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < m_plannedAction); + ThemeControlEnable(m_pControlSuccessRestartButton, fEnableRestartButton); } else if (m_rgdwPageIds[WIXSTDBA_PAGE_FAILURE] == dwNewPageId) // on the "Failure" page, show error message and check if the restart button should be enabled. { @@ -3347,7 +3334,7 @@ private: StrAllocFormatted(&sczText, L"0x%08x - %ls", m_hrFinal, sczUnformattedText); } - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, sczText); + ThemeSetTextControl(m_pControlFailureMessageText, sczText); fShowErrorMessage = TRUE; } @@ -3359,9 +3346,9 @@ private: } } - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK, fShowLogLink); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, fShowErrorMessage); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON, fEnableRestartButton); + ThemeControlEnable(m_pControlFailureLogFileLink, fShowLogLink); + ThemeControlEnable(m_pControlFailureMessageText, fShowErrorMessage); + ThemeControlEnable(m_pControlFailureRestartButton, fEnableRestartButton); } HRESULT hr = ThemeShowPage(m_pTheme, dwOldPageId, SW_HIDE); @@ -3379,7 +3366,7 @@ private: // On the install page set the focus to the install button or the next enabled control if install is disabled. if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId) { - ThemeSetFocus(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON); + ThemeSetFocus(m_pControlInstallButton); } } } @@ -3423,7 +3410,7 @@ private: // If we canceled, disable cancel button since clicking it again is silly. if (fClose) { - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, FALSE); + ThemeControlEnable(m_pControlProgressCancelButton, FALSE); } fClose = FALSE; @@ -3447,8 +3434,8 @@ private: // void OnClickAcceptCheckbox() { - BOOL fAcceptedLicense = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX); - ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense); + BOOL fAcceptedLicense = ThemeIsControlChecked(m_pControlEulaAcceptCheckbox); + ThemeControlEnable(m_pControlInstallButton, fAcceptedLicense); } @@ -3954,12 +3941,12 @@ LExit: WCHAR wzProgress[5] = { }; ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallPercentage); - ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT, wzProgress); + ThemeSetTextControl(m_pControlCacheProgressText, wzProgress); - ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR, dwOverallPercentage); + ThemeSetProgressControl(m_pControlCacheProgressbar, dwOverallPercentage); m_dwCalculatedCacheProgress = dwOverallPercentage * WIXSTDBA_ACQUIRE_PERCENTAGE / 100; - ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress); + ThemeSetProgressControl(m_pControlOverallCalculatedProgressbar, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress); SetTaskbarButtonProgress(m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress); } @@ -4088,6 +4075,8 @@ public: __in IBootstrapperEngine* pEngine ) : CBalBaseBootstrapperApplication(pEngine, 3, 3000) { + THEME_ASSIGN_CONTROL_ID* pAssignControl = NULL; + m_hModule = hModule; m_command = { }; m_createArgs = { }; @@ -4141,6 +4130,148 @@ public: m_hBAFModule = NULL; m_pfnBAFunctionsProc = NULL; m_pvBAFunctionsProcContext = NULL; + + C_ASSERT(0 == WIXSTDBA_CONTROL_INSTALL_BUTTON - WIXSTDBA_FIRST_ASSIGN_CONTROL_ID); + pAssignControl = m_rgInitControls; + + pAssignControl->wId = WIXSTDBA_CONTROL_INSTALL_BUTTON; + pAssignControl->wzName = L"InstallButton"; + pAssignControl->ppControl = &m_pControlInstallButton; + m_pControlInstallButton = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_EULA_RICHEDIT; + pAssignControl->wzName = L"EulaRichedit"; + pAssignControl->ppControl = &m_pControlEulaRichedit; + m_pControlEulaRichedit = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_EULA_LINK; + pAssignControl->wzName = L"EulaHyperlink"; + pAssignControl->ppControl = &m_pControlEulaHyperlink; + m_pControlEulaHyperlink = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX; + pAssignControl->wzName = L"EulaAcceptCheckbox"; + pAssignControl->ppControl = &m_pControlEulaAcceptCheckbox; + m_pControlEulaAcceptCheckbox = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_REPAIR_BUTTON; + pAssignControl->wzName = L"RepairButton"; + pAssignControl->ppControl = &m_pControlRepairButton; + m_pControlRepairButton = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_UNINSTALL_BUTTON; + pAssignControl->wzName = L"UninstallButton"; + pAssignControl->ppControl = &m_pControlUninstallButton; + m_pControlUninstallButton = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT; + pAssignControl->wzName = L"CacheProgressPackageText"; + pAssignControl->ppControl = &m_pControlCacheProgressPackageText; + m_pControlCacheProgressPackageText = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR; + pAssignControl->wzName = L"CacheProgressbar"; + pAssignControl->ppControl = &m_pControlCacheProgressbar; + m_pControlCacheProgressbar = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT; + pAssignControl->wzName = L"CacheProgressText"; + pAssignControl->ppControl = &m_pControlCacheProgressText; + m_pControlCacheProgressText = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT; + pAssignControl->wzName = L"ExecuteProgressPackageText"; + pAssignControl->ppControl = &m_pControlExecuteProgressPackageText; + m_pControlExecuteProgressPackageText = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR; + pAssignControl->wzName = L"ExecuteProgressbar"; + pAssignControl->ppControl = &m_pControlExecuteProgressbar; + m_pControlExecuteProgressbar = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT; + pAssignControl->wzName = L"ExecuteProgressText"; + pAssignControl->ppControl = &m_pControlExecuteProgressText; + m_pControlExecuteProgressText = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT; + pAssignControl->wzName = L"ExecuteProgressActionDataText"; + pAssignControl->ppControl = &m_pControlExecuteProgressActionDataText; + m_pControlExecuteProgressActionDataText = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT; + pAssignControl->wzName = L"OverallProgressPackageText"; + pAssignControl->ppControl = &m_pControlOverallProgressPackageText; + m_pControlOverallProgressPackageText = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR; + pAssignControl->wzName = L"OverallProgressbar"; + pAssignControl->ppControl = &m_pControlOverallProgressbar; + m_pControlOverallProgressbar = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR; + pAssignControl->wzName = L"OverallCalculatedProgressbar"; + pAssignControl->ppControl = &m_pControlOverallCalculatedProgressbar; + m_pControlOverallCalculatedProgressbar = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT; + pAssignControl->wzName = L"OverallProgressText"; + pAssignControl->ppControl = &m_pControlOverallProgressText; + m_pControlOverallProgressText = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON; + pAssignControl->wzName = L"ProgressCancelButton"; + pAssignControl->ppControl = &m_pControlProgressCancelButton; + m_pControlProgressCancelButton = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_LAUNCH_BUTTON; + pAssignControl->wzName = L"LaunchButton"; + pAssignControl->ppControl = &m_pControlLaunchButton; + m_pControlLaunchButton = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON; + pAssignControl->wzName = L"SuccessRestartButton"; + pAssignControl->ppControl = &m_pControlSuccessRestartButton; + m_pControlSuccessRestartButton = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK; + pAssignControl->wzName = L"FailureLogFileLink"; + pAssignControl->ppControl = &m_pControlFailureLogFileLink; + m_pControlFailureLogFileLink = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT; + pAssignControl->wzName = L"FailureMessageText"; + pAssignControl->ppControl = &m_pControlFailureMessageText; + m_pControlFailureMessageText = NULL; + ++pAssignControl; + + pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON; + pAssignControl->wzName = L"FailureRestartButton"; + pAssignControl->ppControl = &m_pControlFailureRestartButton; + m_pControlFailureRestartButton = NULL; + + C_ASSERT(LAST_WIXSTDBA_CONTROL == WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON + 1); } @@ -4201,11 +4332,48 @@ private: LPWSTR m_sczLanguage; THEME* m_pTheme; + THEME_ASSIGN_CONTROL_ID m_rgInitControls[LAST_WIXSTDBA_CONTROL - WIXSTDBA_FIRST_ASSIGN_CONTROL_ID]; DWORD m_rgdwPageIds[countof(vrgwzPageNames)]; HANDLE m_hUiThread; BOOL m_fRegistered; HWND m_hWnd; + // Welcome page + const THEME_CONTROL* m_pControlInstallButton; + const THEME_CONTROL* m_pControlEulaRichedit; + const THEME_CONTROL* m_pControlEulaHyperlink; + const THEME_CONTROL* m_pControlEulaAcceptCheckbox; + + // Modify page + const THEME_CONTROL* m_pControlRepairButton; + const THEME_CONTROL* m_pControlUninstallButton; + + // Progress page + const THEME_CONTROL* m_pControlCacheProgressPackageText; + const THEME_CONTROL* m_pControlCacheProgressbar; + const THEME_CONTROL* m_pControlCacheProgressText; + + const THEME_CONTROL* m_pControlExecuteProgressPackageText; + const THEME_CONTROL* m_pControlExecuteProgressbar; + const THEME_CONTROL* m_pControlExecuteProgressText; + const THEME_CONTROL* m_pControlExecuteProgressActionDataText; + + const THEME_CONTROL* m_pControlOverallProgressPackageText; + const THEME_CONTROL* m_pControlOverallProgressbar; + const THEME_CONTROL* m_pControlOverallCalculatedProgressbar; + const THEME_CONTROL* m_pControlOverallProgressText; + + const THEME_CONTROL* m_pControlProgressCancelButton; + + // Success page + const THEME_CONTROL* m_pControlLaunchButton; + const THEME_CONTROL* m_pControlSuccessRestartButton; + + // Failure page + const THEME_CONTROL* m_pControlFailureLogFileLink; + const THEME_CONTROL* m_pControlFailureMessageText; + const THEME_CONTROL* m_pControlFailureRestartButton; + WIXSTDBA_STATE m_state; HRESULT m_hrFinal; diff --git a/src/ext/Bal/wixstdba/precomp.h b/src/ext/Bal/wixstdba/precomp.h index 547183bd..ba56ae6d 100644 --- a/src/ext/Bal/wixstdba/precomp.h +++ b/src/ext/Bal/wixstdba/precomp.h @@ -29,6 +29,7 @@ #include "resrutil.h" #include "shelutil.h" #include "strutil.h" +#include "wndutil.h" #include "thmutil.h" #include "verutil.h" #include "uriutil.h" diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj index a02e638a..3ab8285f 100644 --- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj +++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj @@ -107,6 +107,7 @@ + @@ -164,6 +165,7 @@ + diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters index b93d166b..6444b19c 100644 --- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters +++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters @@ -165,6 +165,9 @@ Source Files + + Source Files + Source Files @@ -338,6 +341,9 @@ Header Files + + Header Files + Header Files diff --git a/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h b/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h index 7d512cb3..6affb392 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h @@ -61,6 +61,7 @@ typedef enum DUTIL_SOURCE DUTIL_SOURCE_WUAUTIL, DUTIL_SOURCE_XMLUTIL, DUTIL_SOURCE_VERUTIL, + DUTIL_SOURCE_WNDUTIL, DUTIL_SOURCE_EXTERNAL = 256, } DUTIL_SOURCE; diff --git a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h index cd286854..2f0bfeac 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h @@ -8,6 +8,7 @@ extern "C" { // forward declare +typedef struct _THEME_CONTROL THEME_CONTROL; typedef struct _THEME THEME; #define ReleaseTheme(p) if (p) { ThemeFree(p); p = NULL; } @@ -194,11 +195,12 @@ struct THEME_ASSIGN_CONTROL_ID { WORD wId; // id to apply to control LPCWSTR wzName; // name of control to match + const THEME_CONTROL** ppControl; }; const WORD THEME_FIRST_ASSIGN_CONTROL_ID = 0x4000; // Recommended first control id to be assigned. -struct THEME_CONTROL +typedef struct _THEME_CONTROL { THEME_CONTROL_TYPE type; @@ -296,7 +298,7 @@ struct THEME_CONTROL HWND hWnd; DWORD dwData; // type specific data THEME* pTheme; -}; +} THEME_CONTROL; struct THEME_IMAGELIST @@ -580,8 +582,7 @@ HRESULT DAPI ThemeLoadStrings( *******************************************************************/ HRESULT DAPI ThemeLoadRichEditFromFile( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in_z LPCWSTR wzFileName, __in HMODULE hModule ); @@ -591,19 +592,7 @@ HRESULT DAPI ThemeLoadRichEditFromFile( *******************************************************************/ HRESULT DAPI ThemeLoadRichEditFromResource( - __in THEME* pTheme, - __in DWORD dwControl, - __in_z LPCSTR szResourceName, - __in HMODULE hModule - ); - -/******************************************************************** - ThemeLoadRichEditFromResourceToHWnd - Attach a richedit control (by - HWND) to resource data. - - *******************************************************************/ -HRESULT DAPI ThemeLoadRichEditFromResourceToHWnd( - __in HWND hWnd, + __in const THEME_CONTROL* pThemeControl, __in_z LPCSTR szResourceName, __in HMODULE hModule ); @@ -682,18 +671,28 @@ ThemeShowChild - shows a control's specified child control, hiding the rest. *******************************************************************/ void DAPI ThemeShowChild( - __in THEME* pTheme, __in THEME_CONTROL* pParentControl, __in DWORD dwIndex ); /******************************************************************** - ThemeControlExists - check if a control with the specified id exists. + ThemeControlExistsByHwnd - check if a control with the specified hWnd exists. + + *******************************************************************/ +BOOL DAPI ThemeControlExistsByHWnd( + __in const THEME* pTheme, + __in HWND hWnd, + __out_opt const THEME_CONTROL** ppThemeControl + ); + +/******************************************************************** + ThemeControlExistsById - check if a control with the specified id exists. *******************************************************************/ -BOOL DAPI ThemeControlExists( +BOOL DAPI ThemeControlExistsById( __in const THEME* pTheme, - __in DWORD dwControl + __in WORD wId, + __out_opt const THEME_CONTROL** ppThemeControl ); /******************************************************************** @@ -701,8 +700,7 @@ BOOL DAPI ThemeControlExists( *******************************************************************/ void DAPI ThemeControlEnable( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in BOOL fEnable ); @@ -711,8 +709,7 @@ void DAPI ThemeControlEnable( *******************************************************************/ BOOL DAPI ThemeControlEnabled( - __in THEME* pTheme, - __in DWORD dwControl + __in const THEME_CONTROL* pThemeControl ); /******************************************************************** @@ -720,8 +717,7 @@ BOOL DAPI ThemeControlEnabled( *******************************************************************/ void DAPI ThemeControlElevates( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in BOOL fElevates ); @@ -730,8 +726,7 @@ void DAPI ThemeControlElevates( *******************************************************************/ void DAPI ThemeShowControl( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in int nCmdShow ); @@ -741,8 +736,7 @@ conditional text and notes. *******************************************************************/ void DAPI ThemeShowControlEx( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in int nCmdShow ); @@ -751,24 +745,7 @@ void DAPI ThemeShowControlEx( *******************************************************************/ BOOL DAPI ThemeControlVisible( - __in THEME* pTheme, - __in DWORD dwControl - ); - -BOOL DAPI ThemePostControlMessage( - __in THEME* pTheme, - __in DWORD dwControl, - __in UINT Msg, - __in WPARAM wParam, - __in LPARAM lParam - ); - -LRESULT DAPI ThemeSendControlMessage( - __in const THEME* pTheme, - __in DWORD dwControl, - __in UINT Msg, - __in WPARAM wParam, - __in LPARAM lParam + __in const THEME_CONTROL* pThemeControl ); /******************************************************************** @@ -789,35 +766,13 @@ HRESULT DAPI ThemeDrawControl( __in DRAWITEMSTRUCT* pdis ); -/******************************************************************** - ThemeHoverControl - mark a control as hover. - -*******************************************************************/ -BOOL DAPI ThemeHoverControl( - __in THEME* pTheme, - __in HWND hwndParent, - __in HWND hwndControl - ); - /******************************************************************** ThemeIsControlChecked - gets whether a control is checked. Only really useful for checkbox controls. *******************************************************************/ BOOL DAPI ThemeIsControlChecked( - __in THEME* pTheme, - __in DWORD dwControl - ); - -/******************************************************************** - ThemeSetControlColor - sets the color of text for a control. - -*******************************************************************/ -BOOL DAPI ThemeSetControlColor( - __in THEME* pTheme, - __in HDC hdc, - __in HWND hWnd, - __out HBRUSH* phBackgroundBrush + __in const THEME_CONTROL* pThemeControl ); /******************************************************************** @@ -826,8 +781,7 @@ BOOL DAPI ThemeSetControlColor( *******************************************************************/ HRESULT DAPI ThemeSetProgressControl( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in DWORD dwProgressPercentage ); @@ -837,8 +791,7 @@ HRESULT DAPI ThemeSetProgressControl( *******************************************************************/ HRESULT DAPI ThemeSetProgressControlColor( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in DWORD dwColorIndex ); @@ -847,8 +800,7 @@ HRESULT DAPI ThemeSetProgressControlColor( *******************************************************************/ HRESULT DAPI ThemeSetTextControl( - __in const THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in_z_opt LPCWSTR wzText ); @@ -858,8 +810,7 @@ ThemeSetTextControl - sets the text of a control and optionally *******************************************************************/ HRESULT DAPI ThemeSetTextControlEx( - __in const THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in BOOL fUpdate, __in_z_opt LPCWSTR wzText ); @@ -869,8 +820,7 @@ HRESULT DAPI ThemeSetTextControlEx( *******************************************************************/ HRESULT DAPI ThemeGetTextControl( - __in const THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __inout_z LPWSTR* psczText ); @@ -889,8 +839,7 @@ HRESULT DAPI ThemeUpdateCaption( *******************************************************************/ void DAPI ThemeSetFocus( - __in THEME* pTheme, - __in DWORD dwControl + __in const THEME_CONTROL* pThemeControl ); #ifdef __cplusplus diff --git a/src/libs/dutil/WixToolset.DUtil/inc/wndutil.h b/src/libs/dutil/WixToolset.DUtil/inc/wndutil.h new file mode 100644 index 00000000..8de77f6e --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/inc/wndutil.h @@ -0,0 +1,41 @@ +#pragma once +// 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. + + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************** + WnduLoadRichEditFromFile - Attach a richedit control to a RTF file. + + *******************************************************************/ +HRESULT DAPI WnduLoadRichEditFromFile( + __in HWND hWnd, + __in_z LPCWSTR wzFileName, + __in HMODULE hModule + ); + +/******************************************************************** + WnduLoadRichEditFromResource - Attach a richedit control to resource data. + + *******************************************************************/ +HRESULT DAPI WnduLoadRichEditFromResource( + __in HWND hWnd, + __in_z LPCSTR szResourceName, + __in HMODULE hModule + ); + +/******************************************************************** + WnduGetControlText - gets the text of a control. + +*******************************************************************/ +HRESULT DAPI WnduGetControlText( + __in HWND hWnd, + __inout_z LPWSTR* psczText + ); + +#ifdef __cplusplus +} +#endif + diff --git a/src/libs/dutil/WixToolset.DUtil/precomp.h b/src/libs/dutil/WixToolset.DUtil/precomp.h index 46d29f21..093c16a2 100644 --- a/src/libs/dutil/WixToolset.DUtil/precomp.h +++ b/src/libs/dutil/WixToolset.DUtil/precomp.h @@ -87,6 +87,7 @@ #include "strutil.h" #include "timeutil.h" #include "timeutil.h" +#include "wndutil.h" #include "thmutil.h" #include "uncutil.h" #include "uriutil.h" diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp index e8c23b6c..9adc2ddd 100644 --- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp @@ -44,7 +44,6 @@ const DWORD THEME_INVALID_ID = 0xFFFFFFFF; const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF; const DWORD GROW_FONT_INSTANCES = 3; const DWORD GROW_IMAGE_INSTANCES = 5; -const DWORD GROW_WINDOW_TEXT = 250; static Gdiplus::GdiplusStartupInput vgsi; static Gdiplus::GdiplusStartupOutput vgso = { }; @@ -70,16 +69,29 @@ enum INTERNAL_CONTROL_STYLE INTERNAL_CONTROL_STYLE_OWNER_DRAW = 0x0010, }; -struct MEMBUFFER_FOR_RICHEDIT -{ - BYTE* rgbData; - DWORD cbData; - DWORD iData; -}; +// prototypes +/******************************************************************** + ThemeHoverControl - mark a control as hover. + +*******************************************************************/ +static BOOL ThemeHoverControl( + __in THEME* pTheme, + __in HWND hwndParent, + __in HWND hwndControl + ); +/******************************************************************** + ThemeSetControlColor - sets the color of text for a control. + +*******************************************************************/ +static BOOL ThemeSetControlColor( + __in THEME* pTheme, + __in HDC hdc, + __in HWND hWnd, + __out HBRUSH* phBackgroundBrush + ); -// prototypes static HRESULT RegisterWindowClasses( __in_opt HMODULE hModule ); @@ -258,11 +270,11 @@ static HRESULT ParseNotes( ); static HRESULT StopBillboard( __in THEME* pTheme, - __in DWORD dwControl + __in THEME_CONTROL* pControl ); static HRESULT StartBillboard( __in THEME* pTheme, - __in DWORD dwControl + __in THEME_CONTROL* pControl ); static HRESULT EnsureFontInstance( __in THEME* pTheme, @@ -290,7 +302,6 @@ static HRESULT LoadControls( __in_opt THEME_CONTROL* pParentControl ); static HRESULT ShowControl( - __in THEME* pTheme, __in THEME_CONTROL* pControl, __in int nCmdShow, __in BOOL fSaveEditboxes, @@ -376,18 +387,6 @@ static BOOL DrawHoverControl( __in THEME* pTheme, __in BOOL fHover ); -static DWORD CALLBACK RichEditStreamFromFileHandleCallback( - __in DWORD_PTR dwCookie, - __in_bcount(cb) LPBYTE pbBuff, - __in LONG cb, - __in LONG *pcb - ); -static DWORD CALLBACK RichEditStreamFromMemoryCallback( - __in DWORD_PTR dwCookie, - __in_bcount(cb) LPBYTE pbBuff, - __in LONG cb, - __in LONG *pcb - ); static void FreeFontInstance( __in THEME_FONT_INSTANCE* pFontInstance ); @@ -475,6 +474,11 @@ static BOOL OnWmNotify( __in const THEME_CONTROL* pThemeControl, __inout LRESULT* plResult ); +static const THEME_CONTROL* FindControlFromId( + __in const THEME* pTheme, + __in WORD wId, + __in_opt const THEME_CONTROL* pParentControl = NULL + ); static const THEME_CONTROL* FindControlFromHWnd( __in const THEME* pTheme, __in HWND hWnd, @@ -974,83 +978,39 @@ LExit: DAPI_(HRESULT) ThemeLoadRichEditFromFile( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in_z LPCWSTR wzFileName, __in HMODULE hModule ) { - HRESULT hr = S_OK; - LPWSTR sczFile = NULL; - HANDLE hFile = INVALID_HANDLE_VALUE; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - - hr = PathRelativeToModule(&sczFile, wzFileName, hModule); - ThmExitOnFailure(hr, "Failed to read resource data."); + HRESULT hr = E_INVALIDARG; - hFile = ::CreateFileW(sczFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (INVALID_HANDLE_VALUE == hFile) + if (pThemeControl) { - ThmExitWithLastError(hr, "Failed to open RTF file."); - } - else - { - LONGLONG llRtfSize; - hr = FileSizeByHandle(hFile, &llRtfSize); - if (SUCCEEDED(hr)) - { - ::SendMessageW(hWnd, EM_EXLIMITTEXT, 0, static_cast(llRtfSize)); - } - - EDITSTREAM es = { }; - es.pfnCallback = RichEditStreamFromFileHandleCallback; - es.dwCookie = reinterpret_cast(hFile); + AssertSz(THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type, "ThemeLoadRichEditFromFile called for non-RichEdit control."); - ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast(&es)); - hr = es.dwError; - ThmExitOnFailure(hr, "Failed to update RTF stream."); + hr = WnduLoadRichEditFromFile(pThemeControl->hWnd, wzFileName, hModule); } -LExit: - ReleaseStr(sczFile); - ReleaseFile(hFile); - return hr; } DAPI_(HRESULT) ThemeLoadRichEditFromResource( - __in THEME* pTheme, - __in DWORD dwControl, - __in_z LPCSTR szResourceName, - __in HMODULE hModule - ) -{ - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - return ThemeLoadRichEditFromResourceToHWnd(hWnd, szResourceName, hModule); -} - -DAPI_(HRESULT) ThemeLoadRichEditFromResourceToHWnd( - __in HWND hWnd, + __in const THEME_CONTROL* pThemeControl, __in_z LPCSTR szResourceName, __in HMODULE hModule ) { - HRESULT hr = S_OK; - MEMBUFFER_FOR_RICHEDIT buffer = { }; - EDITSTREAM es = { }; - - hr = ResReadData(hModule, szResourceName, reinterpret_cast(&buffer.rgbData), &buffer.cbData); - ThmExitOnFailure(hr, "Failed to read resource data."); + HRESULT hr = E_INVALIDARG; - es.pfnCallback = RichEditStreamFromMemoryCallback; - es.dwCookie = reinterpret_cast(&buffer); + if (pThemeControl) + { + AssertSz(THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type, "ThemeLoadRichEditFromResource called for non-RichEdit control."); - ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast(&es)); - hr = es.dwError; - ThmExitOnFailure(hr, "Failed to update RTF stream."); + hr = WnduLoadRichEditFromResource(pThemeControl->hWnd, szResourceName, hModule); + } -LExit: return hr; } @@ -1293,141 +1253,127 @@ LExit: } -DAPI_(BOOL) ThemeControlExists( +DAPI_(BOOL) ThemeControlExistsByHWnd( __in const THEME* pTheme, - __in DWORD dwControl + __in HWND hWnd, + __out_opt const THEME_CONTROL** ppThemeControl ) { - BOOL fExists = FALSE; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - if (hWnd) + const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); + + if (ppThemeControl) { - const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); - fExists = (pControl && hWnd == pControl->hWnd); + *ppThemeControl = pControl; } - return fExists; + return NULL != pControl; +} + + +DAPI_(BOOL) ThemeControlExistsById( + __in const THEME* pTheme, + __in WORD wId, + __out_opt const THEME_CONTROL** ppThemeControl + ) +{ + const THEME_CONTROL* pControl = FindControlFromId(pTheme, wId); + + if (ppThemeControl) + { + *ppThemeControl = pControl; + } + + return NULL != pControl; } DAPI_(void) ThemeControlEnable( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in BOOL fEnable ) { - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - THEME_CONTROL* pControl = const_cast(FindControlFromHWnd(pTheme, hWnd)); - if (pControl) + if (pThemeControl) { + THEME_CONTROL* pControl = const_cast(pThemeControl); pControl->dwInternalStyle = fEnable ? (pControl->dwInternalStyle & ~INTERNAL_CONTROL_STYLE_DISABLED) : (pControl->dwInternalStyle | INTERNAL_CONTROL_STYLE_DISABLED); - ::EnableWindow(hWnd, fEnable); + ::EnableWindow(pControl->hWnd, fEnable); if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_HIDE_WHEN_DISABLED) { - ::ShowWindow(hWnd, fEnable ? SW_SHOW : SW_HIDE); + ::ShowWindow(pControl->hWnd, fEnable ? SW_SHOW : SW_HIDE); } } } DAPI_(BOOL) ThemeControlEnabled( - __in THEME* pTheme, - __in DWORD dwControl + __in const THEME_CONTROL* pThemeControl ) { - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); - return pControl && !(pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_DISABLED); + BOOL fEnabled = FALSE; + + if (pThemeControl) + { + fEnabled = !(pThemeControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_DISABLED); + } + + return fEnabled; } DAPI_(void) ThemeControlElevates( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in BOOL fElevates ) { - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - ::SendMessageW(hWnd, BCM_SETSHIELD, 0, fElevates); + if (pThemeControl) + { + ::SendMessageW(pThemeControl->hWnd, BCM_SETSHIELD, 0, fElevates); + } } DAPI_(void) ThemeShowControl( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in int nCmdShow ) { - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - ::ShowWindow(hWnd, nCmdShow); - - // Save the control's visible state. - THEME_CONTROL* pControl = const_cast(FindControlFromHWnd(pTheme, hWnd)); - if (pControl) + if (pThemeControl) { + THEME_CONTROL* pControl = const_cast(pThemeControl); + ::ShowWindow(pControl->hWnd, nCmdShow); + + // Save the control's visible state. pControl->dwInternalStyle = (SW_HIDE == nCmdShow) ? (pControl->dwInternalStyle | INTERNAL_CONTROL_STYLE_HIDDEN) : (pControl->dwInternalStyle & ~INTERNAL_CONTROL_STYLE_HIDDEN); } } DAPI_(void) ThemeShowControlEx( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in int nCmdShow ) { - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - THEME_CONTROL* pControl = const_cast(FindControlFromHWnd(pTheme, hWnd)); - if (pControl) + if (pThemeControl) { - ShowControl(pTheme, pControl, nCmdShow, THEME_CONTROL_TYPE_EDITBOX == pControl->type, THEME_SHOW_PAGE_REASON_REFRESH, 0, NULL); + THEME_CONTROL* pControl = const_cast(pThemeControl); + ShowControl(pControl, nCmdShow, THEME_CONTROL_TYPE_EDITBOX == pControl->type, THEME_SHOW_PAGE_REASON_REFRESH, 0, NULL); } } DAPI_(BOOL) ThemeControlVisible( - __in THEME* pTheme, - __in DWORD dwControl + __in const THEME_CONTROL* pThemeControl ) { - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - return ::IsWindowVisible(hWnd); -} - + BOOL fVisible = FALSE; -DAPI_(BOOL) ThemePostControlMessage( - __in THEME* pTheme, - __in DWORD dwControl, - __in UINT Msg, - __in WPARAM wParam, - __in LPARAM lParam - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - - if (!::PostMessageW(hWnd, Msg, wParam, lParam)) + if (pThemeControl) { - er = ::GetLastError(); - hr = HRESULT_FROM_WIN32(er); + fVisible = ::IsWindowVisible(pThemeControl->hWnd); } - return SUCCEEDED(hr); -} - - -DAPI_(LRESULT) ThemeSendControlMessage( - __in const THEME* pTheme, - __in DWORD dwControl, - __in UINT Msg, - __in WPARAM wParam, - __in LPARAM lParam - ) -{ - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - return ::SendMessageW(hWnd, Msg, wParam, lParam); + return fVisible; } @@ -1453,9 +1399,15 @@ DAPI_(HRESULT) ThemeDrawControl( ) { HRESULT hr = S_OK; - const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, pdis->hwndItem); + const THEME_CONTROL* pControl = NULL; + BOOL fExists = ThemeControlExistsByHWnd(pTheme, pdis->hwndItem, &pControl); + + AssertSz(fExists, "Expected control window from owner draw window."); + if (!fExists) + { + ExitFunction1(hr = E_INVALIDARG); + } - AssertSz(pControl, "Expected control window from owner draw window."); AssertSz(pControl->hWnd == pdis->hwndItem, "Expected control window to match owner draw window."); AssertSz(pControl->nWidth < 1 || pControl->nWidth == pdis->rcItem.right - pdis->rcItem.left, "Expected control window width to match owner draw window width."); 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: } -DAPI_(BOOL) ThemeHoverControl( +static BOOL ThemeHoverControl( __in THEME* pTheme, __in HWND hwndParent, __in HWND hwndControl @@ -1519,16 +1471,21 @@ DAPI_(BOOL) ThemeHoverControl( DAPI_(BOOL) ThemeIsControlChecked( - __in THEME* pTheme, - __in DWORD dwControl + __in const THEME_CONTROL* pThemeControl ) { - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - return BST_CHECKED == ::SendMessageW(hWnd, BM_GETCHECK, 0, 0); + BOOL fChecked = FALSE; + + if (pThemeControl) + { + fChecked = BST_CHECKED == ::SendMessageW(pThemeControl->hWnd, BM_GETCHECK, 0, 0); + } + + return fChecked; } -DAPI_(BOOL) ThemeSetControlColor( +static BOOL ThemeSetControlColor( __in THEME* pTheme, __in HDC hdc, __in HWND hWnd, @@ -1537,6 +1494,7 @@ DAPI_(BOOL) ThemeSetControlColor( { THEME_FONT* pFont = NULL; BOOL fHasBackground = FALSE; + const THEME_CONTROL* pControl = NULL; *phBackgroundBrush = NULL; @@ -1544,10 +1502,9 @@ DAPI_(BOOL) ThemeSetControlColor( { pFont = (THEME_INVALID_ID == pTheme->dwFontId) ? NULL : pTheme->rgFonts + pTheme->dwFontId; } - else + else if (ThemeControlExistsByHWnd(pTheme, hWnd, &pControl)) { - const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); - pFont = (!pControl || THEME_INVALID_ID == pControl->dwFontId) ? NULL : pTheme->rgFonts + pControl->dwFontId; + pFont = THEME_INVALID_ID == pControl->dwFontId ? NULL : pTheme->rgFonts + pControl->dwFontId; } if (pFont) @@ -1577,44 +1534,40 @@ DAPI_(BOOL) ThemeSetControlColor( DAPI_(HRESULT) ThemeSetProgressControl( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in DWORD dwProgressPercentage ) { - HRESULT hr = E_NOTFOUND; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); + HRESULT hr = E_INVALIDARG; - if (hWnd) + if (pThemeControl && THEME_CONTROL_TYPE_PROGRESSBAR == pThemeControl->type) { - THEME_CONTROL* pControl = const_cast(FindControlFromHWnd(pTheme, hWnd)); - if (pControl && THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type) + THEME_CONTROL* pControl = const_cast(pThemeControl); + + DWORD dwCurrentProgress = LOWORD(pControl->dwData); + + if (dwCurrentProgress != dwProgressPercentage) { - DWORD dwCurrentProgress = LOWORD(pControl->dwData); + DWORD dwColor = HIWORD(pControl->dwData); + pControl->dwData = MAKEDWORD(dwProgressPercentage, dwColor); - if (dwCurrentProgress != dwProgressPercentage) + if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW) { - DWORD dwColor = HIWORD(pControl->dwData); - pControl->dwData = MAKEDWORD(dwProgressPercentage, dwColor); - - if (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW) + if (!::InvalidateRect(pControl->hWnd, NULL, FALSE)) { - if (!::InvalidateRect(hWnd, NULL, FALSE)) - { - ThmExitWithLastError(hr, "Failed to invalidate progress bar window."); - } - } - else - { - ::SendMessageW(hWnd, PBM_SETPOS, dwProgressPercentage, 0); + ThmExitWithLastError(hr, "Failed to invalidate progress bar window."); } - - hr = S_OK; } else { - hr = S_FALSE; + ::SendMessageW(pControl->hWnd, PBM_SETPOS, dwProgressPercentage, 0); } + + hr = S_OK; + } + else + { + hr = S_FALSE; } } @@ -1624,37 +1577,37 @@ LExit: DAPI_(HRESULT) ThemeSetProgressControlColor( - __in THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in DWORD dwColorIndex ) { - HRESULT hr = S_FALSE; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - if (hWnd) + HRESULT hr = E_INVALIDARG; + + // Only set color on owner draw progress bars. + if (pThemeControl && THEME_CONTROL_TYPE_PROGRESSBAR == pThemeControl->type && (pThemeControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW)) { - THEME_CONTROL* pControl = const_cast(FindControlFromHWnd(pTheme, hWnd)); + THEME_CONTROL* pControl = const_cast(pThemeControl); - // Only set color on owner draw progress bars. - if (pControl && (pControl->dwInternalStyle & INTERNAL_CONTROL_STYLE_OWNER_DRAW) && THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type) + if (pControl->ProgressBar.cImageRef <= dwColorIndex) { - if (pControl->ProgressBar.cImageRef <= dwColorIndex) - { - ThmExitWithRootFailure(hr, E_INVALIDARG, "Invalid progress bar color index: %u", dwColorIndex); - } - - if (HIWORD(pControl->dwData) != dwColorIndex) - { - DWORD dwCurrentProgress = LOWORD(pControl->dwData); - pControl->dwData = MAKEDWORD(dwCurrentProgress, dwColorIndex); + ThmExitWithRootFailure(hr, E_INVALIDARG, "Invalid progress bar color index: %u", dwColorIndex); + } - if (!::InvalidateRect(hWnd, NULL, FALSE)) - { - ThmExitWithLastError(hr, "Failed to invalidate progress bar window."); - } + if (HIWORD(pControl->dwData) != dwColorIndex) + { + DWORD dwCurrentProgress = LOWORD(pControl->dwData); + pControl->dwData = MAKEDWORD(dwCurrentProgress, dwColorIndex); - hr = S_OK; + if (!::InvalidateRect(pControl->hWnd, NULL, FALSE)) + { + ThmExitWithLastError(hr, "Failed to invalidate progress bar window."); } + + hr = S_OK; + } + else + { + hr = S_FALSE; } } @@ -1664,41 +1617,40 @@ LExit: DAPI_(HRESULT) ThemeSetTextControl( - __in const THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in_z_opt LPCWSTR wzText ) { - return ThemeSetTextControlEx(pTheme, dwControl, FALSE, wzText); + return ThemeSetTextControlEx(pThemeControl, FALSE, wzText); } DAPI_(HRESULT) ThemeSetTextControlEx( - __in const THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __in BOOL fUpdate, __in_z_opt LPCWSTR wzText ) { - HRESULT hr = S_OK; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); + HRESULT hr = E_INVALIDARG; - if (hWnd) + if (pThemeControl) { if (fUpdate) { - ::ShowWindow(hWnd, SW_HIDE); + ::ShowWindow(pThemeControl->hWnd, SW_HIDE); } - if (!::SetWindowTextW(hWnd, wzText)) + if (!::SetWindowTextW(pThemeControl->hWnd, wzText)) { ThmExitWithLastError(hr, "Failed to set control text."); } if (fUpdate) { - ::ShowWindow(hWnd, SW_SHOW); + ::ShowWindow(pThemeControl->hWnd, SW_SHOW); } + + hr = S_OK; } LExit: @@ -1707,50 +1659,17 @@ LExit: DAPI_(HRESULT) ThemeGetTextControl( - __in const THEME* pTheme, - __in DWORD dwControl, + __in const THEME_CONTROL* pThemeControl, __inout_z LPWSTR* psczText ) { - HRESULT hr = S_OK; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - SIZE_T cbSize = 0; - DWORD cchText = 0; - DWORD cchTextRead = 0; - - // Ensure the string has room for at least one character. - hr = StrMaxLength(*psczText, &cbSize); - ThmExitOnFailure(hr, "Failed to get text buffer length."); + HRESULT hr = E_INVALIDARG; - cchText = (DWORD)min(DWORD_MAX, cbSize); - - if (!cchText) + if (pThemeControl) { - cchText = GROW_WINDOW_TEXT; - - hr = StrAlloc(psczText, cchText); - ThmExitOnFailure(hr, "Failed to grow text buffer."); + hr = WnduGetControlText(pThemeControl->hWnd, psczText); } - // Read (and keep growing buffer) until we finally read less than there - // is room in the buffer. - for (;;) - { - cchTextRead = ::GetWindowTextW(hWnd, *psczText, cchText); - if (cchTextRead + 1 < cchText) - { - break; - } - else - { - cchText = cchTextRead + GROW_WINDOW_TEXT; - - hr = StrAlloc(psczText, cchText); - ThmExitOnFailure(hr, "Failed to grow text buffer again."); - } - } - -LExit: return hr; } @@ -1771,25 +1690,26 @@ LExit: DAPI_(void) ThemeSetFocus( - __in THEME* pTheme, - __in DWORD dwControl + __in const THEME_CONTROL* pThemeControl ) { - HWND hwndFocus = ::GetDlgItem(pTheme->hwndParent, dwControl); - if (hwndFocus && !ThemeControlEnabled(pTheme, dwControl)) - { - hwndFocus = ::GetNextDlgTabItem(pTheme->hwndParent, hwndFocus, FALSE); - } + if (pThemeControl) + { + HWND hwndFocus = pThemeControl->hWnd; + if (hwndFocus && !ThemeControlEnabled(pThemeControl)) + { + hwndFocus = ::GetNextDlgTabItem(pThemeControl->pTheme->hwndParent, hwndFocus, FALSE); + } - if (hwndFocus) - { - ::SetFocus(hwndFocus); + if (hwndFocus) + { + ::SetFocus(hwndFocus); + } } } DAPI_(void) ThemeShowChild( - __in THEME* pTheme, __in THEME_CONTROL* pParentControl, __in DWORD dwIndex ) @@ -1798,7 +1718,7 @@ DAPI_(void) ThemeShowChild( for (DWORD i = 0; i < pParentControl->cControls; ++i) { THEME_CONTROL* pControl = pParentControl->rgControls + i; - ShowControl(pTheme, pControl, dwIndex == i ? SW_SHOW : SW_HIDE, FALSE, THEME_SHOW_PAGE_REASON_DEFAULT, 0, NULL); + ShowControl(pControl, dwIndex == i ? SW_SHOW : SW_HIDE, FALSE, THEME_SHOW_PAGE_REASON_DEFAULT, 0, NULL); } } @@ -4322,28 +4242,24 @@ LExit: static HRESULT StartBillboard( __in THEME* pTheme, - __in DWORD dwControl + __in THEME_CONTROL* pControl ) { HRESULT hr = E_NOTFOUND; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); + UINT_PTR idEvent = reinterpret_cast(pControl); - if (hWnd) + if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) { - THEME_CONTROL* pControl = const_cast(FindControlFromHWnd(pTheme, hWnd)); - if (pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type) - { - // kick off - pControl->dwData = 0; - OnBillboardTimer(pTheme, pTheme->hwndParent, dwControl); + // kick off + pControl->dwData = 0; + OnBillboardTimer(pTheme, pTheme->hwndParent, idEvent); - if (!::SetTimer(pTheme->hwndParent, pControl->wId, pControl->wBillboardInterval, NULL)) - { - ThmExitWithLastError(hr, "Failed to start billboard."); - } - - hr = S_OK; + if (!::SetTimer(pTheme->hwndParent, idEvent, pControl->wBillboardInterval, NULL)) + { + ThmExitWithLastError(hr, "Failed to start billboard."); } + + hr = S_OK; } LExit: @@ -4353,23 +4269,19 @@ LExit: static HRESULT StopBillboard( __in THEME* pTheme, - __in DWORD dwControl + __in THEME_CONTROL* pControl ) { HRESULT hr = E_NOTFOUND; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); + UINT_PTR idEvent = reinterpret_cast(pControl); - if (hWnd) + if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) { - const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); - if (pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type) - { - ThemeControlEnable(pTheme, dwControl, FALSE); + ThemeControlEnable(pControl, FALSE); - if (::KillTimer(pTheme->hwndParent, pControl->wId)) - { - hr = S_OK; - } + if (::KillTimer(pTheme->hwndParent, idEvent)) + { + hr = S_OK; } } @@ -5039,81 +4951,33 @@ static void FreeImageInstance( } -static DWORD CALLBACK RichEditStreamFromFileHandleCallback( - __in DWORD_PTR dwCookie, - __in_bcount(cb) LPBYTE pbBuff, - __in LONG cb, - __in LONG* pcb - ) -{ - HRESULT hr = S_OK; - HANDLE hFile = reinterpret_cast(dwCookie); - - if (!::ReadFile(hFile, pbBuff, cb, reinterpret_cast(pcb), NULL)) - { - ThmExitWithLastError(hr, "Failed to read file"); - } - -LExit: - return hr; -} - - -static DWORD CALLBACK RichEditStreamFromMemoryCallback( - __in DWORD_PTR dwCookie, - __in_bcount(cb) LPBYTE pbBuff, - __in LONG cb, - __in LONG* pcb - ) -{ - HRESULT hr = S_OK; - MEMBUFFER_FOR_RICHEDIT* pBuffer = reinterpret_cast(dwCookie); - DWORD cbCopy = 0; - - if (pBuffer->iData < pBuffer->cbData) - { - cbCopy = min(static_cast(cb), pBuffer->cbData - pBuffer->iData); - memcpy(pbBuff, pBuffer->rgbData + pBuffer->iData, cbCopy); - - pBuffer->iData += cbCopy; - Assert(pBuffer->iData <= pBuffer->cbData); - } - - *pcb = cbCopy; - return hr; -} - - static void CALLBACK OnBillboardTimer( - __in THEME* pTheme, + __in THEME* /*pTheme*/, __in HWND hwnd, __in UINT_PTR idEvent ) { - HWND hwndControl = ::GetDlgItem(hwnd, static_cast(idEvent)); - if (hwndControl) + THEME_CONTROL* pControl = reinterpret_cast(idEvent); + + if (pControl) { - THEME_CONTROL* pControl = const_cast(FindControlFromHWnd(pTheme, hwndControl)); - AssertSz(pControl && THEME_CONTROL_TYPE_BILLBOARD == pControl->type, "Only billboard controls should get billboard timer messages."); + AssertSz(THEME_CONTROL_TYPE_BILLBOARD == pControl->type, "Only billboard controls should get billboard timer messages."); - if (pControl) + if (pControl->dwData < pControl->cControls) { - if (pControl->dwData < pControl->cControls) - { - ThemeShowChild(pTheme, pControl, pControl->dwData); - } - else if (pControl->fBillboardLoops) - { - pControl->dwData = 0; - ThemeShowChild(pTheme, pControl, pControl->dwData); - } - else // no more looping - { - ::KillTimer(hwnd, idEvent); - } - - ++pControl->dwData; + ThemeShowChild(pControl, pControl->dwData); } + else if (pControl->fBillboardLoops) + { + pControl->dwData = 0; + ThemeShowChild(pControl, pControl->dwData); + } + else // no more looping + { + ::KillTimer(hwnd, idEvent); + } + + ++pControl->dwData; } } @@ -5151,7 +5015,7 @@ static void OnBrowseDirectory( if (pTargetControl && THEME_CONTROL_TYPE_EDITBOX == pTargetControl->type && !pTargetControl->fDisableVariableFunctionality) { - hr = ThemeSetTextControl(pTheme, pTargetControl->wId, wzPath); + hr = ThemeSetTextControl(pTargetControl, wzPath); ThmExitOnFailure(hr, "Failed to set text on editbox: %ls", pTargetControl->sczName); } else if (pTheme->pfnSetStringVariable) @@ -5161,7 +5025,7 @@ static void OnBrowseDirectory( } else if (pTargetControl) { - hr = ThemeSetTextControl(pTheme, pTargetControl->wId, wzPath); + hr = ThemeSetTextControl(pTargetControl, wzPath); ThmExitOnFailure(hr, "Failed to set text on control: %ls", pTargetControl->sczName); } @@ -5252,13 +5116,13 @@ static BOOL OnButtonClicked( case THEME_CONTROL_TYPE_CHECKBOX: if (pTheme->pfnSetNumericVariable && pControl->sczName && *pControl->sczName) { - BOOL fChecked = ThemeIsControlChecked(pTheme, pControl->wId); + BOOL fChecked = ThemeIsControlChecked(pControl); pTheme->pfnSetNumericVariable(pControl->sczName, fChecked ? 1 : 0, pTheme->pvVariableContext); fRefresh = TRUE; } break; case THEME_CONTROL_TYPE_RADIOBUTTON: - if (pTheme->pfnSetStringVariable && pControl->sczVariable && *pControl->sczVariable && ThemeIsControlChecked(pTheme, pControl->wId)) + if (pTheme->pfnSetStringVariable && pControl->sczVariable && *pControl->sczVariable && ThemeIsControlChecked(pControl)) { pTheme->pfnSetStringVariable(pControl->sczVariable, pControl->sczValue, FALSE, pTheme->pvVariableContext); fRefresh = TRUE; @@ -5386,6 +5250,42 @@ LExit: return fProcessed; } +static const THEME_CONTROL* FindControlFromId( + __in const THEME* pTheme, + __in WORD wId, + __in_opt const THEME_CONTROL* pParentControl + ) +{ + DWORD cControls = 0; + THEME_CONTROL* rgControls = NULL; + const THEME_CONTROL* pChildControl = NULL; + + GetControls(pTheme, pParentControl, cControls, rgControls); + + // Breadth first search since control ids are technically only valid for direct child windows of a specific parent window. + for (DWORD i = 0; i < cControls; ++i) + { + if (wId == rgControls[i].wId) + { + return rgControls + i; + } + } + + for (DWORD i = 0; i < cControls; ++i) + { + if (0 < rgControls[i].cControls) + { + pChildControl = FindControlFromId(pTheme, wId, rgControls + i); + if (pChildControl) + { + return pChildControl; + } + } + } + + return NULL; +} + static BOOL OnNotifyEnMsgFilter( __in THEME* pTheme, __in const THEME_CONTROL* pThemeControl, @@ -5638,7 +5538,6 @@ LExit: static HRESULT ShowControl( - __in THEME* pTheme, __in THEME_CONTROL* pControl, __in int nCmdShow, __in BOOL fSaveEditboxes, @@ -5654,13 +5553,14 @@ static HRESULT ShowControl( LPWSTR sczText = NULL; THEME_SAVEDVARIABLE* pSavedVariable = NULL; BOOL fHide = SW_HIDE == nCmdShow; + THEME* pTheme = pControl->pTheme; THEME_PAGE* pPage = ThemeGetPage(pTheme, dwPageId); // Save the editbox value if necessary (other control types save their values immediately). if (pTheme->pfnSetStringVariable && !pControl->fDisableVariableFunctionality && fSaveEditboxes && THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName) { - hr = ThemeGetTextControl(pTheme, pControl->wId, &sczText); + hr = ThemeGetTextControl(pControl, &sczText); ThmExitOnFailure(hr, "Failed to get the text for control: %ls", pControl->sczName); hr = pTheme->pfnSetStringVariable(pControl->sczName, sczText, FALSE, pTheme->pvVariableContext); @@ -5675,7 +5575,7 @@ static HRESULT ShowControl( if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type) { - StopBillboard(pTheme, pControl->wId); + StopBillboard(pTheme, pControl); } ExitFunction(); @@ -5767,7 +5667,7 @@ static HRESULT ShowControl( ReleaseNullStr(sczText); } - ThemeSetTextControl(pTheme, pControl->wId, sczText); + ThemeSetTextControl(pControl, sczText); if (wzNote && *wzNote) { @@ -5811,7 +5711,7 @@ static HRESULT ShowControl( ++iPageControl; } - ThemeSendControlMessage(pTheme, pControl->wId, BM_SETCHECK, SUCCEEDED(hr) && llValue ? BST_CHECKED : BST_UNCHECKED, 0); + ::SendMessageW(pControl->hWnd, BM_SETCHECK, SUCCEEDED(hr) && llValue ? BST_CHECKED : BST_UNCHECKED, 0); } // If this is an editbox control, @@ -5838,7 +5738,7 @@ static HRESULT ShowControl( ++iPageControl; } - ThemeSetTextControl(pTheme, pControl->wId, sczText); + ThemeSetTextControl(pControl, sczText); } } @@ -5901,11 +5801,11 @@ static HRESULT ShowControl( { if (fEnabled) { - StartBillboard(pTheme, pControl->wId); + StartBillboard(pTheme, pControl); } else { - StopBillboard(pTheme, pControl->wId); + StopBillboard(pTheme, pControl); } } @@ -5944,7 +5844,7 @@ static HRESULT ShowControls( // Only look at non-page controls and the specified page's controls. if (!pControl->wPageId || pControl->wPageId == dwPageId) { - hr = ShowControl(pTheme, pControl, nCmdShow, fSaveEditboxes, reason, dwPageId, &hwndFocus); + hr = ShowControl(pControl, nCmdShow, fSaveEditboxes, reason, dwPageId, &hwndFocus); ThmExitOnFailure(hr, "Failed to show control '%ls' at index %d.", pControl->sczName, i); } } @@ -6509,7 +6409,7 @@ static HRESULT LoadControls( HRESULT hrFormat = pTheme->pfnFormatString(pControl->sczText, &sczText, pTheme->pvVariableContext); if (SUCCEEDED(hrFormat)) { - ThemeSetTextControl(pTheme, pControl->wId, sczText); + ThemeSetTextControl(pControl, sczText); } } diff --git a/src/libs/dutil/WixToolset.DUtil/wndutil.cpp b/src/libs/dutil/WixToolset.DUtil/wndutil.cpp new file mode 100644 index 00000000..b75b0491 --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/wndutil.cpp @@ -0,0 +1,206 @@ +// 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. + +#include "precomp.h" + + +// Exit macros +#define WnduExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) +#define WnduExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) +#define WnduExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) +#define WnduExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) +#define WnduExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) +#define WnduExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_WNDUTIL, x, e, s, __VA_ARGS__) +#define WnduExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) +#define WnduExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_WNDUTIL, p, x, e, s, __VA_ARGS__) +#define WnduExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_WNDUTIL, p, x, s, __VA_ARGS__) +#define WnduExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_WNDUTIL, p, x, e, s, __VA_ARGS__) +#define WnduExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_WNDUTIL, p, x, s, __VA_ARGS__) +#define WnduExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_WNDUTIL, e, x, s, __VA_ARGS__) +#define WnduExitOnOptionalXmlQueryFailure(x, b, s, ...) ExitOnOptionalXmlQueryFailureSource(DUTIL_SOURCE_WNDUTIL, x, b, s, __VA_ARGS__) +#define WnduExitOnRequiredXmlQueryFailure(x, s, ...) ExitOnRequiredXmlQueryFailureSource(DUTIL_SOURCE_WNDUTIL, x, s, __VA_ARGS__) +#define WnduExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_WNDUTIL, g, x, s, __VA_ARGS__) + +struct MEMBUFFER_FOR_RICHEDIT +{ + BYTE* rgbData; + DWORD cbData; + + DWORD iData; +}; + +const DWORD GROW_WINDOW_TEXT = 250; + + +// prototypes +static DWORD CALLBACK RichEditStreamFromFileHandleCallback( + __in DWORD_PTR dwCookie, + __in_bcount(cb) LPBYTE pbBuff, + __in LONG cb, + __in LONG *pcb + ); +static DWORD CALLBACK RichEditStreamFromMemoryCallback( + __in DWORD_PTR dwCookie, + __in_bcount(cb) LPBYTE pbBuff, + __in LONG cb, + __in LONG *pcb + ); + + +DAPI_(HRESULT) WnduLoadRichEditFromFile( + __in HWND hWnd, + __in_z LPCWSTR wzFileName, + __in HMODULE hModule + ) +{ + HRESULT hr = S_OK; + LPWSTR sczFile = NULL; + HANDLE hFile = INVALID_HANDLE_VALUE; + + hr = PathRelativeToModule(&sczFile, wzFileName, hModule); + WnduExitOnFailure(hr, "Failed to read resource data."); + + hFile = ::CreateFileW(sczFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (INVALID_HANDLE_VALUE == hFile) + { + WnduExitWithLastError(hr, "Failed to open RTF file."); + } + else + { + LONGLONG llRtfSize; + hr = FileSizeByHandle(hFile, &llRtfSize); + if (SUCCEEDED(hr)) + { + ::SendMessageW(hWnd, EM_EXLIMITTEXT, 0, static_cast(llRtfSize)); + } + + EDITSTREAM es = { }; + es.pfnCallback = RichEditStreamFromFileHandleCallback; + es.dwCookie = reinterpret_cast(hFile); + + ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast(&es)); + hr = es.dwError; + WnduExitOnFailure(hr, "Failed to update RTF stream."); + } + +LExit: + ReleaseStr(sczFile); + ReleaseFile(hFile); + + return hr; +} + +DAPI_(HRESULT) WnduLoadRichEditFromResource( + __in HWND hWnd, + __in_z LPCSTR szResourceName, + __in HMODULE hModule + ) +{ + HRESULT hr = S_OK; + MEMBUFFER_FOR_RICHEDIT buffer = { }; + EDITSTREAM es = { }; + + hr = ResReadData(hModule, szResourceName, reinterpret_cast(&buffer.rgbData), &buffer.cbData); + WnduExitOnFailure(hr, "Failed to read resource data."); + + es.pfnCallback = RichEditStreamFromMemoryCallback; + es.dwCookie = reinterpret_cast(&buffer); + + ::SendMessageW(hWnd, EM_STREAMIN, SF_RTF, reinterpret_cast(&es)); + hr = es.dwError; + WnduExitOnFailure(hr, "Failed to update RTF stream."); + +LExit: + return hr; +} + + +DAPI_(HRESULT) WnduGetControlText( + __in HWND hWnd, + __inout_z LPWSTR* psczText + ) +{ + HRESULT hr = S_OK; + SIZE_T cbSize = 0; + DWORD cchText = 0; + DWORD cchTextRead = 0; + + // Ensure the string has room for at least one character. + hr = StrMaxLength(*psczText, &cbSize); + WnduExitOnFailure(hr, "Failed to get text buffer length."); + + cchText = (DWORD)min(DWORD_MAX, cbSize); + + if (!cchText) + { + cchText = GROW_WINDOW_TEXT; + + hr = StrAlloc(psczText, cchText); + WnduExitOnFailure(hr, "Failed to grow text buffer."); + } + + // Read (and keep growing buffer) until we finally read less than there + // is room in the buffer. + for (;;) + { + cchTextRead = ::GetWindowTextW(hWnd, *psczText, cchText); + if (cchTextRead + 1 < cchText) + { + break; + } + else + { + cchText = cchTextRead + GROW_WINDOW_TEXT; + + hr = StrAlloc(psczText, cchText); + WnduExitOnFailure(hr, "Failed to grow text buffer again."); + } + } + +LExit: + return hr; +} + + +static DWORD CALLBACK RichEditStreamFromFileHandleCallback( + __in DWORD_PTR dwCookie, + __in_bcount(cb) LPBYTE pbBuff, + __in LONG cb, + __in LONG* pcb + ) +{ + HRESULT hr = S_OK; + HANDLE hFile = reinterpret_cast(dwCookie); + + if (!::ReadFile(hFile, pbBuff, cb, reinterpret_cast(pcb), NULL)) + { + WnduExitWithLastError(hr, "Failed to read file"); + } + +LExit: + return hr; +} + + +static DWORD CALLBACK RichEditStreamFromMemoryCallback( + __in DWORD_PTR dwCookie, + __in_bcount(cb) LPBYTE pbBuff, + __in LONG cb, + __in LONG* pcb + ) +{ + HRESULT hr = S_OK; + MEMBUFFER_FOR_RICHEDIT* pBuffer = reinterpret_cast(dwCookie); + DWORD cbCopy = 0; + + if (pBuffer->iData < pBuffer->cbData) + { + cbCopy = min(static_cast(cb), pBuffer->cbData - pBuffer->iData); + memcpy(pbBuff, pBuffer->rgbData + pBuffer->iData, cbCopy); + + pBuffer->iData += cbCopy; + Assert(pBuffer->iData <= pBuffer->cbData); + } + + *pcb = cbCopy; + return hr; +} diff --git a/src/samples/thmviewer/display.cpp b/src/samples/thmviewer/display.cpp index 9ef88018..f40b50b5 100644 --- a/src/samples/thmviewer/display.cpp +++ b/src/samples/thmviewer/display.cpp @@ -188,7 +188,7 @@ static DWORD WINAPI DisplayThreadProc( THEME_CONTROL* pControl = pCurrentHandle->pTheme->rgControls + i; if (!pControl->wPageId) { - ThemeShowControl(pCurrentHandle->pTheme, pControl->wId, nCmdShow); + ThemeShowControl(pControl, nCmdShow); } } @@ -264,7 +264,7 @@ static LRESULT CALLBACK DisplayWndProc( break; case WM_TIMER: - if (!lParam && SUCCEEDED(ThemeSetProgressControl(pHandleTheme->pTheme, wParam, dwProgress))) + if (!lParam && SUCCEEDED(ThemeSetProgressControl(reinterpret_cast(wParam), dwProgress))) { dwProgress += rand() % 10 + 1; if (dwProgress > 100) @@ -322,12 +322,12 @@ static BOOL DisplayOnThmLoadedControl( // Pre-populate some control types with data. if (THEME_CONTROL_TYPE_RICHEDIT == pControl->type) { - hr = ThemeLoadRichEditFromResource(pTheme, pControl->wId, MAKEINTRESOURCEA(THMVWR_RES_RICHEDIT_FILE), ::GetModuleHandleW(NULL)); + hr = WnduLoadRichEditFromResource(pControl->hWnd, MAKEINTRESOURCEA(THMVWR_RES_RICHEDIT_FILE), ::GetModuleHandleW(NULL)); ExitOnFailure(hr, "Failed to load richedit text."); } else if (THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type) { - DWORD dwId = ::SetTimer(pTheme->hwndParent, pControl->wId, 500, NULL); + DWORD dwId = ::SetTimer(pTheme->hwndParent, reinterpret_cast(pControl), 500, NULL); dwId = dwId; // prevents warning in "ship" build. Assert(dwId == pControl->wId); } diff --git a/src/samples/thmviewer/precomp.h b/src/samples/thmviewer/precomp.h index f11d3534..762a0623 100644 --- a/src/samples/thmviewer/precomp.h +++ b/src/samples/thmviewer/precomp.h @@ -28,6 +28,7 @@ #include "shelutil.h" #include "strutil.h" #include "thmutil.h" +#include "wndutil.h" #include "resource.h" diff --git a/src/samples/thmviewer/thmviewer.cpp b/src/samples/thmviewer/thmviewer.cpp index 94b1ef55..38f3c4dc 100644 --- a/src/samples/thmviewer/thmviewer.cpp +++ b/src/samples/thmviewer/thmviewer.cpp @@ -390,6 +390,12 @@ static void OnThemeLoadError( LPWSTR* psczErrors = NULL; UINT cErrors = 0; TVINSERTSTRUCTW tvi = { }; + const THEME_CONTROL* pTreeControl = NULL; + + if (!ThemeControlExistsById(pTheme, THMVWR_CONTROL_TREE, &pTreeControl)) + { + ExitWithRootFailure(hr, E_INVALIDSTATE, "THMVWR_CONTROL_TREE control doesn't exist."); + } // Add the application node. tvi.hParent = NULL; @@ -397,7 +403,7 @@ static void OnThemeLoadError( tvi.item.mask = TVIF_TEXT | TVIF_PARAM; tvi.item.lParam = 0; tvi.item.pszText = L"Failed to load theme."; - tvi.hParent = reinterpret_cast(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi))); + tvi.hParent = reinterpret_cast(::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi))); if (!vsczThemeLoadErrors) { @@ -405,13 +411,13 @@ static void OnThemeLoadError( ExitOnFailure(hr, "Failed to format error message."); tvi.item.pszText = sczMessage; - ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi)); + ::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi)); hr = StrAllocFromError(&sczMessage, hrFailure, NULL); ExitOnFailure(hr, "Failed to format error message text."); tvi.item.pszText = sczMessage; - ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi)); + ::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi)); } else { @@ -421,11 +427,11 @@ static void OnThemeLoadError( for (DWORD i = 0; i < cErrors; ++i) { tvi.item.pszText = psczErrors[i]; - ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi)); + ::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi)); } } - ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_EXPAND, TVE_EXPAND, reinterpret_cast(tvi.hParent)); + ::SendMessage(pTreeControl->hWnd, TVM_EXPAND, TVE_EXPAND, reinterpret_cast(tvi.hParent)); LExit: ReleaseStr(sczMessage); @@ -439,6 +445,7 @@ static void OnNewTheme( __in HANDLE_THEME* pHandle ) { + const THEME_CONTROL* pTreeControl = NULL; HANDLE_THEME* pOldHandle = reinterpret_cast(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); THEME* pNewTheme = pHandle->pTheme; @@ -460,17 +467,23 @@ static void OnNewTheme( ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast(pHandle)); + if (!ThemeControlExistsById(pTheme, THMVWR_CONTROL_TREE, &pTreeControl)) + { + TraceError(E_INVALIDSTATE, "Tree control doesn't exist."); + return; + } + // Remember the currently selected item by name so we can try to automatically select it later. // Otherwise, the user would see their window destroyed after every save of their theme file and // have to click to get the window back. item.mask = TVIF_TEXT; item.pszText = wzSelectedPage; item.cchTextMax = countof(wzSelectedPage); - item.hItem = reinterpret_cast(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_GETNEXTITEM, TVGN_CARET, NULL)); - ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_GETITEM, 0, reinterpret_cast(&item)); + item.hItem = reinterpret_cast(::SendMessage(pTreeControl->hWnd, TVM_GETNEXTITEM, TVGN_CARET, NULL)); + ::SendMessage(pTreeControl->hWnd, TVM_GETITEM, 0, reinterpret_cast(&item)); // Remove the previous items in the tree. - ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_DELETEITEM, 0, reinterpret_cast(TVI_ROOT)); + ::SendMessage(pTreeControl->hWnd, TVM_DELETEITEM, 0, reinterpret_cast(TVI_ROOT)); // Add the application node. tvi.hParent = NULL; @@ -480,7 +493,7 @@ static void OnNewTheme( tvi.item.pszText = pHandle && pHandle->pTheme && pHandle->pTheme->sczCaption ? pHandle->pTheme->sczCaption : L"Window"; // Add the pages. - tvi.hParent = reinterpret_cast(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi))); + tvi.hParent = reinterpret_cast(::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi))); tvi.hInsertAfter = TVI_SORT; for (DWORD i = 0; i < pNewTheme->cPages; ++i) { @@ -490,7 +503,7 @@ static void OnNewTheme( tvi.item.pszText = pPage->sczName; 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. - HTREEITEM hti = reinterpret_cast(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi))); + HTREEITEM hti = reinterpret_cast(::SendMessage(pTreeControl->hWnd, TVM_INSERTITEMW, 0, reinterpret_cast(&tvi))); if (*wzSelectedPage && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pPage->sczName, -1, wzSelectedPage, -1)) { htiSelected = hti; @@ -503,10 +516,10 @@ static void OnNewTheme( htiSelected = tvi.hParent; } - ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_EXPAND, TVE_EXPAND, reinterpret_cast(tvi.hParent)); + ::SendMessage(pTreeControl->hWnd, TVM_EXPAND, TVE_EXPAND, reinterpret_cast(tvi.hParent)); if (htiSelected) { - ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_SELECTITEM, TVGN_CARET, reinterpret_cast(htiSelected)); + ::SendMessage(pTreeControl->hWnd, TVM_SELECTITEM, TVGN_CARET, reinterpret_cast(htiSelected)); } } diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp index b502285f..6c37fbd8 100644 --- a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp +++ b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp @@ -365,18 +365,23 @@ private: void UpdateProgressBarProgress() { + const THEME_CONTROL* pControlProgressbarImage = NULL; + const THEME_CONTROL* pControlProgressbarStandard = NULL; static DWORD dwProgress = 0; DWORD dwCurrent = dwProgress < 100 ? dwProgress : 200 - dwProgress; + ThemeControlExistsById(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, &pControlProgressbarImage); + ThemeControlExistsById(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_STANDARD, &pControlProgressbarStandard); + if (0 == dwProgress || 100 == dwProgress) { - ThemeSetProgressControlColor(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, 100 == dwProgress ? 1 : 0); + ThemeSetProgressControlColor(pControlProgressbarImage, 100 == dwProgress ? 1 : 0); } dwProgress = (dwProgress + 10) % 200; - ThemeSetProgressControl(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, dwCurrent); - ThemeSetProgressControl(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_STANDARD, dwCurrent); + ThemeSetProgressControl(pControlProgressbarImage, dwCurrent); + ThemeSetProgressControl(pControlProgressbarStandard, dwCurrent); } public: -- cgit v1.2.3-55-g6feb