title: how to use a class method as a WIN32 application callback method (WINPROC)... Error static struct HINSTANCE__
body: <p>I am receiving errors and at the same time trying to make this work so please read what I got to say. Thanks....</p>
  
  <p>I am creating a c++ application and majority of the application is encapsulated into a class. That means that my WinProc function is a static class method that I use as my call back method for my win32 application. The problem is that since I created that as a win32 application, every class member I use inside that method has to be static as well. Including my HINSTANCE class which I use inside of it. Now I receive this error</p>
  
  <pre><code>error LNK2001: unresolved external symbol "public: static struct HINSTANCE__
  </code></pre>
  
  <p>I need to figure out how to make this all work and below is my class declaration. My static member static HINSTANCE m_hInst is causing the error I believe. </p>
  
  <pre><code>#pragma once
  #include "stdafx.h"
  #include "resource.h"
  #define MAX_LOADSTRING 100
  
  class RenderEngine {
  protected:
      int m_width;
      int m_height;
  
      ATOM RegisterEngineClass();
  
  public:
      static HINSTANCE m_hInst;   //&lt;------ This is causing the error 
      HWND m_hWnd;
      int m_nCmdShow;
      TCHAR m_szTitle[MAX_LOADSTRING];                    // The title bar text
      TCHAR m_szWindowClass[MAX_LOADSTRING];          // the main window class name
  
      bool InitWindow();
      bool InitDirectX();
      bool InitInstance();
  
      //static functions
      static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
      static INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  
      int Run();
  
  };
  </code></pre>
  
  <p>Below is the implementation </p>
  
  <pre><code>#include "stdafx.h"
  #include "RenderEngine.h"
  
  bool RenderEngine::InitWindow()
  {
      RenderEngine::m_hInst = NULL;
      // Initialize global strings
      LoadString(m_hInst, IDS_APP_TITLE, m_szTitle, MAX_LOADSTRING);
      LoadString(m_hInst, IDC_RENDERENGINE, m_szWindowClass, MAX_LOADSTRING);
  
      if(!RegisterEngineClass())
      {
          return false;
      }
  
      if(!InitInstance())
      {
          return false;
      }
  
      return true;
  }
  
  ATOM RenderEngine::RegisterEngineClass()
  {
      WNDCLASSEX wcex;
  
      wcex.cbSize = sizeof(WNDCLASSEX);
  
      wcex.style          = CS_HREDRAW | CS_VREDRAW;
      wcex.lpfnWndProc    = RenderEngine::WndProc;
      wcex.cbClsExtra     = 0;
      wcex.cbWndExtra     = 0;
      wcex.hInstance      = m_hInst;
      wcex.hIcon          = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_RENDERENGINE));
      wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
      wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
      wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_RENDERENGINE);
      wcex.lpszClassName  = m_szWindowClass;
      wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  
      return RegisterClassEx(&amp;wcex);
  }
  
  LRESULT CALLBACK RenderEngine::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  {
      int wmId, wmEvent;
      PAINTSTRUCT ps;
      HDC hdc;
  
      switch (message)
      {
      case WM_COMMAND:
          wmId    = LOWORD(wParam);
          wmEvent = HIWORD(wParam);
          // Parse the menu selections:
          switch (wmId)
          {
          case IDM_ABOUT:
              DialogBox(m_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
              break;
          case IDM_EXIT:
              DestroyWindow(hWnd);
              break;
          default:
              return DefWindowProc(hWnd, message, wParam, lParam);
          }
          break;
      case WM_PAINT:
          hdc = BeginPaint(hWnd, &amp;ps);
          // TODO: Add any drawing code here...
          EndPaint(hWnd, &amp;ps);
          break;
      case WM_DESTROY:
          PostQuitMessage(0);
          break;
      default:
          return DefWindowProc(hWnd, message, wParam, lParam);
      }
      return 0;
  }
  
  bool RenderEngine::InitInstance()
  {
     m_hWnd = NULL;
     m_hWnd = CreateWindow(m_szWindowClass, m_szTitle, WS_OVERLAPPEDWINDOW,
         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, m_hInst, NULL);
  
     if (!m_hWnd)
     {
        return FALSE;
     }
  
     if(!ShowWindow(m_hWnd, m_nCmdShow))
     {
          return false;
     }
     UpdateWindow(m_hWnd);
  
     return true;
  }
  
  // Message handler for about box.
  INT_PTR CALLBACK RenderEngine::About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  {
      UNREFERENCED_PARAMETER(lParam);
      switch (message)
      {
      case WM_INITDIALOG:
          return (INT_PTR)TRUE;
  
      case WM_COMMAND:
          if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
          {
              EndDialog(hDlg, LOWORD(wParam));
              return (INT_PTR)TRUE;
          }
          break;
      }
      return (INT_PTR)FALSE;
  }
  
  int RenderEngine::Run()
  {
      MSG msg;
      HACCEL hAccelTable;
  
      hAccelTable = LoadAccelerators(m_hInst, MAKEINTRESOURCE(IDC_RENDERENGINE));
  
      // Main message loop:
      while (GetMessage(&amp;msg, NULL, 0, 0))
      {
          if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg))
          {
              TranslateMessage(&amp;msg);
              DispatchMessage(&amp;msg);
          }
      }
  
      return (int) msg.wParam;
  }
  </code></pre>
  
  <p>and below is the code being used within the WinMain</p>
  
  <pre><code>RenderEngine go;
  
  int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
  {
      UNREFERENCED_PARAMETER(hPrevInstance);
      UNREFERENCED_PARAMETER(lpCmdLine);
  
      // TODO: Place code here.
      RenderEngine::m_hInst = hInstance;
      go.m_nCmdShow = nCmdShow;
      if(!go.InitWindow())
      {
          return 0;
      }
          go.Run();
  
      return 0;
  }
  </code></pre>
  
  <p>If anything does not make any sense, then I apologize, I am a newb. Thanks for the help!!</p>