MFC中使用Picture控件描画背景及图片的几个问题

FredHuang85 2016-03-22 10:12:15
程序整体架构是用多视图来实现的,新添加的图片显示的框架是采用CStatic上面描画背景图片加一些Icon,关于显示方面有几个问题麻烦帮忙咨询一下:
1. 我们在切换view的时候,重新进入带有新图片的view的时候,画面会直接显示退出前的画面,如何能够在init的时候对原来的图片进行清空?
2. 在调用invalidate函数之后,画面抖动的很厉害,有其他方法对画面进行重新描绘吗?

背景:
Resource:
在Dialog上拖了一个Picture控件,名为:IDC_BITMAP_SHORTTEST, 在BITMAP中添加一个背景图片资源 IDB_BITMAP_SHORTTEST。
代码:
ShortTestRectInformation.h

class CIconData
{
public:
CIconData();
CIconData(const CIconData& rhs);

CIconData& operator=(const CIconData& rhs);

public:
CRect m_rectFrame;
CString m_strText;
CPoint m_ptText;
unsigned int m_colorBack;
};


class CShortTestData
{
public:
CShortTestData();
~CShortTestData();

public:
int Count();
CIconData* GetIcon(int index);
int InsertIcon(int index,const CIconData& icon);
int AppendIcon(const CIconData& icon);
int DeleteIcon(int index);
int DeleteAllIcon();
void ClearIcon();

public:
CIconData* m_arrayIconData;
int m_nCount;
};

