问题描述
这里记录了这一点
Why is my MFC application hanging after interacting with both scroll-bars?
所以,我已经取消了对 ScrollWindowEx 的调用,现在我可以毫无问题地移动我的滚动条,但是当我放开滚动条时,窗口及其所有子项只会被绘制在新位置。
当按住滚动条时,我的整个程序似乎停顿并卡在消息循环中。如果我们可以强制滚动条附加到的窗口更新,这不是问题。但我该怎么做?
我已经试过了
UpdateWindow(pPane);
RedrawWindow(pPane,NULL,RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_ERASE | RDW_INTERNALPAINT | RDW_UPDATENow);
它确实更新和重绘 - 你可以看到故障 - 但它会在上次留下的位置重绘它。不是滚动条的新位置会设置它的位置。
我打电话
SetScrollInfo(...)
参数正确,否则无法正常工作
如何在按住滚动条的同时使用正确的参数重绘窗口及其子窗口?
这是我的滚动消息处理程序
case WM_VSCROLL:
{
int iVScrollPos;
SCROLLINFO vsi;
ZeroMemory(&vsi,sizeof(SCROLLINFO));
vsi.cbSize=sizeof(SCROLLINFO);
vsi.fMask=SIF_ALL;
GetScrollInfo(hWnd,SB_VERT,&vsi);
iVScrollPos=vsi.nPos;
switch(LOWORD(wParam))
{
case SB_LINEUP:
if(vsi.nPos>vsi.nMin)
vsi.nPos=vsi.nPos-10;
break;
case SB_PAGEUP:
vsi.nPos = vsi.nPos - vsi.nPage;
break;
case SB_LINEDOWN:
if(vsi.nPos<vsi.nMax)
vsi.nPos=vsi.nPos+10;
break;
case SB_PAGEDOWN:
vsi.nPos = vsi.nPos + vsi.nPage;
break;
case SB_THUMBTRACK:
vsi.nPos=vsi.nTrackPos;
break;
}
vsi.nMin=0;
vsi.nMax=pOW->dialogysize;
vsi.nPage=sy;
SetScrollInfo(hWnd,&vsi,TRUE);
GetScrollInfo(hWnd,&vsi);
if(vsi.nPos != iVScrollPos)
{
RedrawWindow(hWnd,RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_ERASE | RDW_INTERNALPAINT | RDW_UPDATENow);
}
当您移动滚动条时,窗口会重新绘制,但在您将鼠标按住滚动条时的位置相同。它仅在您松开鼠标按钮时更新位置。
谢谢
肖恩
编辑 - 我创建了一个重现行为的示例。请注意,我们有一个单独的窗口类来保存多个编辑窗口。我还没有在这个演示中处理 WM_SIZE 和 WM_MOVE 消息,但代码应该可以按原样处理窗口。
如果定义了 USESCROLL 并且您上下移动滚动条,它会导致 DesktopWindowManager 中的锁定
如果 USESCROLL 没有被注释,那么结构中的 trackPos 仍然会更新并且我调用 reDrawWindow,但是当我滚动滚动条时子编辑窗口不会移动。
因为我不想被锁定,请问如何让他们移动?
再次感谢
肖恩
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WParaM wParam,LParaM lParam);
LRESULT CALLBACK PaneProc(HWND hwnd,LParaM lParam);
int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE,PWSTR pCmdLine,int nCmdshow)
{
// Register the window class.
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = "Class";
RegisterClass(&wc);
wc.lpfnWndProc = PaneProc;
wc.hInstance = hInstance;
wc.lpszClassName = "Pane";
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0,// Optional window styles.
(LPCSTR)"Class",// Window class
(LPCSTR)"Test",// Window text
WS_OVERLAPPEDWINDOW| WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | WS_THICKFRAME | WS_SYSMENU,// Window style
200,200,400,hInstance,NULL);
if (hwnd == NULL)
{
return 0;
}
HWND hwndPane = CreateWindowEx(
0,// Optional window styles.
(LPCSTR)"Pane",// Window text
WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_VSCROLL,// Window style
220,220,hwnd,NULL);
if (hwndPane == NULL)
{
return 0;
}
for(int i=0;i<200;i++)
{
HWND eb = CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("Edit"),ES_AUTOHSCROLL | WS_CHILD| WS_VISIBLE,16,16+24*i,64,24,hwndPane,(HMENU)i+10000,NULL);
char tmp[64];
sprintf(tmp,"%d",i);
SetwindowText(eb,tmp);
}
ShowWindow(hwnd,nCmdshow);
ShowWindow(hwndPane,nCmdshow);
// Run the message loop.
while(1)
{
MSG msg = { };
while (PeekMessage(&msg,PM_REMOVE))
{
TranslateMessage(&msg);
dispatchMessage(&msg);
}
Sleep(10);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd,LParaM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,&ps);
FillRect(hdc,&ps.rcPaint,(HBrush) (COLOR_WINDOW+1));
EndPaint(hwnd,&ps);
}
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
LRESULT CALLBACK PaneProc(HWND hwnd,LParaM lParam)
{
switch (uMsg)
{
case WM_CREATE:
int iVScrollPos;
SCROLLINFO vsi;
ZeroMemory(&vsi,sizeof(SCROLLINFO));
vsi.cbSize=sizeof(SCROLLINFO);
vsi.fMask=SIF_ALL;
GetScrollInfo(hwnd,&vsi);
iVScrollPos=vsi.nPos;
vsi.nMin=0;
vsi.nMax=16+24*200+40;
vsi.nPage=400;
SetScrollInfo(hwnd,TRUE);
GetScrollInfo(hwnd,&vsi);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_VSCROLL:
{
int iVScrollPos;
SCROLLINFO vsi;
ZeroMemory(&vsi,sizeof(SCROLLINFO));
vsi.cbSize=sizeof(SCROLLINFO);
vsi.fMask=SIF_ALL;
GetScrollInfo(hwnd,&vsi);
iVScrollPos=vsi.nPos;
switch(LOWORD(wParam))
{
case SB_THUMBTRACK:
vsi.nPos=vsi.nTrackPos;
break;
}
vsi.nMin=0;
vsi.nMax=16+24*200+40;
vsi.nPage=400;
SetScrollInfo(hwnd,TRUE);
GetScrollInfo(hwnd,&vsi);
if(vsi.nPos != iVScrollPos)
{
float ScrollAmtY=-(vsi.nPos - iVScrollPos);
#define USESCROLL
#ifdef USESCROLL
int ok=ScrollWindowEx(hwnd,ScrollAmtY,SW_INVALIDATE|SW_ERASE|SW_SCROLLCHILDREN);
#else
UpdateWindow(hwnd);
RedrawWindow(hwnd,RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_ERASE | RDW_INTERNALPAINT | RDW_UPDATENow);
#endif
}
return 0;
}
break;
}
return DefWindowProc(hwnd,lParam);
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)