[英]MFC Draw Stuff Outside OnPaint in a Dialog-based App
I'm currently trying to draw something outside OnPaint function. I know there are many duplicate questions on the inte.net, however, I failed to get any of them to work.我目前正在尝试在 OnPaint function 之外绘制一些东西。我知道在 inte.net 上有很多重复的问题,但是,我没有让他们中的任何一个工作。 This is entirely because of my lack of understanding of MFC.这完全是因为我对MFC缺乏了解。
What works inside OnPaint: OnPaint 内部的工作原理:
CDC* pDC = GetDC();
HDC hDC = pDC->GetSafeHdc();
CRect lDisplayRect;
GetDlgItem(IDC_DISPLAYPOS)->GetClientRect(&lDisplayRect);
GetDlgItem(IDC_DISPLAYPOS)->ClientToScreen(&lDisplayRect);
ScreenToClient(&lDisplayRect);
pDC->FillSolidRect(&lDisplayRect, GetSysColor(COLOR_3DDKSHADOW));
pDC->TextOutW(300, 300, TEXT("test"));
It fills the area of the button control I have with a defined colour.它用定义的颜色填充按钮控件的区域。 And it prints out the "test" string without any issue.它会毫无问题地打印出“测试”字符串。
But it won't work outside OnPaint.但它不会在 OnPaint 之外工作。
I've seen numerous suggestions such as using CmemDC,CPaintDC, etc But none of them worked outside OnPaint.我已经看到许多建议,例如使用 CmemDC、CPaintDC 等,但没有一个在 OnPaint 之外工作。
For example,例如,
CClientDC dc(this);
dc.rectangle( ....);
does not work.不起作用。
Please note that this is a temporary test code and what I am eventually trying to do is draw incoming frames from a frame grabber within my display thread (a separate thread from the main UI thread) on the DisplayPos area and my dlg object(the dialog) owns an instance of the DisplayThread class. And I'm passing HWND and displayrect upon creating the member mDisplayThread so I can draw stuff within the display thread and that's the reason why I need to be able to draw to DC outside OnPaint (DisplayThread class does not have OnPaint or inherit any class that has it).请注意,这是一个临时测试代码,我最终要做的是在 DisplayPos 区域和我的 dlg 对象(对话框) 拥有 DisplayThread class 的一个实例。我在创建成员 mDisplayThread 时传递了 HWND 和 displayrect,这样我就可以在显示线程中绘制东西,这就是为什么我需要能够在 OnPaint 之外绘制到 DC (DisplayThread class没有 OnPaint 或继承任何具有它的 class)。
I'm in dire need of help...Please help!我急需帮助...请帮忙!
Added: I have overridden PreTranslateMessage(MSG* pMsg) and made it return without calling the default function just in case WM_ERASE msg is erasing everything, but this approach didn't work either.补充:我已经覆盖了 PreTranslateMessage(MSG* pMsg) 并使其返回而不调用默认值 function 以防 WM_ERASE msg 擦除所有内容,但这种方法也不起作用。
For example:例如:
void CMFCApplicationDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
HDC hdc = ::GetDC(m_hWnd);
Ellipse(hdc, point.x - 10, point.y - 10, point.x + 10, point.y + 10);
::ReleaseDC(m_hWnd, hdc);
CDialogEx::OnLButtonDown(nFlags, point);
}
Two important suggestions:两个重要的建议:
Do not draw outside of OnPaint
.不要在OnPaint
之外绘制。 The content may be erased or painted over at the direction of OS.内容可能会在操作系统的指导下被擦除或涂上。
Do not draw on the dialog surface.不要在对话框表面上绘制。 First, it is not designed for that.首先,它不是为此而设计的。 It may be affected by other controls or by theming, skinning, etc. Just create a window with your own window procedure, so you are in control.它可能会受到其他控件或主题、皮肤等的影响。只需使用您自己的 window 过程创建一个 window,这样您就可以控制了。
I would store the information needed for drawing in you frame grabber
, and cause an immediate window painting by calling RedrawWindow我会将绘图所需的信息存储在您的frame grabber
中,并通过调用RedrawWindow立即进行 window 绘图
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.