scrollwindowex抛出参数

发布于 2025-01-26 12:52:36 字数 4645 浏览 1 评论 0 原文

我有一个带有一堆按钮的窗口。当按钮超过窗口的高度时,我想拥有一个滚动条,但是当我尝试实现它时,它会抛出参数,但是Windows API表示值可以为null(这就是我在做的)。这是我要谈论的功能:。如果您想在计算机中运行我的代码,这是

”这是错误消息: ctypes.argumentError:参数4:< class'typeError'>:预期rect实例而不是nontype

,这是main.py:

from os import listdir
from user32 import *
from button import Button
from pathlib import Path

hInst = windll.kernel32.GetModuleHandleW(0)
buttons = []

BTN_WIDTH = 300
BTN_HEIGHT = 100
LINES = 28

def window_proc(hwnd: HWND, umsg: UINT, wparam: WPARAM, lparam: LPARAM) -> LRESULT:
    si = SCROLLINFO()
    si_pointer = pointer(si)
    match umsg:
        case WindowMessage.CREATE:
            create_list_of_buttons(get_files(), hwnd)
        case WindowMessage.DESTROY:
            PostQuitMessage(0)
            return 0
        
        case WindowMessage.SIZE:
            height = (HIWORD(lparam))
            width = (LOWORD(lparam))

            si.cbSize = sizeof(si)
            si.fMask = ScrollInfoMessage.RANGE | ScrollInfoMessage.PAGE
            si.nMin = 0
            si.nMax = LINES
            si.nPage = int(height.value) // BTN_HEIGHT;
            SetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer, True)

        case WindowMessage.COMMAND:
            if wparam >= 100:
                btn_clicked = ([button for button in buttons if button.hMenu == wparam])
                filename = btn_clicked[0].btn_text
                print(filename)
        case WindowMessage.VSCROLL:
            si.cbSize = sizeof(si)
            si.fMask = ScrollInfoMessage.ALL
            GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)

            yPos = si.nPos
            print(LOWORD(wparam).value)
            match LOWORD(wparam).value:
                case ScrollBarCommands.LINEUP:
                    si.nPos -= 1
                case ScrollBarCommands.THUMBTRACK:
                    print(si.nPos)
                    si.nPos = si.nTrackPos
                    print(si.nPos)

            si.fMask = ScrollInfoMessage.POS
            SetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer, True)
            GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)
            if(si.nPos != yPos):
                # This line causes the error
                ScrollWindowEx(hwnd, 0, yPos - si.nPos, None, None, None, None, 0x0010)
                UpdateWindow(hwnd)

    return DefWindowProcW(hwnd, umsg, wparam, lparam)


def create_window(className, windowName):
    wnd_main = CreateWindowExW(
        0,
        className,
        windowName,
        WindowStyles.OVERLAPPED
        | WindowStyles.CAPTION
        | WindowStyles.SYSMENU
        | WindowStyles.THICKFRAME
        | WindowStyles.MINIMIZEBOX
        | WindowStyles.MAXIMIZEBOX
        | WindowStyles.CAPTION
        | WindowStyles.VSCROLL,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        600,
        600,
        0,
        0,
        hInst,
        0,
    )
    if not wnd_main:
        print("Window Creation Falid: ", GetLastError())
        return
    return wnd_main


def get_files():
    folder_path = Path(__file__).parent / "log"
    return [file for file in listdir(folder_path) if file.endswith(".txt")]

def create_list_of_buttons(filenames: list[str], parent_window):
    """
    Makes a list of button that have the file's name as their heading
    """
    x, y = 0, 0
    for button_id, filename in enumerate(filenames, 100):
        button = Button(filename, x, y, BTN_WIDTH, BTN_HEIGHT, parent_window, button_id)
        button.create_button()
        buttons.append(button)
        y += BTN_HEIGHT

    return buttons




def main():
    wclassName = ctypes.c_wchar_p("My")
    wname = ctypes.c_wchar_p("Left")
    wndClass = WNDCLASSEXW()
    wndClass.cbSize = sizeof(WNDCLASSEXW)
    wndClass.style = ClassStyles.HREDRAW | ClassStyles.VREDRAW
    wndClass.lpfnWndProc = WNDPROC(window_proc)
    wndClass.cbClsExtra = 0
    wndClass.cbWndExtra = 0
    wndClass.hInstance = hInst
    wndClass.hIcon = 0
    wndClass.hCursor = 0
    wndClass.hBrush = windll.gdi32.GetStockObject(0)
    wndClass.lpszMenuName = 0
    wndClass.lpszClassName = wclassName
    wndClass.hIconSm = 0

    RegisterClassExW(byref(wndClass))
    wnd_main = create_window(wclassName, wname)
    ShowWindow(wnd_main, 5)
    UpdateWindow(wnd_main)

    msg = MSG()
    lpmsg = pointer(msg)

    while (GetMessageW(lpmsg, 0, 0, 0)) != 0:
        TranslateMessage(lpmsg)
        DispatchMessageW(lpmsg)


