When code accidently starts to work without a real change - c++

I have run into similar situations before when my code is not working properly and on my quest to solve the problem I made some changes than comment those changes and boom it fixed the problem. All of sudden just a an 'edit' in the file somewhere has fixed the issue but there was no real change in the code. I ran into similar problem again and I am just wondering how does this happen?
void CDlgResizeHelper::Init(HWND hparent)
{
m_hParent = hparent;
m_CtrlsList.clear();
if (::IsWindow(m_hParent))
{
::GetWindowRect(m_hParent, m_OrigParentSize);
// get all child windows and store their original sizes and positions
HWND hCtrl = ::GetTopWindow(m_hParent);
while (hCtrl)
{
CtrlSize cs;
cs.hctrl = hCtrl;
::GetWindowRect(hCtrl, cs.orig_size);
::ScreenToClient(m_hParent, &cs.orig_size.TopLeft());
::ScreenToClient(m_hParent, &cs.orig_size.BottomRight());
// CString msg;
// msg.Format("Old Size: %d %d %d %d\r\n", cs.orig_size.left, cs.orig_size.top, cs.orig_size.right, cs.orig_size.bottom );
// TRACE( msg );
m_CtrlsList.push_back(cs);
hCtrl = ::GetNextWindow(hCtrl, GW_HWNDNEXT);
}
}
}
This class/function resizes controls based on the dialog size. It was working in debug version but the same code doesn't work (=resize properly) in release version. I made changes and added the three lines in the loop above for TRACE function. It starts to work properly in release version as well. Than I commented these lines, it still works in release build. I removed them and it doesn't work in release build anymore. I have to have these lines just commented present for release build to do the right thing. How can this be justified? What could really cause this 'edit' of file which is really no change in the real code fix the problem?
I also want to add that I have tried 'edit' or commented new code else where in the file that doesn't necessarily fixes the problem. I only need to have the commented code in the above function that would fix it.
Update Here is the complete class. I must say this class is available free somewhere on web and I am not the original author.
Init is called from the OnInitDialog of the dialog which needs resizing. It just stores the coordinates of all controls.
OnSize() actually does the resizing.
CDlgResizeHelper::CDlgResizeHelper()
{
}
void CDlgResizeHelper::Init(HWND hparent)
{
m_hParent = hparent;
m_CtrlsList.clear();
if (::IsWindow(m_hParent))
{
::GetWindowRect(m_hParent, m_OrigParentSize);
// get all child windows and store their original sizes and positions
HWND hCtrl = ::GetTopWindow(m_hParent);
while (hCtrl)
{
CtrlSize cs;
cs.hctrl = hCtrl;
::GetWindowRect(hCtrl, cs.orig_size);
::ScreenToClient(m_hParent, &cs.orig_size.TopLeft());
::ScreenToClient(m_hParent, &cs.orig_size.BottomRight());
CString msg;
msg.Format("Old Size: %d %d %d %d\r\n", cs.orig_size.left, cs.orig_size.top, cs.orig_size.right, cs.orig_size.bottom );
Sleep( 50 );
m_CtrlsList.push_back(cs);
hCtrl = ::GetNextWindow(hCtrl, GW_HWNDNEXT);
}
}
}
void CDlgResizeHelper::Remove(HWND hwnd)
{
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
if (it->hctrl == hwnd)
{
m_CtrlsList.erase(it);
return;
}
}
}
void CDlgResizeHelper::Update(HWND hwnd)
{
if (m_hParent && hwnd)
{
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
if (it->hctrl == hwnd)
{
::GetWindowRect(hwnd, &(it->orig_size));
::ScreenToClient(m_hParent, &(it->orig_size.TopLeft()));
::ScreenToClient(m_hParent, &(it->orig_size.BottomRight()));
}
}
}
}
void CDlgResizeHelper::Add(HWND hwnd)
{
if (m_hParent && hwnd)
{
CtrlSize cs;
cs.hctrl = hwnd;
::GetWindowRect(hwnd, cs.orig_size);
::ScreenToClient(m_hParent, &cs.orig_size.TopLeft());
::ScreenToClient(m_hParent, &cs.orig_size.BottomRight());
m_CtrlsList.push_back(cs);
}
}
void CDlgResizeHelper::OnSize()
{
if (::IsWindow(m_hParent))
{
CRect currparentsize;
::GetWindowRect(m_hParent, currparentsize);
double xratio = ((double) currparentsize.Width()) / m_OrigParentSize.Width();
double yratio = ((double) currparentsize.Height()) / m_OrigParentSize.Height();
HDWP hdwp;
hdwp = BeginDeferWindowPos((int)m_CtrlsList.size());
// resize child windows according to their fix attributes
CtrlList::const_iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
CRect currctrlsize;
HorizFix horiz_fix = it->horiz_fix;
VertFix vert_fix = it->vert_fix;
if (horiz_fix & LEFT)
currctrlsize.left = it->orig_size.left;
else
currctrlsize.left = (LONG)( ((horiz_fix & WIDTH) && (horiz_fix & RIGHT)) ? (it->orig_size.left + currparentsize.Width() - m_OrigParentSize.Width()) : (it->orig_size.left * xratio));
if (horiz_fix & RIGHT)
currctrlsize.right = it->orig_size.right + currparentsize.Width() - m_OrigParentSize.Width();
else
currctrlsize.right = (LONG)((horiz_fix & WIDTH) ? (currctrlsize.left + it->orig_size.Width()) : (it->orig_size.right * xratio));
if (vert_fix & TOP)
currctrlsize.top = it->orig_size.top;
else
currctrlsize.top = (LONG)(((vert_fix & HEIGHT) && (vert_fix & BOTTOM)) ? (it->orig_size.top + currparentsize.Height() - m_OrigParentSize.Height()) : (it->orig_size.top * yratio));
if (vert_fix & BOTTOM)
currctrlsize.bottom = it->orig_size.bottom + currparentsize.Height() - m_OrigParentSize.Height();
else
currctrlsize.bottom = (LONG)((vert_fix & HEIGHT) ? (currctrlsize.top + it->orig_size.Height()) : (it->orig_size.bottom * yratio));
UINT flags = SWP_NOZORDER;
if (! it->resize)
flags |= SWP_NOSIZE;
hdwp = ::DeferWindowPos(hdwp, it->hctrl, NULL, currctrlsize.left, currctrlsize.top, (it->resize)? currctrlsize.Width() : 0, (it->resize)? currctrlsize.Height() : 0, flags);
if (hdwp == NULL)
return;
} //end for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
EndDeferWindowPos(hdwp);
} //end if (::IsWindow(m_hParent))
}
BOOL CDlgResizeHelper::Fix(HWND a_hCtrl, HorizFix a_hFix, VertFix a_vFix, bool resize /= true/)
{
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
if (it->hctrl == a_hCtrl)
{
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
return TRUE;
}
}
return FALSE;
}
BOOL CDlgResizeHelper::Fix(int a_itemId, HorizFix a_hFix, VertFix a_vFix, bool resize /= true/)
{
return Fix(::GetDlgItem(m_hParent, a_itemId), a_hFix, a_vFix, resize);
}
BOOL CDlgResizeHelper::Fix(HorizFix a_hFix, VertFix a_vFix, bool resize /= true/)
{
CtrlList::iterator it;
for(it = m_CtrlsList.begin(); it!=m_CtrlsList.end(); ++it)
{
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
}
return TRUE;
}
UINT CDlgResizeHelper::Fix(LPCTSTR a_pszClassName, HorizFix a_hFix, VertFix a_vFix, bool resize /= true/)
{
char cn_buf[200];
memset(cn_buf, 0, 200);
UINT cnt = 0;
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it!= m_CtrlsList.end(); ++it)
{
::GetClassName(it->hctrl, cn_buf, sizeof(cn_buf));
if (strcmp(cn_buf, a_pszClassName) == 0)
{
cnt++;
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
}
}
return cnt;
}

