MFC应用程序中AFX_WM_DRAW2D和WM_PAINT的关系

Relationship between AFX_WM_DRAW2D and WM_PAINT in MFC Application

本文关键字:WM PAINT 关系 DRAW2D AFX 应用程序 MFC      更新时间:2023-10-16

主题中两个消息之间的关系是什么?当AFX_WM_DRAW2D被传递到应用程序队列时。

我问,因为我遇到了AFX_WM_DRAW2D处理程序最奇怪的递归调用。每当我试图在AFX_WM_DRAW2Din兼容渲染目标内绘制一些东西时,处理程序以某种方式递归地称为我难以解释的。MFC应用程序的结构如下:-

BEGIN_MESSAGE_MAP(CTACSIView, CView)
    // Standard printing commands
    ...
    ON_REGISTERED_MESSAGE(AFX_WM_DRAW2D, &CTACSIView::OnDraw2D)
END_MESSAGE_MAP()

afx_msg LRESULT CTACSIView::OnDraw2D(WPARAM wParam, LPARAM lParam)
{
    CHwndRenderTarget* pRenderTarget = (CHwndRenderTarget*)lParam;
    ASSERT_VALID(pRenderTarget);

    CRect clientRect;
    GetClientRect(clientRect);
    if (m_BackGroundHasChanged)
    {

        CBitmapRenderTarget compatibleRenderTarget;
        pRenderTarget->CreateCompatibleRenderTarget(compatibleRenderTarget, m_viewScreenSize);
        compatibleRenderTarget.BeginDraw();

        // 
        // ----> HERE THE RECURSIVE CALL OCCURS <----
        //
            D2D1::Matrix3x2F shiftRightTranslation = D2D1::Matrix3x2F::Translation(D2D1::SizeF(TACSI_VIEW_BATTLE_FIELD_OFFSET_X, 0));
    m_pRulerBitmapBrush_X.SetTransform(&shiftRightTranslation);
    compatibleRenderTarget.FillRectangle(rulerRectangle_X, &m_pRulerBitmapBrush_X);

MFC内部处理WM_PAINT消息(查看CWnd::OnWndMsg源)并尝试做D2D油漆(调用受保护的CWnd::DoD2DPaint()方法)。该方法检查窗口是否启用了D2D(方法CWnd::EnableD2DSupport),并为该窗口发送内部MFC消息AFX_WM_DRAW2D。

因此,如果你在代码中处理AFX_WM_DRAW2D,那么CWnd::DoD2DPaint()返回TRUE,进一步处理WM_PAINT被阻塞。如果AFX_WM_DRAW2D未被处理或D2D不被操作系统支持或未启用,则标准WM_PAIT算法正在工作。

注:: MFC 12只支持D2D 1.0,不支持D2D 1.1或D2D 1.2!因为D2D。x需要完整的Direct3D初始化为D2D的地下关卡,因此很难在MFC中为它们编写通用代码。

P.P.S.:如果你的APP执行打印抛出MFC,那么查看器OnDraw方法将被调用。这是因为D2D渲染不支持绘制到打印机上下文。任何打印的D2D应用程序必须实现两个方法:用于打印和旧操作系统(不支持D2D)的OnDraw()和用于屏幕上绘制的AFX_WM_DRAW2D处理。