2010-05-23 6 views
0

Je reçois des erreurs et essaye en même temps de faire ce travail alors s'il vous plaît lisez ce que j'ai à dire. Merci ....comment utiliser une méthode de classe en tant que méthode de rappel d'application WIN32 (WINPROC) ... Erreur structure statique HINSTANCE__

Je crée une application C++ et la majorité de l'application est encapsulée dans une classe. Cela signifie que ma fonction WinProc est une méthode de classe statique que j'utilise comme méthode de rappel pour mon application win32. Le problème est que depuis que j'ai créé cela en tant qu'application win32, chaque membre de classe que j'utilise à l'intérieur de cette méthode doit aussi être statique. Y compris ma classe HINSTANCE que j'utilise à l'intérieur. Maintenant, je reçois cette erreur

error LNK2001: unresolved external symbol "public: static struct HINSTANCE__ 

J'ai besoin de comprendre comment faire tout cela fonctionne et ci-dessous est ma déclaration de classe. Mon membre statique HINSTANCE m_hInst provoque l'erreur je crois.

#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; //<------ 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(); 

}; 

est inférieure à la mise en œuvre

#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(&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, &ps); 
     // TODO: Add any drawing code here... 
     EndPaint(hWnd, &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(&msg, NULL, 0, 0)) 
    { 
     if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 

    return (int) msg.wParam; 
} 

et ci-dessous est le code étant utilisé dans le WinMain

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

Si quelque chose ne fait pas de sens, je présente mes excuses, je suis newb. Merci pour l'aide!!

Répondre

2

Vous avez une déclaration d'une variable statique dans un fichier d'en-tête, mais il n'y a pas définition partout!

Quelque part dans un objet (cpp) le fichier que vous devez « affecter » la mémoire à la variable à portée globale :

HINSTANCE RenderEngine::m_hInst = NULL; 

Essayez de mettre avant la mise en œuvre InitWindow.

Les variables statiques, contrairement aux normales, peuvent exister depuis le début du programme même si aucune classe de leur type de support n'a été allouée. Par conséquent, vous devez pointer vers le compilateur une place pour eux, tout comme vous devez pointer un espace pour les variables globales lors de l'utilisation d'extern.

+0

Je pense que ça l'a fait. Merci mec. Mais j'ai aussi d'autres problèmes, mais je vais créer un autre post pour ça. – numerical25

Questions connexes