class CShortTestPanel : public CStatic
{
// Construction
public:
CShortTestPanel();
virtual ~CShortTestPanel();

public:
CShortTestData* ShortTestData();
void SaveBitMapRect(LONG lLeft, LONG lRight, LONG lTop, LONG lBottom);
void RedrawScanArea();

public:
CShortTestData* m_pShortTestData;

private:
CFont* m_fontError;
class CIconData
{
public:
CIconData();
CIconData(const CIconData& rhs);

CIconData& operator=(const CIconData& rhs);

public:
CRect m_rectFrame;
CString m_strText;
CPoint m_ptText;
unsigned int m_colorBack;
};


class CShortTestData
{
public:
CShortTestData();
~CShortTestData();

public:
int Count();
CIconData* GetIcon(int index);
int InsertIcon(int index,const CIconData& icon);
int AppendIcon(const CIconData& icon);
int DeleteIcon(int index);
int DeleteAllIcon();
void ClearIcon();

public:
CIconData* m_arrayIconData;
int m_nCount;
};

class CShortTestPanel : public CStatic
{
// Construction
public:
CShortTestPanel();
virtual ~CShortTestPanel();

public:
CShortTestData* ShortTestData();
void SaveBitMapRect(LONG lLeft, LONG lRight, LONG lTop, LONG lBottom);
void RedrawScanArea();

public:
CShortTestData* m_pShortTestData;

private:
CFont* m_fontError;
LONG m_lShortTestLeft;
LONG m_lShortTestTop;
LONG m_lShortTestBottom;
LONG m_lShortTestRight;

// Generated message map functions
protected:
//{{AFX_MSG(CScanningPanel)
afx_msg void OnPaint();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};
// Generated message map functions
protected:
//{{AFX_MSG(CScanningPanel)
afx_msg void OnPaint();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

ShortTestInformation.cpp

CIconData::CIconData()
{
}
CIconData::CIconData(const CIconData& rhs)
{
m_rectFrame = rhs.m_rectFrame;
m_strText = rhs.m_strText;
m_ptText = rhs.m_ptText;
m_colorBack = rhs.m_colorBack;
}
CIconData& CIconData::operator=(const CIconData& rhs)
{
if(this != &rhs)
{
m_rectFrame = rhs.m_rectFrame;
m_strText = rhs.m_strText;
m_ptText = rhs.m_ptText;
m_colorBack = rhs.m_colorBack;
}
return *this;
}


//////////////////////////////////////////////////////////////////////
//CScanningData
//////////////////////////////////////////////////////////////////////

CShortTestData::CShortTestData()
:m_arrayIconData(new CIconData[MAX_ICON_DATA_COUNT])
,m_nCount(0)
{

}

CShortTestData::~CShortTestData()
{
ClearIcon();
}

int CShortTestData::Count()
{
return m_nCount;
}
CIconData* CShortTestData::GetIcon(int index)
{
CIconData* pIcon = 0;
if(0 <= index && index < m_nCount)
{
pIcon = &m_arrayIconData[index];
}
return pIcon;
}
int CShortTestData::InsertIcon(int index,const CIconData& icon)
{
if(m_nCount >= MAX_ICON_DATA_COUNT)
return -100;

int iRet = 0;
if(0 <= index && index <= m_nCount)
{
for(int i = m_nCount-1; i >= index; --i)
{
m_arrayIconData[i+1] = m_arrayIconData[i];
}
m_arrayIconData[index] = icon;
++m_nCount;
}
else
{
iRet = -1;
}
return iRet;
}
int CShortTestData::AppendIcon(const CIconData& icon)
{
return InsertIcon(m_nCount,icon);
}
int CShortTestData::DeleteIcon(int index)
{
int iRet = 0;
if(0 <= index && index < m_nCount)
{
for(int i = index; i < m_nCount; ++i)
{
m_arrayIconData[i] = m_arrayIconData[i+1];
}
--m_nCount;
}
else
{
iRet = -1;
}
return iRet;
}
int CShortTestData::DeleteAllIcon()
{
int iRet = 0;
while(0 != m_nCount)
{
DeleteIcon(m_nCount);
}

return iRet;
}
void CShortTestData::ClearIcon()
{
delete[] m_arrayIconData;
m_arrayIconData = 0;
m_nCount = 0;
}

// CScanningPanel

CShortTestPanel::CShortTestPanel()
: m_pShortTestData(new CShortTestData)
, m_fontError(0)
// For change UI on short test function, Add by Fred 20160204 --- start
, m_lShortTestLeft(0)
, m_lShortTestTop(0)
, m_lShortTestBottom(0)
, m_lShortTestRight(0)
// For change UI on short test function, Add by Fred 20160204 --- end
{
}

CShortTestPanel::~CShortTestPanel()
{
delete m_pShortTestData;
delete m_fontError;
}


BEGIN_MESSAGE_MAP(CShortTestPanel, CStatic)
//{{AFX_MSG_MAP(CScanningPanel)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CScanningPanel message handlers

void CShortTestPanel::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
//获得背景图片
// CBitmap bitmap;
// bitmap.LoadBitmap(IDB_BITMAP_SHORTTEST_EMGRANDX718);
// BITMAP bmp;
// bitmap.GetBitmap(&bmp);
// int width = bmp.bmWidth;
// int height = bmp.bmHeight;
CBitmap* bitmap = CBitmap::FromHandle(GetBitmap());
BITMAP bmp;
bitmap->GetBitmap(&bmp);
int width = bmp.bmWidth;
int height = bmp.bmHeight;


//创建警告和错误字体
if(0 == m_fontError)
{
m_fontError = new CFont;
LOGFONT lf0,lf;
CFont* font0 = this->GetParent()->GetFont();
font0->GetLogFont(&lf0);
GetObject(GetStockObject(SYSTEM_FONT),sizeof(LOGFONT),&lf);
lf.lfHeight=lf0.lfHeight*8/10;
lf.lfWeight=lf0.lfWeight*8/10;
lf.lfCharSet=GB2312_CHARSET;
_stprintf(lf.lfFaceName,_T("%s"),lf0.lfFaceName);
m_fontError->CreateFontIndirect(&lf);
}

CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap* oldBmp = dcMem.SelectObject(bitmap);
// LONG width = m_lShortTestRight - m_lShortTestLeft;
// LONG height = m_lShortTestBottom - m_lShortTestTop;
//绘制透明背景图
::TransparentBlt(dc.m_hDC,0,0,width,height,dcMem.m_hDC,0,0,width,height,COLOR_WHITE);
//绘制基于背景的动态过程
int nCount = m_pShortTestData->Count();
for(int i = 0; i < nCount; ++i)
{
CIconData* icon = m_pShortTestData->GetIcon(i);
dc.FillSolidRect(icon->m_rectFrame,icon->m_colorBack);
CFont* font = dc.SelectObject(m_fontError);
dc.TextOut(icon->m_ptText.x,icon->m_ptText.y,icon->m_strText);
dc.SelectObject(font);
}
dcMem.SelectObject(oldBmp);
dcMem.DeleteDC();
// Do not call CStatic::OnPaint() for painting messages
}
CShortTestData* CShortTestPanel::ShortTestData()
{
return m_pShortTestData;
}
void CShortTestPanel::SaveBitMapRect(LONG lTop, LONG lLeft, LONG lRight, LONG lBottom)
{
m_lShortTestLeft = lLeft;
m_lShortTestRight = lRight;
m_lShortTestTop = lTop;
m_lShortTestBottom = lBottom;
}
void CShortTestPanel::RedrawScanArea()
{
SetRedraw();
CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
//获得背景图片
CBitmap* bitmap = CBitmap::FromHandle(GetBitmap());
BITMAP bmp;
bitmap->GetBitmap(&bmp);
int width = bmp.bmWidth;
int height = bmp.bmHeight;

//创建警告和错误字体
if(0 == m_fontError)
{
m_fontError = new CFont;
LOGFONT lf0,lf;
CFont* font0 = this->GetParent()->GetFont();
font0->GetLogFont(&lf0);
GetObject(GetStockObject(SYSTEM_FONT),sizeof(LOGFONT),&lf);
lf.lfHeight=lf0.lfHeight*8/10;
lf.lfWeight=lf0.lfWeight*8/10;
lf.lfCharSet=GB2312_CHARSET;
_stprintf(lf.lfFaceName,_T("%s"),lf0.lfFaceName);
m_fontError->CreateFontIndirect(&lf);
}

CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap* oldBmp = dcMem.SelectObject(bitmap);
//绘制透明背景图
::TransparentBlt(dc.m_hDC,m_lShortTestLeft,m_lShortTestTop,width,height,dcMem.m_hDC,0,0,width,height,COLOR_WHITE);
//绘制基于背景的动态过程
int nCount = m_pShortTestData->Count();
for(int i = 0; i < nCount; ++i)
{
CIconData* icon = m_pShortTestData->GetIcon(i);
dc.FillSolidRect(icon->m_rectFrame,icon->m_colorBack);
dc.TextOut(icon->m_ptText.x,icon->m_ptText.y,icon->m_strText);
}
dcMem.SelectObject(oldBmp);
dcMem.DeleteDC();
}


