Note that there are some explanatory texts on larger screens.

plurals
  1. PO"Unresolved external _WinMain@16" if I move WndProc to another cpp file
    primarykey
    data
    text
    <p>For a Windows application I'm trying to get <code>CreateWindow()</code> and <code>WndProc()</code> (or my versions of them) to be part of a singleton class that is created at the beginning of <code>_tWinMain()</code> but since trying to shift the functions to <code>GameHandler.h</code> and <code>GameHandler.cpp</code> I keep getting "unresolved external symbol _WinMain@16". They were originally global functions in <code>main.cpp</code> and everything was compiling fine then I decided to move them to GameHandler and ever since all I get is the unresolved external, even if I try to move them back to <code>main.cpp</code>.</p> <p>I'm doing this in VS2010, the project was created as a Windows Application and there's no specific entry point set in properties (I double checked as every solution I've found so far says that it's because it's a console app - this isn't). </p> <p>The code I currently have is shown below. The actual project has a couple of thousand lines of other code that I've left out as I don't think it's relevant (but will happily proved wrong. While the actual window creation code is related, I don't think the code itself is the problem (apart from what I left in), it's the location of GameWindowProc() &amp;/or CreateGameWindow() or how they're called. The actual window creation code is taken from <a href="http://nehe.gamedev.net/tutorial/creating_an_opengl_window_%28win32%29/13001/" rel="nofollow">NeHe's tutorial</a>. Trying to compile the following code only gives the aforementioned unresolved external.</p> <p>main.cpp:</p> <pre><code>#include &lt;Windows.h&gt; #include "GameManager.h" #ifndef USEGMGR bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag); LRESULT CALLBACK GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); #endif int APIENTRY _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, int nCmdShow) { GameManager::Startup(); GameManager* GMgr = GameManager::GetInstance(); GMgr-&gt;SetProgramState(GAME_MODE); while(GMgr-&gt;GetProgramState() != GAME_MODE) // Normally this would be if (State != GAME_QUIT) { /* do game related stuff */ } GameManager::Shutdown(); return 0; } #ifndef USEGMGR bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag) { // Fairly complex but flexible creation code, taken from NeHe's tutorials. Of relevant interest is: WNDCLASS wc; // Windows Class Structure wc.lpfnWndProc = (WNDPROC) GameWindowProc; // WndProc Handles Messages if (!RegisterClass(&amp;wc)) // Attempt To Register The Window Class { MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION); return false; } return true; } LRESULT CALLBACK GameWindowProc(HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { // various custom message handling, if not processed: return DefWindowProc(hWnd,uMsg,wParam,lParam); } #endif </code></pre> <p>in GameManager.h:</p> <pre><code>#ifndef GAMEMANAGER_H #define GAMEMANAGER_H #define USEGMGR // makes CreateGameWindow() and GameWindowProc() methods in GameManager instead of global #include &lt;Windows.h&gt; enum ProgramState { GAME_MODE, GAME_QUIT, }; class GameManager { public: static void Startup(); static void Shutdown(); static GameManager* GetInstance(); void Update(); // code not shown, check quit key etc #ifdef USEGMGR const bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag); static LRESULT CALLBACK GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); #endif void KillGameWindow(void); const int GetProgramState() const; void SetProgramState(const int&amp; newMode); private: GameManager(); ~GameManager(); GameManager(const GameManager&amp;); GameManager&amp; operator=(const GameManager&amp;); HINSTANCE m_hInstance; HWND m_hWnd; HDC m_hDC; static GameManager* s_instance; int m_programState; // uses ProgramState enum }; #endif </code></pre> <p>in GameManager.cpp:</p> <pre><code>#include "GameManager.h" #include &lt;Windows.h&gt; #include &lt;assert.h&gt; #ifndef USEGMGR extern bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag); #endif GameManager* GameManager::s_instance = NULL; GameManager::GameManager(){} GameManager::~GameManager(){} void GameManager::Startup() { assert(s_instance == NULL); s_instance = new GameManager; #ifdef USEGMGR if (! (s_instance-&gt;CreateGameWindow("Game Window", 800, 600, 32, true )) ) #else if (! (CreateGameWindow("Game Window", 800, 600, 32, true )) ) #endif assert("CreateGameWindow failed! Need an error here"); // Quit If Window Was Not Created - clean this up later } void GameManager::Shutdown() { assert(s_instance != NULL); delete s_instance; s_instance = NULL; } GameManager* GameManager::GetInstance(){return s_instance;} void GameManager::Update(){/* msg handling, watch for quit key, etc */} const int GameManager::GetProgramState() const{return s_instance-&gt;m_programState;} void GameManager::SetProgramState(const int&amp; newState){s_instance-&gt;m_programState = newState;} #ifdef USEGMGR const bool GameManager::CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag) { // Fairly complex but flexible creation code, taken from NeHe's tutorials. Of relevant interest is: WNDCLASS wc; // Windows Class Structure wc.lpfnWndProc = (WNDPROC) GameManager::GameWindowProc; // WndProc Handles Messages if (!RegisterClass(&amp;wc)) // Attempt To Register The Window Class { MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION); return false; } return true; } LRESULT CALLBACK GameManager::GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // various custom message handling, if not processed: return DefWindowProc(hWnd,uMsg,wParam,lParam); } #endif </code></pre> <p>As you can see, I've set up some preprocessor conditionals to switch between the troublesome functions being in <code>main.cpp</code> or as part of GameManager. Comment out <code>#define USEGMGR</code> at the beginning of <code>GameManager.h</code> to have them as global funcs in <code>main.cpp</code>.</p> <p>Can someone please tell me what I'm doing wrong?</p> <p><em>Edit:</em> removed comment about not being able to quit if you get it to run.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload