Skip to content

Instantly share code, notes, and snippets.

@cremno

cremno/browseforfolder.rb

Last active Aug 29, 2015
Embed
What would you like to do?
# ★ 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
You can’t perform that action at this time.