Problème de message windows

cs_Jbs106 Messages postés 32 Date d'inscription mardi 9 septembre 2003 Statut Membre Dernière intervention 27 avril 2010 - 27 avril 2010 à 22:26
cs_Jbs106 Messages postés 32 Date d'inscription mardi 9 septembre 2003 Statut Membre Dernière intervention 27 avril 2010 - 27 avril 2010 à 22:27
Bonjour
Bonjour,

comme je l'ai précisé dans le titre, je souhaite réaliser une application de dessin, un SKETCHER avec les MFCs, je l'ai réalisé grace à un bouquain, le mien, je le nomme Drawer.

J'ai trouvé sur le net, une (autre) application structuré comme les mfc, sans les mfc(ce que je souhaitai!) mais qui ne possede pas d'objet Application..


Dans mon application, j'ai un objet Programme contenant le hinstance, un objet TMainFrame contenant l'objets Drawer (qui est sensé être l'objet doc et view mais pour le moment je simplifie) dans lequel je souhaite dessiner et normalement les objet de barre d'outil...


Mes soucis:
- les messages n'arrivent pas jusqu'à la fenetre de dessin comme dans le logiciel paint.
- si je force l'envoie de message de TMainFrame, mon application bug un peu...

Je pense avoir besoin d'une brillante explication, d'une lumière, d'un petit cour

pour détailler, j'ai un fichier Window.h de la GNU qui m'offre quelque fonctionnalité de base pour mes controles..

Code :

#ifndef WINDOW_CONTROL_H
#define WINDOW_CONTROL_H

class Window
{
public:
Window(){}
virtual ~Window() {};
virtual void init(HWND hSelf, HWND parent){_hSelf= hSelf;_hParent=parent;}
virtual void destroy() = 0;
virtual void display(bool toShow = true) const {::ShowWindow(_hSelf, toShow?SW_SHOW:SW_HIDE);};
virtual void reSizeTo(RECT & rc) // should NEVER be const !!!
{ ::MoveWindow(_hSelf, rc.left, rc.top, rc.right, rc.bottom, TRUE);
redraw();
};

virtual void reSizeToWH(RECT & rc) // should NEVER be const !!!
{ ::MoveWindow(_hSelf, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
redraw();
};

virtual void redraw(bool forceUpdate = false) const
{ ::InvalidateRect(_hSelf, NULL, TRUE);
if (forceUpdate) ::UpdateWindow(_hSelf);
};

virtual void getClientRect(RECT & rc) const { ::GetClientRect (_hSelf, &rc); };
virtual void getWindowRect(RECT & rc) const { ::GetWindowRect (_hSelf, &rc); };
virtual int getWidth() const { RECT rc; GetClientRect(_hSelf, &rc); return (rc.right - rc.left); };
virtual int getHeight() const { RECT rc; GetClientRect(_hSelf, &rc);
if (::IsWindowVisible(_hSelf) == TRUE) return (rc.bottom - rc.top); return 0; };

virtual bool isVisible () const { return (::IsWindowVisible(_hSelf)?true:false); };
inline HWND getHSelf () const { return _hSelf; }; //assert(_hSelf);
inline HWND getHParent () const { return _hParent;};
void getFocus() const { ::SetFocus(_hSelf); };
protected:

HWND _hParent;
HWND _hSelf;
};

#endif //WINDOW_CONTROL_H
une class programme permettant le démarrage de mon programme...

Code :

#ifndef PROGRAMME_H
#define PROGRAMME_H
class TMainFrame;
class Programme
{
public:

~Programme(){}
Programme();
WPARAM Run();
BOOL Init(HINSTANCE hInst,int nCmdShow);
void SetCmdShow(int nCmdShow){_nCmdShow=nCmdShow;};
inline HINSTANCE GetHInst() const {return _hInst;};
inline TMainFrame* GetMainFrame(){return _pMainFrame;}
inline TCHAR* GetAppTitle(){return _szTitle;}
private:
TMainFrame* _pMainFrame;
int _nCmdShow;
HINSTANCE _hInst;
HINSTANCE _hPrevInst;
LPSTR _lpCmdLine;
TCHAR _szTitle[MAX_LOADSTRING];
TCHAR _szWindowClass[MAX_LOADSTRING];
HACCEL _hAccelTable;

};
#endifet son fichier cpp

Code :


#include "stdafx.h"

Programme::Programme()
{
this->_hInst=NULL;
this->_hAccelTable=NULL;
this->_hPrevInst=NULL;
this->_lpCmdLine=NULL;
this->_pMainFrame=NULL;
this->_nCmdShow=NULL;
LoadString(_hInst, IDS_APP_TITLE, _szTitle, MAX_LOADSTRING);
LoadString(_hInst, IDS_DRAWER, _szWindowClass, MAX_LOADSTRING);

}
BOOL Programme::Init(HINSTANCE hInst,int nCmdShow)
{
_hInst = hInst;
if (!_hInst){::MessageBox(NULL, TEXT("_hInst == NULL"), TEXT("class Window"), MB_OK);throw int(1999);}

this->_pMainFrame = new TMainFrame(); // création fenêtre principale
if(!this->_pMainFrame->Create(this))
return FALSE;
ShowWindow(this->_pMainFrame->getHSelf(), nCmdShow);
UpdateWindow(this->_pMainFrame->getHSelf());
return TRUE; // initialisation réussie
}


WPARAM Programme::Run()
{
MSG _msg;
_hAccelTable = LoadAccelerators(_hInst, MAKEINTRESOURCE(IDR_DRAWER));

while (GetMessage(&_msg, NULL, 0, 0)) // Boucle de messages principale*:
{
if (!TranslateAccelerator(_msg.hwnd, _hAccelTable, &_msg))
{
TranslateMessage(&_msg);
DispatchMessage(&_msg);
}
}
return (int) _msg.wParam;
}
la classe TMAINFRAME

Code :

#ifndef MAINFRAME_H_INCLUDED
#define MAINFRAME_H_INCLUDED
class Drawer;
class TMainFrame:public Window
{

protected :

Programme* _pApp;
Drawer* _pDrawer;
void destroy(){}
public :
// constructeur, destructeur
TMainFrame();
~TMainFrame();

BOOL Create(Programme*);
inline Drawer* GetDrawer() { return _pDrawer ;}
inline Programme* GetProgramme() { return _pApp ;}

protected :
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT MsgCreate (HWND, WPARAM, LPARAM); // WM_CREATE
LRESULT MsgClose (WPARAM, LPARAM); // WM_CLOSE
LRESULT MsgDestroy (WPARAM, LPARAM); // WM_DESTROY
LRESULT MsgSetFocus (WPARAM, LPARAM); // WM_SETFOCUS
LRESULT MsgCommand (WPARAM, LPARAM); // WM_COMMAND
void CmdFileQuit (); // "Fichier->Quitter"
};
#endif // MAINFRAME_H_INCLUDED
son fichier cpp

Code :
#include "stdafx.h"

TMainFrame::TMainFrame()
{
_hSelf = NULL;
this->_hParent = NULL;
this->_pApp = NULL;
this->_pDrawer = new Drawer();
}

TMainFrame::~TMainFrame(){ delete _pDrawer;}

BOOL TMainFrame::Create(Programme* aApp)
{
this->_pApp = aApp;
// classe de fenêtre
TCHAR szWndClass[] = _T("Drawer_MainFrame");

// initialisation classe de fenêtre
WNDCLASS wc;

ZeroMemory(&wc, sizeof(WNDCLASS));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = this->_pApp->GetHInst();
wc.hIcon = LoadIcon(this->_pApp->GetHInst(), MAKEINTRESOURCE(IDI_DRAWER));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_DRAWER);
wc.lpszClassName = szWndClass;
wc.hbrBackground = NULL;
// enregistrement classe de fenêtre
if(!RegisterClass(&wc))
return FALSE;

// création fenêtre principale
this->_hSelf = CreateWindowEx(0, szWndClass, this->_pApp->GetAppTitle(), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, this->_pApp->GetHInst(), this);

return (_hSelf != NULL);
}

LRESULT CALLBACK TMainFrame::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// affecter l'objet TMainFrame lors de la création de la fenêtre, contenu dans la
// structure CREATESTRUCT pointée par lParam
if(msg == WM_CREATE)
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
SetWindowLong(hWnd, GWL_USERDATA, (LONG)lpcs->lpCreateParams);
}

