Probleme de WNDPROC

threadom Messages postés 101 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 1 novembre 2007 - 30 mars 2005 à 16:04
threadom Messages postés 101 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 1 novembre 2007 - 31 mars 2005 à 10:06
Explication

Voila j'essaye tout simplement de me faire une classe pour crée facilement des fenetres, que je compte bien sur réutilisé par la suite.

Fichier M3D_Windows.h

#include <windows.h>
#include "M3D_Messages.h"


class WINPROP {


public:
WINPROP() {
WINPROP::M_lpClassName = "MainWClass";
WINPROP::M_lpWindowName = "Sample";
WINPROP::M_dwStyle = WS_OVERLAPPEDWINDOW;
WINPROP::M_iX = CW_USEDEFAULT;
WINPROP::M_iY = CW_USEDEFAULT;
WINPROP::M_nWidth = CW_USEDEFAULT;
WINPROP::M_nHeight = CW_USEDEFAULT;
WINPROP::M_hWndParent = (HWND)NULL;
WINPROP::M_hMenu = (HMENU)NULL;
WINPROP::M_hInstance = NULL;
WINPROP::M_lpParam = (LPVOID)NULL;
};
~WINPROP() {};


void SetClassName(LPCTSTR P_lpClassName) { M_lpClassName = P_lpClassName; };
void SetWindowName(LPCTSTR P_lpWindowName) { M_lpWindowName = P_lpWindowName; };
void SetStyle(DWORD P_dwStyle) { M_dwStyle = P_dwStyle; };
void SetX(int P_iX) { M_iX = P_iX; };
void SetY(int P_iX) { M_iY = P_iX; };
void SetWidth(int P_nWidth) { M_nWidth = P_nWidth; };
void SetHeight(int P_nHeight) { M_nHeight = P_nHeight; };
void SetWndParent(HWND P_hWndParent) { M_hWndParent = P_hWndParent; };
void SetMenu(HMENU P_hMenu) { M_hMenu = P_hMenu; };
void SetInstance(HINSTANCE P_hInstance) { M_hInstance = P_hInstance; };
void SetParam(LPVOID P_lpParam) { M_lpParam = P_lpParam; };


LPCTSTR GetClassName() { return M_lpClassName; };
LPCTSTR GetWindowName() { return M_lpWindowName; };
DWORD GetStyle() { return M_dwStyle; };
int GetX() { return M_iX; };
int GetY() { return M_iY; };
int GetWidth() { return M_nWidth; };
int GetHeight() { return M_nHeight; };
HWND GetWndParent() { return M_hWndParent; };
HMENU GetMenu() { return M_hMenu; };
HINSTANCE GetInstance() { return M_hInstance; };
LPVOID GetParam() { return M_lpParam; };


private:
LPCTSTR M_lpClassName;
LPCTSTR M_lpWindowName;
DWORD M_dwStyle;
int M_iX;
int M_iY;
int M_nWidth;
int M_nHeight;
HWND M_hWndParent;
HMENU M_hMenu;
HINSTANCE M_hInstance;
LPVOID M_lpParam;


};


