NSIS PageEx自定义页调用HandleFileDragDrop拖拽功能失效问题
问题根源
你的拖拽失效是三个代码错误共同导致的,和PageEx本身无关:
- 控件句柄获取错误:你通过
FindWindow $1 "#32770" "" $HWNDPARENT查找的是外层安装向导窗口,不是InstallOptions生成的自定义页面子窗口,后续取0x3FB控件根本不是当前页面里FileRequest的输入框,拖拽注册到了错误的窗口上。 - 缺少拖拽回调函数:
HandleFileDragDrop::Register的第二个参数需要传入拖拽完成后的处理函数名,你传了空字符串,就算拖拽到正确控件上,插件也无法把获取到的文件路径回填到输入框。 - 逻辑笔误:证书分区ID是
SEC0000,你在leaveBasic页面离开回调里判断的是SEC0001,会导致证书选择校验逻辑完全不触发。
修复方案
按以下步骤修改代码即可:
- 新增拖拽事件处理函数,用于把拖拽得到的证书路径回填到输入框、同步更新InstallOptions的配置值
- 修正控件句柄获取逻辑,在InstallOptions对话框初始化完成后,拿到FileRequest对应的输入框真实句柄再注册拖拽
- 修正分区ID笔误,页面离开时反注册拖拽避免内存泄漏
修正后的完整代码片段
// 先定义拖拽处理函数,放在creatorBasic函数前面即可 Function OnCertDrop Pop $0 # 弹出拖拽的文件总数 Pop $1 # 弹出第一个拖拽文件的完整路径 # 把路径写入FileRequest输入框 !insertmacro MUI_INSTALLOPTIONS_SEND "Certification.ini" 2 ${WM_SETTEXT} 0 "STR:$1" # 同步更新ini配置,保证页面离开时能读到选中的路径 WriteINIStr "$PLUGINSDIR\Certification.ini" "Field 2" "State" "$1" FunctionEnd // Page Part !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_COMPONENTS PageEx custom PageCallBacks creatorBasic leaveBasic PageExEnd !insertmacro MUI_LANGUAGE "Korean" // Install Part Function .onInit InitPluginsDir !insertmacro MUI_INSTALLOPTIONS_EXTRACT "Certification.ini" IntOp $0 ${SF_SELECTED} | ${SF_RO} SectionSetFlags 0 $0 FunctionEnd // Section Part Section "Certification" SEC0000 SetOutPath "$INSTDIR" SectionIn 1 Push $CERTIFICATION Call AddCertificateToStore Pop $0 ${If} $0 != success MessageBox MB_OK "Certification Install Fail : $0" ${EndIf} SetOverwrite on SectionEnd // Page Create Function creatorBasic ${IF} ${SectionIsSelected} ${SEC0000} !insertmacro MUI_HEADER_TEXT "Cert install" "Please Select install certification." !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "Certification.ini" Pop $IO_HWND # 取出当前InstallOptions页面的窗口句柄 // 注册拖拽:Field 2是FileRequest,对应输入框控件ID为1000+字段序号=1002 GetDlgItem $1 $IO_HWND 1002 HandleFileDragDrop::Register $1 "OnCertDrop" !insertmacro MUI_INSTALLOPTIONS_SHOW ${EndIf} abort FunctionEnd // Page leave Function leaveBasic # 离开页面先反注册拖拽 HandleFileDragDrop::UnRegister !insertmacro MUI_INSTALLOPTIONS_READ $CERTIFICATION "Certification.ini" "Field 2" "State" # 修正笔误:SEC0001改为SEC0000 ${IF} ${SectionIsSelected} ${SEC0000} StrCmp $CERTIFICATION "" 0 +2 MessageBox MB_OK "Please Select Cert." IDOK abort IfFileExists $CERTIFICATION found MessageBox MB_OK "Not exist Cert." IDOK abort goto abort found: goto done ${EndIf} goto done abort: Abort done: FunctionEnd
说明:InstallOptions生成的页面中,每个字段对应的控件ID规则为
1000 + 字段序号,FileRequest类型的字段会生成一个编辑框+浏览按钮,其中编辑框ID符合上述规则,浏览按钮ID为1000 + 字段序号 + 0x400,直接注册拖拽到编辑框即可。
内容的提问来源于stack exchange,提问作者Seongtaek OH
相关产品推荐
相关产品推荐

