Skip to content

Instantly share code, notes, and snippets.

@cremno
Last active August 29, 2015 14:06
Show Gist options
  • Save cremno/083ec0237d94eac148b7 to your computer and use it in GitHub Desktop.
Save cremno/083ec0237d94eac148b7 to your computer and use it in GitHub Desktop.
# ★ BrowseForFolder
# ★★★★★★★★★★★★★
#
# Author/s : cremno
# RGSS ver : 1 to 3
module BrowseForFolder
class BrowseForFolderError < StandardError
end
HWND = Win32API.new('user32', 'GetActiveWindow', 'V', 'L').call
SHBrowseForFolder = Win32API.new('shell32', 'SHBrowseForFolderW', 'P', 'L')
SHGetPathFromIDList =
Win32API.new('shell32', 'SHGetPathFromIDListW', 'LP', 'L')
CoTaskMemFree = Win32API.new('ole32', 'CoTaskMemFree', 'L', 'V')
MultiByteToWideChar =
Win32API.new('kernel32', 'MultiByteToWideChar', 'LLPLPL', 'L')
WideCharToMultiByte =
Win32API.new('kernel32', 'WideCharToMultiByte', 'LLPLPLPP', 'L')
BIF_RETURNONLYFSDIRS = 0x0000_0001
BIF_EDITBOX = 0x0000_0010
BIF_NEWDIALOGSTYLE = 0x0000_0040
BIF_USENEWUI = BIF_EDITBOX | BIF_NEWDIALOGSTYLE
CP_UTF8 = 65_001
MAX_PATH = 260
SIZEOF_WCHAR_T = 2
def self.alloc_buffer(size)
"\0" * size
end
def self.str_to_wcs(str)
len = MultiByteToWideChar.call(CP_UTF8, 0, str, -1, 0, 0)
if len <= 0
fail(BrowseForFolderError, "MultiByteToWideChar returned #{len}")
end
wcs = alloc_buffer(len * SIZEOF_WCHAR_T)
MultiByteToWideChar.call(CP_UTF8, 0, str, -1, wcs, len)
wcs
end
def self.wcs_to_str(wcs)
len = WideCharToMultiByte.call(CP_UTF8, 0, wcs, -1, 0, 0, 0, 0)
if len <= 0
fail(BrowseForFolderError, "WideCharToMultiByte returned #{len}")
end
str = alloc_buffer(len - 1)
WideCharToMultiByte.call(CP_UTF8, 0, wcs, -1, str, len, 0, 0)
str
end
def self.select(title = 'Select a folder:', default_if_cancelled = '')
flags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI
bi = [HWND, 0, 0, str_to_wcs(title), flags, 0, 0, 0].pack('LLLpLLl')
pidlist = SHBrowseForFolder.call(bi)
if pidlist == 0
default_if_cancelled
else
path = alloc_buffer(MAX_PATH * SIZEOF_WCHAR_T)
r = SHGetPathFromIDList.call(pidlist, path)
r == 0 && fail(BrowseForFolderError, "SHGetPathFromIDList returned #{r}")
wcs_to_str(path)
end
ensure
CoTaskMemFree.call(pidlist)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment