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

From: Fons Rademakers (Fons.Rademakers@cern.ch)
Date: Tue Jun 06 2000 - 16:37:21 MEST


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