打开任意图片,通过菜单编辑选项弹出对话框,在对话框里,通过选择不同的按钮控件计算并画出图像的灰度。编译连接OK,运行时当按下指定的按钮(预期效果是在对话框的一个区域内用图形显示图片的灰度直方图),结果出现内存错误。
下面是这个控件被选中(单击)的消息响应函数
void NewDialog::OnRadio1() 
{
// TODO: Add your control notification handler code here
//color=1;
CRect picrect;         //得到指定控件所在区域用来画图
GetDlgItem(IDC_STATIC)->GetWindowRect(&picrect);
    CMainFrame * pMain=(CMainFrame*)AfxGetApp()->m_pMainWnd ;
CMyView * pView=(CMyView*)pMain->GetActiveView ();
CMyDoc * pDc=pView->GetDocument ();
ASSERT_VALID(pDc);
    IplImage * img= (pDc->m_image).GetImage();
int count[256];     /////用数组表示灰度值为0-255的像素的个数
for(int k=0;k<256;k++) count[k]=0;///数组初始化
int i=0,j=0;
while(j<=img->height)
{
while(i<=img->width)
{
count[((uchar*)(img->imageData + img->widthStep*j))[i*3+2]]++;
i++;
}
j++;
}/////////////得到数组数据
int whole=img->width*img->height;/////用于得到等比例的图形 PAINTSTRUCT  pts;
CDC * cdc=BeginPaint(&pts);
HDC  hdc=cdc->GetSafeHdc();
    HBRUSH hbrush;
HPEN hpen;

for(int x=0;x<256;x++)
{
hpen=(HPEN)GetStockObject(255);
    hbrush=(HBRUSH)GetStockObject(255);
    SelectObject(hdc,hpen);
    SelectObject(hdc,hbrush);
Rectangle(hdc,x,img->height*(1-(count[x]/whole)),x+1,img->height);///黑色矩形条
        hpen=(HPEN)GetStockObject(0);
    hbrush=(HBRUSH)GetStockObject(0);
    SelectObject(hdc,hpen);
    SelectObject(hdc,hbrush);
        Rectangle(hdc,x,0,x+1,img->height*(1-(count[x]/whole)));//////白色矩形条,防止上次的黑色覆盖掉了非黑色区域  
}
EndPaint(&pts);
DeleteObject(hpen);
DeleteObject(hbrush);}

