1
votes

I have a project, originally developed on Microsoft Visual C++ . NET, Version 7.0.9466 and it works very well. I tried to use MS 2013 to run my project, and when I try to build the project, I have this error menssage:

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

Some actions that I already did:

  • I Selected the option "Use(/Yu)" on Precompiled Header in PropertyPages-> C/C++ -> Precompiled Header
  • I Set the Precompiled Header File to stdafx.h
  • I put #include "stdafx.h" at the beginning of the .cpp file
  • I had to change #include "stdafx.h" to #include "../stdafx.h" because I had this error message:

IntelliSense: cannot open source file "stdafx.h"

Here is the .cpp file where I have this message error

#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);
		}
	}
}

and here is the stdafx.h file

// 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>

I am new on visual studio and I have no ideia what's is wrong on all of this. Someone could help me with it?

1
You'll have to change the /Yc and /Yu compile options on every file. This is unpractical, just use plain "stdafx.h" so the compile options are good. And either move the .h file or use the compiler's Additional Include Directories setting.Hans Passant

1 Answers

5
votes

This is a confusion between intellisense and the compiler.

You should be able to work around it by adding $(ProjectDir) to the Additional Include Directories option for the application and replacing the "..\StdAfx.h" with "StdAfx.h" as intellisense should now start picking up the path.