在Python中使用TaskDialogIndirect

2024-09-24 00:25:23 发布

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

我想从Python调用WindowsTaskDialogIndirect函数。 它需要TaskDialogConfig(它相当大)结构作为指针传递

下面是我的准备运行示例。它给了我“-2147024809”(参数不正确),我无法找出什么是错误的

Python 3.7.4 x32,Windows 7 x64

import ctypes
from ctypes.wintypes import *

TDF_ALLOW_DIALOG_CANCELLATION = 8
TDCBF_OK_BUTTON = 1

class TaskDialogConfig(ctypes.Structure):
    class DUMMYUNIONNAME(ctypes.Union):
        _fields_ = [
            ('hMainIcon', HICON)
            , ('pszMainIcon', LPCWSTR)
        ]

    class DUMMYUNIONNAME2(ctypes.Union):
        _fields_ = [
            ('hFooterIcon', HICON)
            , ('sFooterIcon', LPCWSTR)
        ]

    class _TASKDIALOG_BUTTON(ctypes.Structure):
        _fields_ = [
            ('nButtonID', INT)
            , ('pszButtonText', LPCWSTR)
        ]

    _fields_ = [
        ('cbSize', UINT)
        , ('hwndParent', HWND)
        , ('hInstance', HINSTANCE)
        , ('dwFlags', UINT)
        , ('dwCommonButtons', UINT)
        , ('pszWindowTitle', LPCWSTR)
        , ('DUMMYUNIONNAME', DUMMYUNIONNAME)
        , ('pszMainInstruction', LPCWSTR)
        , ('pszContent', LPCWSTR)
        , ('cButtons', UINT)
        , ('pButtons', _TASKDIALOG_BUTTON)
        , ('nDefaultButton', INT)
        , ('cRadioButtons', UINT)
        , ('pRadioButtons', _TASKDIALOG_BUTTON)
        , ('nDefaultRadioButton', INT)
        , ('pszVerificationText', LPCWSTR)
        , ('pszExpandedInformation', LPCWSTR)
        , ('pszExpandedControlText', LPCWSTR)
        , ('pszCollapsedControlText', LPCWSTR)
        , ('DUMMYUNIONNAME2', DUMMYUNIONNAME2)
        , ('pszFooter', LPCWSTR)
        , ('pfCallBack', ctypes.POINTER(None))
        , ('lpCallbackData', LPLONG)
        , ('cxWidth', UINT)
    ]

    def __init__(s):
        s.cbSize = ctypes.sizeof(s)

tdi = ctypes.WinDLL('comctl32.dll').TaskDialogIndirect
tdc = TaskDialogConfig()
tdc.hwndParent = None
tdc.hInstance = None
tdc.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION
tdc.dwCommonButtons = TDCBF_OK_BUTTON
tdc.pszWindowTitle = ctypes.c_wchar_p('Title')
tdc.pszMainInstruction = ctypes.c_wchar_p('Main instruction')
tdc.pszContent = ctypes.c_wchar_p('Content')
print( tdi(ctypes.byref(tdc), None, None, None) )

Tags: importnonefieldsbuttonctypesclassintuint
1条回答
网友
1楼 · 发布于 2024-09-24 00:25:23

两个问题

  • CommCtrl.h头使用1字节的压缩。在所有结构中的_pack_ = 1定义之前添加_fields_
  • 两个_TASKDIALOG_BUTTON字段的类型应为ctypes.POINTER(_TASKDIALOG_BUTTON)

我使用一个C程序来打印结构的大小和几个字段的偏移量,并用Python打印了相同的信息,从而找到了这些字段:

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("%zu\n",sizeof(TASKDIALOGCONFIG));
    printf("%zu\n",offsetof(TASKDIALOGCONFIG,pszWindowTitle));
    printf("%zu\n",offsetof(TASKDIALOGCONFIG,pszMainInstruction));
    printf("%zu\n",offsetof(TASKDIALOGCONFIG,pszFooter));
}
tdc = TaskDialogConfig()
print(tdc.cbSize)
print(TaskDialogConfig.pszWindowTitle)
print(TaskDialogConfig.pszMainInstruction)
print(TaskDialogConfig.pszFooter)

相关问题 更多 >