wxDev.fr, le portail francophone consacré à wxWidgets ! ( The french portal for wxWidgets )  
Esp. membre
Recheche rapide



Recherche avancée
Statistiques
Membres inscrits :2359

Membres en ligne : 0
Invités en ligne : 3

Valid XHTML 1.0 Transitional

Valid CSS2

Menu forum (navigation):
Pages: 1 2  
 
Accueil » Accueil forums » Création de composants spécifiques
» Access violation
Conversation : Access violation
19-09-2010 08:40:11  Access violation #1
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Salut!

Je suis en train de m'essayer a wxWidgets, et comme le dit mon pseudo je ne suis pas bon.

J'ai fait un petit composant personnel qui est une sorte de slider.

Il est derive de wxPanel sur lequel je dessine le curseur en traitant successivement les evenements wxEVT_MOTION pour savoir ou est la souris, puis wxEVT_PAINT pour redessiner le curseur a la position voulue.

Pour l'etape suivante, je voudrais un EditBox ou s'affiche la position du curseur, et aussi pour permettre de taper la position du curseur au lieu de le bouger avec la souris.

J'ai donc ajoute dans les membres de ma petite classe un wxTextCtrl. Le drame est que lorsque dans le traitement de l'evenement j'appelle:

Code Cpp:

 
MyTextCtrl->SetValue(...);


ca plante et le compilo me dit 'access violation'.

Y-a-t'il une solution simple a ce probleme? (je pense a deriver le composant de wxPanel ET wxTextCtrl, mais je prefererais eviter ca pour mon premier exercice ;) )

A++

Le mauvais
19-09-2010 13:11:45  Re: Access violation #2
Sem (Membre)
Inscrit le : 31-05-2008
Messages: 64
Snippets: 0
Tutoriels: 0
Hors ligne
bonjour,
tu as bien créé ton MyTextCtrl dans le constructeur ?

du style :

Code wxWidgets:

MyTextCtrl = new wxTextCtrl(this, wxID_ANY, ...);
 


Sem
19-09-2010 14:12:33  Re: Access violation #3
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Sem:
bonjour,
tu as bien créé ton MyTextCtrl dans le constructeur ?

du style :

Code wxWidgets:

MyTextCtrl = new wxTextCtrl(this, wxID_ANY, ...);
 


Sem
Salut Sem

Oui, l'edit box est dans le constructeur

Code wxWidgets:

wxMaClasse::wxMaClasse(wxPanel *parent, int id ...):wxPanel(parent, id) {
 
...
 
wxTextCtrl *MonEditTexte = new wxTextCtrl(parent, wxID_ANY, ...);
 
...
 


ou le 'parent' est le panel sur lequel est place le composant.

J'ai aussi essaye avec 'this' et ca plante quand meme - mais en plus l'edit box n'est pas visible.

A++
19-09-2010 14:47:14  Re: Access violation #4
Sem (Membre)
Inscrit le : 31-05-2008
Messages: 64
Snippets: 0
Tutoriels: 0
Hors ligne
coucou,
tu pourrais nous mettre un peu plus de code stp ?
y a aucune raison apparente que le SetValue segfault si MyTextCtrl est créé et valide,
Sem
19-09-2010 15:13:23  Re: Access violation #5
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Sem:
coucou,
tu pourrais nous mettre un peu plus de code stp ?
y a aucune raison apparente que le SetValue segfault si MyTextCtrl est créé et valide,
Sem
Arf c'est un peu la mouise parce que je code sur un pc qui n'a pas la connexion internet et je poste sur un autre... (et ma cle usb s'est fait la malle).

Enfin il n'y a pas grand chose de plus. Dans le constructeur j'ai aussi

Code wxWidgets:

Connect(wxEVT_MOTION, wxMouseEventHandler(wxMaClasse::OnDrag));


et c'est dans le corps de cette fonction OnDrag que je veux modifier le text de l'edit box.
19-09-2010 17:01:31  Re: Access violation #6
Sem (Membre)
Inscrit le : 31-05-2008
Messages: 64
Snippets: 0
Tutoriels: 0
Hors ligne
coucou,
c'est le compilo qui plante ou c'est à l'exécution de ton programme ?
et si c'est à l'exécution, c'est à l'affichage de ton contrôle ou quand tu commences à drag ?
Sem
20-09-2010 00:35:40  Re: Access violation #7
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Salut Sem,

Ca plante a l'execution - le code compile bien - quand j'essaie d'acceder a MyTextCtrl depuis la fonction qui traite wxEVT_MOTION - donc quand je commence a dragger la souris.

A++

Nico


Sem:
coucou,
c'est le compilo qui plante ou c'est à l'exécution de ton programme ?
et si c'est à l'exécution, c'est à l'affichage de ton contrôle ou quand tu commences à drag ?
Sem
20-09-2010 00:48:06  Re: Access violation #8
etrange02 (Membre)
Lieu: Nantes
Inscrit le : 24-07-2009
Messages: 23
Snippets: 0
Tutoriels: 0
Site web
Hors ligne
mauvais:

Code wxWidgets:

wxTextCtrl *MonEditTexte = new wxTextCtrl(parent, wxID_ANY, ...);
Essaye en remplaçant 'parent' par this.

Dernière modification par etrange02 (20-09-2010 00:48:41)

20-09-2010 00:59:17  Re: Access violation #9
Sem (Membre)
Inscrit le : 31-05-2008
Messages: 64
Snippets: 0
Tutoriels: 0
Hors ligne
coucou,
tu peux nous mettre le code de "wxMaClasse::OnDrag" stp ?
Sem
20-09-2010 07:53:43  Re: Access violation #10
cubbiste (Membre)
Inscrit le : 14-07-2010
Messages: 11
Snippets: 0
Tutoriels: 0
Hors ligne
Bonjour,

Tu initialises ici une variable MonEditTexte locale au constructeur :

Code wxWidgets:

wxMaClasse::wxMaClasse(wxPanel *parent, int id ...):wxPanel(parent, id) {
...
wxTextCtrl *MonEditTexte = new wxTextCtrl(parent, wxID_ANY, ...);
...
 


Et tu utilises là un MyTextCtrl qui semble être un membre de ta classe :

Code wxWidgets:

MyTextCtrl->SetValue(...);


Mais on ne voit nulle part (dans les extraits que tu nous as donnés) le lien entre les deux variables de type wxTextCtrl*.
MyTextCtrl ne serait donc jamais initialisé. Si c'est bien le cas, ce n'est pas étonnant que ça plante à l'exécution.

Cubbiste
20-09-2010 09:22:05  Re: Access violation #11
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Bonjour a tous, et merci pour votre aide.

@Cubbiste: dans la definition de la classe wxMaClasse, je declare le pointeur de la facon suivante:

wxTextCtrl *MyTextCtrl;

Ensuite le controle est initialise dans le constructeur. Pour moi ca a l'air bon... mais en effet le debuggueur me montre que le controle n'est pas initialise.

@etrange02: j'ai essaye mais ca plante aussi.

@Sem: je vais tacher de faire ca ce soir - je suis au boulot la, et il n'y a pas de wxWidgets ici ;)

A++

Nico

PS: j'ai aussi poste sur le forum ORG, et on m'a pointe vers une partie de la FAQ:

"Why does my app crash in the callback of an event bound with Connect() ?
Most likely you passed the wrong event sink parameter (or omitted it) while calling ->Connect(...); By default wx expects the event callback to be in the object you connect. If your callback is not in the very object you connected, you need to pass an event sink parameter."

Il faut que je digere ca...
20-09-2010 09:50:33  Re: Access violation #12
cubbiste (Membre)
Inscrit le : 14-07-2010
Messages: 11
Snippets: 0
Tutoriels: 0
Hors ligne
mauvais:
Ensuite le controle est initialise dans le constructeur.
Donc, il y a une ligne

Code wxWidgets:

MyTextCtrl = MonEditTexte;

dans ton constructeur, après

Code wxWidgets:

wxTextCtrl *MonEditTexte = new wxTextCtrl(parent, wxID_ANY, ...);

?
Je demande ça, parce qu'elle n'apparaît pas dans tes extraits de code ... et ton debuggeur n'a pas non plus l'air de l'avoir trouvée.
20-09-2010 10:04:28  Re: Access violation #13
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Oui desole! je me suis emmele les pinceaux... Il n'y a en fait qu'un seul identifiant MonEditText ou MyTextCtrl. (Si ca se trouve j'ai une faute de frappe entre la definition du controle et l'initialisation...)

Bon j'ai trouve ma cle USB au boulot, ca va etre plus facile pour poster du code et eviter ce genre de malentendu.

(Si seulement je pouvais aussi trouver une cle UBS :) )
----------
Bon j'ai trouve le bug, c'est un peu ridicule mais bon autant cracher le morceau.

Dans la definition de la classe j'avais:

wxTextCtrl *MonEditTexte;

Puis dans le constructeur:

wxTextCtrl *MonEditTexte = new wxTextCtrl(parent, wxID_ANY);

alors que j'aurais du ici me contenter de:

MonEditTexte = newTextCtrl(parent, ...);

Si je comprends bien, je creais dans le constructeur une instance locale de wxTextCtrl ayant le meme nom que le membre de la classe et sans initialiser celui-ci.

Je vous avais prevenu avec mon pseudo :)

Merci de m'avoir mis sur la piste!

Dernière modification par mauvais (20-09-2010 13:28:50)

20-09-2010 13:33:28  Re: Access violation #14
Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1383
Snippets: 25
Tutoriels: 6
Site web
Hors ligne
Salut.

mauvais:
Si je comprends bien, je creais dans le constructeur une instance locale de wxTextCtrl ayant le meme nom que le membre de la classe et sans initialiser celui-ci.
C'est exactement ça.
Ce qui faisait qu'une fois sorti du constructeur, la variable locale était détruite, et la variable membre restait non-initialisée.

@+
Xav'

Le nouveau portail wxWidgets francophone : www.wxdev.fr
Ben en fait, vous y êtes déjà...
09-10-2010 11:10:01  Re: Access violation #15
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Bonjour a tout le monde,

Vous m'aviez bien bien depanne sur le precedent probleme, et puis j'ai ete pris par autre chose. Me voila de retour sur mon modeste composant, qui entre temps est devenu une sorte de potard, c'est-a-dire un composant circulaire qui emule les potentiometres qu'on trouve classiquement sur les appareils audio.

J'ai un nouveau souci. Je crois qu'il me faudrait poster le code, mais voila: le composant derive donc d'un wxPanel et comprend un wxTextCtrl. Or je n'arrive pas a intercepter les evenements du clavier quand j'edite la valeur dans wxTextCtrl.
----------
Voila donc le code.

Header:

Code wxWidgets:

#ifndef WXDIAL_H
#define WXDIAL_H
 
#include <wx/wx.h>
#include <math.h>
 
class wxDial : public wxPanel
{
public:
    wxDial(wxPanel *parent, int id, int radius, bool logtype, float value, float minvalue, float maxvalue);
    wxPanel *m_parent;
 
    wxTextCtrl *m_tcvalue;
 
    //void OnSize(wxSizeEvent& event);
    void OnPaint(wxPaintEvent& event);
    void OnClick(wxMouseEvent& event);
    void OnDrag(wxMouseEvent& event);
    void OnRelease(wxMouseEvent& event);
    void OnMouseLeaveWindow(wxMouseEvent& event);
    void OnDoubleClick(wxMouseEvent& event);
    void OnKeyboard(wxKeyEvent& event);
 
    bool m_log;          // 0: linear 1: log
    int m_radius;        // radius of the dial knob
 
    float m_pos;         // Current position of the dial cursor
    float m_minpos;      // Minimal position
    float m_maxpos;   
 
    int m_xpos;          // Coordinates of upper left corner in parent panel
    int m_ypos;
 
    bool m_click;        // Is mouse down on the widget?
 
    int m_cursor_org;    // Don't remember
 
    float m_value;       
    float m_minvalue;
    float m_maxvalue;
 
    wxColor m_bg;        // Parent background colour
 
};
 
#endif


et le corps:

Code wxWidgets:

#include <wx/wx.h>
#include <wx/dcbuffer.h>
#include "wxDial.h"
 
wxDial::wxDial(wxPanel *parent, int id, int radius, bool logtype, float value, float minvalue, float maxvalue)
    :wxPanel(parent, id)
{
    m_parent = parent;
    m_radius = radius;
    m_log = logtype;
    m_value = value;
    m_minvalue = minvalue;
    m_maxvalue = maxvalue;
    m_minpos = (float)(30.0/180.0*M_PI);
    m_maxpos = (float)(330.0/180.0*M_PI);
    m_xpos = 30;
    m_ypos = 50;
    m_click = false;
 
    // Get initial led position
    if (!m_log)
        m_pos = (m_value-m_minvalue)/(m_maxvalue-m_minvalue)*(m_maxpos-m_minpos) + m_minpos;
    else
        m_pos = log(m_maxvalue/m_value)/log(m_maxvalue/m_minvalue)*(m_maxpos-m_minpos) + m_minpos;
 
    SetSize(m_xpos, m_ypos, 2*m_radius, 2*m_radius + 20);
 
    SetBackgroundStyle(wxBG_STYLE_CUSTOM);        // required for wxBufferedPaintDC
 
    m_bg = m_parent->GetBackgroundColour();        // To redraw the backgound on the component
 
    m_tcvalue = new wxTextCtrl(parent, wxID_ANY, wxT(""), wxPoint(m_xpos+2, m_ypos+2*m_radius+2), wxSize(2*m_radius-4,18), wxTE_CENTRE);
    m_tcvalue->Show(false);
 
    Connect(wxEVT_PAINT, wxPaintEventHandler(wxDial::OnPaint));
    Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxDial::OnClick));
    Connect(wxEVT_MOTION, wxMouseEventHandler(wxDial::OnDrag));
    Connect(wxEVT_LEFT_UP, wxMouseEventHandler(wxDial::OnRelease));
    Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(wxDial::OnMouseLeaveWindow));
    Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(wxDial::OnDoubleClick));
    Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));
};
 
