2016-04-27 5 views
3

Ich schreibe eine Bootstrapper-Anwendung und möchte die Benutzeroberfläche dafür mit der WixStandardBootstrapperApplication erstellen. Ich möchte die Benutzeroberfläche so, dass auf der ersten Seite (Install-Seite), sehe ich die Standard EULA und ein Kontrollkästchen, das ich akzeptiere und eine Schaltfläche, um auf der nächsten Seite (Optionen Seite), die erst aktiviert werden soll, nachdem ich das Kontrollkästchen aktiviert . Auf der nächsten Seite listet ich einen Text auf und möchte ein anderes Kontrollkästchen haben, das wiederum sagt, ich akzeptiere und eine Schaltfläche zum Installieren, die erst aktiviert wird, nachdem ich das Kontrollkästchen ausgewählt habe.Bootstrapper Application UI - Wie man zwischen den Seiten wechselt

<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> 

Die zweite Seite (Seite Optionen) arbeitet nach dem, was ich brauche - Checkbox und Schaltfläche Installieren deaktiviert, und es nur nach der Auswahl der Kontrollkästchen aktiviert wird. Aber auf der ersten Seite (Installseite) kann ich es nicht funktionieren lassen. Die Schaltfläche ist aktiviert, auch wenn das Kontrollkästchen nicht aktiviert ist. Ich habe verschiedene Optionen für die Checkbox und den Button-Namen ausprobiert, aber ich kann es nicht funktionieren lassen. Was kann ich tun, damit es funktioniert? Wenn Sie einen Link für eine Dokumentation zu den verschiedenen Optionen haben, teilen Sie diese bitte mit. Ich habe die Hilfedatei mit Thmutil-Schema gefunden, aber es enthält nicht die verschiedenen Optionen für Checkboxen oder Buttons.

Alle Vorschläge willkommen. Frag ruhig ob etwas unklar ist. Danke im Vorraus für deine Hilfe.

+0

Oh, das ist eine lustige Sache zu implementieren. Es gibt eigentlich viel zu tun, um das zu erreichen. Ich werde versuchen, eine gute Antwort auf meine Mittagspause später heute aufzuschreiben, –

Antwort

3

Um dies zu tun, müssen Sie in den Code für Ihre Bootstrapper Anwendung (WixStdBootstrapperApplication.cpp) vertiefen.

Glücklicherweise basiert dies auf der WixStdBootstrapperApplication, die ich seit einiger Zeit kenne.

Als erstes müssen Sie die EulaAcceptCheckbox auf die Seite mit der aktuellen Eula zurücksetzen. Wenn Sie die aktivierten/deaktivierten Benutzeroberflächenelemente steuern möchten, müssen Sie dies innerhalb des Codes der Bootstrapper-Anwendung tun. Die BA besitzt die Benutzeroberfläche.

Jetzt müssen wir das Verhalten dieser EulaAcceptCheckbox so ändern, dass sie den OptionsButton aktiviert/deaktiviert.

Im WndProc werden alle Nachrichten verarbeitet, die der Benutzer beim Klicken auf eine Schaltfläche oder beim Scrollen oder Ausführen von Aktionen generiert. Unter WM_COMMAND haben wir einen Schalter basierend auf LOWORD (wParam), die die ID des Steuerelements ist, das die Nachricht ausgelöst hat.

Suchen Sie "WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX" und sehen Sie, dass es pBA-> OnClickAcceptCheckbox() aufruft;

Hier ist die Methode

void OnClickAcceptCheckbox() 
{ 
    BOOL fAcceptedLicense = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX); 
    ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense); 
} 

Sieht super einfach nicht wahr? Hier müssen Sie nur WIXSTDBA_CONTROL_INSTALL_BUTTON in WIXSTDBA_CONTROL_OPTIONS_BUTTON ändern

Wir müssen auch die Schaltfläche Optionen auf Standard deaktiviert deaktivieren. Dazu müssen wir in „OnChangeState“ gehen und suchen Sie nach, ob für 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); 
    } 
} 

Wir müssen dieser Block aktualisieren

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

Hier werden wir die erhöhten Sachen entfernt, da diese auf dem Installations geht und aktivieren/deaktivieren Sie stattdessen die Optionsschaltfläche, je nachdem, ob sie im Design definiert ist und ob das Annehmen-Kontrollkästchen aktiviert ist oder nicht.

