关于VC的古怪问题 我在stdafx.h定义了一个宏,然后在CXXXView.cpp里使用这个宏,编译时竟然报告undefined identifer的错误。请问这是怎么回事啊。谢谢。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 把这个宏放在CXXXView.cpp中试试 CXXXView.cpp中有#include "stdafx.h"吗? CXXXView.cpp中有#include "stdafx.h"吗? 问题大概找到了,不知谁在CMyDraw.h的开头加了一句#include "stdafx.h"注掉这句就好了。不过还是不明白加上这句为何报错? 但同时还有一个错误是在MainFrame.cpp里我用了一句bmpMark.LoadOEMBitmap(OBM_CHECK);然而VC报告这个OBM_CHECK是undefined identifer。我用VC Assist 6都可以看到他的值是32760.现在我把MainFrame.h和MainFrame.cpp贴一下,请注意,上边报错的这句在MainFrame.cpp的OnDrawItem函数里// MainFrm.h : interface of the CMainFrame class///////////////////////////////////////////////////////////////////////////////#if !defined(AFX_MAINFRM_H__112FC2C4_0DEE_4284_AE76_ED7AFEA526AF__INCLUDED_)#define AFX_MAINFRM_H__112FC2C4_0DEE_4284_AE76_ED7AFEA526AF__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class CMainFrame : public CFrameWnd{ protected: // create from serialization only CMainFrame(); DECLARE_DYNCREATE(CMainFrame)// Attributespublic:// Operationspublic:// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMainFrame) public: virtual BOOL PreCreateWindow(CREATESTRUCT& cs); //}}AFX_VIRTUAL// Implementationpublic: virtual ~CMainFrame();#ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const;#endifprotected: // control bar embedded members CStatusBar m_wndStatusBar; CToolBar m_wndToolBar;// Generated message map functionsprotected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); //}}AFX_MSG afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis); afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis); DECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MAINFRM_H__112FC2C4_0DEE_4284_AE76_ED7AFEA526AF__INCLUDED_)////////////////////////////////////////////////////////////////////////////////////////// MainFrm.cpp : implementation of the CMainFrame class//#include "stdafx.h"#include "MyDraw.h"#include "MainFrm.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CMainFrameIMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() //}}AFX_MSG_MAP ON_WM_MEASUREITEM() ON_WM_DRAWITEM()END_MESSAGE_MAP()static UINT indicators[] ={ ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL,};/////////////////////////////////////////////////////////////////////////////// CMainFrame construction/destructionCMainFrame::CMainFrame(){}CMainFrame::~CMainFrame(){}int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){ if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } // TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0;}BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs){ if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE | WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_MAXIMIZE; return TRUE;}void CMainFrame::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis){ lpmis->itemHeight = ::GetSystemMetrics(SM_CYMENU); lpmis->itemWidth = lpmis->itemHeight * 4;}void CMainFrame::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis){ COLORREF colorItem; //select color according menu item switch (lpdis->itemID) { case ID_TOOL_BLACK: colorItem = RGB(0, 0, 0); break; case ID_TOOL_RED: colorItem = RGB(255, 0, 0); break; case ID_TOOL_YELLOW: colorItem = RGB(255, 255, 0); break; case ID_TOOL_GREEN: colorItem = RGB(0, 255, 0); break; case ID_TOOL_CYAN: colorItem = RGB(0, 255, 255); break; case ID_TOOL_BLUE: colorItem = RGB(0, 0, 255); break; } /////////////////////////////////////////////////////////// // draw each item of the menu CDC dc; dc.Attach(lpdis->hDC); // draw the backgroud of menu item CBrush * pBrushFrame = new CBrush(::GetSysColor((lpdis->itemState & ODS_SELECTED)? COLOR_HIGHLIGHT : COLOR_MENU)); dc.FrameRect(&(lpdis->rcItem), pBrushFrame); // draw the check if(lpdis->itemState & ODS_CHECKED) { BITMAP bm; CBitmap bmpCheck; bmpCheck.LoadOEMBitmap(OBM_CHECK); bmpCheck.GetBitmap(&bm); CDC dcMem; dcMem.CreateCompatibleDC(&dc); CBitmap * pOldBmp = dcMem.SelectObject(&bmpCheck); dc.BitBlt( lpdis->rcItem.left + 2, lpdis->rcItem.top + ((lpdis->rcItem.bottom - lpdis->rcItem.top) - bm.bmHeight) / 2 , lpdis->rcItem.bottom - lpdis->rcItem.top, lpdis->rcItem.bottom - lpdis->rcItem.top, &dcMem, 0, 0, SRCCOPY ); dcMem.SelectObject(pOldBmp); } // draw color item CRect rectMenuItem(lpdis->rcItem.left + (lpdis->rcItem.bottom - lpdis->rcItem.top), lpdis->rcItem.top, lpdis->rcItem.right, lpdis->rcItem.bottom); rectMenuItem.DeflateRect(0, 2, 3, 2); CBrush brush(colorItem); dc.FillRect(&rectMenuItem, &brush); //end drawing dc.Detach(); }/////////////////////////////////////////////////////////////////////////////// CMainFrame diagnostics#ifdef _DEBUGvoid CMainFrame::AssertValid() const{ CFrameWnd::AssertValid();}void CMainFrame::Dump(CDumpContext& dc) const{ CFrameWnd::Dump(dc);}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CMainFrame message handlers 第一,你在VIEW里面去掉#include "stdafx.h"这个是不行的,会出问题。第二,MAINFRAME里面你搜索到包含这个定义的头文件,然后加上去就可以了。 也没想让大家看全部的啊,只是我提供出来供参考。OBM_CHECK这个宏是在<afxwin.h>里定义的,而<afxwin.h>是被include在"stdafx.h"里的啊。这个宏是MFC自己的,不是我加的。另外楼上的话也有道理,不过问题是我去掉了反而确实正常运行了啊。这正是我觉得怪异的地方 树控件拖动问题 希望大家帮忙解决下这个问题!谢谢 问一个system的问题,分数不多,希望能得到解决 如何获得当前浏览页的所有框架(CHtmlView) 欢迎大家来看看这个软件,题些宝贵意见! 关于640K基本内存的问题!!! 请教: 如何知道某个窗口获得当前的焦点? 如何得到按键呀? 求助:实现图形学里的一些变换 请问如何解释执行一个自定义脚本文本? 还是处理中文英文和标点的问题 在生成 .exe文件时总出错,请大侠们帮忙,再现等=====
#include "stdafx.h"注掉这句就好了。不过还是不明白加上这句为何报错?
bmpMark.LoadOEMBitmap(OBM_CHECK);
然而VC报告这个OBM_CHECK是undefined identifer。我用VC Assist 6都可以看到他的值是32760.
现在我把MainFrame.h和MainFrame.cpp贴一下,请注意,上边报错的这句在MainFrame.cpp的OnDrawItem函数里// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////#if !defined(AFX_MAINFRM_H__112FC2C4_0DEE_4284_AE76_ED7AFEA526AF__INCLUDED_)
#define AFX_MAINFRM_H__112FC2C4_0DEE_4284_AE76_ED7AFEA526AF__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)// Attributes
public:// Operations
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endifprotected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis);
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis);
DECLARE_MESSAGE_MAP()
};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MAINFRM_H__112FC2C4_0DEE_4284_AE76_ED7AFEA526AF__INCLUDED_)////////////////////////////////////////////////////////////////////////////////////////
// MainFrm.cpp : implementation of the CMainFrame class
//#include "stdafx.h"
#include "MyDraw.h"#include "MainFrm.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMainFrameIMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_WM_MEASUREITEM()
ON_WM_DRAWITEM()
END_MESSAGE_MAP()static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destructionCMainFrame::CMainFrame()
{}CMainFrame::~CMainFrame()
{
}int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
} if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
} // TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar); return 0;
}BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE
| WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_MAXIMIZE; return TRUE;
}void CMainFrame::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis)
{
lpmis->itemHeight = ::GetSystemMetrics(SM_CYMENU);
lpmis->itemWidth = lpmis->itemHeight * 4;
}void CMainFrame::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis)
{
COLORREF colorItem;
//select color according menu item
switch (lpdis->itemID)
{
case ID_TOOL_BLACK:
colorItem = RGB(0, 0, 0);
break;
case ID_TOOL_RED:
colorItem = RGB(255, 0, 0);
break;
case ID_TOOL_YELLOW:
colorItem = RGB(255, 255, 0);
break;
case ID_TOOL_GREEN:
colorItem = RGB(0, 255, 0);
break;
case ID_TOOL_CYAN:
colorItem = RGB(0, 255, 255);
break;
case ID_TOOL_BLUE:
colorItem = RGB(0, 0, 255);
break;
}
///////////////////////////////////////////////////////////
// draw each item of the menu
CDC dc;
dc.Attach(lpdis->hDC); // draw the backgroud of menu item
CBrush * pBrushFrame = new CBrush(::GetSysColor((lpdis->itemState & ODS_SELECTED)? COLOR_HIGHLIGHT : COLOR_MENU));
dc.FrameRect(&(lpdis->rcItem), pBrushFrame); // draw the check
if(lpdis->itemState & ODS_CHECKED)
{
BITMAP bm;
CBitmap bmpCheck;
bmpCheck.LoadOEMBitmap(OBM_CHECK);
bmpCheck.GetBitmap(&bm);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap * pOldBmp = dcMem.SelectObject(&bmpCheck);
dc.BitBlt( lpdis->rcItem.left + 2,
lpdis->rcItem.top + ((lpdis->rcItem.bottom - lpdis->rcItem.top) - bm.bmHeight) / 2 ,
lpdis->rcItem.bottom - lpdis->rcItem.top,
lpdis->rcItem.bottom - lpdis->rcItem.top,
&dcMem,
0,
0,
SRCCOPY
);
dcMem.SelectObject(pOldBmp);
}
// draw color item
CRect rectMenuItem(lpdis->rcItem.left + (lpdis->rcItem.bottom - lpdis->rcItem.top),
lpdis->rcItem.top,
lpdis->rcItem.right,
lpdis->rcItem.bottom);
rectMenuItem.DeflateRect(0, 2, 3, 2);
CBrush brush(colorItem);
dc.FillRect(&rectMenuItem, &brush); //end drawing
dc.Detach(); }/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
OBM_CHECK这个宏是在<afxwin.h>里定义的,而<afxwin.h>是被include在"stdafx.h"里的啊。这个宏是MFC自己的,不是我加的。另外楼上的话也有道理,不过问题是我去掉了反而确实正常运行了啊。这正是我觉得怪异的地方