首页 > 解决方案 > 在目录页面对话框中设置运行时光标位置 - NSIS

问题描述

我想在路径的末尾添加我的应用程序的安装文件夹名称。单击“浏览”按钮后我成功了,但是经过多次尝试,如果我直接在文本框中修改文本,我就无法做到。

Function .onVerifyInstDir
    Push $0
        FindWindow $0 "#32770" "" $HWNDPARENT
        GetDlgItem $0 $0 0x3FB
    ;in alternative for MUI >2.0 I could use directly $mui.DirectoryPage.Directory. Is it right?

    ;does path end with "\MyApp"?
    StrLen $R1 "\${APP_FOLDER_NAME}"
    StrCpy $R0 $INSTDIR "" -$R1
    StrCmp $R0 "\${APP_FOLDER_NAME}" +2

        ;add "\MyApp" after browse button clicking (OK)
    StrCpy $INSTDIR "$INSTDIR\${APP_FOLDER_NAME}"

        ;add "\MyApp" after typing directly into the textbox but the cursor position reset to the first character. Tried to solve saving the current cursor position and then reapply it (NOK)
        SendMessage $0 ${EM_GETSEL} null $1
          SendMessage $0 ${WM_SETTEXT} 0 "STR:$INSTDIR"
    SendMessage $0 ${EM_SETSEL} $1 $1
FunctionEnd

我没有成功地维护我正在修改路径字符串的光标,它总是重置为第一个字符。

在安装过程的前一个阶段,我初始化安装路径如下

StrCpy $INSTDIR "$APPDATA\${APP_FOLDER_NAME}"

标签: nsis

解决方案


NSIS 应该已经为你做这件事了。

从文档:

...如果用户选择“浏览”,则将使用最后一个 \ 后面的字符串部分,并且可能会在安装时附加回字符串(要禁用此功能,请以 \ 结束目录(这将需要用引号括起来的整个参数)。如果这没有任何意义,请稍微使用浏览按钮。

意义,

InstallDir "$ProgramFiles\MyApp"

不一样

InstallDir "$ProgramFiles\MyApp\"

官方不支持设置文本,.onVerifyInstDir但此代码有些工作:

!define APP_FOLDER_NAME MyApp
Page Directory
Page InstFiles

!include WinMessages.nsh
!include LogicLib.nsh

Function .onInit
StrCpy $INSTDIR "$APPDATA\${APP_FOLDER_NAME}"
FunctionEnd

Var InOnVerifyInstDir
Var SeenModal

Function .onVerifyInstDir
${IfThen} $InOnVerifyInstDir <> 0 ${|} Return ${|} ; Don't recurse into .onVerifyInstDir
!if ${MUI_SYSVERSION} >= 2.0
    StrCpy $0 $mui.DirectoryPage.Directory
!else
    FindWindow $0 "#32770" "" $hWndParent
    GetDlgItem $0 $0 0x3FB
!endif

    System::Call 'USER32::GetActiveWindow()p.r2'
    System::Call 'USER32::GetFocus()p.r1'
    ${If} $1 P<> $0 
        ${If} $hWndParent P<> $2
            StrCpy $SeenModal 1
            Return
        ${EndIf}
        ${If} $SeenModal = 0
            Return
        ${EndIf}
    ${EndIf}
    StrCpy $SeenModal ""

    ;does path end with "\MyApp"?
    StrLen $R1 "\${APP_FOLDER_NAME}"
    StrCpy $R0 $INSTDIR "" -$R1
    ${If} $R0 != "\${APP_FOLDER_NAME}"
        StrCpy $InOnVerifyInstDir 1
        StrCpy $INSTDIR "$INSTDIR\${APP_FOLDER_NAME}"
        SendMessage $0 ${EM_GETSEL} "" "" $1
        IntOp $1 $1 >> 16    ; shift hiword
        IntOp $1 $1 & 0xffff ; mask possible sign bit
        SendMessage $0 ${WM_SETTEXT} 0 "STR:$INSTDIR"
        SendMessage $0 ${EM_SETSEL} $1 $1
        StrCpy $InOnVerifyInstDir 0
    ${EndIf}
FunctionEnd

但我仍然建议只使用InstallDir.


推荐阅读