This sounds like you have uninitialized variable used somewhere. It can get different values depending on build mode and it just so happens that it is assigned something harmless in debug.
Try running CppCheck application against your code. Won't hurt anyway.

Related

How to change the MFC Menu background color?

I use OnInitMenuPopup,and it does not work.Like this:
void CMainFrame::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
HBRUSH oMenuBackgroundColor = CreateSolidBrush(RGB(233, 238, 255) );
MENUINFO MenuInfo = { 0 };
MenuInfo.cbSize = sizeof(MenuInfo);
MenuInfo.hbrBack = oMenuBackgroundColor; // Brush you want to draw
MenuInfo.fMask = MIM_BACKGROUND;
if (IsMenu(*pPopupMenu))
{
SetMenuInfo(*pPopupMenu, &MenuInfo);
}
BOOL bEnableMnBordList = AfxGetApp()->GetProfileInt("Other", "EnableMnBordList", FALSE );
if ( !bEnableMnBordList && pPopupMenu != NULL && pPopupMenu->GetMenuItemCount() > 0)
{
pPopupMenu->RemoveMenu(ID_ACC_MN_BORD_LIST, MF_BYCOMMAND);
DrawMenuBar();
}
}
But OnInitMenuPopup doesn't seem to be able to change the ITEM Background.

