У меня проблема с методом OnPaint CFrameWnd, и я не могу понять, что происходит. OnPaint вызывается примерно каждые 10 мс, что приводит к зависанию компьютера. Проверено использование процессора и это приложение занимает 50%!
Приложение представляет собой очень простое приложение MFC, которое написано в одном файле.
// Includes are done here...
class MFC_Tutorial_Window : public CFrameWnd
{
std::string data;
public:
MFC_Tutorial_Window()
{
this->data = "";
Create(NULL, "Data Win"); // Create window
}
void OnPaint()
{
CDC* pDC = GetDC();
CString s = CString(this->data.c_str());
RECT rc;
HWND hwnd = this->m_hWnd;
if(hwnd != NULL) {
::GetWindowRect(hwnd, &rc);
rc.top = rc.bottom/2;
if(pDC != NULL && pDC->m_hDC != NULL) {
pDC->DrawText(s, &rc, DT_CENTER);
}
}
}
void UpdateWithNewData(std::string up) {
this->data = up;
Invalidate();
}DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(MFC_Tutorial_Window, CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
// App class
class MyApp :public CWinApp
{
MFC_Tutorial_Window *wnd;
BOOL InitInstance()
{
wnd = new MFC_Tutorial_Window();
m_pMainWnd = wnd;
m_pMainWnd->ShowWindow(3);
wnd->UpdateWithNewData("Hello world!");
return 1;
}
};
Кто-нибудь знает, почему OnPaint спамится системой? Я смотрел на этот код целую вечность, и я просто не могу его найти.
Деструктор CPaintDC должен вызываться для сброса флага перерисовки. Вам нужно позвонить beginPaint();
а также endPaint();
на ваше CDC
который на самом деле должен быть изменен на CPaintDC
, Что еще важнее, не звонить endPaint();
приведет к перерисовке контекста, несмотря ни на что.
WM_PAINT
сообщение генерируется всякий раз, когда в очереди сообщений и в области обновления окна нет других сообщений (см. InvalidateRect
) не пусто. При обращении с WM_PAINT
сообщение приложение сигнализирует, что область обновления была перекрашена путем вызова EndPaint
. Неспособность позвонить EndPaint
не будет помечать регион обновления как обработанный, поэтому в следующий раз, когда приложение запросит сообщение, WM_PAINT
является действительным кандидатом.
В MFC функционал для вызова BeginPaint
а также EndPaint
заключен в CPaintDC
Учебный класс. Стандартный обработчик сообщений MFC для WM_PAINT
выглядит так:
void OnPaint()
{
CPaintDC dc(this); // calls BeginPaint()
// Perform rendering operations on dc
// ...
} // CPaintDC::~CPaintDC() calls EndPaint()
Более подробную информацию об использовании контекстов устройства можно найти по адресу Контекст устройства.