class M3D_WINDOW {
protected:
HINSTANCE M_hInstance;
HWND M_hWnd;
int M_iScreenWidth;
int M_iScreenHeight;
bool M_bFullScreen;
char *M_szAppName;
char *M_szAppTitle;
M3D_MESSAGE *M_mMessage;


public:
M3D_WINDOW();
M3D_WINDOW(int P_iScreenWidth, int P_iScreenHeight);
M3D_WINDOW(bool P_bFullScreen);
M3D_WINDOW(int P_iScreenWidth, int P_iScreenHeight, bool P_bFullScreen);
M3D_WINDOW(char *P_szAppName);
M3D_WINDOW(char *P_szAppName, int P_iScreenWidth, int P_iScreenHeight);
M3D_WINDOW(char *P_szAppName, bool P_bFullScreen);
M3D_WINDOW(char *P_szAppName, int P_iScreenWidth, int P_iScreenHeight, bool P_bFullScreen);


~M3D_WINDOW();


void SetInstance(HINSTANCE P_hInstance);
void SetScreenWidth(int P_iScreenWidth);
void SetScreenHeight(int P_iScreenHeight);
void SetFullScreen(bool P_bFullScreen);
void SetAppName(char *P_szAppName);
void SetAppTitle(char *P_szAppTitle);


void Init(HINSTANCE P_hInstance, char *P_szAppName, int P_iScreenWidth, int P_iScreenHeight, bool P_bFullScreen);
bool Create();
bool RegisterFrame();
bool ChangeWndProc(WNDPROC P_pWindow);
bool CreateFrame();
bool ChangeMode();
bool BuildFrame();
bool ChangeResolution();
bool RestoreResolution();
bool CenterFrame();
bool QuitApplication();
bool KillFrame();


LRESULT CALLBACK M3D_WINDOW::WindowProc(HWND P_hWnd, UINT P_uMmsg, WPARAM P_wParam, LPARAM P_lParam);
};

Fichier M3D_Windows.cpp

#include "M3D_Windows.h"


