gpt4 book ai didi

C++ MFC 覆盖 OnPaint() 不在另一台计算机上绘画

转载 作者:搜寻专家 更新时间:2023-10-31 01:28:32 26 4
gpt4 key购买 nike

我向 OnPaint() 添加了代码,它在我的 Windows 10 笔记本电脑上正确绘制,但在另一台计算机 (Windows 8) 上未显示该绘制。我是绘画方面的新手,我可能做错了什么——可能是 invalidate 和 updatewindow。无论如何,这是我的代码:

我正在对话框窗口上绘画; OnPaint() 的代码主要由 Visual Studios 创建——我只是在最后添加了 DrawValveImage()。另外,here是显示 DrawValveImage() 绘制内容的图片。我认为您不需要查看 DrawValveImage() 的所有代码来解决问题;我认为我的错误是调用 DrawValveImage() 的位置。也许 OnPaint() 不是自定义绘画的正确事件。

void CCleaningAndScreeningDlg::OnPaint()

{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);


}
else
{
CDialogEx::OnPaint();
}

DrawValveImage();

}

void CCleaningAndScreeningDlg::DrawValveImage()
{
//my own drawing
CClientDC* pDC = new CClientDC(this);
pDC->SelectStockObject(NULL_BRUSH);
COLORREF blueBorder = RGB(67, 99, 155);
COLORREF blueFill = RGB(218, 227, 243);

int x1 = 1050;
int y1 = 50;
int width = 300;
int x2 = x1 + width;
int y2 = y1 + width;


CPen pen;
CBrush brush;
pen.CreatePen(PS_SOLID, 5, blueBorder);
brush.CreateSolidBrush(blueFill);

// select brush and pen
pDC->SelectObject(&pen);
pDC->SelectObject(&brush);

if (valveImageDrawn == FALSE)
pDC->Ellipse(x1, y1, x2, y2);

DeleteObject(brush);
DeleteObject(pen);
DeleteObject(&brush);
DeleteObject(&pen);


int heightWidth = width;
int smallHeightWidth = heightWidth / 7;
int radiusFromOriginSmallCircle = heightWidth / 2.75;

for (int circleIndex = 0; circleIndex < 10; circleIndex++) {
POINT centerSmallCircle = FindPointOnCircle(POINT{ heightWidth / 2, heightWidth / 2 }, radiusFromOriginSmallCircle, (circleIndex * 360 / 10) - 90);
int smallCircleX = centerSmallCircle.x - smallHeightWidth / 2 + x1;
int smallCircleY = centerSmallCircle.y - smallHeightWidth / 2 + y1;
rectangle smallCircleRect = { smallCircleX, smallCircleY, smallCircleX + smallHeightWidth, smallCircleY + smallHeightWidth };
rectsSmallCircles[circleIndex] = smallCircleRect;

bool greenFilled = false;
if (valvePosition - 1 == circleIndex) {
CPen pen;
CBrush brush;
COLORREF greenFill = RGB(181, 230, 29);
pen.CreatePen(PS_SOLID, 5, blueBorder);
brush.CreateSolidBrush(greenFill);
pDC->SelectObject(&pen);
pDC->SelectObject(&brush);
pDC->Ellipse(smallCircleRect.x1, smallCircleRect.y1, smallCircleRect.x2, smallCircleRect.y2);

DeleteObject(brush);
DeleteObject(pen);
DeleteObject(&brush);
DeleteObject(&pen);

greenFilled = true; //if mouse clicked and green color is painted on the valve image
}
else {
CPen pen;
CBrush brush;
pen.CreatePen(PS_SOLID, 5, blueBorder);
brush.CreateSolidBrush(blueFill);
pDC->SelectObject(&pen);
pDC->SelectObject(&brush);
pDC->Ellipse(smallCircleRect.x1, smallCircleRect.y1, smallCircleRect.x2, smallCircleRect.y2);

DeleteObject(brush);
DeleteObject(pen);
DeleteObject(&brush);
DeleteObject(&pen);
}

CString circleText;
int CircleNumber = circleIndex + 1;
circleText.Format(_T("%d"), CircleNumber);


CRect testRect = { smallCircleRect.x1,
smallCircleRect.y1, smallCircleRect.x2, smallCircleRect.y2 };
pDC->SetBkMode(TRANSPARENT);

CClientDC dc(this);
CFont font;
VERIFY(font.CreateFont(
30, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_BOLD, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("Arial"))); // lpszFacename
CFont* def_font = pDC->SelectObject(&font);
pDC->DrawText(circleText, testRect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
pDC->SelectObject(def_font);
font.DeleteObject();



}

//redraw the combobox infront of the valve-image
UpdateData(TRUE);
comboPorts.Invalidate();
comboPorts.UpdateWindow();

valveImageDrawn = true;
}

最佳答案

OnPaint() 是进行自定义绘画的正确方法。当您覆盖 OnPaint() 时,您应该调用基类的 OnPaint() 方法。您有责任自行绘制窗口的所有内容(子窗口除外)。

你只需要这段代码:

void CCleaningAndScreeningDlg::OnPaint()
{
CPaintDC dc(this); // constructor of CPaintDC calls ::BeginPaint()

DrawValveImage( dc ); // pass device context to the drawing function

// Destructor of CPaintDC automatically calls ::EndPaint()!
}

你可以看到我给DrawValveImage添加了一个参数。声明看起来像这样:

void DrawValveImage( CDC& dc );

确保在您的绘图函数中,您只使用 dc 参数进行绘图。

这是错误的:

CClientDC* pDC = new CClientDC(this);

你不应该创建任何额外的设备上下文。

另一个错误的例子:

pDC->SelectObject(&pen);
pDC->SelectObject(&brush);

if (valveImageDrawn == FALSE)
pDC->Ellipse(x1, y1, x2, y2);

DeleteObject(brush);
DeleteObject(pen);
DeleteObject(&brush);
DeleteObject(&pen);

首先,在删除选定的对象之前,您不会恢复设备上下文的原始状态。当一个对象仍然被选择到设备上下文中时,它不能被正确删除。要解决这个问题,请存储 SelectObject()SelectStockObject() 的返回值,它是指向先前在设备上下文中选择的对象的指针(如果您没有选择一个,有一个默认对象)。在删除对象之前,调用 SelectObject(),传递存储的指针。

第二,为什么要删除对象两次?要么让对象在离开当前作用域时自动销毁自身,要么调用 DeleteObject() member 函数(很少需要)。

更正后的代码:

auto pOldPen = dc.SelectObject(&pen);
auto pOldBrush = dc.SelectObject(&brush);

if (valveImageDrawn == FALSE)
dc.Ellipse(x1, y1, x2, y2);

if(pOldPen)
dc.SelectObject(pOldPen);
if(pOldBrush)
dc.SelectObject(pOldBrush );

// No need for DeleteObject(), the destructor of each object will delete it at the
// end of the current scope (before the function returns). But if you actually need it
// (say you want to reuse the variable), it would look like this:
// pen.DeleteObject();
// brush.DeleteObject();

这段代码是不必要的:

//redraw the combobox infront of the valve-image
UpdateData(TRUE);
comboPorts.Invalidate();
comboPorts.UpdateWindow();

只需设置对话框窗口的 WS_CLIPCHILDREN 样式(使用对话框编辑器)即可防止绘制代码覆盖组合框。

关于C++ MFC 覆盖 OnPaint() 不在另一台计算机上绘画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51984181/

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