void wxDial::OnPaint(wxPaintEvent& event)
{
 
    wxAutoBufferedPaintDC dc(this);
 
    dc.SetBackgroundMode(wxTRANSPARENT);
 
    wxColour col1, col2;
    col1.Set(wxT("#000000"));
    col2.Set(wxT("#ffffff"));
 
    // Redraw background
    dc.SetBrush(wxBrush(m_bg));
    dc.SetPen(wxPen(m_bg, 1, wxTRANSPARENT));
 
    int height, width;
    GetSize(&width, &height);
    //if (!m_tcvalue->IsShownOnScreen())
        dc.DrawRectangle(0,0,width,height);
    //else
    //    dc.DrawRectangle(0,0,2*m_radius,2*m_radius);
 
    //Draw outer circle
    dc.SetBrush(wxBrush(col2));
    dc.SetPen(wxPen(col1, 2, wxSOLID));
    dc.DrawCircle(m_radius, m_radius, m_radius);
    //dc.SetPen(wxPen(m_bg, 2, wxSOLID));
    //dc.DrawArc(m_radius, 2, 2, m_radius, m_radius, m_radius);   //(m_radius, m_radius, m_radius-2);
    //dc.SetPen(wxPen(col1, 3, wxSOLID));
    //dc.DrawCircle(m_radius, m_radius, m_radius/2+2);
 
    // Draw inner circle
    dc.SetPen(wxPen(col1, 2, wxSOLID));
    dc.DrawCircle(m_radius, m_radius, m_radius/2);
 
    // Led
    wxColour ledcolour;
    ledcolour.Set((m_click) ? wxT("#fa8e00") : wxT("#619e1b"));
    dc.SetPen(wxPen(ledcolour, 1, wxSOLID));
    dc.SetBrush(wxBrush(ledcolour));
    dc.DrawCircle(m_radius-sin(m_pos)*(3*m_radius/4), m_radius+cos(m_pos)*(3*m_radius/4), 5);
    // Text
    //if (!m_tcvalue->IsShownOnScreen()) {
    wxSize size = dc.GetTextExtent(wxString::Format(wxT("%3.1f"), m_value));
    dc.SetPen(wxPen(wxColour(90,80,60)));
    dc.DrawText(wxString::Format(wxT("%3.1f"), m_value), width/2-size.GetWidth()/2, height-15);
    //    }
    //else
    //    m_tcvalue->SetFocus();
    m_tcvalue->Raise();
    m_tcvalue->Update();
    m_tcvalue->SetFocus();
 
    m_tcvalue->ClearBackground();
    m_tcvalue->Refresh(false);
};
 