M3D_WINDOW::M3D_WINDOW() {
this->Init(NULL, "M3D Window", 640, 480, false);
}
M3D_WINDOW::M3D_WINDOW(int P_iScreenWidth, int P_iScreenHeight) {
this->Init(NULL, "M3D Window", P_iScreenWidth, P_iScreenHeight, false);
}
M3D_WINDOW::M3D_WINDOW(bool P_bFullScreen) {
this->Init(NULL, "M3D Window", 640, 480, P_bFullScreen);
}
M3D_WINDOW::M3D_WINDOW(int P_iScreenWidth, int P_iScreenHeight, bool P_bFullScreen) {
this->Init(NULL, "M3D Window", P_iScreenWidth, P_iScreenHeight, P_bFullScreen);
}
M3D_WINDOW::M3D_WINDOW(char *P_szAppName) {
this->Init(NULL, P_szAppName, 640, 480, false);
}
M3D_WINDOW::M3D_WINDOW(char *P_szAppName, int P_iScreenWidth, int P_iScreenHeight) {
this->Init(NULL, P_szAppName, P_iScreenWidth, P_iScreenHeight, false);
}
M3D_WINDOW::M3D_WINDOW(char *P_szAppName, bool P_bFullScreen) {
this->Init(NULL, P_szAppName, 640, 480, P_bFullScreen);
}
M3D_WINDOW::M3D_WINDOW(char *P_szAppName, int P_iScreenWidth, int P_iScreenHeight, bool P_bFullScreen) {
this->Init(NULL, P_szAppName, P_iScreenWidth, P_iScreenHeight, P_bFullScreen);
}
M3D_WINDOW::~M3D_WINDOW() {
free(M_szAppName);
free(M_szAppTitle);
free(M_mMessage);
}
void M3D_WINDOW::SetInstance(HINSTANCE P_hInstance) {
this->M_hInstance = P_hInstance;
}
void M3D_WINDOW::SetScreenWidth(int P_iScreenWidth) {
this->M_iScreenWidth = P_iScreenWidth;
}
void M3D_WINDOW::SetScreenHeight(int P_iScreenHeight) {
this->M_iScreenHeight = P_iScreenHeight;
}
void M3D_WINDOW::SetFullScreen(bool P_bFullScreen) {
this->M_bFullScreen = P_bFullScreen;
}
void M3D_WINDOW::SetAppName(char *P_szAppName) {
this->M_szAppName = (char *)malloc(strlen(P_szAppName)+1);
strcpy(this->M_szAppName, P_szAppName);
}
void M3D_WINDOW::SetAppTitle(char *P_szAppTitle) {
this->M_szAppTitle = (char *)malloc(strlen(P_szAppTitle)+1);
strcpy(this->M_szAppTitle, P_szAppTitle);
}
void M3D_WINDOW::Init(HINSTANCE P_hInstance, char *P_szAppName, int P_iScreenWidth, int P_iScreenHeight, bool P_bFullScreen) {
M_mMessage = new M3D_MESSAGE(P_szAppName);
this->M_hInstance = P_hInstance;
this->M_iScreenWidth = P_iScreenWidth;
this->M_iScreenHeight = P_iScreenHeight;
this->M_bFullScreen = P_bFullScreen;
this->SetAppName(P_szAppName);
this->SetAppTitle(P_szAppName);
}
bool M3D_WINDOW::Create() {
if (!this->RegisterFrame()) {
M_mMessage->MsgError("Unable to Register Frame.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Register Frame.");
}
if (!this->CreateFrame()) {
M_mMessage->MsgError("Unable to Create Frame.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Create Frame.");
}
return true;
}
bool M3D_WINDOW::RegisterFrame() {
WNDCLASS L_cWnd;
L_cWnd.style = CS_OWNDC;
L_cWnd.cbClsExtra = 0;
L_cWnd.cbWndExtra = 0;
L_cWnd.lpfnWndProc = this->WindowProc;
L_cWnd.hInstance = this->M_hInstance;
L_cWnd.hIcon = LoadIcon(this->M_hInstance, this->M_szAppName);
L_cWnd.hCursor = LoadCursor(NULL, IDC_ARROW);
L_cWnd.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
L_cWnd.lpszMenuName = this->M_szAppName;
L_cWnd.lpszClassName = this->M_szAppName;
if (!RegisterClass(&L_cWnd))
return false;
return true;
}
bool M3D_WINDOW::CreateFrame() {
if (!this->M_bFullScreen) {
if (!this->RestoreResolution()) {
M_mMessage->MsgError("Unable to Change Resolution.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Change Resolution.");
}
}
if (!this->BuildFrame()) {
M_mMessage->MsgError("Unable to Create Frame.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Create Frame");
}
if (M_bFullScreen) {
if (!ChangeResolution()) {
M_mMessage->MsgError("Unable to Change Resolution.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Change Resolution.");
}
} else {
if (!this->CenterFrame()) {
M_mMessage->MsgError("Unable to Center Frame.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Center Frame.");
}
}
if (!ShowWindow(this->M_hWnd, SW_SHOW)) {
M_mMessage->MsgError("Unable to Diplay Frame.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Display Frame.");
}
return true;
}
bool M3D_WINDOW::BuildFrame() {
WINPROP L_cWpp;
L_cWpp.SetClassName(this->M_szAppName);
L_cWpp.SetWindowName(this->M_szAppTitle);
L_cWpp.SetWidth(this->M_iScreenWidth);
L_cWpp.SetHeight(this->M_iScreenHeight);
L_cWpp.SetInstance(this->M_hInstance);
if (this->M_bFullScreen)
L_cWpp.SetStyle(WS_POPUP | WS_VISIBLE);
else
L_cWpp.SetStyle(WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE);
this->M_hWnd = CreateWindow(
L_cWpp.GetClassName(),
L_cWpp.GetWindowName(),
L_cWpp.GetStyle(),
L_cWpp.GetX(),
L_cWpp.GetY(),
L_cWpp.GetWidth(),
L_cWpp.GetHeight(),
L_cWpp.GetWndParent(),
L_cWpp.GetMenu(),
L_cWpp.GetInstance(),
L_cWpp.GetParam()
);
if (!this->M_hWnd)
return false;
return true;
}
bool M3D_WINDOW::ChangeResolution() {
DEVMODE L_uDm;
memset(&L_uDm, 0, sizeof(L_uDm));
if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &L_uDm)) {
M_mMessage->MsgError("Could Not Enum Display Settings");
return false;
}
L_uDm.dmPelsWidth = this->M_iScreenWidth;
L_uDm.dmPelsHeight = this->M_iScreenHeight;
if (ChangeDisplaySettings(&L_uDm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
M_mMessage->MsgError("Display Mode Not Compatible");
return false;
}
return true;
}
bool M3D_WINDOW::RestoreResolution() {
DEVMODE L_uDm;
memset(&L_uDm, 0, sizeof(L_uDm));
if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &L_uDm)) {
M_mMessage->MsgError("Could Not Enum Display Settings");
return false;
}
if (ChangeDisplaySettings(NULL,0) != DISP_CHANGE_SUCCESSFUL) {
M_mMessage->MsgError("Display Mode Not Compatible");
return false;
} else {
return true;
}
return true;
}
bool M3D_WINDOW::ChangeMode() {
this->KillFrame();
this->M_bFullScreen = !this->M_bFullScreen;
this->CreateFrame();
return true;
}
bool M3D_WINDOW::CenterFrame() {
RECT L_lpRect;
int L_bSetWP;
GetWindowRect(this->M_hWnd, &L_lpRect);
L_bSetWP = SetWindowPos(
this->M_hWnd,
NULL,
((GetSystemMetrics(SM_CXSCREEN) - L_lpRect.right) / 2),
((GetSystemMetrics(SM_CYSCREEN) - L_lpRect.bottom) / 2),
NULL,
NULL,
SWP_NOSIZE
);
if (L_bSetWP == 0)
return false;


return true;
}
bool M3D_WINDOW::QuitApplication() {
if (!this->KillFrame()) {
M_mMessage->MsgError("Unable to Kill Frame.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Kill Frame");
}
if (!UnregisterClass(this->M_szAppName, this->M_hInstance)) {
M_mMessage->MsgError("Unable to UnRegister Frame.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to UnRegister Frame.");
}
this->M_hInstance = NULL;
PostQuitMessage(0);
return true;
}
bool M3D_WINDOW::KillFrame() {
if (!DestroyWindow(this->M_hWnd)) {
M_mMessage->MsgError("Unable to Destroy Window.");
return false;
} else {
M_mMessage->MsgSuccess("Enable to Destroy Window.");
}
this->M_hWnd = NULL;
return true;
}
LRESULT CALLBACK M3D_WINDOW::WindowProc(HWND P_hWnd, UINT P_uMmsg, WPARAM P_wParam, LPARAM P_lParam) {
switch (P_uMmsg) {
case WM_SIZE:
break;
case WM_CREATE:
break;
case WM_PAINT:
break;
case WM_CLOSE:
this->QuitApplication();
break;
case WM_KEYDOWN:
switch (P_wParam) {
case VK_ESCAPE:
this->QuitApplication();
break;


case VK_F1:
this->ChangeMode();
break;


default:
break;
}
break;
default:
return DefWindowProc(P_hWnd, P_uMmsg, P_wParam, P_lParam);
break;
}
return 0;
}

