2016-11-23 4 views
0

NSIS SelectFolderDialogでは、HDDのみでツリーを何とか表示できますか?私は、ユーザーがHDDにないディレクトリを選択するのを制限する必要があります。特定のドライブを持つNSIS SelectFolderDialog

+0

別のアプローチは、ユーザーがあなたに受け入れられないものを選択した場合、[OK]ボタンを無効にするのですか?ネットワークのものではない?具体的にはフロッピーやcdrwを除くローカルハードドライブですか? – Anders

+0

また、Vista上でネットワーク上の場所を示すHDDにシンボリックリンクを作成することもできます。 – Anders

+0

はい、フロッピー、cdrwなどローカルのハードドライブのみです。 – Erlas

答えて

0

どの項目が存在するかを完全に制御するには、SHBrowseForFolderを呼び出して、IFolderFilterSiteの実装を提供するカスタムNSISプラグインを作成する必要があります。あなたはHDDで、正確に何を意味する

!include LogicLib.nsh 

!ifndef DRIVE_FIXED 
!define DRIVE_FIXED 3 
!endif 
; This function decides which items are acceptable 
Function MyFolderValidator ; Input: $1=PIDL, $2=Path Output:$0=0 if invalid 
System::Call 'KERNEL32::GetVolumePathName(tr2, t.r4, i ${NSIS_MAX_STRLEN})i.r5' 
${If} $5 <> 0 
    StrCpy $2 $4 
${ElseIf} $5 == "error" ; GetVolumePathName is Win2000+ 
    StrCpy $2 $2 3 ; GetDriveType only accepts root paths (This will not work for UNC) 
${EndIf} 
System::Call 'KERNEL32::GetDriveType(tr2)i.r3' 
${If} $3 = ${DRIVE_FIXED} 
    StrCpy $0 1 ; Allow this path 
${Else} 
    StrCpy $0 0 ; Don't allow this path 
${EndIf} 
FunctionEnd 

!include WinMessages.nsh 
!define /math BFFM_ENABLEOK ${WM_USER} + 101 
!define BFFM_SELCHANGED 2 
!define BFFM_VALIDATEFAILEDA 3 
!define BFFM_VALIDATEFAILEDW 4 
!if "${NSIS_CHAR_SIZE}" > 1 
!define BFFM_VALIDATEFAILED ${BFFM_VALIDATEFAILEDW} 
!else 
!define BFFM_VALIDATEFAILED ${BFFM_VALIDATEFAILEDA} 
!endif 
!if "${NSIS_PTR_SIZE}" <= 4 
Function BrowseForValidatedFolder ; NSIS 2.51+ 
System::Store S 
Pop $2 ; HeadingText 
Pop $1 ; ValidatorFunc 
System::Get "(p.R1, i.R2, p.R3, p)i R8R8" ; BFFCALLBACK 
Pop $R9 ; The system plug-in callback function 
StrCpy $4 "kR9" ; SHBrowseForFolder callback parameter 
System::Call '*(&t261 "")p.r7' ; pszDisplayName buffer 
System::Call '*(p $hwndparent, p0, pr7, t r2, i 0x51, $4, p0, i)p.r8' ; BROWSEINFO struct 
!if "${NSIS_CHAR_SIZE}" > 1 
System::Call 'SHELL32::SHBrowseForFolderW(pr8)p.r9' 
!else 
System::Call 'SHELL32::SHBrowseForFolderA(pr8)p.r9' 
!endif 
BFFCALLBACK_loop: 
    StrCpy $R8 $R8 8 ; HACKHACK: Working around 2.x bug where the callback IDs are never released 
    StrCmp $R8 "callback" 0 BFFCALLBACK_done 
    ${If} $R2 = ${BFFM_SELCHANGED} 
    ${AndIf} $R3 P<> 0 
     System::Store S 
     StrCpy $0 $1 
     StrCpy $1 $R3 
     System::Call 'SHELL32::SHGetPathFromIDList(p $R3, t.r2)' 
     Call $0 
     SendMessage $R1 ${BFFM_ENABLEOK} 0 $0 
     System::Store L 
    ${EndIf} 
    StrCpy $R8 0 ; Yep, the return value is in the same place as the callback id 
    ${IfThen} $R2 = ${BFFM_VALIDATEFAILED} ${|} StrCpy $R8 1 ${|} ; Keep the dialog open 
    System::Call $R9 
    goto BFFCALLBACK_loop 
BFFCALLBACK_done: 
System::Free $R9 ; BFFCALLBACK 
System::Free $7 ; pszDisplayName 
System::Free $8 ; BROWSEINFO 
${If} $9 Z<> 0 
    System::Call 'SHELL32::SHGetPathFromIDList(p r9, t.s)i' 
    System::Call 'OLE32::CoTaskMemFree(p r9)' 
${Else} 
    Push "" ; Error/cancel, return empty string 
${EndIf} 
System::Store L 
FunctionEnd 
!endif 
!macro BrowseForValidatedFolder HeadingText ValidatorFuncName VarResult 
GetFunctionAddress ${VarResult} ${ValidatorFuncName} 
Push ${VarResult} 
Push "${HeadingText}" 
Call BrowseForValidatedFolder 
Pop ${VarResult} 
!macroend 

Section 
!insertmacro BrowseForValidatedFolder "Choose a location for blah blah" MyFolderValidator $0 
${If} $0 != "" 
    MessageBox mb_ok "Result: $0" 
${Else} 
    MessageBox mb_iconstop "User cancelled" 
${EndIf} 
SectionEnd 
関連する問題