gpt4 book ai didi

c++: RedrawWindow() 闪烁

转载 作者:行者123 更新时间:2023-11-28 01:42:53 29 4
gpt4 key购买 nike

作为一名使用从 CWnd 继承的自定义类构建 Custome Splitter Wnd 的开发人员。最初,屏幕有一个窗口(自定义类 - CTile),它有两个按钮(垂直 - 拆分,水平 - 拆分)。当用户单击两个按钮之一时,会出现红色拆分条并出现两个子窗口 (CTile)。如您所知,当用户拖动红色分割条时,必须修改子窗口。我在这里说的是,此时出现了闪烁。父wnd只有三个元素(两个子窗口和一个分割条),所以我认为它从来不需要绘制内容。我的意思是 WM_PAINT 消息处理程序。这是我的代码。

this->cDiv = new CDivider(this->wth_tile / 2, 1);
this->cDiv->CreateDivider(this, this->hgt_tile);

//cDiv is split bar I used custom class which is inherited from CWnd.
//CreateDivider() is also my self-defined method.

this->first_child = new CTile();

// As I mentioned above, CTile is divided child window which is also inherited from CWnd.

POINT pt;
pt.x = 0;
pt.y = 0;
this->first_child->CreateTile(this, this->cDiv->sd_pos, this->hgt_tile, pt);

this->second_child = new CTile();


pt.x = this->cDiv->sd_pos + 5;
pt.y = 0;

this->second_child->CreateTile(this, this->cDiv->sd_pos, this->hgt_tile, pt);

This is make movable split bar wnd creation code.

And next is about modified child window size while drag the split bar.

void CDivider::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

POINT pt;
HDC hdc;
RECT rect;

this->parentWnd->GetWindowRect(&rect);

//convert the mouse coordinates relative to the top-left of
//the window
ClientToScreen(&point);
pt = point;
pt.x -= rect.left;
pt.y -= rect.top;

if (this->sd_mode == 1)
{
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
if (GetCapture() == this && this->dragged)
{
this->sd_pos = pt.x;
if (pt.x != oldPos.x && nFlags & MK_LBUTTON)
{
this->length = this->parentWnd->hgt_tile;
this->MoveWindow(this->sd_pos, 0, 4, this->length);
this->parentWnd->ResizeParent();
this->parentWnd->Invalidate();
this->parentWnd->UpdateWindow();
TRACE("Resize Parent\n");
/*this->parentWnd->first_child->Invalidate();
this->parentWnd->second_child->Invalidate();*/
}
}

}
else if (this->sd_mode == 2)
{
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));

if (GetCapture() == this && this->dragged)
{
this->sd_pos = pt.y;
if (pt.y != oldPos.y && nFlags & MK_LBUTTON)
{
this->Invalidate();
this->length = this->parentWnd->wth_tile;
this->MoveWindow(0, this->sd_pos, this->length, 4);

this->parentWnd->ResizeParent();
this->parentWnd->Invalidate();
this->parentWnd->UpdateWindow();
TRACE("Resize Parent\n");
/*this->parentWnd->first_child->Invalidate();
this->parentWnd->second_child->Invalidate();*/
}
}
}

CWnd::OnMouseMove(nFlags, point);

这里,parentWnd 是拆分栏的父窗口——只是父初始窗口。first_child 和 second_child 是 child 划分的窗口。sd_mode 表示拆分方法 - 垂直和水平。

为什么这段代码不起作用?

最佳答案

闪烁的发生是因为在大多数普通窗口中绘画是一个两阶段操作。 1.背景删除,2.窗口重绘。

所以问题是需要重绘的子窗口。关于不闪烁绘画的文章很多。

您还可以通过仅使受影响的窗口部分无效来优化重绘。您强制重绘整个窗口。那不理想。在这种情况下,大部分窗口可能会闪烁。

顺便说一句:带有特定标志的 RedrawWindow 比调用 Invalidate/Update 序列要好,而且可能会快一点。

此外,在拖动过程中使用异或绘画绘制条形图的方法可能会更好。并在 LButtonUp-Event 发生时更新窗口大小。 CSplitterWnd 的操作方式...您有源代码。调查一下。

关于c++: RedrawWindow() 闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46464232/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com