我有一个像这样创建的EDIT控件:
hwndEDIT_5 = CreateWindowEx (
0, "EDIT", NULL,
WS_VSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_READONLY,
135, 450, 555, 200,
h2, ( HMENU ) ID_EDIT_CONSOLE,
h1, NULL
);
Run Code Online (Sandbox Code Playgroud)
如您所见,它是一个只读编辑区域,可以显示多行文本.它应该是一个控制台,我可以在用户使用该程序时显示一些信息.我希望每当添加新行(或用户的消息)时,文本区域会自动滚动到最底部的条目(最新的条目).我实现了这个:
SetDlgItemText ( h2, ID_EDIT_CONSOLE, ch_s );
SCROLLINFO scr;
SCROLLINFO * scr_p = &scr;
scr.cbSize = sizeof ( SCROLLINFO );
scr.fMask = SIF_RANGE;
GetScrollInfo ( GetDlgItem ( h2, ID_EDIT_CONSOLE), SB_VERT, scr_p );
int mmax = scr.nMax;
scr.fMask = SIF_POS;
scr.nPos = mmax;
SetScrollInfo ( GetDlgItem ( h2, ID_EDIT_CONSOLE), SB_VERT, …Run Code Online (Sandbox Code Playgroud) 我根据滚动条中的当前 nPos 值使 WM_PAINT 中的所有内容无效并重新绘制,从而滚动父窗口。我想滚动而不闪烁,所以我处理 WM_ERASEBKGND 以避免重绘背景。我还为我的 TextOut 调用和一些显示的位图做简单的双缓冲。除了我的孩子控制之外,它工作得很好。它们闪烁得很厉害,尤其是当 nPos == 0 并且应用程序处理 SB_LINEUP 或 nPos == nMax 并且应用程序处理 SB_LINEDOWN 或拖放滚动条时。我用 MoveWindow() 移动它们。我也试过 DeferWindowPos()。我在谷歌上搜索了闪烁的解决方案,但它不起作用或我没有正确使用它。如何消除子控件的闪烁?
PS 当我为主窗口使用 WS_CLIPCHILDREN 样式时,控件不会闪烁,但是当滚动窗口的某些部分时会变得混乱,尤其是我通过处理 WM_DRAWITEM 在其上绘制一些东西的静态控件。
编辑:(简化代码)我像这样在 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 ); …Run Code Online (Sandbox Code Playgroud)