Win32 API:如何避免基本窗口控件的闪烁
Win32 API: How to avoid flickering of basic window controls?
我根据滚动条中的当前nPos值,通过使WM_PAINT内的所有内容无效并重新绘制来滚动父窗口。我想滚动而不闪烁,所以我处理WM_ERASEBKGND以避免重新绘制背景。我还为TextOut调用和显示的一些位图做了简单的双缓冲。除了我的孩子控制之外,它运行良好。它们闪烁得很厉害,尤其是当nPos==0且应用程序处理SB_LINEUP或nPos==nMax且应用程序控制SB_LINEDOWN时,或者当拖放滚动条时。我用MoveWindow()移动它们。我也尝试过DeferWindowPos()。我在谷歌上搜索了一下闪烁的解决方案,但它不起作用,或者我没有正确使用它。如何消除儿童控件的闪烁?
附言:当我使用WS_CLIPCHILLS样式作为主窗口时,控件不会闪烁,但当滚动窗口的某些部分时,会出现混乱,尤其是我的静态控件,我通过处理WM_DRAWTITEM在其上绘制一些东西。
编辑:(简化代码)我在WM_PAINT中加倍缓冲,如下所示:
case WM_PAINT: {
hDC = BeginPaint( hwnd, &PS );
hDCMem = CreateCompatibleDC( hDC );
hBMMem = CreateCompatibleBitmap( hDC, wnd_x, wnd_y );
SelectObject( hDCMem, hBMMem );
Font = CreateFont( 130, 50, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN, "Arial" );
SelectObject( hDCMem, Font );
SetTextColor( hDCMem, RGB( 30, 144, 255 ) );
SetBkColor( hDCMem, RGB( 192, 192, 192 ) );
TextOut( hDCMem, 650, 69 - scr_pos, "ABC", 3 );
MoveWindow( GetDlgItem( hwnd, ID_BUTT_START ), 720, 500 - scr_pos, 160, 150, TRUE );
BitBlt( hDC, 0, 0, wnd_x, wnd_y, hDCMem, 0, 0, SRCCOPY );
DeleteObject( hBMMem );
DeleteDC( hDCMem );
EndPaint( hwnd, &PS );
}
scr_pos是从滚动条获取的当前nPos值。
case WM_ERASEBKGND:
return 1;
break;
case WM_VSCROLL: {
SCROLLINFO sinfo;
ZeroMemory( &sinfo, sizeof( SCROLLINFO ) );
sinfo.cbSize = sizeof( SCROLLINFO );
sinfo.fMask = SIF_POS | SIF_PAGE | SIF_TRACKPOS;
GetScrollInfo( hwnd, SB_VERT, &sinfo );
scr_pos = sinfo.nPos;
switch( LOWORD( wParam ) ) {
case SB_TOP:
scr_pos = 0;
break;
case SB_BOTTOM:
scr_pos = 4000;
break;
case SB_LINEUP: {
scr_pos -= 200;
if ( scr_pos < 0 ) {
scr_pos = 0;
}
}
break;
case SB_LINEDOWN: {
scr_pos += 200;
if ( scr_pos > 4000 ) {
scr_pos = 4000;
}
}
break;
case SB_PAGEUP: {
scr_pos -= si.nPage;
if( scr_pos < 0 ) {
scr_pos = 0;
}
}
break;
case SB_PAGEDOWN: {
scr_pos += si.nPage;
if( scr_pos > 4000 ) {
scr_pos = 4000;
}
}
break;
case SB_THUMBPOSITION:
scr_pos = HIWORD(wParam);
break;
case SB_THUMBTRACK:
scr_pos = HIWORD(wParam);
break;
}
RedrawWindow( hwnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT );
// InvalidateRect ( hwnd, NULL, true );
// UpdateWindow( hwnd );
ZeroMemory( & sinfo, sizeof( SCROLLINFO ) );
sinfo.cbSize = sizeof( SCROLLINFO );
sinfo.fMask = SIF_POS;
snfo.nPos = scr_pos;
SetScrollInfo( hwnd, SB_VERT, & sinfo, TRUE );
}
}
break;
除了儿童控制外,什么都不闪烁。。。
WS_CLIPCHILDREN
确实是解决方案。继续激活它,你必须找出"我的窗户部分被弄砸了"的原因,但你还没有提供足够的细节。
您也可以查看ScrollWindowEx
。该文档专门描述了如何在滚动过程中正确定位子窗口。
相关文章:
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 我的主窗口在创建时或单击更新区域时是否会收到编辑控件?
- 如何在单击QT窗口时将键盘控件返回到QT窗口
- 如何隐藏显示HTML5标记的Web浏览器控件(IE)的滚动条和窗口边框
- 如何在WebBrowser控件窗口中生成异常.MFC中实现的外部方法
- 在运行时向窗口添加控件
- 如何在不显示文本的情况下分配Win32编辑控件的窗口名称
- 从另一个窗口上的控件获取文本时出现问题
- 用c++和OpenGL创建一个带有简单控件的简单窗口
- 如何检测焦点窗口是否为编辑"类型"控件?
- 使用控件(按钮等)动态填充100%窗口的算法
- 如何将文本从编辑控件设置为窗口
- 在自定义控件中创建子按钮窗口后崩溃
- 有没有办法获取对 MFC 对话框中所有子窗口或控件的引用,因为我有一个引用该控件的 CWnd 对象
- Win32 API:如何避免基本窗口控件的闪烁
- 在窗口循环中,在窗口控件上获取鼠标移动比子类化更容易
- 用于获取窗口控件的 API 方法
- 从无窗口控件获取文本
- 如何获取标题栏窗口控件的 RECT(最大化、最小化、关闭按钮)?我尝试制作自定义颜色标题栏
- 是否可以将cout流重定向到具有hwnd句柄的特定窗口(控件)