Résultat de compilation

--------------------Configuration: PASDENOM - Win32 Release--------------------
Compiling...
Eternia.cpp
M3D_Windows.cpp
C:\Documents and Settings\Administrator\Desktop\PASDENOM\M3D_Windows.cpp(81) : error C2440: '=' : cannot convert from 'long (__stdcall M3D_WINDOW::*)(struct HWND__ *,unsigned int,unsigned int,long)' to 'long (__stdcall *)(struct HWND__ *,unsigned int
,unsigned int,long)'
There is no context in which this conversion is possible
Error executing cl.exe.
Creating browse info file...


PASDENOM.exe - 1 error(s), 0 warning(s)

Problème

C'est simple ca marche pas... je sais que je pourrais mettre ma fonction a l'exterieur de la classe le seul probleme c'est que pour rendre la classe independante il faut que je connaisse l'objet. Donc comment faire en gardant mon principe actuelle ou quel autre principe séduisant pourrais je utilisé ?

(__stdcall M3D_WINDOW::*) != (__stdcall *)

11 réponses

ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
30 mars 2005 à 16:33
la wndproc peut appartenir à la classe mais doit être static. Cependant en faisant ça tu père l'ovjet appelant il faut donc associer le hWnd reçu par la wndproc en un pointeur vers l'objet associé. Pour ce faire :
- passer le pointeur sur l'objet en dernier param de CreateWindow.
- dans la wndproc statique, faire un cas spécial de WM_CREATE qui a pour lParam un pointeur sur une structure LPCREATESTRUCT qui contient le dernier param de CreateWindow (le pointeur sur l'objet).
- donc pour WM_CREATE, tu associe ce pointeur à la fenêtre par un SetWindowLond GWL_USERDATA.
- pour les autres messages tu récupère le pointeur par GetWindowlong.
- il ne reste plus qu'à traiter le message par un wnproc non statique.

Un exemple de cette technique dans mes sources (paint normalement).
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
30 mars 2005 à 16:34
ta windProc doit être STATIC dans ta classe pour que son adresse soit connue à la compilation.

ciao...
BruNews, MVP VC++
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
30 mars 2005 à 16:36
une longueur d'avance pour ymca2003...

ciao...
BruNews, MVP VC++
0
threadom Messages postés 101 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 1 novembre 2007
30 mars 2005 à 17:15
Snif j'aurai aimé une autre solution ... je vais quand mème cherché ... inutilement ... et si je trouve rien ... y'a de grande chance ... j'opterai pour celle ci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
threadom Messages postés 101 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 1 novembre 2007
30 mars 2005 à 18:25
Finalement la solution du passage d'objet est sublime :) et je la trouve assez élégante finalement :) MERCI BEAUCOUP :) surtout a toi YMCA :) (au faite j'adore ta facon de codé)
0
anarchysniper Messages postés 65 Date d'inscription jeudi 28 août 2003 Statut Membre Dernière intervention 29 septembre 2005 1
30 mars 2005 à 23:26
Je n'en reviens pas ... j'allais poser exactemement la même question dans le même contexte quand j'ai vu le topic !!!



