错误 C1010:查找预编译 header 时文件意外结束。您是否忘记在源代码中添加“#include "stdafx.h"”?

error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?

我有一个项目,最初是在 Microsoft Visual C++ 上开发的。 NET,版本 7.0.9466,它工作得很好。我尝试使用 MS 2013 来 运行 我的项目,当我尝试构建项目时,出现此错误信息:

error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?

我已经做过的一些动作:

IntelliSense: cannot open source file "stdafx.h"

这是我收到此消息错误的 .cpp 文件

#include "../stdafx.h"
#include "timedmsgbox.h"

/////////////////////////////////////////////////////////////////////////
//
// CDlgTimedMessageBox
//
/////////////////////////////////////////////////////////////////////////

CMapPtrToPtr  CDlgTimedMessageBox::m_mapTimerIdToClassMe;
CCriticalSection CDlgTimedMessageBox::m_sectMap;
extern BOOL AFXAPI AfxIsDescendant(HWND hWndParent, HWND hWndChild);

// the static one to call the messagebox with one line
UINT CDlgTimedMessageBox::TimedMessageBox(UINT flags, LPCTSTR ptszMessage, LPCTSTR ptszTitle, 
      DWORD dwTimeout, UINT dDefaultReturn,
      LPCTSTR ptszMessageTimer, HWND hwndParent, BOOL *pbStoppedByUser)
{
 CDlgTimedMessageBox  msgBox(flags, ptszMessage, ptszTitle, 
         dwTimeout, dDefaultReturn, 
         ptszMessageTimer, hwndParent);

 return msgBox.ShowMessageBox(pbStoppedByUser);
}

CDlgTimedMessageBox::CDlgTimedMessageBox(UINT flags, 
        LPCTSTR ptszMessage, LPCTSTR ptszTitle, 
        DWORD dwTimeout, UINT dDefaultReturn,
        LPCTSTR ptszMessageTimer, 
        HWND hwndParent)
{
 m_hParent   = hwndParent;
 m_Message   = ptszMessage;
 m_Title    = ptszTitle;
 m_flags    = flags;
 m_dwTimeout   = dwTimeout-1;
 m_MessageTimer  = ptszMessageTimer;
 m_DefaultReturn  = dDefaultReturn;
 
 m_hMsgBox   = NULL;
 m_hStaticText  = NULL;
 m_hDefaultButton = NULL;
 m_bRunning   = FALSE;
 m_bStoppedByTimer = FALSE;

 if( !m_hParent )
 {
  CWnd *m_pParent = AfxGetApp()->GetMainWnd();
  m_hParent = m_pParent->m_hWnd;
 }
}

CDlgTimedMessageBox::~CDlgTimedMessageBox()
{
}

#pragma warning( push)
#pragma warning (disable : 4312) // conversion to type of greater size
UINT CDlgTimedMessageBox::ShowMessageBox(BOOL *pbStoppedByUser)
{
 // start timer 
 CDlgTimedMessageBox::m_sectMap.Lock();
 {
  m_idTimer = (UINT)::SetTimer(NULL, 0, 1000, (TIMERPROC) CDlgTimedMessageBox::GlobalTimerProc);
  CDlgTimedMessageBox::m_mapTimerIdToClassMe.SetAt((void*)m_idTimer, this);
 }
 CDlgTimedMessageBox::m_sectMap.Unlock();
 
 // show MessageBox
 m_bRunning = TRUE;
 m_dwStarted = ::GetTickCount();
 
 m_CurrentMessage = m_Message;
 if( !m_MessageTimer.IsEmpty() )
 {
  CString second;
  second.Format(m_MessageTimer, (m_dwTimeout+1)/1000);
  m_CurrentMessage.Format("%s%s", m_Message, second);
 }
 UINT erg = ::MessageBox(m_hParent, m_CurrentMessage, m_Title, m_flags);
 m_bRunning = FALSE;

 CDlgTimedMessageBox::m_sectMap.Lock();
 {
  ::KillTimer(NULL, m_idTimer);
  m_idTimer = 0;
  CDlgTimedMessageBox::m_mapTimerIdToClassMe.RemoveKey((void*)m_idTimer);
 }
 CDlgTimedMessageBox::m_sectMap.Unlock();

 if( pbStoppedByUser )
  *pbStoppedByUser = !m_bStoppedByTimer;
 
 return erg;
}
#pragma warning( pop )

void CALLBACK CDlgTimedMessageBox::GlobalTimerProc(HWND hwnd, UINT uiMsg, UINT_PTR idEvent, DWORD dwTime)
{
 //TRACE("Global timer with id=%u\n", idEvent);
 
 CDlgTimedMessageBox *pMe = NULL;
 
 // Find the corresponding class by the timer-id
 CDlgTimedMessageBox::m_sectMap.Lock();
 {
  CDlgTimedMessageBox::m_mapTimerIdToClassMe.Lookup((void*)idEvent, (void *&) pMe);
 } 
 CDlgTimedMessageBox::m_sectMap.Unlock();
 
 if( pMe!=NULL )
  pMe->LocalTimerProc();
}

