Question

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.

Was it helpful?

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;
}

OTHER TIPS

I used EnumEnhMetaFile function:

EnumEnhMetaFile(dc->m_hDC, hMetaFile, myMetafileProc, NULL, rect  );

Then I used callback procedure that retrives each record of metafile:

int metafileProc( HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, int nObj, LPARAM lpData) {
if ( lpEMFR->iType == EMR_EXTTEXTOUTW ) {
        COLORREF_STRUCT *c = (COLORREF_STRUCT *)&(lastBgColor);
        EMR_EXTTEXTOUTW_STRUCT *s = (EMR_EXTTEXTOUTW_STRUCT *)lpEMFR;
        s->textStruct.options = 0x00;
        if ( bgColorFlag ) {
            bgColorFlag = false;
            renderRect( hDC, s->textStruct.rect, c );
        }
        PlayEnhMetaFileRecord( hDC, lpHTable, lpEMFR, nObj );
} else if ( lpEMFR->iType == EMR_SETBKCOLOR ) {
    BYTE *ptr = (BYTE*)lpEMFR;
    COLORREF temp = *((COLORREF*)(ptr+8));
    if ( temp != 0xFFFFFF ) {
        lastBgColor = temp;
        bgColorFlag = true;
    }
}
return 1;
}

where renderRect( hDC, s->textStruct.rect, c ) is function which draws transparent background in c color. I have to zero options flag for text becouse there was different behaviour in Windows XP and Windows 7 and 8 - after that everything works ok. Thanks for help. Best regards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top