void wxDial::OnClick(wxMouseEvent& event)
{
    int y;
    //event.GetPosition(&x,&y);
    y = event.GetY();
    // Don't do anything if it's a single click on the text field
    if (y <= 2*m_radius) {
        m_click = true;
        m_cursor_org = y;
        m_tcvalue->Show(false);
        Refresh();
    }
};
 
void wxDial::OnDrag(wxMouseEvent& event)
{
    // If control was not clicked priorly do nothing
    if (event.m_leftDown && m_click == true) {
        int y;
        y = event.GetY();
        // Dragging on the whole component is turning the dial form min to max
        m_pos += (float)(m_cursor_org-y)/(float)m_radius*M_PI;
        // Keep angle between min and max
        if (m_pos < m_minpos)
            m_pos = m_minpos;
        else if (m_pos > m_maxpos)
            m_pos = m_maxpos;       
        m_cursor_org = y;
        // Compute corresponding parameter
        if (!m_log)
            m_value = (m_pos-m_minpos)/(m_maxpos-m_minpos)*(m_maxvalue-m_minvalue) + m_minvalue;
        else
            m_value = m_minvalue*pow(m_maxvalue/m_minvalue, (m_pos-m_minpos)/(m_maxpos-m_minpos));
 
        Refresh();
    }
};
 