Display Issue with resized PNG images in MFC application

in our MFC application, we are using lots of images(jpg and png). when we launch the application we are loading all the images into a map.
whenever we resize the application we are resizing all the images in the map.
we are using nearly 300 images so it is taking 3secs to resize the application.
we tried to split the images into different maps based on requirement but that also has an impact on performance. managing is also becoming tuff.
Along with this, there is one more issue on quality when we resize .png images. After resizing all the transparent area is becoming a blur.
In our code we are using CxImage class for loading, rendering and resizing the image.
Below is the code sample. Please suggest how to handle these kind of issues.
can we use SVG files in MFC application?
Loading the image
int CPicture::Load(CString sFileName)
{
CString strFullFileName = sFileName;
CString strOrigFileName = strFullFileName;
int nRet = strFullFileName.ReverseFind('.');
if(nRet != -1)
{
strFullFileName.Insert(nRet, _T("_bl"));
}
if( FALSE == CheckIfFileExists(strFullFileName) )
{
strFullFileName = strOrigFileName;
}
}
CString ss = sFileName;
ss.MakeLower();
if(ss.Find(_T(".png")) > 0)
{
// forcefully loading new images
if(m_pXImage)
{
SAFE_DELETE(m_pXImage);
}
if(NULL == m_pXImage)
{
m_pXImage = new CxImage(strFullFileName, CXIMAGE_FORMAT_PNG);
}
if (!m_pXImage->IsValid()){
SAFE_DELETE(m_pXImage);
//AfxMessageBox(m_pXImage->GetLastError());
return E_IMAGEFILE_NOTLOADED;
}
msName = strFullFileName;
return E_IMAGEFILE_LOADED;
}
if(ss.Find(_T(".gif")) > 0)
{
// forcefully loading new images
if(m_pXImage)
{
SAFE_DELETE(m_pXImage);
}
if(NULL == m_pXImage)
{
m_pXImage = new CxImage(strFullFileName, CXIMAGE_FORMAT_GIF);
}
if (!m_pXImage->IsValid()){
SAFE_DELETE(m_pXImage);
//AfxMessageBox(m_pXImage->GetLastError());
return E_IMAGEFILE_NOTLOADED;
}
msName = strFullFileName;
return E_IMAGEFILE_LOADED;
}
int bResult = E_IMAGEFILE_NOTLOADED;
if (m_pPicture != NULL)
UnLoad();
if (m_pPicture == NULL)
{
CFile cFile;
CFileException fileException;
if(!cFile.Open(strFullFileName, CFile::modeRead | CFile::typeBinary, &fileException))
{
if(!cFile.Open(strFullFileName, CFile::modeRead | CFile::typeBinary, &fileException))
{
return E_IMAGEFILE_MISSING;
}
}
msName = strFullFileName;
if(cFile.GetLength() <= 0)
{
cFile.Close();
return E_IMAGEFILE_MISSING;
}
int nSize = static_cast<int> (cFile.GetLength());
BYTE* pBuff = new BYTE[nSize];
if (cFile.Read(pBuff, nSize) > 0)
{
if(LoadFromBuffer(pBuff, nSize))
{
bResult = E_IMAGEFILE_LOADED;
}
else
{
bResult = E_IMAGEFILE_NOMEMORYTOLOAD;
}
}
else
{
bResult = E_IMAGEFILE_MISSING;
}
cFile.Close();
delete [] pBuff;
}
return bResult;
}
Image scaling code
CPicture* CPicture::GetScaledClone(double fRatioX, double fRatioY)
if(m_pXImage)
{
CPicture* pPic = new CPicture();
pPic->m_nTotalParts = m_nTotalParts;
pPic->m_pXImage = new CxImage(*m_pXImage);
CSize size = GetSize();
long lX = static_cast<LONG>(size.cx*fRatioX);
long lY = static_cast<LONG>(size.cy*fRatioY);
if(m_nTotalParts > 1)
{
int nX = lX % m_nTotalParts;
int nY = nX * lY/lX;
lX -= nX;
lY -= nY;
}
pPic->m_pXImage->Resample(lX, lY, 0);
return pPic;
}

