Bootstrapper应用程序用户界面-如何在页面之间移动 [英] Bootstrapper Application UI - How To move between pages

查看:131
本文介绍了Bootstrapper应用程序用户界面-如何在页面之间移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个Bootstrapper应用程序,并希望使用WixStandardBootstrapperApplication为它创建UI.我希望用户界面在第一页(安装"页)上看到标准EULA和一个复选框,上面说我接受,并在下一页(选项"页)上单击一个继续进行操作的按钮,只有在选中该复选框后才能启用.在下一页上,我列出了一些文本,并希望有另一个复选框,该复选框再次表示我接受,并且有一个安装"按钮,只有选中该复选框后,该按钮才能启用.

I am writing a Bootstrapper Application and want to create the UI for it using the WixStandardBootstrapperApplication. I want the UI such that on the first page(Install page), I see the standard EULA and a checkbox which says I accept and a button to proceed on the next page (Options page) which should get enabled only after I select the checkbox. On the next page, I list some text and want to have another checkbox, which kind of again says I accept and a button to Install which gets enabled only after I select the checkbox.

<Page Name="Install">
  <Text X="154" Y="12" Width="-65" Height="21" DisablePrefix="yes">#(loc.Title)</Text>
  <Image X="120" Y="20" Width="54" Height="325" ImageFile="logo.png"/>
  <Richedit Name="EulaRichedit" X="154" Y="60" Width="-21" Height="-76" TabStop="yes" FontId="0" HexStyle="0x800000" />
  <Checkbox Name="OptionsCheckbox" X="-11" Y="-41" Width="246" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">I accept.</Checkbox>
  <Button Name="WelcomeCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
  <Button Name="OptionsButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" Text="Proceed" HideWhenDisabled="yes">Next</Button>
</Page>
<Page Name="Options">
  <Text X="185" Y="11" Width="-11" Height="32" FontId="1">#(loc.OptionsHeader)</Text>
  <Image X="0" Y="0" Width="177" Height="325" ImageFile="logoside.png"/>
  <Text X="180" Y="61" Width="-11" Height="17" FontId="3">Some text.</Text>
  <Checkbox Name="EulaAcceptCheckbox" X="180" Y="251" Width="246" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.OptionsButton)</Checkbox>
  <Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" Text="Proceed">#(loc.InstallInstallButton)</Button>
  <Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
</Page>

第二页(选项"页)正在根据我的需要工作-禁用复选框"和安装"按钮,并且只有在选中该复选框后才能启用.但是在第一页(安装"页)上,我无法使其工作.即使未选中该复选框,也会启用该按钮.我为复选框"和按钮名称"尝试了其他选项,但无法使其正常运行.我该怎么做才能使其正常工作?另外,如果您有任何指向不同选项的文档的链接,请共享.我找到了具有Thmutil模式的帮助文件,但没有列出复选框"或按钮"的各种选项.

The second page(Options page) is working according to what I need - Checkbox and Install button disabled, and it gets enabled only after selecting the checkbox. But on the first page(Install page) I am not able to make it work. The button is enabled even if the checkbox is not checked. I tried different options for the Checkbox and Button Name but I am unable to make it work. What can I do to make it work? Also if you have any link for any documentation for the different options then please share. I found the help file with Thmutil schema but it doesn't list the various options for Checkboxes or Buttons.

欢迎提出任何建议.随时询问是否有不清楚的地方.感谢您的提前帮助.

Any suggestions welcome. Feel free to ask if anything is unclear. Thanks for your help in advance.

推荐答案

为此,您需要深入研究bootstrapperapplication(WixStdBootstrapperApplication.cpp)的代码.

To do this you'll need to delve into the code for your bootstrapperapplication (WixStdBootstrapperApplication.cpp).

幸运的是,您是基于WixStdBootstrapperApplication的,我花了很多时间来了解它.

Luckily you're basing this off of the WixStdBootstrapperApplication which I've spend quite some time getting to know.

您需要做的第一件事是将EulaAcceptCheckbox放回带有实际Eula的页面上.当您要控制UI元素的启用/禁用时,您需要从引导程序应用程序的代码中执行此操作. BA拥有UI.

First thing you need to do is put the EulaAcceptCheckbox back onto the page with the actual Eula on it. When you're going to control the UI elements being enabled/disabled you need to do this from within the bootstrapper application's code. The BA owns the UI.

现在,我们需要更改EulaAcceptCheckbox的行为,以便启用/禁用OptionsButton.

