ScrollWindowex无法正确滚动窗口。 [Windows API]
我有一个带有一堆的窗口,当按钮超过窗口高度时,我想使用滚动条。问题在于,当我使用scrollwindowex时,它会将东西移动。确切地说,最后一个按钮的高度不断增加,并隐藏了应该显示的按钮。当我悬停在按钮上时,新按钮会在窗口中呈现。我不确定是什么原因导致这种行为。以前有人告诉我阅读“ Noreferrer”>“ Noreferrer”>文档,我做到了。我不确定他们在段落中到底指的是什么。我猜这是备注部分中的第三段,它告诉使用deferwindowpos,但我不确定是否应该使用它。请帮助我,因为我必须使其适用于学校项目:)
为了运行代码,您还需要 user32.py
这是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 = height * 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)
rect = RECT()
rect_p = pointer(rect)
print(GetClientRect(hwnd, rect_p))
print(rect.top, rect.bottom, rect.left, rect.right)
case WindowMessage.VSCROLL:
si.cbSize = sizeof(si)
si.fMask = ScrollInfoMessage.ALL
GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)
yPos = si.nPos
match LOWORD(wparam).value:
case ScrollBarCommands.LINEUP:
si.nPos -= 1
case ScrollBarCommands.TOP:
si.nPos = si.nMin
case ScrollBarCommands.BOTTOM:
si.nPos = si.nMax
case ScrollBarCommands.LINEUP:
si.nPos -= 1
case ScrollBarCommands.LINEDOWN:
si.nPos += 1
case ScrollBarCommands.PAGEUP:
si.nPos -= si.nPage
case ScrollBarCommands.PAGEDOWN:
si.nPos += si.nPage
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):
ScrollWindowEx(hwnd, 0, (yPos - si.nPos), None, None, None, None, 0x0001)
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 and I want to use a scrollbar when the buttons exceed the height of the window. The problem is that when I use ScrollWindowEx, it kind of moves stuff up. Precisely, the last button's height keeps on increasing and hides the buttons that are supposed to show up . When I hover over the buttons, the new buttons render in the window. I am not sure what is causing that behavior. Someone previously told me to read the remarks from the documentation, which I did. I am not sure what exactly they were referring to in the paragraph. I am guessing it's the third paragraph in the remarks section that tells to use DeferWindowPos, but I am not sure if am supposed to use that. Please help me, as I have to make it work for a school project :)
In order to run the code, you will also need user32.py
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 = height * 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)
rect = RECT()
rect_p = pointer(rect)
print(GetClientRect(hwnd, rect_p))
print(rect.top, rect.bottom, rect.left, rect.right)
case WindowMessage.VSCROLL:
si.cbSize = sizeof(si)
si.fMask = ScrollInfoMessage.ALL
GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)
yPos = si.nPos
match LOWORD(wparam).value:
case ScrollBarCommands.LINEUP:
si.nPos -= 1
case ScrollBarCommands.TOP:
si.nPos = si.nMin
case ScrollBarCommands.BOTTOM:
si.nPos = si.nMax
case ScrollBarCommands.LINEUP:
si.nPos -= 1
case ScrollBarCommands.LINEDOWN:
si.nPos += 1
case ScrollBarCommands.PAGEUP:
si.nPos -= si.nPage
case ScrollBarCommands.PAGEDOWN:
si.nPos += si.nPage
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):
ScrollWindowEx(hwnd, 0, (yPos - si.nPos), None, None, None, None, 0x0001)
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论