在目录页面对话框中设置 运行-time 光标位置 - NSIS

Set run-time cursor position in directory page dialog box - NSIS

我想在路径末尾添加我的应用程序的安装文件夹名称。我点了浏览按钮就成功了,但是试探了很多次,直接在文本框里修改文本就不行了。

Function .onVerifyInstDir
    Push [=11=]
        FindWindow [=11=] "#32770" "" $HWNDPARENT
        GetDlgItem [=11=] [=11=] 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 [=11=] ${EM_GETSEL} null 
          SendMessage [=11=] ${WM_SETTEXT} 0 "STR:$INSTDIR"
    SendMessage [=11=] ${EM_SETSEL}  
FunctionEnd

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

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

StrCpy $INSTDIR "$APPDATA${APP_FOLDER_NAME}"

NSIS 应该已经为您完成了。

来自文档:

... the part of this string following the last \ will be used if the user selects 'browse', and may be appended back on to the string at install time (to disable this, end the directory with a \ (which will require the entire parameter to be enclosed with quotes). If this doesn't make any sense, play around with the browse button a bit.

意义,

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 [=12=] $mui.DirectoryPage.Directory
!else
    FindWindow [=12=] "#32770" "" $hWndParent
    GetDlgItem [=12=] [=12=] 0x3FB
!endif

    System::Call 'USER32::GetActiveWindow()p.r2'
    System::Call 'USER32::GetFocus()p.r1'
    ${If}  P<> [=12=] 
        ${If} $hWndParent P<> 
            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 [=12=] ${EM_GETSEL} "" "" 
        IntOp   >> 16    ; shift hiword
        IntOp   & 0xffff ; mask possible sign bit
        SendMessage [=12=] ${WM_SETTEXT} 0 "STR:$INSTDIR"
        SendMessage [=12=] ${EM_SETSEL}  
        StrCpy $InOnVerifyInstDir 0
    ${EndIf}
FunctionEnd

但我仍然建议只使用 InstallDir