Why app sometimes crashes when getting Icon from file?

I have functions to load and get Icon from files as follows:
std::map<wstring, HICON> m_map_icons;
void WindowSysTray::_loadIconFromFiles()
{
...
for (int i = 0; i < 3; ++i) {
wstring temp = path + trayList[i];
HICON hIcon = NULL;
Gdiplus::Bitmap bitmap(temp.c_str(), false);
bitmap.GetHICON(&hIcon);
pair<wstring, HICON> _pair = make_pair(trayList[i], hIcon);
m_map_icons.insert(_pair);
}
}
HICON WindowSysTray::getIconFromFile(const wchar_t* iconPath)
{
auto iter = m_map_icons.find(wstring(iconPath));
if (iter == m_map_icons.end()) {
return NULL;
}
else {
return iter->second; // ---Issue here---
}
}
...
hIcon = getIconFromFile(L"tray.png");
if (hIcon)
{
TrayIcon.SetIcon(hIcon);
}
...
When I invoke getIconFromFile function, it sometimes crashes while returning value at the end of the function:
return iter->second;
I verified and make sure that I loaded Icon before by invoking _loadIconFromFiles function.
Does anyone know what is the possible root cause of this issue?
m_map_icons.find() could go wrong. This might be the case if m_map_icons is empty. You can start WindowSysTray::getIconFromFile with a check:
if (m_map_icons.size() == 0) return 0;

Random crash for MFC dialog member variable not in scope