// récupération objet TMainFrame associé à la fenêtre
TMainFrame* pWnd = (TMainFrame*) GetWindowLong(hWnd, GWL_USERDATA);
if(!pWnd)
return DefWindowProc(hWnd, msg, wParam, lParam);
switch(msg)
{
case WM_SETFOCUS : return pWnd->MsgSetFocus (wParam, lParam);
case WM_CREATE : return pWnd->MsgCreate (hWnd, wParam, lParam);
case WM_CLOSE : return pWnd->MsgClose (wParam, lParam);
case WM_DESTROY : return pWnd->MsgDestroy (wParam, lParam);
case WM_COMMAND : return pWnd->MsgCommand (wParam, lParam);
default : return DefWindowProc(hWnd, msg, wParam, lParam);
}


}
LRESULT TMainFrame::MsgCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{ this->_hSelf=hWnd;
this->_pDrawer->Create(this);

ShowWindow(this->_pDrawer->getHSelf(), SW_SHOW);
return 0;
}

LRESULT TMainFrame::MsgClose(WPARAM wParam, LPARAM lParam)
{
DestroyWindow(_hSelf);
return 0;
}
LRESULT TMainFrame::MsgSetFocus(WPARAM wParam, LPARAM lParam)
{ this->_pDrawer->getFocus();

return 0;
}

