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

From: Olivier D'Arcy (darcy@ligo.mit.edu)
Date: Tue Jun 06 2000 - 19:54:49 MEST


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
> 



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