Visual Studio 2015を使用し、MFCの複数ドキュメントアプリケーション(リボンスタイル)を使用します。 CViewにpngイメージを追加し、WM_TIMERを使用してスライドショーを作成しようとしています。 最初に同じ目的でダイアログベースのアプリケーションを作ったが、それは完全に機能する。これらのアプリケーションの違いは、ImageControl(CStatic)のダイアログウィンドウで最初のアプリケーションに画像が描画され、ツールボックスで追加されることです。そして、2番目のアプリでは、CViewのCStaticに同じように画像を追加しようとしています。しかし、CViewでは正しく再描画されません。ウィンドウのサイズを変更する(ストレッチ、最大化する)ときのみ、pngイメージが変更されますが、ウィンドウのサイズ変更を停止するとイメージが再びフリーズします。Visual C++ CPaintDC、CDCを使用してCViewでイメージを再描画する方法
CStaticコントロールの作成。
void CCardioAppView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CRect rect;
GetClientRect(rect);
BOOL b = m_ctrlImage.Create(_T(""), WS_CHILD | WS_VISIBLE, rect,this,2);
m_ctrlImage.ModifyStyle(0, SS_BITMAP, SWP_NOSIZE);
}
タイマーとOnSize関数(で再描画)
void CCardioAppView::OnTimer(UINT_PTR nIDEvent)
{
if (ShowImageTimer == nIDEvent)
{
auto bmp_iter = theApp.FullBmpMap.begin();
int sz = theApp.FullBmpMap.size();
CRect ImageRect;
GetClientRect(&ImageRect);
if (m_iCurrentImage < sz)
{
m_iCurrentImage++;
InvalidateRect(ImageRect, false);
}
else
{
m_iCurrentImage = 1;
}
}
CView::OnTimer(nIDEvent);
}
void CCardioAppView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
CRect rect;
if (m_ctrlImage.GetSafeHwnd())
{
GetClientRect(rect);
m_ctrlImage.DestroyWindow();
BOOL b = m_ctrlImage.Create(_T(""), WS_CHILD | WS_VISIBLE, rect, this, 2);
m_ctrlImage.ModifyStyle(0, SS_BITMAP);
}
}
再描画のOnPaint()
void CCardioAppView::OnPaint()
{
CPaintDC view_dc(this); // device context for painting
CBitmap bmp;
CRect rect, scaleRect;
BITMAP b;
auto bmp_iter = theApp.FullBmpMap.find(m_iCurrentImage);
GetClientRect(&rect);
if (bmp_iter == theApp.FullBmpMap.end()) return;
bmp.Attach((*bmp_iter).second);
bmp.GetObject(sizeof(BITMAP), &b);
CPaintDC dc(&m_ctrlImage);
CDC memdc;
memdc.CreateCompatibleDC(&dc);
memdc.SelectObject(&bmp);
if (rect.Height() <= b.bmHeight) //scaling image
{
scaleRect = rect;
scaleRect.right = rect.left + ((b.bmWidth*rect.Height())/ b.bmHeight);
}
dc.FillSolidRect(rect, RGB(255, 255, 255));
dc.StretchBlt(0, 0, scaleRect.Width(), scaleRect.Height(), &memdc,
0, 0, b.bmWidth, b.bmHeight, SRCCOPY);
//dc.MoveTo(0, 0);
(*bmp_iter).second.Detach();
(*bmp_iter).second.Attach(bmp);
bmp.Detach();
}
のOnPaintが正しくタイマーによって呼び出されます。メインウィンドウのサイズが変更されたときにのみイメージが表示されるのはなぜですか?
「ON_WM_ERASEBKGND()」とそのハンドラ「OnEraseBkgnd(CDC * pDC)」でいくつか試してみることをお勧めします。デフォルトの親クラス実装とは反対の値を返すことがあります。 – sergiol
ちなみに、すべてのサイズ変更で 'm_ctrlImage'を破壊して再作成するのはなぜですか?単純にサイズを変更しないでください([CWnd :: SetWindowPos](https://msdn.microsoft.com/en-us/library/a1yzfz6d.aspx))? – IInspectable