Als nächstes müssen Sie einen Weg hinzufügen, um das neue OptionsPage-Kontrollkästchen zu finden.

Sie sollten eine ENUM in Ihrer CPP-Datei haben

enum WIXSTDBA_CONTROL 

Es sollte in Kontrollen auf den Seiten bestellt werden. Hier müssen Sie einen neuen Eintrag für die neue Optionen Checkbox Steuerelement hinzuzufügen, vielleicht WIXSTDBA_CONTROL_OPTIONS_CHECKBOX

Unterhalb dieser Enum Sie eine 2-D-Array haben werden

static THEME_ASSIGN_CONTROL_ID vrgInitControls[] = 

Sie erhalten eine neue hinzufügen müssen Eingabe hier, das ist eingefügt an der gleichen Stelle, die Sie in Ihr enum eingefügt. Das Array eingefügte Element sollte so aussehen

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

Jetzt müssen wir einen Weg Mitteilungen dieses Control Griff. Gehen Sie zurück zu WndProc und fügen Sie einen neuen Fall an den Schalter unter WM_COMMAND sollte es

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

nun eine OnClickOptionsCheckbox Methode Ihre Bootstrap-Anwendung sein hinzufügen ebenso wie die OnClickAcceptCheckbox()

void OnClickOptionsCheckbox() 
{ 
    BOOL fAccepted = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX); 
    ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAccepted); 
} 

Schließlich brauchen wir die llElevated Sachen fügen wir aus dem OnChangeState WIXSTDBA_PAGE_INSTALL Fall WIXSTDBA_PAGE_OPTIONS entfernt und stellen Sie auch den Standardstatus der Schaltfläche Installieren

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

Wird zu

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

umziehen Es gibt ein paar Dinge, die ich immer noch mit dieser Implementierung drehen würde, aber ich würde versuchen, sehr empfehlen, durch zu gehen, was die Bootstrap-Anwendung tut und wie es funktioniert.

Wenn Sie das Verhalten der Benutzeroberfläche während der Installation ändern möchten, müssen Sie sich hier mit dem Code vertraut machen. Sie können neue Seiten hinzufügen, Steuerelemente hinzufügen und Variablen zusammen mit anderen Elementen festlegen.

Wenn dies scheint eine Menge Arbeit (herauszufinden, alles aus mir selbst war definitiv) zu prüfen, ob Sie wirklich brauchen diese Art von Verhalten über das Standardverhalten eines der Standard-Wixstdba Themen.

+0

Vielen Dank für die großartige detaillierte Antwort. Werde es versuchen und aktualisieren wie es für mich ging. Eine Frage allerdings, ich nehme an, nachdem ich das geändert habe, muss ich eine DLL für das selbe erzeugen. Wie schließe ich das im Projekt an (ich verwende VS2012). Fügen Sie für diese DLL einen Verweis auf VS hinzu, muss ich irgendwelche Änderungen in der WXS-Datei vornehmen? Kollidiert dies auch mit der vorhandenen DLL, die für die WixStdBootstrapperApplication vorhanden sein wird? – randomuser15995183

+0

Sie müssen eine neue DLL generieren und Sie können entweder die WIX-Datei ersetzen oder Ihre eigene erstellen, die auf die SourceFile verweist, die Ihre modifizierte DLL ist. Sehen Sie sich diese beiden Dateien an, um zu erfahren, wie Sie Ihren eigenen BA definieren können. https://github.com/wixtoolset/wix3/blob/eaf9325e30a7ee7337a0a04c3fc3980f22136e96/src/ext/BalExtension/wixlib/wixstdba_platform.wxi https://github.com/wixtoolset/wix3/blob/eaf9325e30a7ee7337a0a04c3fc3980f22136e96/src/ext/BalExtension/wixlib/wixstdba.wxs –

+0

Ich versuche, die DLL durch Ändern der Datei, die Sie erwähnten, aber Fehler beim Öffnen der wixstdba.vcxproj-Datei zu machen. Ich habe einen neuen Beitrag dafür erstellt - [hier] (http://stackoverflow.com/questions/37023191/unable-to-build-wixstdbootstrapperapplication-get-error-c-tools-wixbuild-pro) - könntest du ein sieh dir das bitte an. – randomuser15995183

Verwandte Themen