void wxDial::OnRelease(wxMouseEvent& event)
{
    // Mouse up -> signal it and redraw so that cursor is modified accordingly
    m_click = false;
    Refresh();
};
 
void wxDial::OnMouseLeaveWindow(wxMouseEvent& event)
{
    // when mouse is out of window, turn off led
    if (m_click) {
        m_click = false;
        Refresh();
    }
};
 
void wxDial::OnDoubleClick(wxMouseEvent& event)
{
    // Check click is on the text field
    int y;
    y = event.GetY();
    // If it is, make edit visible and set string to dial current value
    if (y >= 2*m_radius) {
        m_tcvalue->SetValue(wxString::Format(wxT("%3.1f"), m_value));
        m_tcvalue->SelectAll();
        m_tcvalue->Show(true);
        Refresh();
    }
};
 
void wxDial::OnKeyboard(wxKeyEvent& event)
{
    wxBell();
    if (wxIsdigit(event.KeyCode()))
        event.Skip();
    else
        wxBell();
};
 
 


Donc premier souci: l'evenement wxEVT_KEY_DOWN n'est jamais intercepte. J'essaie plusieurs choses un peu au pif, desole si le code n'est pas tres clair.

Si on double-clique sur le 'label' qui indique la valeur avec des chiffres, on devrait voir apparaitre le fameux wxTextCtrl dont il a ete question tout le long. Il apparait bien, mais seulement partiellement; en effet, les bords en reliefs sont escamotes. Ca c'est le second probleme.

Voila mes petits soucis :)

PS: desole pour les commentaires angliches, je suis bilingue et ecris d'Australie (sur un clavier sans accents).

Dernière modification par mauvais (09-10-2010 11:39:47)

09-10-2010 12:09:58  Re: Access violation #16
etrange02 (Membre)
Lieu: Nantes
Inscrit le : 24-07-2009
Messages: 23
Snippets: 0
Tutoriels: 0
Site web
Hors ligne
Salut, j'ai jeté un coup d'œil rapide à ton code. Afin de respecter l'encapsulation, tu dois mettre les attributs de ta classe en private !

Je ne suis pas trop sûr de ce que je vais avancer, mais c'est mon "expérience" qui parle.

La doc sur le wxTextCtrl est ici. Il y est spécifié qu'elle ne peut émettre que des wxCommandEvent.
http://docs.wxwidgets.org/trunk/classwx_text_ctrl.html

Ensuite je pense que tu dois préciser l'identifiant de ton wxTextCtrl dans le Connect. Je pense en fait que lorsque l'identifiant n'est pas précisé, wxWidget met celui qui est attaché à ta classe dérivée/wxPanel.

Dite-moi si je me trompe !
10-10-2010 04:37:16  Re: Access violation #17
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Salut etrange02,

Merci pour ton post.

