2
votes

I have a dialog which lets the user choose a network share with the help of a custom action. I don't want the user to be able to continue the installation unless this location has been set. To achieve this aim, I disabled the PushButton Control that takes the user to the next dialog. My CustomAction sets a property which is checked for in the Condition element of that PushButton control.

This all works well. What is bothering me is that I want the user to be able to navigate through the dialogs as easily as possible. That's why I made the PushButton control, which takes the user to the browse dialog CustomAction, the Default control of the Dialog. This also is based on the condition of the property set by the CustomAction. After the property has been set, the PushButton taking the user to the next dialog is enabled and set as the default control. As you can see in the screenshots this actually works.

The interesting thing is that the Default control of the Dialog has indeed been changed, but the tabbed control still remains the PushButton which opens the browse dialog CustomAction. This circumstance leads to the erratic behaviour that when the Return key is pressed, the browse Dialog opens up again, although the Property has already been set, i.e. the folder path has already been chosen. First screen of a sample installer showing the disabled next button. The default and focused Control is the Change PushButton control which brings up a dialog created by a CustomAction.Second screen of a sample installer showing the same Dialog after the user has chosen a folder, i.e. the VIEWDIR property has been set (see code)

Is there any way I can correct this behaviour? I want the focus to move away from one control to the other based on the state of a property. How would I do that?

Also: How do the TabSkip and the Default attribute go together?

Here is the Code for the Dialog:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <CustomActionRef Id="OpenFolderBrowser"/>
    <UI>
      <Dialog Id="RemoteViewDirectory" X="0" Y="0" Width="374" Height="266" Title="!(loc.GlobalDialogTitle)" NoMinimize="yes">
        <Control Id="TopBanner" Type="Bitmap" X="0" Y="0" Width="374" Height="44" Text="TopBanner" TabSkip="yes" Disabled="yes" />
        <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="373" Height="0" TabSkip="yes" Disabled="yes" />
        <Control Id="DlgSubTitle" Type="Text" X="13" Y="6" Width="292" Height="25" TabSkip="yes" Transparent="yes">
          <Text><![CDATA[{&MSSansBold8}!(loc.VwDrctryDlgSubtitle)]]></Text>
        </Control>
        <Control Id="DlgDesc" Type="Text" X="21" Y="23" Width="292" Height="25" TabSkip="yes" Transparent="yes">
          <Text><![CDATA[{&Tahoma8}!(loc.VwDrctryDlgDesc)]]></Text>
        </Control>
        <Control Id="GroupBox" Type="GroupBox" X="15" Y="174" Width="344" Height="41" TabSkip="yes">
          <Text><![CDATA[!(loc.VwDrctryDlgSubtitle)]]></Text>
        </Control>
        <Control Id="ChangeRemoteFolder" Type="PushButton" X="285" Y="189" Width="66" Height="17" TabSkip="no">
          <Text><![CDATA[!(loc.BtnTextChange)]]></Text>
          <Condition Action="default"><![CDATA[NOT VIEWDIR]]></Condition>
          <Publish Event="DoAction" Value="OpenFolderBrowser" Order="1">1</Publish>
          <Publish Property="VIEWDIR" Value="[REMOTEDIR]" Order="2"><![CDATA[REMOTEDIR]]></Publish>
          <Publish Property="REMOTEDIR" Order="3">1</Publish>
        </Control>
        <Control Id="ChgdLocation" Type="Text" X="57" Y="192" Width="220" Height="20" Property="VIEWDIR" Text="[VIEWDIR]" TabSkip="yes">
          <Condition Action="show"><![CDATA[VIEWDIR]]></Condition>
          <Condition Action="hide"><![CDATA[NOT VIEWDIR]]></Condition>
        </Control>
        <Control Id="DummyNetworkLocation" Type="Text" X="57" Y="192" Width="220" Height="20" Text="!(loc.TxtDummyViewNetworkPath)" TabSkip="yes">
          <Condition Action="show"><![CDATA[NOT VIEWDIR]]></Condition>
          <Condition Action="hide"><![CDATA[VIEWDIR]]></Condition>
        </Control>
        <Control Id="Back" Type="PushButton" X="164" Y="243" Width="66" Height="16" TabSkip="yes">
          <Text>!(loc.BtnTextBack)</Text>
          <Publish Event="NewDialog" Value="PreviousDialog">1</Publish>
        </Control>
        <Control Id="Next" Type="PushButton" X="230" Y="243" Width="66" Height="17" TabSkip="yes">
          <Text>!(loc.BtnTextNext)</Text>
          <Condition Action="enable"><![CDATA[VIEWDIR]]></Condition>
          <Condition Action="disable"><![CDATA[NOT VIEWDIR]]></Condition>
          <Condition Action="default"><![CDATA[VIEWDIR]]></Condition>
          <Publish Event="NewDialog" Value="NextDialog">1</Publish>
        </Control>
        <Control Id="Cancel" Type="PushButton" X="301" Y="243" Width="66" Height="17" TabSkip="yes" Cancel="yes">
          <Text>!(loc.BtnTextCancel)</Text>
          <Publish Event="SpawnDialog" Value="CancelSetup">1</Publish>
        </Control>
        <Control Id="DlgLine" Type="Line" X="0" Y="234" Width="373" Height="0" TabSkip="yes" Disabled="yes" />
      </Dialog>
    </UI>
  </Fragment>
</Wix>

And here is the output of the log created by Windows Installer:

Action 17:36:08: RemoteViewDirectory. Dialog created
MSI (c) (68:AC) [17:36:09:525]: Doing action: OpenFolderBrowser
Action 17:36:09: OpenFolderBrowser. 
Action start 17:36:09: OpenFolderBrowser.
MSI (c) (68:28) [17:36:09:525]: Invoking remote custom action. DLL: C:\...\Temp\MSI9B.tmp, Entrypoint: OpenFolderBrowser
MSI (c) (68!1C) [17:36:18:608]: PROPERTY CHANGE: Adding \\Win2k3iis6\cmak property. Its value is 'exists'.
MSI (c) (68!1C) [17:36:18:608]: PROPERTY CHANGE: Adding REMOTEDIR property. Its value is '\\Win2k3iis6\cmak'.
Action ended 17:36:18: OpenFolderBrowser. Return value 1.
MSI (c) (68:AC) [17:36:18:638]: PROPERTY CHANGE: Adding VIEWDIR property. Its value is '\\Win2k3iis6\cmak'.
MSI (c) (68:AC) [17:36:18:638]: PROPERTY CHANGE: Deleting REMOTEDIR property. Its current value is '\\Win2k3iis6\cmak'.
1
This behavior is exists in WIX built in dialogs too. We can reproduce it, when we change the InstallDir location using the Change button. - Vinoth

1 Answers

2
votes

I'm not aware of a way to control focus in the MSI UI. One thing you could try is to leave the Next button Default but Disabled. That might make the Enter key cause the focused button (the Change button) to be pressed. There is also a good chance that won't work. MSI UI is fairly limited in many ways.

To answer you second question TabSkip attribute removes a control from the tab order. In other words, a control with TabSkip='yes' should never be selected when pressing tab to navigate amongst the controls. The Default attribute indicates what button should be pressed when the Enter key is hit.