为此,您需要深入研究引导程序应用程序的代码 (WixStdBootstrapperApplication.cpp)。
幸运的是,您基于 WixStdBootstrapperApplication 进行了此操作,我已经花了很长时间了解它。
您需要做的第一件事是将 EulaAcceptCheckbox 放回页面上,并在其上显示实际的 Eula。当您要控制启用/禁用的 UI 元素时,您需要在引导程序应用程序的代码中执行此操作。BA 拥有 UI。
现在我们需要更改 EulaAcceptCheckbox 的行为,以便它启用/禁用 OptionsButton。
在 WndProc 中,我们处理用户单击按钮或滚动或执行任何操作时生成的所有消息。在 WM_COMMAND 下,我们有一个基于 LOWORD(wParam) 的开关,它是引发消息的控件的 ID。
找到“WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX”并看到它调用了 pBA->OnClickAcceptCheckbox();
这是方法
void OnClickAcceptCheckbox()
{
BOOL fAcceptedLicense = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense);
}
看起来超级简单对吧?在这里,您只需将 WIXSTDBA_CONTROL_INSTALL_BUTTON 更改为 WIXSTDBA_CONTROL_OPTIONS_BUTTON
我们还需要将选项按钮设置为默认禁用。为此,我们进入“OnChangeState”并查找 WIXSTDBA_PAGE_INSTALL 的 if
if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId) // on the "Install" page, ensure the install button is enabled/disabled correctly.
{
LONGLONG llElevated = 0;
if (m_Bundle.fPerMachine)
{
BalGetNumericVariable(WIXBUNDLE_VARIABLE_ELEVATED, &llElevated);
}
ThemeControlElevates(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, (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))
{
BOOL fEulaLink = (m_sczLicenseUrl && *m_sczLicenseUrl);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK, fEulaLink);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, 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);
// If there is an "Options" page, the "Options" button exists, and it hasn't been suppressed, then enable the button.
BOOL fOptionsEnabled = m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] && ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_BUTTON) && !m_fSuppressOptionsUI;
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_BUTTON, fOptionsEnabled);
// Show/Hide the version label if it exists.
if (m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] && ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_VERSION_LABEL) && !m_fShowVersion)
{
ThemeShowControl(m_pTheme, WIXSTDBA_CONTROL_VERSION_LABEL, SW_HIDE);
}
}
我们需要将这个块更新为
if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId) // on the "Install" page, ensure the install button is enabled/disabled correctly.
{
// If the EULA control exists, show it only if a license URL is provided as well.
if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK))
{
BOOL fEulaLink = (m_sczLicenseUrl && *m_sczLicenseUrl);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK, fEulaLink);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, 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);
// If there is an "Options" page, the "Options" button exists, and it hasn't been suppressed, then enable the button.
BOOL fOptionsEnabled = m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] && ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_BUTTON) && !m_fSuppressOptionsUI;
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_BUTTON, fOptionsEnabled & fAcceptedLicense);
// Show/Hide the version label if it exists.
if (m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] && ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_VERSION_LABEL) && !m_fShowVersion)
{
ThemeShowControl(m_pTheme, WIXSTDBA_CONTROL_VERSION_LABEL, SW_HIDE);
}
}
在这里,我们删除了提升的东西,因为它在安装按钮上,而是根据它是否在主题中定义以及是否选中了接受复选框来启用/禁用选项按钮。
接下来,您需要添加一种方法来定位新的 OptionsPage 复选框。
您的 cpp 文件中应该有一个枚举
enum WIXSTDBA_CONTROL
它应该被排序到页面上的控件中。在这里,您需要为新的 Options 复选框控件添加一个新条目,可能是 WIXSTDBA_CONTROL_OPTIONS_CHECKBOX
在此枚举下方,您将有一个二维数组
static THEME_ASSIGN_CONTROL_ID vrgInitControls[] =
您需要在此处添加一个新条目,该条目插入到您插入 enum 的同一位置。插入的数组项应如下所示
{ WIXSTDBA_CONTROL_OPTIONS_CEHCKBOX, L"OptionsCheckbox" }, //The string should match the Name of the checkbox in the theme xml.
现在我们需要一种方法来处理来自这个控件的消息。返回 WndProc 并在 WM_COMMAND 下的开关中添加一个新案例,它应该是
case WIXSTDBA_CONTROL_OPTIONS_CHECKBOX:
pBA->OnClickOptionsCheckbox();
return 0;
现在像 OnClickAcceptCheckbox() 一样向您的引导程序应用程序添加一个 OnClickOptionsCheckbox 方法
void OnClickOptionsCheckbox()
{
BOOL fAccepted = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAccepted);
}
最后,我们需要将我们从 OnChangeState WIXSTDBA_PAGE_INSTALL 案例中删除的 llElevated 内容添加到 WIXSTDBA_PAGE_OPTIONS 并设置安装按钮的默认状态
else if (m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] == dwNewPageId)
{
HRESULT hr = BalGetStringVariable(WIXSTDBA_VARIABLE_INSTALL_FOLDER, &sczUnformattedText);
if (SUCCEEDED(hr))
{
// If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe
// so don't go down the rabbit hole of making sure that this is securely freed.
BalFormatString(sczUnformattedText, &sczText);
ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_FOLDER_EDITBOX, sczText);
}
}
将更改为
else if (m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] == dwNewPageId)
{
LONGLONG llElevated = 0;
if (m_Bundle.fPerMachine)
{
BalGetNumericVariable(WIXBUNDLE_VARIABLE_ELEVATED, &llElevated);
}
ThemeControlElevates(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, (m_Bundle.fPerMachine && !llElevated));
BOOL fAccepted = !ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX) || !ThemeControlEnabled(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX) || ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAccepted);
HRESULT hr = BalGetStringVariable(WIXSTDBA_VARIABLE_INSTALL_FOLDER, &sczUnformattedText);
if (SUCCEEDED(hr))
{
// If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe
// so don't go down the rabbit hole of making sure that this is securely freed.
BalFormatString(sczUnformattedText, &sczText);
ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_FOLDER_EDITBOX, sczText);
}
}
对于这个实现,我仍然会改变一些事情,但我强烈建议尝试了解引导程序应用程序的功能以及它是如何工作的。
如果您想在安装期间更改 UI 的行为,您需要熟悉此处的代码。您可以添加新页面、添加控件和设置变量以及其他一些内容。
如果这看起来像很多工作(我自己肯定要弄清楚这一切),请考虑您是否真的需要这种类型的行为而不是默认 wixstdba 主题之一的默认行为。