J'ai essaye ce que tu proposes:
- Passer l'identifiant du wxTextCtrl dans le Connect. Pour cela j'ai au prealable construit le wxTextCtrl avec un identifiant dedie au lieu de wxID_ANY.

- Ensuite j'ai essaye d'intercepter wxEVT_COMMAND_TEXT_UPDATED.

Malheureusement rien n'y fait: je n'arrive pas a intercepter un evenement du clavier sur le wxTextCtrl.
----------
(Re)salut etrange02,

Bon j'ai trouve - tu m'as bien mis sur la piste, un grand merci.

Plutot que:

Code wxWidgets:

 
Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));
 


Il fallait:

Code wxWidgets:

 
m_tcvalue->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));
 


ou m_tcvalue est le pointeur du wxTextCtrl.

Bon ca fait un probleme de moins :)

Sinon toujours le probleme d'affichage: les bords en relief du wxTextCtrl sont passes a la trappe.

Et sinon une rigolade: quand j'execute le code en debug, le compilo me dit 'memory leak'.

A++!

Dernière modification par mauvais (10-10-2010 07:00:26)

10-10-2010 09:21:31  Re: Access violation #18
Sem (Membre)
Inscrit le : 31-05-2008
Messages: 64
Snippets: 0
Tutoriels: 0
Hors ligne
bonjour,
pourquoi tu ne créé pas le wxTextCtrl sur ton wxDial ? par exemple,  dans le constructeur :


m_tcvalue = new wxTextCtrl(this, ...


Sem

Dernière modification par Sem (10-10-2010 09:21:48)

10-10-2010 12:29:46  Re: Access violation #19
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Bon j'ai un nouveau souci, qui ressemble pas mal au tout premier en debut de thread.

Donc maintenant j'intercepte bien les evenements sur le wxTextCtrl, mais dans le corps de la fonction qui traite l'evenement le wxTextCtrl n'est pas initialise.

En fait, wxDial a alors 2 wxTextCtrl:
- un premier [wxTextCtrl], je ne sais pas d'ou il sort
- le second s'appelle bien m_tcvalue, mais il n'est pas initialise...

Je n'y comprends rien!

Sem, j'ai regarde ta suggestion.
Si je fais comme tu dis, de nouveau je n'intercepte pas l'evenement sur le wxTextCtrl.
10-10-2010 12:48:18  Re: Access violation #20
Sem (Membre)
Inscrit le : 31-05-2008
Messages: 64
Snippets: 0
Tutoriels: 0
Hors ligne
coucou,
meme en remettant du coup le connect sur this ?


    Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));

Sem

PS: Il est jamais bon de mettre des controls sur le parent. Tu fais un composant qu'est basé sur un panel, un panel c'est une boite ou on y met ce qu'on veut. Donc tout ce qui compose ton composant doit être dans cette boite, tu ne devrais avoir que des new wxControl(this, ... ), on ne sait pas qui est le parent, en plus sur la gestion automatique des destructions, ca met la pagaille, donc si tu n'as pas une raison précise de le faire, tu ne devrais avoir que des controls dont le parent est this.

Dernière modification par Sem (10-10-2010 12:52:44)

10-10-2010 12:55:50  Re: Access violation #21
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Sem:
coucou,
meme en remettant du coup le connect sur this ?


    Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));

Sem
Oui, si

Code wxWidgets:

m_tcvalue = new wxTextCtrl(this, wxID_ANY, ... 


Alors

Code wxWidgets:

 Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));


et

Code wxWidgets:

 m_tcvalue->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));


compilent bien mais l'evenement n'est pas intercepte.

Precision: avec 'this' le wxTextCtrl ne s'affiche pas.

Dernière modification par mauvais (10-10-2010 13:21:04)

10-10-2010 14:08:20  Re: Access violation #22
etrange02 (Membre)
Lieu: Nantes
Inscrit le : 24-07-2009
Messages: 23
Snippets: 0
Tutoriels: 0
Site web
Hors ligne
Il faut que tu insères un wxSizer dans ton wxPanel et que tu attaches tout dessus.

Dernière modification par etrange02 (10-10-2010 14:08:59)

10-10-2010 14:34:11  Re: Access violation #23
Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1383
Snippets: 25
Tutoriels: 6
Site web
Hors ligne
Hello

