Re: [ROOT] ProcessMessage() is never called?

From: Fons Rademakers (Fons.Rademakers@cern.ch)
Date: Tue Jun 06 2000 - 20:01:29 MEST


Hi Olivier,

   you have to do:

.L mymain.C++ (while the file is called mymain.C)

the ++ extension will trigger the compilation of the code in the script
mymain.C. Then it will work. If you interpret the code I mailed you
should only see:

entering processmesg
entering kcCommand switch
text button id 1 pressed
(unsigned char)1

If you compile it using the ++ extension then the rest will work too.

The ClassDef/ClassImp etc. is if you want to access yoyr compiled code
via the interpreter.

Cheers, Fons.


Olivier D'Arcy wrote:
> 
> It doesn't work ! I tried exactly what you told me and there is no
> reaction when I pressed abutton or select an item from the listbox.
> There even is a bus error when I press on the version button and the
> fButton1->SetCommand(cmd); is not commented out.
> Is there something missing? Do I have to declare my ProcessMessage method
> as virtual?
> 
> My real program is a lot more complex than this simple example but I would
> like to understand before continuing my real application.
> 
> I just read about classDef and ClassImp and How to generate a dictionnary
> Should I compile my code following the example on Dictionary Generation at
> http://root.cern.ch/root/CintGenerator.html ?
> 
> On Tue, 6 Jun 2000, Fons Rademakers wrote:
> 
> > Hi Olivier,
> >
> >    you cannot interpret a class derived from a compiled class. Here
> > TGMainFrame is a compiled class. If you look in the $ROOTSYS/tutorials/dialogs.C
> > example you see that the classes don't derive from any compiled class.
> > The "trick" with the cmd string is only needed in the interpreter because
> > ProcessMessage() is normally called via a virtual function of the base class
> > which won't work if the class is interpreted (because the baseclass is
> > compiled).
> >
> > A solution is to use the ROOT script compiler. The script compiler creates a
> > dictionary, compiles the script into a shared library and links the shared lib
> > into the root session.
> >
> > I've modified you script to work with the script compiler (you need to specify
> > the right include statements) and fixed some other small typos in your code.
> >
> > To use it with the script compiler do:
> >
> > root [1] .L mymain.C++
> > root [2] mymain()
> >
> >
> > Cheers, Fons.
> >
> >
> > Olivier D'Arcy wrote:
> > >
> > > Hi, I'm trying to run the following simple GUI example in order to
> > > understand how does the function ProcessMessage() work. I read that when a
> > > button is pressed, the message (kC_COMMAND, kCM_BUTOON,button_id,...) is
> > > sent and when an item from the listbox is selected, the message
> > > (kC_COMMAND, kCM_LISTBOX, listbox_id, item_id) is sent. Still the
> > > ProcessMessage() of the following code is never called even if I press
> > > one of the button or click an item in the list box. Why?
> > >
> >
> > //---------------- fixed version of macro
> > #ifndef __CINT__
> > #include <TGButton.h>
> > #include <TGFrame.h>
> > #include <TGListBox.h>
> > #include <iostream.h>
> > #else
> > class TGTextButton;
> > class TGLayoutHints;
> > class TGListBox;
> > class TGWindow;
> > #endif
> > #include <TGFrame.h>
> >
> >
> > class MyMainFrame : public TGMainFrame {
> >
> > private:
> >     TGTextButton    *fButton1, *fButton2;
> >     TGLayoutHints   *fLayout;
> >     TGListBox       *fListBox;
> >
> > public:
> >     MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h);
> >     ~MyMainFrame();
> >     Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2);
> > };
> >
> >
> > MyMainFrame::MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h)
> >     : TGMainFrame(p, w, h)
> > {
> >    // set the cmd string, cmd is a string that calls the processmessage
> >    // method when any of the button is called
> >
> >     char cmd[128];
> >     sprintf(cmd, "{long
> > r__ptr=0x%lx;((MyMainFrame*)r__ptr)->ProcessMessage($MSG,$PARM1,$PARM2);}",
> > (Long_t)this);
> >
> >     fLayout = new TGLayoutHints(kLHintsCenterX | kLHintsTop);
> >
> >     fButton1 = new TGTextButton(this, "&Version", 1);
> >     AddFrame(fButton1, fLayout);
> >     fButton1->Associate(this);
> >     fButton1->SetCommand(cmd);  // ProcessMessage will be executed twice
> >                                 // for fButton1 (via Associate and SetCommand)
> >     fButton2 = new TGTextButton(this, "&Exit", 2);
> >     AddFrame(fButton2, fLayout);
> >     fButton2->Associate(this);
> >
> >
> >     fListBox = new TGListBox(this, 3);
> >     fListBox->Associate(this);
> >     AddFrame(fListBox, fLayout);
> >     fListBox->Resize(180,200);
> >     fListBox->AddEntry("entry 1", -1 );
> >     fListBox->AddEntry("entry 2", -1 );
> >     fListBox->AddEntry("entry 3", -1 );
> >     fListBox->AddEntry("entry 4", -1 );
> >     fListBox->MapSubwindows();
> >     fListBox->Layout();
> >
> >
> >     MapSubwindows();
> >
> >
> >     SetWindowName("Listbox test");
> >     Resize( GetDefaultSize());
> >
> >     MapWindow();
> > }
> >
> > MyMainFrame::~MyMainFrame()
> > {
> >         delete fListBox;
> >         delete fButton2;
> >         delete fButton1;
> >         delete fLayout;
> > }
> >
> > Bool_t MyMainFrame::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
> > {
> >     // Process events generated by the buttons in the frame.
> >         cout<<"entering processmesg"<<endl;
> >
> >     switch (GET_MSG(msg))
> >     {
> >         case kC_COMMAND:
> >         cout<<"entering kcCommand switch"<<endl;
> >             switch (GET_SUBMSG(msg))
> >             {
> >                 case kCM_BUTTON:
> >                     printf("text button id %ld pressed\n", parm1);
> >                     break;
> >                 case kCM_LISTBOX:
> >                     printf("item id %ld selected from listbox id %ld \n", parm2,
> > parm1);
> >                     break;
> >                 default:
> >                     break;
> >             }
> >         default:
> >             break;
> >     }
> >     return kTRUE;
> > }
> >
> >
> > void mymain()
> > {
> >    new MyMainFrame(gClient->GetRoot(), 600, 1000);
> > }
> >
> >
> > //---------------------------------------
> > --
> > Org:    CERN, European Laboratory for Particle Physics.
> > Mail:   1211 Geneve 23, Switzerland
> > E-Mail: Fons.Rademakers@cern.ch              Phone: +41 22 7679248
> > WWW:    http://root.cern.ch/~rdm/            Fax:   +41 22 7677910
> >

-- 
Org:    CERN, European Laboratory for Particle Physics.
Mail:   1211 Geneve 23, Switzerland
E-Mail: Fons.Rademakers@cern.ch              Phone: +41 22 7679248
WWW:    http://root.cern.ch/~rdm/            Fax:   +41 22 7677910



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:27 MET