MFC CImage 사용 시 stretchblt 부분 Debug assertion failed 오류
글쓴이: cylee / 작성시간: 목, 2016/08/04 - 9:42오전
제목 그대로 컴파일 해보면 debug assertion failed 오류가 뜨는데
Expression에는 hBitmap == m_hBitmap 부분에 문제가 있다고 뜨네요ㅠㅠ
순서대로 디버그 해보면 stretchblt 부분 지나면서 저렇게 뜨는데 무슨 문제일까요ㅠㅠ
void CBMPDlg::OnBnClickedLoad() { CImage BMPDlgImg; BMPDlgImg.Destroy(); CString strBMPpath; CFileDialog dlg(TRUE, _T("bmp"),_T("*.bmp"),OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, _T("BMP File(*.bmp)|*.bmp|모든파일(*.*)|*.*|"),NULL); if(dlg.DoModal()==IDOK) { strBMPpath = dlg.GetPathName(); } else { return ; } BMPDlgImg.Load(strBMPpath); m_nWidth = BMPDlgImg.GetWidth(); m_nHeight = BMPDlgImg.GetHeight(); m_nDepth = BMPDlgImg.GetBPP(); if(m_pView != NULL) { m_pView->SetFocus(); m_pView->m_BMPViewImg = BMPDlgImg; m_pView->SetWindowPos(NULL, 0, 0, m_nWidth, m_nHeight + 10, SWP_NOREPOSITION); m_pView->CenterWindow(GetDesktopWindow()); m_pView->Invalidate(); } else { m_pView = new CBMPVeiw(); m_pView->m_BMPViewImg = BMPDlgImg; m_pView->Create(IDD_BMPViewDlg, GetDesktopWindow()); m_pView->ShowWindow(SW_SHOW); } }
------------------------------------------------------------------------------------
BOOL CBMPVeiw::OnInitDialog() { CDialogEx::OnInitDialog(); m_pParent = (CBMPDlg*)AfxGetMainWnd(); SetWindowPos(NULL, 0, 0, m_BMPViewImg.GetWidth(), m_BMPViewImg.GetHeight()+15, SWP_NOREPOSITION); return TRUE; } void CBMPVeiw::OnPaint() { CPaintDC dc(this); CRect rect; this->GetWindowRect(&rect); this->ScreenToClient(rect); m_BMPViewImg.StretchBlt(dc, rect, SRCCOPY); }
---------------------------------------------------------------------
다 복붙할수는 없어 일단 오류가 나는 지점만 복붙햇어요
간단하게 설명드리면 load 버튼 클릭하면 파일 불러오기 창이 떠서
파일을 선택하면 modeless창에 뿌리도록 만든 소스입니다.
CBMPDlg class에서 파일 선택한 후 else 문으로 들어가면 차례로 진행하다가
create함수에서 CBMPView class의 OnInitDialog 지나고
다시 Dlg class의 ShowWindow 거쳐 View class의 OnPaint 함수로 들어갑니다.
이 때 차례로 진행 되다가 m_BMPViewImg.Stretchblt(); 지나면
debug assertion failed 오류가 뜨네요ㅠㅠㅠㅠ
어떻게 수정해야할까요?? 조언 부탁드려요ㅠㅠㅠ!!!
+ call stack 으로 추적해보니 stretchblt는 잘넘어가는데
atlimage.h의 CImage::ReleaseDC()에서 말썽이네요...!
inline void CImage::ReleaseDC() const throw() { HBITMAP hBitmap; ATLASSUME( m_hDC != NULL ); m_nDCRefCount--; if( m_nDCRefCount == 0 ) { hBitmap = HBITMAP( ::SelectObject( m_hDC, m_hOldBitmap ) ); ATLASSERT( hBitmap == m_hBitmap ); s_cache.ReleaseDC( m_hDC ); m_hDC = NULL; } }
여기 중에서도 ATLASSERT( hBitmap == m_hBitmap );
이 부분 때문에 그러는 것 같은데ㅠㅠ 이유가 뭘까요??
Forums:
MSDN 확인해보시면...
인자값. 리턴값. 오류값을 하나씩 확인해보셔야 할거 같습니다.
첫번째 인자값은 HDC
두번째 인자값은 const RECT& - (값을 얻을 경우에는 &rt 이렇게도 사용하곤 합니다. 해보니. 그냥해도 되네요. ㅇ_ㅇ'')
세번째 인자값은 DWORD 데이터형이네요.
CImage::StretchBlt
https://msdn.microsoft.com/ko-kr/library/x180d9tc.aspx
BOOL StretchBlt(
HDC hDestDC,
const RECT& rectDest,
DWORD dwROP = SRCCOPY
) const throw( );
StretchBlt function
https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd145120%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
-----------------------------------------------------
다시 확인해보니. 다이얼로그 헤더로 옮겨넣으면 되네요.
CImage BMPDlgImg;
-----------------------------------------------------
되도록 잘되는 책 예제소스를 보시면. 메모리 누수와 오류가 적을겁니다.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
아 네네! 감사해요 ㅎㅎㅎ 사실 원래 그렇게
아 네네! 감사해요 ㅎㅎㅎ
사실 원래 그렇게 했다가
컴펌 받았는데 CImage를 멤버변수로 사용하면 메모리 낭비라고 해서
그냥 지역변수로 바꿔본거 거든요ㅠㅠ 근데 어제부터 계속 매달려봐도 해결이 잘 안되네요ㅠㅠ..
아예 구조를 싹 다 바꿔야할 것 같아요 ㅠㅠ!ㅋㅋㅋㅋ
혹시 그럼 왜 지역 변수로 선언했을 때는 오류가
혹시 그럼 왜 지역 변수로 선언했을 때는 오류가 나는지 알 수 있을까요?? ㅠㅠㅠㅠ
저는 아직까지 도저히 이유도 모르겟고 해결이 안되네요..
엉터리로 포인터와 HBITMAP을 사용하니 되네요.
되기는 하지만.
책 예제 찾아보시는게 좋을겁니다.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
댓글 달기