使用windowsapi从Python创建choose folderdialog

2024-10-01 04:59:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从Python创建一个选择文件夹对话框,但是在设置对话框的初始文件夹路径时遇到问题。我认为在设置_BROWSEINFO结构时,将字符串转换为LPARAM是个问题。在

bi.lParam = cast(path.encode("ascii", "ignore"), POINTER(LPARAM)).contents

我在回叫中收到这个错误:

^{pr2}$

下面是我使用的代码,除了调用sendmagesa之外,它似乎运行得很好。在

我在browse_folder中设置_BROWSEINFO结构

_WM_USER = 0x400
_BFFM_INITIALIZED = 1
_BFFM_SETSELECTIONA = _WM_USER + 102
_BFFM_SETSELECTIONW = _WM_USER + 103
_BIF_RETURNONLYFSDIRS = 0x00000001
_BIF_NEWDIALOGSTYLE = 0x00000040
_BFFCALLBACK = WINFUNCTYPE(None, HWND, UINT, LPARAM, LPARAM)

def _browse_callback(handle, umsg, lparam, lpdata):
    if(umsg == _BFFM_INITIALIZED):
        if(lpdata is not None):
            windll.user32.SendMessageA(handle, _BFFM_SETSELECTIONA, 1, lpdata)
    return 0

class _SHITEMID(Structure):
    _fields_ = [
                ("cb", USHORT),
                ("abID", BYTE)]

class _ITEMIDLIST(Structure):
    _fields_ = [
                ("mkid", POINTER(_SHITEMID))]

class _BROWSEINFO(Structure):
    _fields_ = [
                ("hwndOwner", HWND),
                ("pidlRoot", UINT),
                ("pszDisplayName", LPCSTR),
                ("lpszTitle", LPCSTR),
                ("ulFlags", UINT),
                ("lpfn", _BFFCALLBACK),
                ("lParam", LPARAM),
                ("iImage", INT)]

def browse_folder(path, message):
    display_name = create_string_buffer(MAX_PATH)
    end_path = create_string_buffer(MAX_PATH)

    pidl_root =  _ITEMIDLIST()

    bi = _BROWSEINFO()
    bi.hwndOwner = 0
    bi.pidlRoot = 0
    bi.pszDisplayName = addressof(display_name)
    bi.lpszTitle = message.encode("ascii", "ignore")
    bi.ulFlags = _BIF_RETURNONLYFSDIRS | _BIF_NEWDIALOGSTYLE
    bi.lpfn = _BFFCALLBACK(_browse_callback)
    bi.lParam = cast(path.encode("ascii", "ignore"), POINTER(LPARAM)).contents
    bi.iImage = 0

    pidl = windll.shell32.SHBrowseForFolder(addressof(bi))
    print(display_name.value)
    windll.shell32.SHGetPathFromIDList(pidl, addressof(end_path))
    print(repr(end_path.value))

Tags: pathasciiencodeignorebiwmbrowseuser
1条回答
网友
1楼 · 发布于 2024-10-01 04:59:00

我切换到unicode和注释建议的宽字符类型。在

问题是将其转换为LPARAM,然后取消引用,但是这些注释将我引向LPARAM上的方法from_buffer。在

我设置lParam如下:

bi.lParam = LPARAM.from_buffer(c_wchar_p(path))

相关问题 更多 >