Re: ROOT used inside MFC MDI app

From: Valery Fine (fine@bnl.gov)
Date: Mon Mar 02 1998 - 23:39:33 MET


On  2 Mar 98 at 13:28, William J Deninger wrote:

> From:          "William J Deninger" <deninger@uiuc.edu>
> To:            "roottalk" <roottalk@hpsalo.cern.ch>
> Subject:       ROOT used inside MFC MDI app
> Date:          Mon, 2 Mar 1998 13:28:11 -0600

> keywords:
>     MS - Microsoft
>     MFC - Microsoft Foundation Class
>     MDI - Multiple Document Interface
> 
> 
> >From previous roottalk correspondences, I remember mentioned that 
> the WinNT/Win95 port actually has two threads (composing two message 
> handling loops): one for the CINT commands, the other for CINT window 
> messages. 

  First is build a WIN32 Console application !!!
  Why? By historic reason and because ROOT has a so-called batch mode.
  It is very WIN32 console application anyway.

  It has 3 threads (the last one was introduced 7 momths ago)

    1. Console - initial appl thread
    2. Main CINT thread to call CINT
    3. Windows - to manage Windows 


> One of these (I think) is the initial application thread.  

  Right, It it thread #1.

> The MFC application itself has a message loop (virtual CWndApp::Run()) which
> can be overloaded in order to change application behavior.  The MFC
> message loop traditionally is the application thread because it 
> makes no special thread provisions
                                                        ^

> What I'm trying to do in the simplest of terms is get the ROOT
> canvases attached (as child windows) to the MDI application main
> frame window, and have the all window messaging handled by the same
> application thread message loop.  

> The ROOT CINT command thread would be an additional thread worker thread. 

   See my first remark. The current ROOT is designed as WIN32 Console
application. I doesn't create any console itself. It expects the OS 
creates the console (a'la UNIX). Changing things may lead to some 
significant change in the WIN32 classes. 

> 
> Adding WS_EX_MDICHILD to the window style  and replacing the NULL
> window handle with the HWND of the mainframe in
> TGWin32WindowsObject::CreateWindowsObject was a failed attempt, but
> I had not combined CWndApp and ROOT message loops.  Does anyone in
> ROOTLAND have a suggestion for implementing this, or perhaps know of
> a place I might go for more information?
> 


  Uhhh, It seems to me it would be not easy.

  I have no clue but would like to provide a few tips.

  1. TGWin32WindowsObject is derived from TGWin32Object
  2. TGWin32Object has  the data member:  

     TWin32CallBackList fWinAction;   // List of the callback  functions to manage the events tips to let 

     and the method:
     LRESULT  CallCallback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

        Since you are making WIN32 application I hope you may recognize the
     list of the parameter for "CallCallback" is just a "native" WIN32 message.

   3. Now I am calling your attention to WIN32_GWIN32.cxx file.

      Here one can find the  Windows Procedure for all ROOT windows:

LRESULT APIENTRY WndROOT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Main Universal Windows procedure to manage all dispatched events     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

 if (uMsg == WM_CREATE) return ::OnCreate(hwnd, uMsg, wParam, lParam);
 else {
     TGWin32Object* lpWin32Object = ((TGWin32Object*)GetWindowLong(hwnd,GWL_USERDATA));
     if (lpWin32Object) {
               ((TGWin32WindowsObject *)lpWin32Object)->StartPaint();
               LRESULT ret_value = lpWin32Object->CallCallback(hwnd, uMsg, wParam, lParam);
               ((TGWin32WindowsObject *)lpWin32Object)->FinishPaint();
               return ret_value;
     }
     else return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
 }
}

  Just you may call  this WinProc for all ROOT MDI you carted it 
will (may be ?) live.

   4. The last, How to manage the Windows thread ? That's question for you. But 
      I'd like to call your attention to 

    unsigned int _stdcall ROOT_MsgLoop(HANDLE ThrSem)
    //*-*-*-*-*-*-*-*-*-*-*-*-* ROOT_MsgLoop*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
    //*-*                       ============
    //*-*  Launch a separate thread to handle the ROOTCLASS messages
    //*-*
    //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
    {


    When ROOT is going to create any Canvas it sends the message 
IX_OPNWI.    
   You have to catch the FIRST message and create the object of 
CWndApp *ROOT_MDI_Parent = new CWndApp(...),
then call    

((TGWin32WindowsObject*)(msg.lParam))->Win32CreateObject(); 


   Very likely you have to supply your own version of 

          ROOT_MsgLoop(HANDLE ThrSem).    

It should not difficaul since it is a simple function, and it belongs 
NO class   at all.

    Hope this helps, 
             With my regards,
                         Valery
=================================================================
Dr. Valeri Faine (Fine)
    -------------------          Phone: +1 516 344 7806
Brookhaven National Laboratory   FAX  : +1 516 344 4206
Bldg. 510A /STAR                 mailto:fine@rsgi01.rhic.bnl.gov
Upton, New York, 11973-5000      http://nicewww.cern.ch/~fine
USA
                                 
Dr. Valery Fine                  Telex : 911621 dubna su
    -----------
LCTA/Joint Inst.for Nuclear Res. Phone : +7 09621 6 40 80
141980 Dubna, Moscow region      Fax   : +7 09621 6 51 45
Russia                           mailto:fine@main1.jinr.dubna.su                              



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:30 MET