AHK自带的命令中,FileSelectFile只能选择文件。FileSelectFolder可以选择文件夹,但是样式老旧太丑了。

以下的SelectFolderEx函数就是用来解决这个问题:

SelectFolder := SelectFolderEx( A_Desktop, "标题栏名称" , 0, "选择文件夹按钮名称" )

Msgbox % SelectFolder

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=18939 
SelectFolderEx(StartingFolder := "", Prompt := "", OwnerHwnd := 0, OkBtnLabel := "") {
  Static OsVersion := DllCall("GetVersion", "UChar")
    , IID_IShellItem := 0
    , InitIID := VarSetCapacity(IID_IShellItem, 16, 0)
            & DllCall("Ole32.dll\IIDFromString", "WStr", "{43826d1e-e718-42ee-bc55-a1e261c37bfe}", "Ptr", &IID_IShellItem)
    , Show := A_PtrSize * 3
    , SetOptions := A_PtrSize * 9
    , SetFolder := A_PtrSize * 12
    , SetTitle := A_PtrSize * 17
    , SetOkButtonLabel := A_PtrSize * 18
    , GetResult := A_PtrSize * 20
  SelectedFolder := ""
  If (OsVersion < 6) { ; Vista+系统以下, 则恢复使用FileSelectFolder
    FileSelectFolder, SelectedFolder, *%StartingFolder%, 3, %Prompt%
    Return SelectedFolder
  }
  OwnerHwnd := DllCall("IsWindow", "Ptr", OwnerHwnd, "UInt") ? OwnerHwnd : 0
  If !(FileDialog := ComObjCreate("{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}", "{42f85136-db7e-439c-85f1-e4075d135fc8}"))
    Return ""
  VTBL := NumGet(FileDialog + 0, "UPtr")
  ; FOS_CREATEPROMPT | FOS_NOCHANGEDIR | FOS_PICKFOLDERS
  DllCall(NumGet(VTBL + SetOptions, "UPtr"), "Ptr", FileDialog, "UInt", 0x00002028, "UInt")
  If (StartingFolder <> "")
    If !DllCall("Shell32.dll\SHCreateItemFromParsingName", "WStr", StartingFolder, "Ptr", 0, "Ptr", &IID_IShellItem, "PtrP", FolderItem)
      DllCall(NumGet(VTBL + SetFolder, "UPtr"), "Ptr", FileDialog, "Ptr", FolderItem, "UInt")
  If (Prompt <> "")
    DllCall(NumGet(VTBL + SetTitle, "UPtr"), "Ptr", FileDialog, "WStr", Prompt, "UInt")
  If (OkBtnLabel <> "")
    DllCall(NumGet(VTBL + SetOkButtonLabel, "UPtr"), "Ptr", FileDialog, "WStr", OkBtnLabel, "UInt")
  If !DllCall(NumGet(VTBL + Show, "UPtr"), "Ptr", FileDialog, "Ptr", OwnerHwnd, "UInt") {
    If !DllCall(NumGet(VTBL + GetResult, "UPtr"), "Ptr", FileDialog, "PtrP", ShellItem, "UInt") {
      GetDisplayName := NumGet(NumGet(ShellItem + 0, "UPtr"), A_PtrSize * 5, "UPtr")
      If !DllCall(GetDisplayName, "Ptr", ShellItem, "UInt", 0x80028000, "PtrP", StrPtr) ; SIGDN_DESKTOPABSOLUTEPARSING
        SelectedFolder := StrGet(StrPtr, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "Ptr", StrPtr)
      ObjRelease(ShellItem)
  }  }
  If (FolderItem)
    ObjRelease(FolderItem)
  ObjRelease(FileDialog)
  Return SelectedFolder
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。