mauvais:

Code wxWidgets:

 Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));


et

Code wxWidgets:

 m_tcvalue->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard));


compilent bien mais l'evenement n'est pas intercepte.
Tu y étais presque ;)

En fait, la deuxième version est incorrecte (tu as même de la chance, car dans certains cas, ça fait purement et simplement crasher l'application).

Si tu regardes la doc officielle de la méthode Connect, tu remarqueras qu'il te manques les deux paramètres finaux.

Le premier (userData) n'est pas utile.
Par contre, il faut faire très attention au deuxième (eventSink).
Il correspond au pointeur de la classe qui va traiter l'événement. S'il n'est pas spécifié, sa valeur vaut NULL, et dans ce cas, c'est this qui est utilisé.
Mais dans ce cas, this correspond à la classe que l'on connecte : c'est à dire ton wxTextCtrl.
Or, dans ton code, l'événement est traité par le panel. Il faut donc que tu spécifies this pour que tout rentre dans l'ordre.

Ce qui donne :

Code wxWidgets:

 m_tcvalue->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(wxDial::OnKeyboard), NULL, this);


Avec ça, l'événement est bien intercepté.


Autre petite chose : J'ai testé ton code (pris sur un des posts précédents).
J'ai inséré ton composant dans une fenêtre possédant un sizer (qui donc s'est chargé de le positionner), et là, il y a un petit soucis.
- en laissant ton code tel-quel (le wxTextCtrl comme enfant direct du parent du composant), ça se passe pas trop mal (hormis le fait que le wxTextCtrl s'affiche en dessous du composant, c'est à dire par dessus l'éventuel contrôle suivant).
- en mettant le wxTextCtrl comme enfant du wxPanel, le composant tout entier n'apparaît plus. Il faut que tu lui donne une taille minimale (en l'occurence, la taille définie dans le constructeur). Avec le code ci-dessous, le composant s'affiche correctement :

Code wxWidgets:

SetSize(m_xpos, m_ypos, 2*m_radius, 2*m_radius + 20);
SetMinSize(wxSize(2*m_radius, 2*m_radius + 20));

Par contre, dans le 2ème cas, il y a effectivement un soucis avec le wxTextCtrl qui n'apparaît plus. Je pense que son affichage est bloqué par la méthode "OnPaint".

Pour simplifier le truc, voici ce que tu peux faire (ce n'est qu'une piste, c'est à toi de voir)

- Ton composant est un wxPanel de base comme tu l'as fait
- Tu lui donnes un "sous-contrôle" wxPanel dans lequel tu vas dessinner le potentiomètre
- Tu ajoutes en dessous de ce wxPanel un wxStaticText (en modifiant la police de caractètres, tu devrais facilement obtenir le même résultat)
- Tu ajoutes le wxTextCtrl pour l'édition
- Tu gères ces 3 composants avec un wxBoxSizer vertical.
- Lorsque tu alternes entre le mode "edition" et "affichage", tu affiches ou caches les deux contrôles concernés, et tu appelles la méthode Layout() du sizer.

@+
Xav'

Le nouveau portail wxWidgets francophone : www.wxdev.fr
Ben en fait, vous y êtes déjà...
10-10-2010 15:06:37  Re: Access violation #24
mauvais (Membre)
Inscrit le : 19-09-2010
Messages: 32
Snippets: 0
Tutoriels: 0
Hors ligne
Merci a tous, Sem, etrange02, Xaviou pour votre interet et votre aide.
Ca fait beaucoup de choses a essayer, je tacherai de faire ca demain.
Ici il est minuit, alors bonne nuit a tous :)
10-10-2010 15:18:25  Re: Access violation #25
Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1383
Snippets: 25
Tutoriels: 6
Site web
Hors ligne
mauvais:
Ici il est minuit, alors bonne nuit a tous :)
Arf ! C'est vrai ! L'australie !
En france, il n'est que 15h :lol:

@+
Xav'

Le nouveau portail wxWidgets francophone : www.wxdev.fr
Ben en fait, vous y êtes déjà...
Menu forum (navigation):
Pages: 1 2  
 
Accueil » Accueil forums » Création de composants spécifiques
» Access violation