解决方案 »

  1.   

    下面是Doc类的定义代码,说明加入了一个CImage对象:
    #if !defined(AFX_DOC_H__2BF6E754_CD66_4D13_B56D_E8BA8CAC9F4D__INCLUDED_)
    #define AFX_DOC_H__2BF6E754_CD66_4D13_B56D_E8BA8CAC9F4D__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #include "highgui.h"class CMyDoc : public CDocument
    {
    protected: // create from serialization only
    CMyDoc();
    DECLARE_DYNCREATE(CMyDoc)
        CImage m_image;  
    // Attributes
    public:// Operations
    public:// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMyDoc)
    public:
    virtual BOOL OnNewDocument();
    virtual void Serialize(CArchive& ar);
    virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
    virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
    //}}AFX_VIRTUAL// Implementation
    public:
    virtual ~CMyDoc();
    #ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
    #endifprotected:// Generated message map functions
    protected:
    //{{AFX_MSG(CMyDoc)
    // NOTE - the ClassWizard will add and remove member functions here.
    //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_DOC_H__2BF6E754_CD66_4D13_B56D_E8BA8CAC9F4D__INCLUDED_)
      

  2.   

    新建的Dialog类定义:
    #if !defined(AFX_NEWDIALOG_H__41997884_E5A1_4661_A080_9C87C3E70BB1__INCLUDED_)
    #define AFX_NEWDIALOG_H__41997884_E5A1_4661_A080_9C87C3E70BB1__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // NewDialog.h : header file
    ///////////////////////////////////////////////////////////////////////////////
    // NewDialog dialogclass NewDialog : public CDialog
    {
    // Construction
    public:
    NewDialog(CWnd* pParent = NULL);   // standard constructor
        //int color;
    // Dialog Data
    //{{AFX_DATA(NewDialog)
    enum { IDD = IDD_DIALOG1 };
    // NOTE: the ClassWizard will add data members here
    //}}AFX_DATA
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(NewDialog)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL// Implementation
    protected: // Generated message map functions
    //{{AFX_MSG(NewDialog)
    afx_msg void OnMenuitem32771();
    afx_msg void OnRadio1();
    afx_msg void OnRadio2();
    afx_msg void OnRadio3();
    afx_msg void OnRadio4();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    };//{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_NEWDIALOG_H__41997884_E5A1_4661_A080_9C87C3E70BB1__INCLUDED_)
      

  3.   

    View类弹出窗口的代码:
    void CMyView::OnMenuitem32771() 
    {
    // TODO: Add your command handler code here
    NewDialog newdialog;
    newdialog.DoModal ();
    }
      

  4.   

    breakpoint在第13行时出现问题:
    Unhandled exception in ***.exe。0X0000005:Access Violation
    请高人指点
      

  5.   

    单步跟踪后黄色的箭头指向的那两行:
    { ASSERT(::IsWindow(m_hWnd)); ::GetWindowRect(m_hWnd, lpRect); }
    _AFXWIN_INLINE void CWnd::GetClientRect(LPRECT lpRect) const
      

  6.   

    是这一行代码出的错GetDlgItem(IDC_STATIC)->GetWindowRect(&picrect); ???
    把这个IDC_STATIC换个名字,再试试看
      

  7.   

    static是一个显示方框的控件,要在这个方框里面显示灰度直方图,没得换
      

  8.   

    GetDlgItem(IDC_STATIC)->GetWindowRect(&picrect); 
    根据出错的代码分析来看,应该是GetDlgItem(IDC_STATIC)返回为空
    确定一下这个STATIC的控件ID是不是正确
      

  9.   

    已经检查出来是因为GetDlgItem(IDC_STATIC)的返回值为空了,但是要怎么改呢?谢谢!
      

  10.   

    1 确定这个控件是不是存在2 确定这个控件的ID是不是IDC_STATIC
      

  11.   

    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    The thread 0xD5C has exited with code 1 (0x1).
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    The thread 0xF58 has exited with code 1 (0x1).
    The thread 0x9A4 has exited with code 1 (0x1).
    The thread 0x328 has exited with code 1 (0x1).
    The thread 0x764 has exited with code 1 (0x1).
    The thread 0xFF8 has exited with code 1 (0x1).
    The thread 0x7B0 has exited with code 1 (0x1).
    The thread 0xC8 has exited with code 1 (0x1).
    The thread 0xA38 has exited with code 1 (0x1).
    The thread 0xA50 has exited with code 1 (0x1).
    The thread 0xE64 has exited with code 1 (0x1).
    The thread 0x29C has exited with code 1 (0x1).
    The thread 0x2E4 has exited with code 1 (0x1).
    The thread 0xEBC has exited with code 1 (0x1).
    The thread 0x7C8 has exited with code 1 (0x1).
    The thread 0x4BC has exited with code 1 (0x1).
      

  12.   

    1.确实存在
    2.是的。
    又:做一些修改后单步运行,发现在打开图片时即出现问题。
    在弹出打开文件的对话框后,出现大量的如下信息:
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    The thread 0xAB8 has exited with code 1 (0x1).
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    The thread 0x530 has exited with code 1 (0x1).
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    The thread 0x4C8 has exited with code 1 (0x1).
    First-chance exception in 单文档直方图.exe (GDIPLUS.DLL): 0xC0000005: Access Violation.
    The thread 0x5F0 has exited with code 1 (0x1).
    The thread 0x95C has exited with code 1 (0x1).
    The thread 0x3A0 has exited with code 1 (0x1).
    打开文件的代码:
    BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName) 
    {
    if (!CDocument::OnOpenDocument(lpszPathName))
    return FALSE;

    // TODO: Add your specialized creation code here
    m_image.Load(lpszPathName);
    return TRUE;
    }
    不知道这样的代码有没有问题,我是照着别的论坛上的教程抄下来的,其中m_image是Doc里面添加的变量