Y'a quelque chose qui m'échappe

[Résolu]
Signaler
Messages postés
154
Date d'inscription
dimanche 1 avril 2001
Statut
Membre
Dernière intervention
2 octobre 2009
-
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
-
Bonjour,



ça faisait longtemps que je n'avais pas fait du win32 pur et dur (merci wxWidgets).



Voulant un peu structurer mon code, j'ai voulu essayer de faire le
maximum avec des classes, et je me suis cassé les dents dès le début:

Voici en gros le code :



class CApp

{

public:

CApp(HINSTANCE hInst);

~CApp(void);

bool Initialize(WNDPROC WndProc);

private:

HINSTANCE p_hInst;

HWND p_hWnd;

};



CApp::CApp(HINSTANCE hInst)

{

if (hInst==NULL)

p_hInst=GetModuleHandle(NULL);

else

p_hInst=hInst;

p_hWnd=NULL;

}





bool CApp::Initialize(WNDPROC WndProc)

{

WNDCLASSEX wcex;



ZeroMemory(&wcex,sizeof(WNDCLASSEX));

wcex.cbSize = sizeof(WNDCLASSEX);



wcex.style = CS_HREDRAW | CS_VREDRAW;

wcex.lpfnWndProc = WndProc;

wcex.cbClsExtra = 0;

wcex.cbWndExtra = 0;

wcex.hInstance = p_hInst;

wcex.hIcon = LoadIcon(p_hInst,(LPCTSTR)IDI_MAINICON);

wcex.hCursor = LoadCursor(NULL,IDC_ARROW);

wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);

wcex.lpszMenuName = NULL;

wcex.lpszClassName = szWindowClass;

wcex.hIconSm = LoadIcon(p_hInst,(LPCTSTR)IDI_SMALL);



RegisterClassEx(&wcex);



p_hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, p_hInst, NULL);

if (!p_hWnd) return false;



ShowWindow(p_hWnd,SW_SHOW);

UpdateWindow(p_hWnd);



return true;

}



J'ai ensuite (dans une autre fichier cpp), une fonction WNDPROC toute simple.

et je fais ceci dans la WinMain:

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPTSTR lpCmdLine,int nCmdShow)

{

MSG msg;

HACCEL hAccelTable;



// Initialize global strings

LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

LoadString(hInstance, IDS_WNDCLASS, szWindowClass, MAX_LOADSTRING);



// Création de l'application

CApp TheApp(hInstance);

if (TheApp.Initialize(MainWindowProc)==false)

return FALSE;



hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_ACCELL);



// Main message loop:

while (GetMessage(&msg, NULL, 0, 0))

{

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}



return (int) msg.wParam;

}



Le problème, c'est que j'obtiens un Acces
Violation lors de l'appel au RegisterClassEx dans CApp::Initialize, et
je n'arrive pas à savoir pourquoi.



Est-ce dû au fait que je passe la WNDPROC en paramètre ?



Merci d'avance.

5 réponses

Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
essaie en les déclarant extern de la même manière que l'original, devrait aller mieux.

extern szWindowClass[MAX_LOADSTRING];

ciao...
BruNews, MVP VC++
Messages postés
154
Date d'inscription
dimanche 1 avril 2001
Statut
Membre
Dernière intervention
2 octobre 2009
1
J'ai trouvé : ça viens des variables szWindowClass et szTitle que VC m'a créé en début de projet de la façon suivante :

#define MAX_LOADSTRING 100

TCHAR szWindowClass[MAX_LOADSTRING];

TCHAR szTitle[MAX_LOADSTRING];



Pour les utiliser avec ma classe CApp, j'avais ajouté, en début du fichier cpp :

extern TCHAR *szWindowClass,*szTitle;



J'ai remplacé ces deux variables par un texte entre guillemets, et plus de plantage.

Par contre, si quelqu'un pouvait m'expliquer quel était le problème, ça serait bien cool.

Merci d'avance.
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
OUPS, oubli du type dans la copie:
extern TCHAR szWindowClass[MAX_LOADSTRING];

ciao...
BruNews, MVP VC++
Messages postés
154
Date d'inscription
dimanche 1 avril 2001
Statut
Membre
Dernière intervention
2 octobre 2009
1
Je pensais pourtant qu'en déclarant un tableau, on pouvait utiliser le nom de ce tableau comme pointeur vers la 1ère entité.



En tout cas, ça marche en respectant la déclaration d'origine.

Merci BruNews
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
la raison est simple à comprendre (si on a fait un peu d'asm...):

TCHAR szWindowClass[MAX_LOADSTRING];
est un tableau à une adresse, le compilo écrira:
mov dword ptr[esp+x], offset szWindowClass
qui est adresse du tableau.

TCHAR *szWindowClass,*szTitle;
mov dword ptr[esp+x], szWindowClass
et tu te retrouves avec les 4 premiers octets qui vont faire pointer sur une adresse invalide.

ciao...
BruNews, MVP VC++