描画调用的代码:
XXX_Menu.h

...
private:
CShortTestPanel m_pShortTestPanel;

XXX_Menu.cpp

void XXX_Menu::Init()
{
int i = 0;
CShortTestData* pShortTestData;

m_pShortTestPanel.SetBitmap(::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP_SHORTTEST)));
pShortTestData = m_pShortTestPanel.ShortTestData();
pShortTestData->DeleteAllIcon();
CIconData icon;

for (i = 0; i < 5; i++)
{
...
icon.m_strText = ArrayECUItemsInfo[i].strECUName;
icon.m_colorBack = COLOR_WHITE;
icon.m_ptText.x = icon.m_rectFrame.left+(icon.m_rectFrame.Width()/4);
icon.m_ptText.y = icon.m_rectFrame.top+(icon.m_rectFrame.Height()/4);
pShortTestData->AppendIcon(icon);
}
m_pShortTestPanel.SaveBitMapRect(rrc.top, rrc.left, rrc.right, rrc.bottom);
m_pShortTestPanel.ShowWindow(SW_HIDE);
}

void XXX_Menu::LoopDisplay() //循环刷新界面
CShortTestData* pShortTestData = m_pShortTestPanel.ShortTestData();
...
for(i = 0; i < usNum; i++)
{
int nCount = pShortTestData->Count();
CIconData icon;
for(int i = 0; i < nCount; ++i)
{
CIconData* icon = pShortTestData->GetIcon(i);
if (!strcmp((const char*)pShareBuff, icon->m_strText))
{
pShareBuff += strlen((char*)pShareBuff) + 1;
if (!strcmp((const char*)pShareBuff, (const char*)strCommunicate))
{
icon->m_colorBack = SHORTTEST_STATE_COMMUNICATE;
}
else if (!strcmp((const char*)pShareBuff, (const char*)strNoDTC))
{
icon->m_colorBack = SHORTTEST_STATE_OK;
}
...
pShareBuff += strlen((char*)pShareBuff) + 1;
break;
}
}
m_pShortTestPanel.Invalidate();



...全文
168 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
FredHuang85 2016-03-22
  • 打赏
  • 举报
回复
在Init函数中即使使用了 m_pShortTestPanel.ShowWindows(SW_HIDE); 但是对其他控件还是有遮挡效果。不明白为什么。

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