void CDlgTimedMessageBox::LocalTimerProc(void)
{
 //TRACE("Local timer with id=%u (%s)\n", m_idTimer, m_Title);

 if( !m_bRunning )
  return;

 // lookup the handles 
 GetWindowHandles();


 if( !m_hStaticText || !m_hMsgBox )
  return;

 DWORD now = GetTickCount()-m_dwStarted;
 
 if( now >= (m_dwTimeout) )
 {
  // done with the box
  m_bStoppedByTimer = TRUE;
  ::PostMessage(m_hMsgBox, WM_COMMAND, (WPARAM) m_DefaultReturn, (LPARAM) m_hDefaultButton);
 }
 else
 {
  m_CurrentMessage = m_Message;
 
  // not done: set text again
  if( !m_MessageTimer.IsEmpty() )
  {
   CString second;
   second.Format(m_MessageTimer, (100+m_dwTimeout-now)/1000);
   m_CurrentMessage.Format("%s%s", m_Message, second);
  }
  ::SetWindowText(m_hStaticText, m_CurrentMessage);
 } 
}

void CDlgTimedMessageBox::GetWindowHandles(void)
{
 HWND  hWnd;
 CWnd  *pWnd;
 CString  title;
 CPtrList allButtons;

 //
 // Handle of the messageBox
 //
 if( !m_hMsgBox )
 {
  hWnd = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
  while( (hWnd!=NULL) && (m_hMsgBox==NULL) )
  {
   pWnd = CWnd::FromHandle(hWnd);
   pWnd->GetWindowText(title);

   if( AfxIsDescendant(m_hParent, hWnd) && ::IsWindowVisible(hWnd) && (m_Title.CompareNoCase(title)==0) )
   {
    m_hMsgBox = hWnd;
    break;
   }
   
   hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  }
 }

 //
 // Handle of the static text
 // TODO only if text-replace is needed
 //
 if( m_hMsgBox && !m_hStaticText )
 {
  // not sure if this will work always
  // under Win2000 it did
  //m_hStaticText = ::GetDlgItem(m_hMsgBox, 0xFFFF);

  // not sure, so lets find it dynamically!

  char  className[_MAX_PATH];
  CString  classNameOk("STATIC");
  LONG  id;

  hWnd = ::GetWindow(m_hMsgBox, GW_CHILD);
  while( (hWnd!=NULL) && (m_hStaticText==NULL) )
  {
   id = ::GetWindowLong(hWnd, GWL_ID);
   
   // small ids only for buttons
   if( id > IDHELP )
   {
    if( ::GetClassName(hWnd, className, _MAX_PATH) )
    {

     // looking only for a static 
     if( classNameOk.CompareNoCase(className) == 0 )
     {
      // not check the text
      pWnd = CWnd::FromHandle(hWnd);
      pWnd->GetWindowText(title);
      
      if( m_CurrentMessage.CompareNoCase(title) == 0 )
      {
       m_hStaticText = hWnd;
       break;
      }

     }
    }
   }
   else
   {
    allButtons.AddTail(hWnd);
   }

   hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  }

 }

 //
 // Handle of the default button
 //
 if( m_hMsgBox && !m_hDefaultButton )
 {
  m_hDefaultButton = ::GetDlgItem(m_hMsgBox, m_DefaultReturn);
  
  // Problem: 
  // if generated with MB_OK the button has NOT IDOK, but IDCANCEL !!
  // then lets take the first button we find !
  // (with and IDCANCEL this works, because it is the only button
  // if this problem encounters also with 2 buttons, I have no chance 
  // to find out which one is the better one!)
  while( allButtons.GetCount()>0 && !m_hDefaultButton )
  {
   m_hDefaultButton = (HWND) allButtons.GetHead();
   allButtons.RemoveHead();
   
   if( m_hDefaultButton )
    m_DefaultReturn = ::GetWindowLong(m_hDefaultButton, GWL_ID);
  }
 }
}

这里是 stdafx.h 文件

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently

#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN  // Exclude rarely-used stuff from Windows headers
#endif

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER    // Allow use of features specific to Windows 95 and Windows NT 4 or later.
//#define WINVER 0x0400  // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#define WINVER 0x0602       // SMS2014XXXX alteração para funcionar windows 8
#endif

#ifndef _WIN32_WINNT  // Allow use of features specific to Windows NT 4 or later.
//#define _WIN32_WINNT 0x0400  // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#define _WIN32_WINNT 0x0602       // SMS2014XXXX alteração para funcionar windows 8
#endif      

#ifndef _WIN32_WINDOWS  // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif

#ifndef _WIN32_IE   // Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
#endif

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit

// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes
#include <afxdtctl.h>  // MFC support for Internet Explorer 4 Common Controls

#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>   // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

#include <afxdhtml.h>

我是 visual studio 的新手,我不知道这一切有什么问题。有人可以帮我吗?

这是智能感知和编译器之间的混淆。

您应该可以通过将 $(ProjectDir) 添加到应用程序的 Additional Include Directories 选项并将 "..\StdAfx.h" 替换为 "StdAfx.h" 来解决此问题,因为智能感知现在应该启动了拾取路径。

添加此内容是因为我在努力将 .pch 添加到项目时 post 阅读了此内容。

将 .pch 添加到现有项目时: 如果你有 /include 和 /src 目录结构,它可能不起作用,除非你将“pch.h”和“pch.cpp”放在同一个目录 /src.

此外:将“pch.cpp”标记为 /Yc - 创建,并在要使用 .pch 的 .cpp 文件中将它们设置为 Yu - 使用。

#include “pch.h”作为 .cpp

中的第一个#include

注意。您需要为所有不包含它们的 .cpp 文件设置“不使用预编译头文件”。是的,这很麻烦。

VC++ 下的“附加包含目录”和一般“包含目录”都设置为我的 /include,当然 /src 在“源目录”中 最初我希望 pch.h 和 pch.cpp 在 /include/pch/ 或 /src/pch/ 这应该有效。但我现在已经受够了痛苦,只是将它们都放在 /src/ 中 - 这确实有效。

( Visual Studio 2019 )