Now we need to change the behaviour of that EulaAcceptCheckbox so that it enables/disables the OptionsButton.

在WndProc中,我们处理用户单击按钮或滚动或执行任何操作时生成的所有消息.在WM_COMMAND下,我们有一个基于LOWORD(wParam)的开关,它是引发消息的控件的ID.

In the WndProc is where we handle all the messages generated by the user when they click on a button or scroll or do anything. Under WM_COMMAND we have a switch based on LOWORD(wParam) which is the ID of the control that raised the message.

找到"WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX",并看到它调用了pBA-> OnClickAcceptCheckbox();

Locate "WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX" and see that it calls 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

Looks super simple right? Here you just have to change WIXSTDBA_CONTROL_INSTALL_BUTTON to the WIXSTDBA_CONTROL_OPTIONS_BUTTON

我们还需要将选项"按钮设置为默认禁用.为此,我们进入"OnChangeState"并查找WIXSTDBA_PAGE_INSTALL的if

We also need to set the Options button to default disabled. To do this we go into "OnChangeState" and look for the if for WIXSTDBA_PAGE_INSTALL

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);
    }
}

在这里,我们删除了提升的内容,因为该内容位于安装按钮上,而是根据是否在主题中定义了选项按钮以及是否选中了接受复选框来启用/禁用选项按钮.

Here we removed the elevated stuff since that goes on the install button and instead enable/disable the options button depending on whether it is defined in the theme and if the accept checkbox is checked or not.

接下来,您需要添加一种方法来找到新的OptionsPage复选框.

Next you'll need to add a way to locate your new OptionsPage checkbox.

您应该在cpp文件中包含一个枚举

You should have an enum in your cpp file

enum WIXSTDBA_CONTROL

应将其订购到页面上的控件中.在这里,您需要为新的选项"复选框控件添加一个新条目,也许是WIXSTDBA_CONTROL_OPTIONS_CHECKBOX

It should be ordered into controls on pages. Here you'll need to add a new entry for your new Options checkbox control, maybe WIXSTDBA_CONTROL_OPTIONS_CHECKBOX

在该枚举下面,您将拥有一个二维数组

Below this enum you'll have a 2-d array

static THEME_ASSIGN_CONTROL_ID vrgInitControls[] = 

您需要在此处添加一个新条目,该条目插入插入枚举的位置相同.插入的数组项应如下所示:

You'll need to add a new entry here that is inserted at the same place you inserted into your enum. The inserted array item should look like this

{ WIXSTDBA_CONTROL_OPTIONS_CEHCKBOX, L"OptionsCheckbox" },  //The string should match the Name of the checkbox in the theme xml.

现在,我们需要一种方法来处理来自此控件的消息.回到WndProc,并在WM_COMMAND下将新案例添加到交换机中

Now we need a way to handle messages from this Control. Head back to WndProc and add a new case to the switch under WM_COMMAND it should be

case WIXSTDBA_CONTROL_OPTIONS_CHECKBOX:
    pBA->OnClickOptionsCheckbox();
    return 0;

现在,像OnClickAcceptCheckbox()一样,将一个OnClickOptionsCheckbox方法添加到您的引导程序中

Now add a OnClickOptionsCheckbox method to your bootstrapper application just like the OnClickAcceptCheckbox()

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,并设置安装"按钮的默认状态

Finally, we need to add the llElevated stuff we removed from the OnChangeState WIXSTDBA_PAGE_INSTALL case to WIXSTDBA_PAGE_OPTIONS and also set the default state of the Install button

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);
    }
}

在此实现中,我仍然需要更改一些内容,但我强烈建议尝试逐步了解bootstrapper应用程序的功能和工作方式.

There are a few things I would still change around with this implementation but I would highly suggest trying to walk through what the bootstrapper application does and how it works.

如果要在安装过程中更改UI的行为,则需要熟悉此处的代码.您可以添加新页面,添加控件以及设置变量以及其他内容.

If you want to change the behaviour of the UI during your install you'll need to get familiar with the code here. You can add new pages, add controls, and set variables along with some other stuff.

如果这似乎需要大量工作(肯定是我自己弄清楚了这一切),请考虑您是否真的需要这种行为,而不是默认wixstdba主题之一的默认行为.

If this seems like a lot of work (figuring all this out myself definitely was) consider whether or not you really need this type of behaviour over the default behaviour of one of the default wixstdba themes.

这篇关于Bootstrapper应用程序用户界面-如何在页面之间移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