I have a MFC application with property window. I property window I have implemented a custom CMFCPropertyGridProperty, So that whenever user click the button added in that property, another dialog pops up.
void CMFCPropertyGridCustomProperty::OnClickButton(CPoint point) {
CSampleDlg* configDlg = new CSampleDlg(NULL);
INT_PTR bResult = configDlg->DoModal();
if(bResult != 1) //If user cancels bResult is 2 ,if select ok bResult is 1
{
return;
}
CString selectedOutput = configDlg->GetSelectionOutput();
CString configValue = configDlg->GetSelectionElemValue();
but the problem is , When I am running in debug mode, sometimes it is working fine but some times it crashes on configDlg->GetSelectionOutput() line. In callStack, I found that the variable is out of scope at that time.
Here is part of my dialog code:
IMPLEMENT_DYNAMIC(CSomeClassDlg, CDialogEx)
CSomeClassDlg::CSomeClassDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CSomeClassDlg::IDD, pParent)
{
m_DevNameStr = "";
m_ElemValue = "";
}
CSomeClassDlg::~CSomeClassDlg()
{
delete m_DataXMLTree;
m_DataXMLTree = NULL;
delete m_TemplateXMLTree;
m_TemplateXMLTree = NULL;
}
void CSomeClassDlg::OnItemchangedElementList(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
int nPos = -1;
nPos = m_ElementListCtrl.GetNextItem(-1,LVNI_SELECTED);
if(nPos != -1)
{
elemDataNode = (CTreeNode*)(m_ElementListCtrl.GetItemData(nSelectedItemIndex));
elemTepmplateNode = GetTemplateElement(elemDataNode);
ShowElemDescription(elemDataNode,elemTepmplateNode);
}
else
{
return;
}
*pResult = 0;
}
void CSomeClassDlg::ShowElemDescription(CTreeNode* dataElemNode, CTreeNode* templateElemNode)
{
if(dataElemNode==NULL || templateElemNode==NULL)
{
m_DescEditCtrl.SetWindowTextA("");
return;
}
CString PIXITStr = templateElemNode->GetAttributeValue("AssociatedPixit");
CString descriptionStr = templateElemNode->GetAttributeValue("Description");
CString valueStr = dataElemNode->GetAttributeValue("Value");
m_DescEditCtrl.SetWindowTextA(descriptionStr);
m_DevNameStr = PIXITStr;
m_ElemValue = valueStr;
}
CString CSomeClassDlg::GetSelectionOutput()
{
return m_DevNameStr;
}
CString CSomeClassDlg::GetSelectionElemValue()
{
return m_ElemValue;
}
But I don't understand if that is the problem then why it is not happening each time. And if it is really the problem what is the best wat to get multiple member variable after doing doModal() . Please help.
Finally I have made some changes which had solved this issue.
1.changes the constructor of custom CMFCPropertyGridProperty class , parameter specially of type COleVariant.
2.Changed the dialog class constructor to take a CTreeNode* and store it as member variable. Somehow that pointer was getting corrupted after DoModal.
3.Added some Assert() to check the validity and a Redraw() in onclickbutton() of custom CMFCPropertyGridProperty class.
I do not know the exact reason for all these changes. Found a reference code in Google code
Here is the OnClickButton of the custom CMFCPropertyGridProperty class:
void CMFCPropertyGridPropertyCustomClass::OnClickButton(CPoint point)
{
ASSERT_VALID(this);
ASSERT_VALID(m_pWndList);
ASSERT_VALID(m_pWndInPlace);
ASSERT(::IsWindow(m_pWndInPlace->GetSafeHwnd()));
m_bButtonIsDown = TRUE;
Redraw();
BOOL bUpdate = FALSE;
CString selOutput = "";
CSomeClassDlg* configDlg = new CSomeClassDlg(m_selNode);
INT_PTR bResult = configDlg->DoModal();
if(bResult == IDOK)
{
bUpdate = TRUE;
//Do Something
}
if (bUpdate)
{
if (m_pWndInPlace != NULL)
{
m_pWndInPlace->SetWindowText(selOutput);
}
m_varValue = (LPCTSTR) selOutput;
}
m_bButtonIsDown = FALSE;
Redraw();
if (m_pWndInPlace != NULL)
{
m_pWndInPlace->SetFocus();
}
else
{
m_pWndList->SetFocus();
}
}
Here is the constructor of the custom CMFCPropertyGridProperty class:
CMFCPropertyGridPropertyCustomClass::CMFCPropertyGridPropertyCustomClass(CTreeNode* pNode, const CString& strName, const CString& varValue, const CString& description) : CMFCPropertyGridProperty(strName, COleVariant((LPCTSTR)varValue), description)
{
//some initialization
}

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