0

I try to display a bitmap (gray image) by using MFC but failed. I am using standard windows API in my MFC codes. Below is the code (view.cpp and I put own code in ::OnDraw()):

lpBits is the BYTE array contains the bitmap BYTE data. When I run the code, I got an "exception thrown" error message and no display of the bitmap (a black bitmap image). Below you can find the code as well as the error message.

extern BYTE lpBits[510][1024 * 4] = { 0 };
extern CRITICAL_SECTION g_cs;

View.h:

class Cmfc_gui_test1View : public CView
{
protected: // create from serialization only
    Cmfc_gui_test1View();
    DECLARE_DYNCREATE(Cmfc_gui_test1View)

// Attributes
public:
    Cmfc_gui_test1Doc* GetDocument() const;

// Operations
public:

// Overrides
public:
    virtual void OnDraw(CDC* pDC);  // overridden to draw this view
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// Implementation
public:
    virtual ~Cmfc_gui_test1View();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
    afx_msg void OnFilePrintPreview();
    afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
    DECLARE_MESSAGE_MAP()

public:
    CBitmap* pBitmap;
    CDC*    pcdcMem;
    CDC*    m_pDC;
    CRect   crect;
    CWnd*   pwndParent;
    int screenX;
    int screenY;
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};

View.cpp:
// Cmfc_gui_test1View drawing

void Cmfc_gui_test1View::OnDraw(CDC* pDC)
{
    Cmfc_gui_test1Doc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: add draw code for native data here

    screenX = GetSystemMetrics(SM_CXSCREEN);
    screenY = GetSystemMetrics(SM_CYSCREEN);

    pBitmap->CreateCompatibleBitmap(m_pDC, 1024, 510);  // Error here
    
    pBitmap->SetBitmapBits(510*1024*4, lpBits);

    pcdcMem->CreateCompatibleDC(m_pDC);
    pcdcMem->SelectObject(pBitmap);
    
    m_pDC->StretchBlt( 0, 0, screenX, screenY, pcdcMem, 0, 0, 1024, 510, SRCCOPY);

    pDC->DeleteDC();
}


// Cmfc_gui_test1View message handlers


int Cmfc_gui_test1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;

    // TODO:  在此添加您专用的创建代码
    m_pDC = new CClientDC(this);

    return 0;
}

Error message occurs when execution hits the line pBitmap->CreateCompatibleBitmap(m_pDC, 1024, 510);:

0x0F7C0AEA (mfc140d.dll)处(位于 mfc_gui_test1.exe 中)引发的异常: 0xC0000005: 读取位置 0xCDCDCDD1 时发生访问冲突。

如有适用于此异常的处理程序,该程序便可安全地继续运行。    

Translated:

Exception thrown at 0x0F7C0AEA (mfc140d.dll) (in mfc_gui_test1.exe): 0xC0000005: Access violation while reading location 0xCDCDCDD1.

If there is a handler for this exception, the program can safely continue running.
JaMiT
  • 14,422
  • 4
  • 15
  • 31
Brian Bai
  • 15
  • 5
  • 1
    It looks like you have a lot of irrelevant code in your example. (E.g., why all those functions related to printing?) Your code should be laser-focused on just what is needed to reproduce the error, a.k.a. a [mre]. Please remove the noise. – JaMiT Jan 10 '22 at 05:35
  • Done of the removing those irrelvant codes and adding the error message info. – Brian Bai Jan 10 '22 at 16:59
  • That is better. Now a bad translation won't interfere with getting help. The error is not "an interrupt of the exception", but an unhandled exception. Furthermore, the exception is not the thing to focus on -- the core error is the second part, "Access violation while reading location [uninitialized pointer]". This is a reason why the original error message should be included verbatim in a question here, even when the message is not in English. (It's also a good idea to provide an English translation to help people get started answering.) – JaMiT Jan 11 '22 at 00:58
  • As for your code, it looks like you've trimmed off too much, as `pBitmap` has no declaration. (Also, it has no initialization, but that might be the case in your code as well.) A good next step is identifying which line triggers the access violation. Then focus on that line. Make sure everything used in that line has a definition, and include any initialization that is performed on those things. – JaMiT Jan 11 '22 at 01:04
  • Hi thanks for highlighting this. Sorry that I delete too much. Now I added ::OnCreate section. I've got the program verified that the line trigger the error is: pBitmap->CreateCompatibleBitmap(m_pDC, 1024, 510); I also replace all m_pDC with pDC in OnDraw function. No lucky to see any improvement. – Brian Bai Jan 11 '22 at 03:23
  • Yes, the translation of the error message is: "Exception thrown at 0x0FC40AEA (mfc140d.dll) (in mfc_gui_test1.exe): 0xC0000005: Access violation while reading location 0xCDCDCDD1. If there is a handler for this exception, the program can safely continue running." Sorry for the inconvenience. – Brian Bai Jan 11 '22 at 03:26
  • By using CClientDC dc(this) and using dc to replace pDC , now I can have a normal display of a black screen in my client window. The result is what I want. Now looks my initial issue is fail to connect "this" to pDC pointer. Can someone highlight it to me? What is "this" ? Thanks. – Brian Bai Jan 11 '22 at 04:30
  • *"Now I added ::OnCreate section."* -- that's good, but there is still no initialization of `pBitmap`. So that is most likely your issue. See [Access violation reading location 0xcdcdcdcd error on calling a function](https://stackoverflow.com/questions/17993591/c-access-violation-reading-location-0xcdcdcdcd-error-on-calling-a-function) – JaMiT Jan 12 '22 at 00:45
  • Thanks JaMiT ! It is fixed by implementing: CBitmap* pBitmap=new CBitmap; Now pBitmap is not a float pointer. Thanks for your help! – Brian Bai Jan 12 '22 at 02:56

0 Answers0