A croire que tout le monde est dégouté des APIs Windows ... vive l'encapsulation !



Personellement c'est pour faire de l'OpenGl ... GLUT me file des boutons ^^
0
anarchysniper Messages postés 65 Date d'inscription jeudi 28 août 2003 Statut Membre Dernière intervention 29 septembre 2005 1
31 mars 2005 à 00:26
Je pensais naïvement que CALLBACK remplissait la fonction de static ...
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
31 mars 2005 à 09:06
CALLBACK n'est qu'un alias de __stdcall.
L'encapsulation n'empêchera jamais qu'on doive par force connaître et se servir de l'API.

ciao...
BruNews, MVP VC++
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
31 mars 2005 à 09:09
CALLBACK est un simple define de __stdcall (c'est pareill que WINAPI). Il s'agit de la convention de passage de paramètres de l'API WINDOWS (par défaut le C est en __cdecl).
La différence vient du fait que c'est la fonction appelée qui se charge de libérer la pile des parmètres passés (mais bon pour mieux comprendre faut se plonger un peu dans l'ASM et les techniques de passage de paramètres aux fonctions).
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
31 mars 2005 à 09:11
Et une longueur d'avance pour Brunews...
0
threadom Messages postés 101 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 1 novembre 2007
31 mars 2005 à 10:06
Et oui anarchysniper je crois que les grands (petit dans mon cas) esprits ce rencontre car c'est pour la même raison que je posais la question :) GLUT me file des boutons et les API windows on tendance a me donné mal au ventre !

Je pense que j'aurai le plaisir de pouvoir comparé nos codes un jours ou l'autre !

Bref je retourne travaillé mon code sur le champ.
0
Rejoignez-nous