main()

I have a window that has a bunch of buttons. When the buttons exceed the window's height, I want to have a scroll bar, but when I tried to implement it, it threw ArgumentError, but the Windows API says that values can be Null (that is what I am doing). This is the function I am talking about: ScrollWindowEx. If you want to run my code in your machine, this is user32.py

Edit: This is the error message: ctypes.ArgumentError: argument 4: <class 'TypeError'>: expected RECT instance instead of NoneType

And this is main.py:

from os import listdir
from user32 import *
from button import Button
from pathlib import Path

hInst = windll.kernel32.GetModuleHandleW(0)
buttons = []

BTN_WIDTH = 300
BTN_HEIGHT = 100
LINES = 28

def window_proc(hwnd: HWND, umsg: UINT, wparam: WPARAM, lparam: LPARAM) -> LRESULT:
    si = SCROLLINFO()
    si_pointer = pointer(si)
    match umsg:
        case WindowMessage.CREATE:
            create_list_of_buttons(get_files(), hwnd)
        case WindowMessage.DESTROY:
            PostQuitMessage(0)
            return 0
        
        case WindowMessage.SIZE:
            height = (HIWORD(lparam))
            width = (LOWORD(lparam))

            si.cbSize = sizeof(si)
            si.fMask = ScrollInfoMessage.RANGE | ScrollInfoMessage.PAGE
            si.nMin = 0
            si.nMax = LINES
            si.nPage = int(height.value) // BTN_HEIGHT;
            SetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer, True)

        case WindowMessage.COMMAND:
            if wparam >= 100:
                btn_clicked = ([button for button in buttons if button.hMenu == wparam])
                filename = btn_clicked[0].btn_text
                print(filename)
        case WindowMessage.VSCROLL:
            si.cbSize = sizeof(si)
            si.fMask = ScrollInfoMessage.ALL
            GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)

            yPos = si.nPos
            print(LOWORD(wparam).value)
            match LOWORD(wparam).value:
                case ScrollBarCommands.LINEUP:
                    si.nPos -= 1
                case ScrollBarCommands.THUMBTRACK:
                    print(si.nPos)
                    si.nPos = si.nTrackPos
                    print(si.nPos)

            si.fMask = ScrollInfoMessage.POS
            SetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer, True)
            GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)
            if(si.nPos != yPos):
                # This line causes the error
                ScrollWindowEx(hwnd, 0, yPos - si.nPos, None, None, None, None, 0x0010)
                UpdateWindow(hwnd)

    return DefWindowProcW(hwnd, umsg, wparam, lparam)


def create_window(className, windowName):
    wnd_main = CreateWindowExW(
        0,
        className,
        windowName,
        WindowStyles.OVERLAPPED
        | WindowStyles.CAPTION
        | WindowStyles.SYSMENU
        | WindowStyles.THICKFRAME
        | WindowStyles.MINIMIZEBOX
        | WindowStyles.MAXIMIZEBOX
        | WindowStyles.CAPTION
        | WindowStyles.VSCROLL,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        600,
        600,
        0,
        0,
        hInst,
        0,
    )
    if not wnd_main:
        print("Window Creation Falid: ", GetLastError())
        return
    return wnd_main


def get_files():
    folder_path = Path(__file__).parent / "log"
    return [file for file in listdir(folder_path) if file.endswith(".txt")]

def create_list_of_buttons(filenames: list[str], parent_window):
    """
    Makes a list of button that have the file's name as their heading
    """
    x, y = 0, 0
    for button_id, filename in enumerate(filenames, 100):
        button = Button(filename, x, y, BTN_WIDTH, BTN_HEIGHT, parent_window, button_id)
        button.create_button()
        buttons.append(button)
        y += BTN_HEIGHT

    return buttons




def main():
    wclassName = ctypes.c_wchar_p("My")
    wname = ctypes.c_wchar_p("Left")
    wndClass = WNDCLASSEXW()
    wndClass.cbSize = sizeof(WNDCLASSEXW)
    wndClass.style = ClassStyles.HREDRAW | ClassStyles.VREDRAW
    wndClass.lpfnWndProc = WNDPROC(window_proc)
    wndClass.cbClsExtra = 0
    wndClass.cbWndExtra = 0
    wndClass.hInstance = hInst
    wndClass.hIcon = 0
    wndClass.hCursor = 0
    wndClass.hBrush = windll.gdi32.GetStockObject(0)
    wndClass.lpszMenuName = 0
    wndClass.lpszClassName = wclassName
    wndClass.hIconSm = 0

    RegisterClassExW(byref(wndClass))
    wnd_main = create_window(wclassName, wname)
    ShowWindow(wnd_main, 5)
    UpdateWindow(wnd_main)

    msg = MSG()
    lpmsg = pointer(msg)

    while (GetMessageW(lpmsg, 0, 0, 0)) != 0:
        TranslateMessage(lpmsg)
        DispatchMessageW(lpmsg)


main()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文