nsis - 在目录页面对话框中设置运行时光标位置 - 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 应该已经为你做这件事了。
从文档:
...如果用户选择“浏览”,则将使用最后一个 \ 后面的字符串部分,并且可能会在安装时附加回字符串(要禁用此功能,请以 \ 结束目录(这将需要用引号括起来的整个参数)。如果这没有任何意义,请稍微使用浏览按钮。
意义,
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
.
推荐阅读
- oracle - Oracle DB 到 Oracle DB Connection Connection forward
- java - Spring Data Elasticsearch 是否支持日期字段的多种日期格式
- django - 带有 Redis 代理和多个队列的 Celery:所有任务都注册到每个队列
- python - 在 python 中迭代 n 行数组,然后是下 n 行,依此类推
- c++ - C++朋友模板函数:找不到函数定义
- java - if语句循环
- c++ - C++ 内联 lambda 参数
- assembly - 为什么没有设置进位标志?
- javascript - 从另一个页面上的触发器加载页面后是否可以执行代码?JS
- websphere-liberty - 在 websphere liberty 中获取数据源连接