LRESULT TMainFrame::MsgDestroy(WPARAM wParam, LPARAM lParam)
{
PostQuitMessage(0);
return 0;
}


LRESULT TMainFrame::MsgCommand(WPARAM wParam, LPARAM lParam)
{
// on laisse la vue de la zone cliente commencer par traiter la commande
if(SendMessage(this->_pDrawer->getHSelf(), WM_COMMAND, wParam, lParam))
return TRUE;

int nIDCtl = LOWORD(wParam); // en fonction de la commande
switch(nIDCtl)
{
case IDM_EXIT : CmdFileQuit (); break;
default : return FALSE;
}
return TRUE;// la commande a été traitée
}
void TMainFrame::CmdFileQuit(){ SendMessage(_hSelf, WM_CLOSE, 0, 0);}
et enfin ma class drawer me servant pour le moment de document et de vue:

Code :

#ifndef DRAWER_H
#define DRAWER_H
class CElement;

class Drawer:public Window
{
protected :
TMainFrame* _pTMainFrame;

public :
Drawer(){}
~Drawer(){}
BOOL Create(TMainFrame* pMainFrame);
protected :
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

LRESULT MsgMouseMove (WPARAM, LPARAM); // WM_MOUSEMOVE
void destroy(){}
protected:
};
#endif
Code :

// Drawer.cpp*: définit le point d'entrée pour l'application.
//

#include "stdafx.h"


BOOL Drawer::Create(TMainFrame* pMainFrame)
{
// classe de fenêtre
TCHAR szWndClass[] = _T("Paint_ChildView");

// initialisation classe de fenêtre
WNDCLASS wc;
ZeroMemory(&wc, sizeof(WNDCLASS));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = pMainFrame->GetProgramme()->GetHInst();
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = szWndClass;

// enregistrement classe de fenêtre
if(!RegisterClass(&wc))
return FALSE;
this->_hParent = pMainFrame->getHSelf();

_hSelf = CreateWindowEx(0, szWndClass, NULL, WS_CHILD,
0, 0, 0, 0, pMainFrame->getHSelf(), NULL, pMainFrame->GetProgramme()->GetHInst(), this);

return (_hSelf != NULL);
}

LRESULT CALLBACK Drawer::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// affecter l'objet Drawer lors de la création de la vue, contenu dans la
// structure CREATESTRUCT pointée par lParam
if(msg == WM_CREATE)
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
SetWindowLong(hWnd, GWL_USERDATA, (LONG)lpcs->lpCreateParams);
}

// récupération objet Drawer associé à la fenêtre
Drawer* pWnd = (Drawer*) GetWindowLong(hWnd, GWL_USERDATA);
if(!pWnd)
return DefWindowProc(hWnd, msg, wParam, lParam);

// en fonction du message
switch(msg)
{
case WM_MOUSEMOVE : return pWnd->MsgMouseMove (wParam, lParam);
default : return FALSE;
}
}


LRESULT Drawer::MsgMouseMove (WPARAM wParam, LPARAM lParam)
{
POINT point;
PAINTSTRUCT ps;
HDC hdc= BeginPaint(_hSelf,&ps);
TCHAR bf2[5];
TCHAR bf1[5];
GetCursorPos(&point);
ScreenToClient(_hSelf,&point);
_itow_s(point.x,bf1,5,10);
_itow_s(point.y,bf2,5,10);
TCHAR aText[MAX_LOADSTRING] =TEXT("Coordonnée cliente :");
wcscat(aText,bf1);
wcscat(aText,TEXT(","));
wcscat(aText,bf2);
SetWindowText(this->getHParent(),aText);
MoveToEx(hdc,0,0,NULL);
LineTo(hdc,point.x,point.y);
EndPaint(this->getHSelf(), &ps);
return 0;

}

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
Programme Apps;
if(Apps.Init(hInstance,nCmdShow))
return Apps.Run();
else return 0;

}
J'ai simplifié au maximum, les messages ne transite pas par mon drawer alors que je sais que c'est possible... mais c'est certain qu'il me manque quelque chose...

Je souhaite avoir un MainFrame comme dans les MFC et un modèle Vue/Document (que je regroupe) dans mon Drawer, Window sert à stocker le HANDLE de ma fenetre et quelques fonctions utilent pour le developpement de mon application.

Je n'arrive pas à faire transiter mes messages "naturellement" vers les evenement utilisateur de Drawer comme l'application paint.

Je comprend pas; merci de votre aide

1 réponse

cs_Jbs106 Messages postés 32 Date d'inscription mardi 9 septembre 2003 Statut Membre Dernière intervention 27 avril 2010
27 avril 2010 à 22:27
0
Rejoignez-nous