Search code examples
mfctransparencygdimetafilecricheditctrl

How to render CRichEditCtrl on CDC with transparent backgorund ? (MFC)


I need help with rendering CRichEditCtrl content with transparent background on graphical context which is displayed on screen and printed as well. Now I have following code, which is working good except transparency issues:

CRichEditCtrl ctrl; // my CRichEditCtrl
CDC *dc; // - my graphical context

dc->SetBkMode(TRANSPARENT);
dc->DPtoHIMETRIC(&targetSize);
CRect cHiMetricRect( 0, 0, origSize.cx*factor,origSize.cy*factor);
CRect cTwipsRect( 0, 0, (TWIPS_INCH * targetSize.cx + HIMETRIC_INCH / 2) / HIMETRIC_INCH, (TWIPS_INCH * targetSize.cy + HIMETRIC_INCH / 2) / HIMETRIC_INCH);

CMetaFileDC metaFile;
metaFile.CreateEnhanced( dc, NULL, cHiMetricRect, NULL );
metaFile.SetBkMode(TRANSPARENT);
metaFile.SetAttribDC( dc->m_hDC );

FORMATRANGE stFR;
stFR.hdcTarget = stFR.hdc = metaFile.m_hDC; 
stFR.rcPage = stFR.rc = cTwipsRect;
stFR.chrg.cpMin = 0;
stFR.chrg.cpMax = -1;

ctrl.FormatRange( &stFR, TRUE);
ctrl.FormatRange( NULL, TRUE);

HENHMETAFILE hMetaFile = metaFile.CloseEnhanced();

dc->PlayMetaFile(hMetaFile,&cr);
DeleteEnhMetaFile(hMetaFile);

I need to render this text with transparency because there are already things drawn on my DC. I tried to search web for any help about metafiles and transparency but found nothing adequate. I will be thankful for any kind of help.


Solution

  • I'm not very sure about MetaFiles, but I've done something similar with EMFs with straight WinAPI which does work -- call EnumEnhMetaFile instead of PlayMetaFile, like:

    BOOL bFirstTime = TRUE;
    EnumEnhMetaFile(hDC, m_hEmf, (ENHMFENUMPROC)EmfEnumProc_Play_TranspBackground, &bFirstTime, &rc);
    

    where the EnumProc is defined as

    int CALLBACK EmfEnumProc_Play_TranspBackground(HDC hDC, LPHANDLETABLE lpHTable, LPENHMETARECORD lpEMFR, int nObj, LPARAM lpData)
    {   BOOL bOK;
        if (lpEMFR->iType == EMR_SETBKMODE)
        {   EMRSETBKMODE* lpEMRBkMode = (EMRSETBKMODE*) lpEMFR;
    
            if (lpEMRBkMode->iMode == OPAQUE)
            {   EMRSETBKMODE EmrBkMode;
                EmrBkMode.emr.iType = EMR_SETBKMODE;
                EmrBkMode.emr.nSize = (sizeof(EmrBkMode) % 4 == 0 ? sizeof(EmrBkMode) : (((sizeof(EmrBkMode) / 4) + 1) * 4));
                EmrBkMode.iMode = TRANSPARENT;
                bOK = PlayEnhMetaFileRecord(hDC, lpHTable, (LPENHMETARECORD)&EmrBkMode, (UINT)nObj);
                return bOK;
            }
        }
    
        bOK = PlayEnhMetaFileRecord(hDC, lpHTable, lpEMFR, (UINT)nObj);
    
        if (lpEMFR->iType == EMR_HEADER)
        {   BOOL* pbFirstTime = (BOOL*)lpData;
            if (*pbFirstTime)
            {   EMRSETBKMODE EmrBkMode;
                EmrBkMode.emr.iType = EMR_SETBKMODE;
                EmrBkMode.emr.nSize = (sizeof(EmrBkMode) % 4 == 0 ? sizeof(EmrBkMode) : (((sizeof(EmrBkMode) / 4) + 1) * 4));
                EmrBkMode.iMode = TRANSPARENT;
                PlayEnhMetaFileRecord(hDC, lpHTable, (LPENHMETARECORD)&EmrBkMode, (UINT)nObj);
    
                *pbFirstTime = FALSE;
            }
        }
    
        return bOK;
    }