question

flaviu avatar image
0 Votes"
flaviu asked RLWA32-6355 commented

Exception thrown on CDC::SelectObject

I have the following code:

 void CMyHeaderCtrl::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
 {
     LPNMLVCUSTOMDRAW pNMCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
     // TODO: Add your control notification handler code here
    
     *pResult = CDRF_DODEFAULT;
    
     switch (pNMCD->nmcd.dwDrawStage)
     {
     case CDDS_PREPAINT:
         *pResult = CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT;
         break;
     case CDDS_ITEMPREPAINT:
         break;
     case CDDS_POSTPAINT:
         CRect rect;
         GetClientRect(&rect);
         const int nWidth = rect.right - rect.left;
         const int nHeight = rect.bottom - rect.top;
    
         CDC* pDC = CDC::FromHandle(pNMCD->nmcd.hdc);
         CDC MemDC;
         MemDC.CreateCompatibleDC(pDC);
         CBitmap bitmap;
         bitmap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
         CBitmap* pOldBitmap = (CBitmap*)MemDC.SelectObject(bitmap);
         // do nothing
         MemDC.SelectObject(pOldBitmap);    // <--- error here
         DeleteObject(bitmap);
         DeleteDC(MemDC);
         break;
     }
 }

but I encountered an error:

 Exception thrown at 0x00007FFF038A5465 (mfc140ud.dll) in MyApp.exe: 0xC0000005: Access violation reading location 0x0000000000850017.


145291-image.png

Why I got this ? What is wrong here ? BTW, pOldBitmap is not null and valid.



c++
image.png (44.2 KiB)
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

CDC::SelectObject takes a CBitmap*, a pointer. You are passing CBitmap. I'm frankly not sure how this code compiles, which overload it ends up calling - but apparently not one that returns CBitmap*

0 Votes 0 ·
flaviu avatar image flaviu IgorTandetnik-1300 ·

Yes, didn't noticed. And it has compiled successfully. Weird.
Thanks.

0 Votes 0 ·

It calls CDC::SelectObject(HGDIOBJ) and returns an HGDIOBJ handle. Then the cast of HGDIOBJ to CBitmap* primes the pump for the subsequent failure. If the cast was not present the code would not compile.

0 Votes 0 ·

0 Answers