/***********************************************************************************************/ 
/*                                                                                             */ 
/*          Implementation des fonctions du package win.pkg                                    */ 
/*                                                                                             */ 
/***********************************************************************************************/ 


//
// Modifications History
//
//$ LB (13/06/2002) : changed objbitmap access, according to the new objbitmap structure
//
//$LB (07/02/2003) : flags debug
//
//$LB (16/12/2003) : add _SETwindowTransparency and SetWindowTransparency
//



#include "x/version.h"
#include "x/scolplugin.h"


#include <stdio.h>
#include <string.h>

#include "objstr.h"

#include "tests.h"
#include "objects/win.h"
#include "objects/win_events.h"
#include "objects/bitmap.h"
#include "objects/font.h"
#include "events.h"
#include "osversion.h"
#include "macros.h"
#include "colors.h"
#include "objects/win_trans.h"
#include "performanceinfo.h"




/****************************************************************************************/
/*                                                                                      */
/*  fonction HWND NewWindow ( PtrObjWindow Wnd , char * Name , HWND Parent )            */
/*                                                                                      */
/*  Cette fonction cree une nouvelle fenetre d'apres la description de celle-ci contenu */
/* dans une structure PtrObjWindow                                                      */
/*                                                                                      */
/****************************************************************************************/

#define WIN_X_BORDER    3
#define WIN_Y_BORDER    3
#define WIN_CAPTION     17

 
HWND NewWindow ( PtrObjWindow Wnd , char * Name , HWND Parent )
{    
int Style ;
//int  MDITest ;
int FF ;
int Ex_Flag = 0 ;
RECT r , rectcli ;
HWND H ;
int DX , DY ;
WINDOWPLACEMENT wnd ;
char classe [255 ] ;
CLIENTCREATESTRUCT client ;
//$LB (16/12/2003)
osinfo theOSinfo = GetOsInfo();

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nNewWindow");
#endif
//***********************************

  Style = 0 ;        
  FF = Wnd->Flags ;
  Wnd->tBuf = NULL;
  Wnd->tSimulated = 0;

  //
  //$LB (16/12/2003) : init data to simulate transparency 
  //
  if (FF & WN_TRANSPARENCY)  
  {
    FF|= WN_NOBORDER;
	  FF|= WN_NOCAPTION;

	  //
	  // WinXP, Win2000
	  //
	  if ( theOSinfo >= kOsInfoWin2000 )
	  { 
		  Wnd->tBuf = NULL;
		  Wnd->tSimulated = 0;
	  }
	  //
	  // Others Versions : simulate transparency with a screen capture
	  //
		else
		{
		  if (!InitWindowTransparency(Wnd))
			  return NULL;
		  Wnd->tSimulated = 1;
		}
  }

  if (FF & WN_NOBACKGROUND)
    strcpy ( classe , "NoBackgroundClass2D" );
  else
    strcpy ( classe , "GenericClass2D" );

  if ( Parent != NULL )
  {
    if  (FF&WN_GROUP)
    {
      Style |= BS_GROUPBOX|WS_CHILD |WS_CLIPSIBLINGS;
      strcpy (classe,"button");              
    }
    else if ( FF & WN_CHILD )
    {
      Style |= (WS_CHILD | WS_CLIPSIBLINGS) ; 
      if ((FF & WN_CHILDMENU) == 0) 
      	FF |= WN_NOCAPTION ;              
    } 
    else 
    	Style |= WS_POPUP  ;                
  } 
  else 
  	Style |= WS_POPUP ;

  if (( FF & WN_NOCLIPCHILDREN ) == 0 ) 
    Style |= WS_CLIPCHILDREN ;

  if (( FF & WN_GROUP ) == 0 )
  {
    if ( ( FF & WN_NOBORDER ) == 0 ) 
    	Style |= WS_BORDER ;
    if ( ( FF & WN_NOCAPTION )== 0 ) 
    	Style |= WS_CAPTION ; //SH
  }

  if ( FF & WN_MINIMIZE ) 		Style |= WS_MINIMIZE ;                
  if ( FF & WN_MINBOX ) 			Style |= WS_MINIMIZEBOX ;
  if ( FF & WN_MAXBOX ) 			Style |= WS_MAXIMIZEBOX ;
  if ( FF & WN_SIZEBOX ) 			Style |= WS_SIZEBOX|WS_MAXIMIZEBOX  ;
  if ( FF & WN_MENU ) 				Style |= WS_SYSMENU ;  
  if ( FF & WN_DRAGDROP ) 		Ex_Flag |= WS_EX_ACCEPTFILES ;
  if ( FF & WN_HSCROLL ) 			Style |= WS_HSCROLL ;
  if ( FF & WN_VSCROLL ) 			Style |= WS_VSCROLL ; 
  if ( FF & WN_DOWN ) 				Ex_Flag |= WS_EX_CLIENTEDGE ;

  //$BLG: v4.6a6 - Add
  if ((theOSinfo >= kOsInfoWin2000) && !(FF & WN_CHILD))
  { 
	  if (FF & WN_EX_LAYERED)   Ex_Flag |= WS_EX_LAYERED;
  }
        
  //MDITest = 0 ;
  
  r.left=0;
  r.top=0;
  r.right= Wnd->TailleW;
  r.bottom=Wnd->TailleH;
  
  AdjustWindowRect(&r,Style,FALSE);
   
  client.hWindowMenu = NULL ;
  client.idFirstChild = 1000 ;

  if ( FF & WN_DIALOG )
  {
    if ( FF & WN_MODAL )
    { 
      H = CreateDialog ( (HINSTANCE)SCgetExtra("this_inst") , MAKEINTRESOURCE (102) , Parent , MyDlgProc ) ;
      MMechostr (1,"Modal window\n");
    }
    else
      H = CreateDialog ( (HINSTANCE)SCgetExtra("this_inst") , MAKEINTRESOURCE (101) , Parent , MyDlgProc ) ;

    GetClientRect ( H , &rectcli ) ;
    GetWindowRect ( H , &r ) ;
    r.bottom += 1 - r.top ;
    r.right += 1 - r.left ;
    DY = r.bottom - rectcli.bottom ;
    DX = r.right - rectcli.right ;
    wnd.length = sizeof ( WINDOWPLACEMENT ) ;
    GetWindowPlacement ( H , &wnd ) ;

    wnd.rcNormalPosition.left = Wnd->PosX ;
    wnd.rcNormalPosition.right = Wnd->PosX + Wnd->TailleW + DX ;
    wnd.rcNormalPosition.top = Wnd->PosY ;
    wnd.rcNormalPosition.bottom = Wnd->PosY + Wnd->TailleH + DY ;
    SetWindowPlacement ( H , &wnd ) ;
    SendMessage ( H , WM_SETTEXT , 0 , ( LPARAM ) Name ) ;         
  }
  else 
  { 
    H = CreateWindowEx ( Ex_Flag , classe ,                	/* classe de fenetre */
                Name , Style ,                  						/* nom, style */
                Wnd->PosX , Wnd->PosY ,                			/* position x,y */
                r.right - r.left , r.bottom - r.top ,				/* taille de la fenetre */
                Parent , NULL ,                							/* parent , menu */
                (HINSTANCE)SCgetExtra("this_inst") , ( LPSTR ) &client  ) ;            /* program inst , params */

    //if ( MDITest ) SetWindowLong ( H , GWL_WNDPROC , ( long ) MDIProcBis ) ;
    
    MMechostr(0, "NewWindow: %d\n", H);

    if ( strcmp ( classe,"button")==0 )            
      SetWindowLong ( H , GWL_WNDPROC , ( long ) WindowProc ) ;
  }
		
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nNewWindow new : %d", (int)H);
#endif
//***********************************

  return H ;
}






/****************************************************************************/ 
/*                                                                          */ 
/*  int GRHideWindow ( mmachine m )                                         */ 
/*                                                                          */ 
/* correspond a la fonction magma Obj _hide_window ( Obj Win ) ;            */ 
/* laquelle dissimule une fenetre                                           */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRHideWindow ( mmachine m )
{
    int s , res ;
    PtrObjVoid O ;
    HWND H ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRHideWindow");
#endif
//***********************************

    s = MMpull(m) ;
    if ( s == NIL ) return MMpush(m,NIL) ;

    O = ( PtrObjVoid ) MMstart(m, ( s>>1 ) ) ;

    switch ( O->Type >> 1 )
    {
        case OBJ_TYPE_WINDOW :
            H = (( PtrObjWindow ) MMstart(m, ( O->Buffer>>1) ) )->WHandler ;
            break ;
        default : H = NULL ;
    }

    if ( H != NULL )
    {
        ShowWindow ( H , SW_HIDE ) ;
        UpdateWindow ( H ) ;
    }

    res = MMpush(m,s) ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRHideWindow new");
#endif
//***********************************

    return res ;
}  

/******************************************************************************************/
/*                                                                                        */
/*      int GRUnhideWindow ( mmachine m )                                                 */
/*                                                                                        */
/*  correspond a la fonction magma Obj _unhide_obj ( Obj win )                            */
/*  laquelle remet une fenetre HIDE en mode SHOW                                          */
/*                                                                                        */
/******************************************************************************************/

int GRUnhideWindow ( mmachine m )
{
    int s , res ;
    PtrObjVoid O ;
    HWND H ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRUnhideWindow");
#endif
//***********************************

    s = MMpull(m) ;
    if ( s == NIL ) return MMpush ( m , NIL ) ;

    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;

    switch ( O->Type >> 1 )
    {
        case OBJ_TYPE_WINDOW :
            H = (( PtrObjWindow ) MMstart(m,(O->Buffer>>1) )) ->WHandler ;
            break ;

        default : H = NULL ;
    }

    if ( H != NULL )
    {
        ShowWindow ( H , SW_SHOW ) ;
        UpdateWindow ( H ) ;
    }

    res = MMpush ( m , s ) ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRUnhideWindow new");
#endif
//***********************************

    return res ;
}


/******************************************************************************************/
/*                                                                                        */
/* int GRGetSizePositionWindow ( mmachine m )                                             */
/*                                                                                        */
/* correspond a la fonction magma [ I I I I I ] _get_size_position_window ( Obj )         */
/*                                                                                        */
/******************************************************************************************/

#define MODE_SIZE_POSITION  0
#define MODE_POSITION_SIZE  1

int GenericGetSizePositionWindow ( mmachine m , int mode )
{
    int s , ww1 , wh , wx , wy , res ;
    WINDOWPLACEMENT wnd ;
    PtrObjVoid O ;
    HWND H ;
    

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGenericGetSizePositionWindow");
#endif
//***********************************

    s = MMpull(m) ;

    if ( s == NIL ) return MMpush(m,NIL ) ;   

    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;
    
    switch ( O->Type >> 1 )
    {
        case OBJ_TYPE_WINDOW :

                H = (( PtrObjWindow ) MMstart(m, (O->Buffer>>1) ) ) ->WHandler ;
                break ;
        case OBJ_TYPE_TEXT :
        case OBJ_TYPE_EDIT_TEXT :
        case OBJ_TYPE_EDIT_LINE :
        case OBJ_TYPE_RICH_TEXT :

                H = (( PtrObjText ) MMstart(m,(O->Buffer>>1) ) ) -> WHandler ;
                break ;

        case OBJ_TYPE_CHECK_BOX :
        case OBJ_TYPE_PUSHBUTTON :

                H = (( PtrObjButton ) MMstart(m,(O->Buffer>>1) ) ) -> WHandler ;
                break ;

        case OBJ_TYPE_LIST_BOX :
         case OBJ_TYPE_COMBO_BOX :

                H = (( PtrObjCombo ) MMstart(m,( O->Buffer>>1) ) ) -> WHandler ;
                break ;

        case OBJ_TYPE_PUSH_BUTTON_BITMAP :
        
                H = (( PtrObjPushButtonBitmap ) MMstart(m,( O->Buffer>>1) )) -> WHandler ;
                break ;        
        case OBJ_TYPE_TREE :
                H = (( PtrObjTree ) MMstart(m,(O->Buffer>>1)))->WHandler ;
                break ;

        case OBJ_TYPE_LISTTAB :

                H = ((PtrObjListTab ) MMstart(m,(O->Buffer>>1)))->WHandler ;

        default : return MMpush(m,NIL ) ;
    }

       
    wnd.length = sizeof ( WINDOWPLACEMENT ) ;
    
        GetWindowPlacement ( H , &wnd ) ;
        wh = wnd.rcNormalPosition.bottom - wnd.rcNormalPosition.top   +1;
        ww1 = wnd.rcNormalPosition.right  - wnd.rcNormalPosition.left  +1;
        wy = wnd.rcNormalPosition.top  ;
        wx = wnd.rcNormalPosition.left  ;
    
    

    /* empile flag , tailley , taillew , posy , posx */     

    if ( mode == MODE_SIZE_POSITION )
    {
        MMpush(m,ww1<<1) ;
        MMpush(m,wh<<1) ;
        MMpush(m,wx<<1) ;
        MMpush(m,wy<<1) ;  
    } else 
    {
        MMpush(m,wx<<1) ;
        MMpush(m,wy<<1) ;
        MMpush(m,ww1<<1) ;
        MMpush(m,wh<<1) ;  
    }

    MMpush(m,8) ;

    res = MBdeftab(m) ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGenericGetSizePositionWindow new");
#endif
//***********************************
                          
    return res ;
}


int GenericGetClientRect ( mmachine m , int mode )
{
    int s , ww1 , wh , wx , wy , res ;
    WINDOWPLACEMENT wnd ;
    PtrObjVoid O ;
    HWND H ;
    RECT r ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGenericGetClientRect");
#endif
//***********************************
    
    s = MMpull(m) ;

    if ( s == NIL ) return MMpush(m,NIL ) ;   

    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;    
    H = (( PtrObjWindow ) MMstart(m, (O->Buffer>>1) ) ) ->WHandler ;
      
    
    wnd.length = sizeof ( WINDOWPLACEMENT ) ;
    
    GetWindowPlacement ( H , &wnd ) ;
    wh = wnd.rcNormalPosition.bottom - wnd.rcNormalPosition.top   +1;
    ww1 = wnd.rcNormalPosition.right  - wnd.rcNormalPosition.left  +1;
    wy = wnd.rcNormalPosition.top  ;
    wx = wnd.rcNormalPosition.left  ;

	if (wnd.showCmd==SW_SHOWMAXIMIZED)
	{
		MMechostr(1,"maximized\n");
		wx=wnd.ptMaxPosition.x;
		wy=wnd.ptMaxPosition.y;
	}
	else if (wnd.showCmd==SW_SHOWMINIMIZED)
	{
		MMechostr(1,"minimized\n");
		wx=wnd.ptMinPosition.x;
		wy=wnd.ptMinPosition.y;
	}
  
    GetClientRect ( H , &r ) ;
    wh = r.bottom ;
    ww1 = r.right ;        

    /* empile flag , tailley , taillew , posy , posx */     
    
    if ( mode == MODE_SIZE_POSITION )
    {
        MMpush(m,ww1<<1) ;
        MMpush(m,wh<<1) ;
        MMpush(m,wx<<1) ;
        MMpush(m,wy<<1) ;  
    } else 
    {
        MMpush(m,wx<<1) ;
        MMpush(m,wy<<1) ;
        MMpush(m,ww1<<1) ;
        MMpush(m,wh<<1) ;  
    }
    MMpush(m,8) ;

    res = MBdeftab(m) ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGenericGetClientRect new");
#endif
//***********************************
                          
    return res ;
}

int GRGetPositionSizeWindow ( mmachine m )
{
    return GenericGetSizePositionWindow ( m , MODE_POSITION_SIZE ) ;
}

int GRGetSizePositionWindow ( mmachine m )
{
    return GenericGetSizePositionWindow ( m , MODE_SIZE_POSITION ) ;
}

int GRGetClientRect2 ( mmachine m )
{
    return GenericGetClientRect (  m , MODE_POSITION_SIZE ) ;
}

int GRGetClientRect ( mmachine m ) 
{
    return GenericGetClientRect (  m , MODE_SIZE_POSITION) ;
}

/****************************************************************************************/
/*                                                                                      */
/* int GRResizeWindow ( mmachine m ) ;                                                  */
/*                                                                                      */
/* correspond a la fonction Obj _resize_window ( Obj I I I I)                           */
/*                                                                                      */
/****************************************************************************************/

int GenericResizeWindow ( mmachine m , int mode , int ext )
{
    int W , H , X , Y , s , res , DX , DY ;
    HWND HW ;
    PtrObjVoid O ;
    WINDOWPLACEMENT wnd ;
    RECT rectex , rectcli ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGenericResizeWindow");
#endif
//***********************************

    if ( mode == MODE_SIZE_POSITION )
    {
        Y = MMpull(m)>>1 ;
        X = MMpull(m)>>1 ;
        H = MMpull(m)>>1 ;
        W = MMpull(m)>>1 ;
    } else 
    {
        H = MMpull(m)>>1 ;
        W = MMpull(m)>>1 ;
        Y = MMpull(m)>>1 ;
        X = MMpull(m)>>1 ;
    }
    s = MMpull(m) ;  

    if ( s == NIL ) return MMpush(m,NIL) ;    

    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;
    DX = 0 ;
    DY = 0 ;

    res = 0 ;
    switch ( O->Type >> 1 )
    {
        case OBJ_TYPE_WINDOW :
                HW = (( PtrObjWindow ) MMstart(m, (O->Buffer>>1) ) ) ->WHandler ;
                if ( !ext  )
                {
                    GetClientRect ( HW , &rectcli ) ;
                    GetWindowRect ( HW , &rectex ) ;
                    rectex.bottom +=1- rectex.top ;
                    rectex.right +=1- rectex.left ;
                    DY = rectex.bottom - rectcli.bottom ;
                    DX = rectex.right - rectcli.right ;
                }
                res = (( PtrObjWindow ) MMstart(m,(O->Buffer>>1)))->Flags & WN_HIDE ;
                break ;
               
        case OBJ_TYPE_EDIT_TEXT :
        case OBJ_TYPE_TEXT :
        case OBJ_TYPE_EDIT_LINE :
        case OBJ_TYPE_RICH_TEXT :

                HW = (( PtrObjText ) MMstart(m, (O->Buffer>>1) )) -> WHandler ;
                break ;
        case OBJ_TYPE_CHECK_BOX :
        case OBJ_TYPE_PUSHBUTTON :

                HW = (( PtrObjButton ) MMstart(m,( O->Buffer>>1) )) ->WHandler ;
                break ;

        case OBJ_TYPE_LIST_BOX :
        case OBJ_TYPE_COMBO_BOX :

                HW = (( PtrObjCombo ) MMstart(m,( O->Buffer>>1) )) -> WHandler ;
                break ;

        case OBJ_TYPE_PUSH_BUTTON_BITMAP :

                HW = (( PtrObjPushButtonBitmap ) MMstart(m,( O->Buffer>>1) )) -> WHandler ;
                break ;

        case OBJ_TYPE_TREE :

                HW =  ((PtrObjTree ) MMstart(m,(O->Buffer>>1)))->WHandler ;
                break ;

        case OBJ_TYPE_LISTTAB :

                HW = ((PtrObjListTab ) MMstart(m,(O->Buffer>>1)))->WHandler ;
                break ;

        default : return MMpush(m,s) ;        
    }    
    wnd.length = sizeof ( WINDOWPLACEMENT ) ;
    GetWindowPlacement ( HW , &wnd ) ;

    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _generic resize :\n");
        if (wnd.flags & WPF_RESTORETOMAXIMIZED ) MMechostr(MSKDEBUG,"FLAG RestoreToMaximized\n");
        if (wnd.flags & WPF_SETMINPOSITION) MMechostr(MSKDEBUG,"FLAG SetMinPosition\n");
        if (wnd.showCmd == SW_HIDE) MMechostr(MSKDEBUG,"SHOW Hide\n");
        else if (wnd.showCmd == SW_MINIMIZE) MMechostr(MSKDEBUG,"SHOW Minimize\n");
        else if (wnd.showCmd == SW_RESTORE) MMechostr(MSKDEBUG,"SHOW Restore\n");
        else if (wnd.showCmd == SW_SHOW) MMechostr(MSKDEBUG,"SHOW Show\n");
        else if (wnd.showCmd == SW_SHOWMAXIMIZED) MMechostr(MSKDEBUG,"SHOW Show Maximized\n");
        else if (wnd.showCmd == SW_SHOWMINIMIZED) MMechostr(MSKDEBUG,"SHOW Show Minimized\n");
        else if (wnd.showCmd == SW_SHOWMINNOACTIVE) MMechostr(MSKDEBUG,"SHOW Show Min Noactive\n");
        else if (wnd.showCmd == SW_SHOWNA) MMechostr(MSKDEBUG,"SHOW Na\n");
        else if (wnd.showCmd == SW_SHOWNOACTIVATE) MMechostr(MSKDEBUG,"SHOW No Active\n");
        else if (wnd.showCmd == SW_SHOWNORMAL) MMechostr(MSKDEBUG,"Show Normal\n");
    #endif
         
    wnd.rcNormalPosition.left = X ;
    wnd.rcNormalPosition.right = X + W + DX -1;
    wnd.rcNormalPosition.top = Y ;
    wnd.rcNormalPosition.bottom = Y + H + DY -1;
    
    if ( res ) { /*MMechostr(MSKDEBUG,"test HIDE 1\n");*/ wnd.showCmd = SW_HIDE ; }

    SetWindowPlacement ( HW , &wnd ) ;
    

    if ( res ) { /*MMechostr(MSKDEBUG,"test HIDE 2\n") ;*/ ShowWindow ( HW , SW_HIDE ) ; }
    UpdateWindow ( HW ) ;


    res = MMpush(m,s) ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGenericResizeWindow new");
#endif
//***********************************


    return res ;
}


int GRReposWindow ( mmachine m )
{
   return GenericResizeWindow ( m , MODE_POSITION_SIZE , 0 ) ;
}


int GRResizeWindow ( mmachine m )
{
   return GenericResizeWindow ( m , MODE_SIZE_POSITION , 0 ) ;
}
   
int GRPositionEx ( mmachine m )
{
    return GenericResizeWindow ( m , MODE_POSITION_SIZE, 1 ) ;
} 

int GRSizeEx ( mmachine m ) 
{
    return GenericResizeWindow ( m , MODE_SIZE_POSITION , 1 ) ;
}

/***************************************************************************************/
/*                                                                                     */
/*  int GRSetFocus ( MMachine m )                                                      */
/*                                                                                     */
/* correspond a la fonction Obj _set_focus ( Obj ) de magma                            */
/*                                                                                     */
/***************************************************************************************/

int GRSetFocus ( mmachine m )
{
    int s , res ;
    PtrObjVoid O ;
    HWND H ;    


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetFocus");
#endif
//***********************************

  s = MMpull(m);
  if (s == NIL) //return MMpush(m,NIL);
	{
		H = (HWND)SCgetExtra("hscol");
	}
	else
	{
		O = (PtrObjVoid) MMstart(m, (s>>1));
		H = NULL;
		switch(O->Type>>1)
		{
        case OBJ_TYPE_WINDOW :
						H = ((PtrObjWindow) MMstart(m, (O->Buffer>>1)))->WHandler;
            break;
			
        case OBJ_TYPE_TEXT :
        case OBJ_TYPE_EDIT_LINE :
        case OBJ_TYPE_EDIT_TEXT :
            H = ((PtrObjText) MMstart(m,(O->Buffer>>1)))->WHandler;
            break;
		}
	}
  if (H != NULL)
	{
		SetForegroundWindow(H);
		SetFocus(H);
	}
    
  res = MMpush(m,s);
 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetFocus new");
#endif
//***********************************

  return res ;
}

/************************************************************************************/
/*                                                                                  */
/*  GRSetWindowName ( mmachine m )                                                  */
/*                                                                                  */
/*  correspond a la fonction magma Obj _set_window_name ( Obj , S )                 */
/*                                                                                  */
/************************************************************************************/

int GRSetWindowName ( mmachine m )
{
    int s , res , s2;
    PtrObjVoid O ;
    HWND H ;
    char NewName [ 33000 ] ;
    //$BLG
    PtrObjWindow blg_wnd;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowName");
#endif
//***********************************
    s2 = MMpull(m) ; 
   
    s = MMpull( m ) ;
    if ( s == NIL ) return MMpush(m,NIL ) ;    

    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;
    switch ( O->Type >> 1 )
    {
        //$BLG
        //case OBJ_TYPE_WINDOW : H = ((PtrObjWindow )MMstart(m,(O->Buffer>>1)))->WHandler ; break ;
        case OBJ_TYPE_WINDOW : blg_wnd = (PtrObjWindow )MMstart(m,(O->Buffer>>1));

                               H = blg_wnd->WHandler; 
                               break ;
        case OBJ_TYPE_CHECK_BOX :
        case OBJ_TYPE_PUSHBUTTON : H = ((PtrObjButton) MMstart(m,(O->Buffer>>1)))->WHandler ; break ;
       
        default : H = NULL ; break ;
    }
     if ( s2 != NIL ) 
     {
         if ( O->Type == ( OBJ_TYPE_WINDOW << 1 ) )
           //$BLG - v4.6a4
           //$BLG Modif
           //sprintf ( NewName ,"(SCOL)%s" , ( char * ) MMstart(m, (s2>>1) + 1) ) ;
           if (blg_wnd->Flags & WN_NOSCOL)
             sprintf ( NewName ,"%s" , ( char * ) MMstart(m, (s2>>1) + 1) ) ;
           else
             sprintf ( NewName ,"(SCOL)%s" , ( char * ) MMstart(m, (s2>>1) + 1) ) ;
           //$BLG End
         else 
           strcpy ( NewName,(char *)MMstart(m,(s2>>1)+1));
     } 
     else 
       //$BLG - v4.6a4
       //$BLG Modif
       //strcpy ( NewName , "(SCOL)" ) ;
       if (O->Type == (OBJ_TYPE_WINDOW << 1))
         if (blg_wnd->Flags & WN_NOSCOL)
           strcpy (NewName, "");
         else
           strcpy(NewName, "(SCOL)");
       else
         strcpy(NewName, "(SCOL)");
       //$BLG End
   
    if ( H ) SendMessage ( H , WM_SETTEXT , 0 , ( LPARAM ) NewName ) ;
    
    res = MMpush(m,s) ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowName new");
#endif
//***********************************

    return res ;
}


/*****************************************************************************/
/*                                                                           */
/*  fonction int GRCreateWindow ( mmachine m ) ;                             */
/*                                                                           */
/*  fonction C correspondant a la fonction magma                             */
/*                                                                           */
/*  Obj _create_window ( Obj parent , int PosX , int PosY , int TailleW      */
/*    int TailleH , int Flags , int MHandler , S Nom , I sock )              */
/*                                                                           */
/*  cette fonction cree une nouvelle fenetre windows                         */
/*                                                                           */
/*****************************************************************************/

int GRCreateWindow ( mmachine m )
{   
        
int s,l , dummy,s2 , res ;

PtrObjWindow Wnd,PW ;
PtrObjVoid O,OP;
HWND HW , Parent ;      
char Name [ 33000 ] ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRCreateWindow");
#endif
//***********************************

  /* test si channel == NIL */
  if ( MMget(m,7) == NIL ) 
  {
      MMechostr (1,"_CRwindow : channel is NIL\n");
      m->pp += 7;
      MMset(m,0,NIL);
      return 0;
  }
  
  dummy           = MMpull(m)     ;
  /* ajouter ici le test sur la taille des noms de fenetres */
  //$BLG - v4.6a4
  //Moved and modified below
  //if ( dummy == NIL ) strcpy ( Name , "(SCOL)" ) ; else
  //    sprintf ( Name , "(SCOL)%s" , ( char * ) MMstart(m, (dummy>>1) + 1) ) ;

  /* creation de la zone memoire pour l'objet de base */
  l = ( sizeof ( struct ObjVoid ) + 3 ) >> 2 ;        
  s = MMmallocCLR(m,l,TYPETAB) ;
  if ( s == NIL )
  {
      MMechostr(MSKDEBUG,"_create_window : Error in Alloc MAGMA memory\n" ) ;
      return MERRMEM ;
  }               
  if ( MMpush ( m,(s<<1)+1 )) return MERRMEM ;
  /* on remet s sur la pile au cas ou le malloc suivant */
  /* causerait un GC */

  /* creation de la zone memoire pour les donnees propres aux fenetres */
  l = ( sizeof ( struct ObjWindow ) + 3 ) >> 2 ;
  
  s2 = MMmalloc (m,l,TYPEBUF);
  if ( s2 == NIL )
  {
          MMechostr (1,"_create_window: Error in Alloc MAGMA MEmory\n" ) ;             
          return MERRMEM ;
  }
                
  Wnd = ( PtrObjWindow ) MMstart(m, s2 ) ;
  s = MMpull(m) ;
  O = ( PtrObjVoid ) MMstart(m, (s >> 1) ) ;

  /* initialisation de la structure fenetre */
  O -> Type             = OBJ_TYPE_WINDOW << 1  ;        
  Wnd -> Flags          = MMpull(m) >> 1 ;

  //$BLG - v4.6a4
  if ( dummy == NIL )
    if (Wnd->Flags & WN_NOSCOL)
      strcpy(Name, "" );
    else
      strcpy(Name, "(SCOL)");  
  else
    if (Wnd->Flags & WN_NOSCOL)
      sprintf(Name, "%s", (char *)MMstart(m, (dummy>>1) + 1));
    else
      sprintf(Name, "(SCOL)%s", (char *)MMstart(m, (dummy>>1) + 1));

  if ( Wnd -> Flags & WN_HSCROLL ) Wnd->Flags -= WN_HSCROLL ;
  if ( Wnd -> Flags & WN_VSCROLL ) Wnd->Flags -= WN_VSCROLL ;
  Wnd -> TailleH        = MMpull(m) >> 1 ;
  Wnd -> TailleW        = MMpull(m) >> 1 ;
  Wnd -> PosY           = MMpull(m) ;
  Wnd -> PosX           = MMpull(m) ;
  Wnd -> MinW           = 32 ;
  Wnd -> MinH           = 32 ;
  Wnd -> MaxW           = 8000 ;
  Wnd -> MaxH           = 8000 ;
  Wnd -> Child          = NULL ;
  Wnd -> Cursor         = NULL ;
  if ( Wnd->PosX == NIL ) Wnd->PosX = CW_USEDEFAULT ; else Wnd->PosX >>= 1 ;
  if ( Wnd->PosY == NIL ) Wnd->PosY = CW_USEDEFAULT ; else Wnd->PosY >>= 1 ;
  O -> Father           = MMpull(m) ;
  O -> Tab              = NIL ;
  O->Buffer = ( s2 << 1 ) + 1 ;
         
  /* recuperation du handler window du parent, si parent il y a */
  if ( O -> Father == NIL ) 
  	Parent = NULL ;
  else
  {
    OP = ( PtrObjVoid ) MMstart(m, (O->Father>>1) ) ;
    /* verifie que le pere est bien de type Fenetre */                          
    PW = ( PtrObjWindow ) MMstart(m,(OP->Buffer >> 1)) ;
    Parent = PW->WHandler ;
  }

  /* creation de la ressource */
  HW = NewWindow ( Wnd , Name , Parent ) ;
  if ( ! HW )
  {
    MMechostr (1,"_create_window : Error in creating the WIN95 Object - Check the values\n" ) ;
    MMset(m,0,NIL) ;
    return 0 ;
  }
  Wnd->WHandler = HW  ;  

  if ( (DefaultFont != NULL) && (( Wnd->Flags & WN_GROUP ) !=0) ) 
  	SendMessage ( HW , WM_SETFONT , ( WPARAM ) DefaultFont , ( LPARAM ) TRUE ) ;  
        
	/* affichage de la fenetre */
  if ( Wnd->Flags & WN_HIDE ) 
  { 
  	ShowWindow ( HW , SW_HIDE ); 
  	MMechostr(MSKDEBUG,"Window %d HIDDEN1\n",HW);
  }
  else if ( Wnd->Flags & WN_MINIMIZE )
  	ShowWindow ( HW , SW_MINIMIZE ) ;
  else
  {
    ShowWindow( HW , SW_SHOW) ; 
    if (Wnd->Flags & WN_NOCURSOR ) SetFocus ( HW ) ;
  }

  UpdateWindow(HW);

	if (!( Wnd->Flags & WN_HIDE ))
	{
		SetForegroundWindow(HW);
		BringWindowToTop(HW) ;
		//$BLG: v4.6a7 - Add
		//$BLG: v4.6a7 - Moved below (Because Containers use hidden windows) - WN_HIDE & WN_TOPMOST can not be compatible
		/*
		if (Wnd->Flags & WN_TOPMOST)
		{
			SetWindowPos(HW, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
		}
		*/
	}

	//$BLG: v4.6a7 - Moved from above
	if (Wnd->Flags & WN_TOPMOST)
	{
		SetWindowPos(HW, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
	}
  
  MMpush(m,s) ;
  res = OBJcreate(m,OBJTYPWINDOW,(int)HW,OBJTYPWINDOW,(int)Parent) ;
      
//  MMechostr (MSKTRACE , "CRwindow : HW = %x\n" , HW ) ;

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRCreateWindow new");
#endif
//***********************************

  return res ;           
}





/*****************************************************************************/
/*                                                                           */
/* int GRShowWindow ( mmachine m ) ;                                         */
/*                                                                           */
/* correspond a la fonction magma Obj _minimize_window ( Obj )               */
/* laquelle minimize une fenetre                                             */
/*                                                                           */
/*****************************************************************************/

int GRShowWindow ( mmachine m )
{
    PtrObjVoid O ;    
    int s , res , etat ;
    HWND HW ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRShowWindow");
#endif
//***********************************

    etat = MMpull(m) >> 1 ;
    s = MMpull(m) ;
    if ( s == NIL ) return MMpush(m,NIL ) ;
    
    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;
    switch ( O->Type >> 1 )
    {
        case OBJ_TYPE_WINDOW : 
            HW = (( PtrObjWindow ) MMstart(m, (O->Buffer>>1) ) ) ->WHandler ; 
             if ( etat == WINDOW_HIDDEN ) 
                (( PtrObjWindow ) MMstart(m,(O->Buffer>>1)))->Flags |= WN_HIDE ;
            //$BLG - v4.6a4
            //This removed all flags beyond first 16 bits!!!
            //else (( PtrObjWindow ) MMstart(m,(O->Buffer>>1)))->Flags &= ( 0xFFFF - WN_HIDE ) ;
            else (( PtrObjWindow ) MMstart(m,(O->Buffer>>1)))->Flags &= ( 0xFFFFFFFF - WN_HIDE ) ;
            break ;
        case OBJ_TYPE_TEXT : 
        case OBJ_TYPE_EDIT_TEXT :
        case OBJ_TYPE_EDIT_LINE :
            HW = (( PtrObjText ) MMstart(m,(O->Buffer>>1))) ->WHandler ; 
            if ( etat != WINDOW_HIDDEN && etat != WINDOW_UNHIDDEN ) etat = 0 ;
            break ;

        case OBJ_TYPE_CHECK_BOX :
        case OBJ_TYPE_PUSHBUTTON :

                HW = (( PtrObjButton ) MMstart(m,(O->Buffer>>1) ) ) -> WHandler ;
                if ( etat != WINDOW_HIDDEN && etat != WINDOW_UNHIDDEN ) etat = 0 ;
                break ;

         case OBJ_TYPE_LIST_BOX :
         case OBJ_TYPE_COMBO_BOX :

                HW = (( PtrObjCombo ) MMstart(m,( O->Buffer>>1) ) ) -> WHandler ;
                if ( etat != WINDOW_HIDDEN && etat != WINDOW_UNHIDDEN ) etat = 0 ;
                break ;

        case OBJ_TYPE_PUSH_BUTTON_BITMAP :
        
                HW = (( PtrObjPushButtonBitmap ) MMstart(m,( O->Buffer>>1) )) -> WHandler ;
                if ( etat != WINDOW_HIDDEN && etat != WINDOW_UNHIDDEN ) etat = 0 ;
                break ;

        default : HW = NULL ; MMechostr ( 1 , "Unknow type of item\n" ) ;
    }
    if ( HW != NULL && etat )
    {
        if ( etat == WINDOW_MINIMIZED ) res = ShowWindow ( HW  , SW_MINIMIZE ) ;
        else if ( etat == WINDOW_MAXIMIZED ) res = ShowWindow ( HW , SW_MAXIMIZE ) ;
        else if ( etat == WINDOW_RESTORED ) res = ShowWindow ( HW , SW_RESTORE ) ;
        else if ( etat == WINDOW_HIDDEN ) {res = ShowWindow ( HW , SW_HIDE ) ;/*MMechostr(MSKDEBUG,"SHOW HIDDEN\n");*/}
        else if ( etat == WINDOW_UNHIDDEN ) {res = ShowWindow ( HW , SW_SHOW ) ;/*MMechostr(MSKDEBUG,"SHOW UNHIDDEN\n");*/}
       
        UpdateWindow ( HW ) ;

    } 
    else 
    	MMechostr(1 ,"Invalid state or Handler set to NIL\n");

    res = MMpush(m,s);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRShowWindow new");
#endif
//***********************************


    return res ;     
}


/****************************************************************************/
/*                                                                          */
/*  int GRReflexWinPaint ( mmachine m ) ;                                   */
/*                                                                          */
/*  correspond a la fonction magma ObjWin _reflex_win_paint ( Obj,Fun, U0 ) */
/* laquelle definit le callback d'une fenetre pour l'evenement paint        */
/*                                                                          */
/****************************************************************************/

int GRReflexWinPaint ( mmachine m )
{
    
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_PAINT);
}

/****************************************************************************/
/*                                                                          */
/*  int GRReflexWindowMove ( mmachine m ) ;                                 */
/*                                                                          */
/* correspond a la fonction magma ObjWin _reflex_win_move ( Obj,Fun,U0)     */
/*                                                                          */
/* laquelle definit le callback d'une fenetre pour l'evenement move         */
/*                                                                          */
/****************************************************************************/

int GRReflexWinMove ( mmachine m )
{
   
    return OBJaddreflex(m,OBJTYPWINDOW,RFLWINDOW_MOVE) ;
}

/****************************************************************************/
/*                                                                          */
/*  int GRReflexCursorMove ( mmachine m ) ;                                 */
/*                                                                          */
/*  correspond a la fonction magma ObjWin _reflex_cursor_move ( Obj,Fun,u)  */
/* laquelle definit le callback d'une fenetre pour l'evenement move souris  */
/*                                                                          */
/****************************************************************************/

int GRReflexCursorMove ( mmachine m )
{
    
    return OBJaddreflex ( m,OBJTYPWINDOW,RFLWINDOW_MOVEMOUSE) ;
}

/****************************************************************************/
/*                                                                          */
/*  int GRReflexWindowSize ( mmachine m ) ;                                 */
/*                                                                          */
/* correspond a la fonction ObjWin _reflex_win_size ( Obj , FUN , U0 )      */
/* laquelle definit le callback d'une fenetre pour l'evenement size         */
/*                                                                          */
/****************************************************************************/

int GRReflexWinSize ( mmachine m )
{
    if ( MMget(m,2)==NIL)
    {
        MMechostr(MSKDEBUG,"_CBwinSize : Window is NIL\n");
        m->pp+=2;
        return 0;
    }
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_SIZE) ;
}

/****************************************************************************/
/*                                                                          */
/*  int GRReflexWindowClick ( mmachine m) ;                                 */
/*                                                                          */
/* correspond a la fonction ObjWin _reflex_win_click ( Obj , Fun , U0 )     */
/* laquelle definit le callback d'une fenetre pour l'evenement click        */
/*                                                                          */
/****************************************************************************/

int GRReflexWinClick ( mmachine m )
{
    
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_CLICK ) ;
}

/****************************************************************************/
/*                                                                          */
/*  int GRReflexWindowUnclick ( mmachine m ) ;                              */
/*                                                                          */
/*  correspond a la fonction ObjWin _reflex_win_unclick ( Obj,Fun,U0)       */
/* laquelle definit le callbackj d'une fenetre pour l'evenement unclick     */
/*                                                                          */
/****************************************************************************/

int GRReflexWinUnclick ( mmachine m )
{
    
    return OBJaddreflex ( m,OBJTYPWINDOW,RFLWINDOW_UNCLICK ) ;
}


/***************************************************************************/
/*                                                                         */
/*  int GRReflexWindowKeyDown ( mmachine m ) ;                             */
/*                                                                         */
/*  correspond a la fonction ObjWin _reflex_win_keydown ( ObjWin,Fun,U0)   */
/* laquelle definit le callback d'une fenetre pour l'evenement key down    */
/*                                                                         */
/***************************************************************************/

int GRReflexWinKeyDown ( mmachine m )
{
    
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_KEYDOWN ) ;
}

/***************************************************************************/
/*                                                                         */
/* int GRReflexWindowKeyUp ( mmachine m ) ;                                */
/*                                                                         */
/* correspond a la fonction ObjWin _reflex_win_keyup ( ObjWin,Fun,U0)      */
/* laquelle definit le callback d'une fenetre pour l'evenement key up      */
/*                                                                         */
/***************************************************************************/

int GRReflexWinKeyUp ( mmachine m )
{
    
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_KEYUP) ;
}

/**************************************************************************/
/*                                                                        */
/*  int GRReflexWinFocus ( mmachine m ) ;                                 */
/*                                                                        */
/*  correspond a la fonction ObjWin _CBwinFocus (ObjWin,Fun,U0) ;         */
/*  laquelle definit le callback d'une fenetre pour l'evenement focus     */
/*                                                                        */
/**************************************************************************/

int GRReflexWinFocus ( mmachine m )
{
    
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_FOCUS);
}

/***************************************************************************/
/*                                                                         */
/*  int GRReflexWinKillFocus ( mmachine m ) ;                              */
/*                                                                         */
/*  correspond a la fonction ObjWin _CBWinKillFocus (ObjWin,Fun,U0);       */
/*  laquelle definit le callback pour l'evenement killfocus                */
/*                                                                         */
/***************************************************************************/

int GRReflexWinKillFocus ( mmachine m )
{
   
    return OBJaddreflex ( m,OBJTYPWINDOW,RFLWINDOW_KILLFOCUS);
}

/***************************************************************************/
/*                                                                         */
/* int GRReflexWindowDestroy ( mmachine m ) ;                              */
/*                                                                         */
/* correspond a la fonction magma ObjWin _reflex_win_destroy (ObjWin,Fun,u0*/
/* laquelle definit le callback d'une fenetre pour l'evenement destroy     */
/*                                                                         */
/***************************************************************************/

int GRReflexWinDestroy ( mmachine m )
{    

    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_DESTROY ) ;
}

int GRReflexWinClose ( mmachine m )
{    

    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_CLOSE ) ;
}

int GRReflexWinWheel ( mmachine m )
{
    
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_WHEEL);
}

int GRReflexWinSuspend ( mmachine m )
{
    
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_SUSPEND);
}

int GRReflexWinResume ( mmachine m )
{
    
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_RESUME);
}

/***************************************************************************/
/*                                                                         */
/*  int GRReflexWinDClick ( mmachine m ) ;                                 */
/*                                                                         */
/*  correspond a la fonction ObjWin _CBwinDClick ( ObjWin,Fun,u0)          */
/*  laquele definit le callback d'une fenetre pour un double click         */
/*                                                                         */
/***************************************************************************/

int GRReflexWinDClick ( mmachine m )
{
    return OBJaddreflex (m,OBJTYPWINDOW,RFLWINDOW_DCLICK ) ;
}

/***************************************************************************/
/*                                                                         */
/*  int GRReflexWinDropFile ( mmachine m ) ;                               */
/*  correspond a la fonction ObjWin _CBwinDropFile (ObjWin,Fun,U);         */
/*  laquelle definit une callback pour le dragdrop de fichier sur la win   */
/*                                                                         */
/***************************************************************************/

int GRReflexWinDropFile ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPWINDOW,RFLWINDOW_DROPFILE);
}


/***************************************************************************/
/*                                                                         */
/*  int GRDestroyObjWin ( mmachine m )                                     */
/*                                                                         */
/* correspond a la gonction magma I _destroy_obj_win                       */
/* laquelle detruit une fenetre                                            */
/*                                                                         */
/***************************************************************************/

int GRDestroyObjWin ( mmachine m )
{
    int s ;
    PtrObjVoid O ;
    HWND h ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRDestroyObjWin");
#endif
//***********************************

    s = MMget(m,0) ;
    if ( s!=NIL) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        h = (( PtrObjWindow ) ( MMstart(m, (O->Buffer>>1 )) ))->WHandler ;
//MMechostr ( MSKTRACE , "_DSwindow : HW= %x\n",h ) ;
        OBJdelTH(m,OBJTYPWINDOW,(int)h) ;
    }    


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRDestroyObjWin end");
#endif
//***********************************

    MMset(m,0,0) ;
    return 0 ;
}


/*****************************************************************************/
/*                                                                           */
/* int GRMoveWindow ( mmachine m ) ;                                         */
/*                                                                           */
/* correspond a la fonction magma Obj _move_window ( Obj , PosX , PosY ) ;   */
/* laquelle deplace une fenetre a une nouvelle position                      */
/*                                                                           */
/*****************************************************************************/


int GRMoveWindow ( mmachine m )
{
    PtrObjVoid O ;
    PtrObjWindow W ;
    int PosX , PosY , s , res ;
    RECT WPos ;
 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRMoveWindow");
#endif
//***********************************

    PosY = MMpull(m)>> 1;
    PosX = MMpull(m)>> 1;
    s = MMget(m, 0);
    if (s == NIL)
    {
        MMechostr (1, "MoveWindow : Window object is NIL\n");
        return 0;
    }
    O = (PtrObjVoid)MMstart(m, (s>>1));
    if (O->Type != OBJ_TYPE_WINDOW <<1)
    {
        MMechostr ( 1 , "MoveWindow : the object isn't a window\n" );
        return 0;
    }
    W = (PtrObjWindow)MMstart(m, (O->Buffer>>1));

    GetWindowRect (W->WHandler, & WPos);
    MoveWindow (W->WHandler, PosX, PosY, WPos.right - WPos.left, WPos.bottom - WPos.top, TRUE);
	
	  // $BB
	  // update the scroll position
	  SCOLupdateScroll(W->WHandler);
 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRMoveWindow new");
#endif
//***********************************

  return 0;
}



/***********************************************************************/
/*                                                                     */
/* int GRTextOut ( mmachine m )                                        */
/*                                                                     */
/* correspond a la fonction magma Obj _text_out                        */
/* ( Obj Buffer , Obj Font,I PosX,I PosY,I FLag,I Color,S Texte )      */
/*                                                                     */
/***********************************************************************/

int GRTextOut ( mmachine m )
{
    PtrObjVoid OB , OF ;
    PtrObjFont F ;
    PtrObjBitmap B ;
    int Flag, PosX , PosY , s , Color , TFlag , s2 , oldbk ;
    HFONT OldFont ;
    HBITMAP OldBuffer ;
    HDC Dc ;
    HWND Hw ;
    char Texte [ 33000 ] ;
    
 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRTextOut");
#endif
//***********************************

    s = MMpull(m) ;
    if ( s == NIL ) strcpy ( Texte , "" ) ;
    else strcpy ( Texte , ( char * ) MMstart(m, ( s >> 1 ) + 1) ) ;
    Color = MMpull(m) >> 1 ;
    Flag = MMpull(m) >> 1 ;
    PosY = MMpull(m) >> 1 ;
    PosX = MMpull(m) >> 1 ;
    s2 = MMpull(m) ;
    s = MMpull(m) ;
    if ( s2 == NIL ) 
    {
        MMechostr(  1, "TextOut : Font is NIL\n" ) ;
        return MMpush(m,s) ;
    }
    OF = ( PtrObjVoid ) MMstart(m, ( s2 >> 1 ) ) ;    
    F = ( PtrObjFont ) MMstart(m, ( OF->Buffer >> 1 ) ) ;

    if ( s == NIL )
    {
        MMechostr ( 1 , "TextOut : Buffer is NIL\n" ) ;
        return MMpush(m,NIL) ;
    }
    OB = ( PtrObjVoid ) MMstart(m, ( s >> 1 ) ) ;
    switch ( OB->Type >> 1 )
    {
        case OBJ_TYPE_BITMAP :
                   B = ( PtrObjBitmap ) MMstart(m, ( OB->Buffer >> 1 ) ) ;


					//$ LB (13/06/2002) : create DIBSection from bitmap buffer
					if (!B->DIBhandler) ObjBitmap_CreateDIBSection (B);

                   Dc = CreateCompatibleDC ( NULL ) ;                 
                   OldBuffer = SelectObject ( Dc , B->DIBhandler ) ;        
                   break ;

        case OBJ_TYPE_WINDOW :
                   Hw = (( PtrObjWindow ) MMstart(m,( OB->Buffer>>1) ) ) -> WHandler ;
                   Dc = GetDC ( Hw ) ;
                   break ;
                
        default :
    
        MMechostr ( 1 , "TextOut : Parameter Win/Bitmap is type %d\n" , OB->Type >> 1) ;
        return MMpush(m,s) ;
    }
   
 

    TFlag = 0 ;
    if ( Flag & TD_BASELINE ) TFlag |= TA_BASELINE ;
    if ( Flag & TD_BOTTOM ) TFlag |= TA_BOTTOM ;
    if ( Flag & TD_TOP ) TFlag |= TA_TOP ;
    if ( Flag & TD_CENTER ) TFlag |= TA_CENTER ;
    if ( Flag & TD_LEFT ) TFlag |= TA_LEFT ;
    if ( Flag & TD_RIGHT ) TFlag |= TA_RIGHT ;
    
    OldFont = SelectObject ( Dc , F->WHandler ) ;
   
    SetTextColor ( Dc , Color ) ;
    oldbk = SetBkMode ( Dc , TRANSPARENT ) ;
    SetTextAlign ( Dc , TFlag ) ;
        
//MMechostr(0,"> %d\n",(GetMapMode(Dc) == MM_TEXT));

    if ( TextOut ( Dc , PosX , PosY , Texte , strlen ( Texte ) ) == FALSE )
        MMechostr ( 1 , "Error in Text Out\n" ) ;       

    SetBkMode ( Dc , oldbk ) ;
    SelectObject ( Dc , OldFont ) ;
  
    if ( OB->Type == ( OBJ_TYPE_BITMAP << 1 )  )
    {
          OldBuffer = SelectObject ( Dc , OldBuffer ) ;         
          DeleteDC ( Dc ) ;
    }

    s = MMpush(m,s) ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRTextOut end");
#endif
//***********************************

    return s ;
 
}


/*****************************************************************************/
/*                                                                           */
/* int GRPaintObjWin ( mmachine m ) ;                                        */
/*                                                                           */
/* correspond ala fonction magma ObjWin _paint_obj_win ( ObjWin ) ;          */
/*                                                                           */
/*****************************************************************************/

int GRPaintObjWin ( mmachine m )
{
    int s ;
    PtrObjVoid O ;
    PtrObjWindow W ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRPaintObjWin");
#endif
//***********************************
    s = MMget(m,0) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        W = ( PtrObjWindow ) MMstart(m,(O->Buffer>>1) ) ;
        InvalidateRect ( W->WHandler, NULL , FALSE ) ;
        UpdateWindow ( W->WHandler ) ;
    }


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRPaintObjWin end");
#endif
//***********************************

    return 0 ;
}



/**************************************************************************************/
/*                                                                                    */
/*  int GRGetScreenSize ( mmachine m ) ;                                              */
/*                                                                                    */
/*  correspond a la fonction [ I I ] _GETscreenSize ( ) ;                             */
/*  qui retourne la definition graphique actuelle                                     */
/*                                                                                    */
/**************************************************************************************/

int GRGetScreenSize ( mmachine m )
{
    RECT r ;
    int res ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRGetScreenSize");
#endif
//***********************************

    GetWindowRect ( GetDesktopWindow () , &r ) ;
    MMpush(m,(r.right - r.left  )<<1) ;
    MMpush(m,(r.bottom - r.top  ) << 1 ) ;
    
    MMpush(m,4) ;
    res = MBdeftab ( m ) ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRGetScreenSize end");
#endif
//***********************************

    return res ;
    
}

/**************************************************************************************/
/*                                                                                    */
/*  int GRGetDesktopSize ( mmachine m ) ;                                             */
/*                                                                                    */
/*  correspond a la fonction [ I I ] _GETdesktopSize ( ) ;                            */
/*  qui retourne la definition graphique actuelle                                     */
/*                                                                                    */
/**************************************************************************************/

int GRGetDesktopSize ( mmachine m )
{
    RECT r ;
    int res ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRGetDesktopSize");
#endif
//***********************************

    SystemParametersInfo(SPI_GETWORKAREA,0,&r,0);

    MMpush(m,(r.right - r.left  )<<1) ;
    MMpush(m,(r.bottom - r.top  ) << 1 ) ;
    
    MMpush(m,4) ;
    res = MBdeftab ( m ) ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRGetDesktopSize end");
#endif
//***********************************

    return res ;
    
}


/**************************************************************************/
/*                                                                        */
/*  int GRSetWindowStyle ( mmachine m ) ;                                 */
/*  correspond a la fonction magma ObjXXX _SETXXstyle ( ObjXXX , I ) ;    */
/*  laquelle change le style d'un objet de l'interface                    */
/*                                                                        */
/**************************************************************************/

int GRSetWindowStyle(mmachine m)
{
	HWND hwndx;
	int s,FF;
	PtrObjVoid O ;
	PtrObjWindow OW ;
	int Style;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowStyle");
#endif
//***********************************
	
//	MMechostr(1,"start windowstyle\n");
	
	FF=MMpull(m)>>1;
	s = MMpull(m) ;
	if ( s == NIL ) return MMpush(m,NIL) ;
	
	O = ( PtrObjVoid ) MMstart(m,s>>1);
	if ( O->Type != OBJ_TYPE_WINDOW << 1 ) return MMpush(m,NIL);
	
	
	OW = ( PtrObjWindow )MMstart(m,(O->Buffer>>1));
	hwndx=OW->WHandler;
	
	if (MMpush(m,-1*2)) return MERRMEM;
	
	Style = WS_POPUP ;
    if (( FF & WN_NOCLIPCHILDREN ) == 0 ) 
		Style |= WS_CLIPCHILDREN ;
	
    if (( FF & WN_GROUP ) == 0 )
	{
		if ( ( FF & WN_NOBORDER ) == 0 ) Style |= WS_BORDER ;
		if ( ( FF & WN_NOCAPTION )== 0 ) Style |= WS_CAPTION ; //SH
	}
	if ( FF & WN_MINIMIZE ) Style |= WS_MINIMIZE ;                
	if ( FF & WN_MINBOX ) Style |= WS_MINIMIZEBOX ;
	if ( FF & WN_MAXBOX ) Style |= WS_MAXIMIZEBOX ;
	if ( FF & WN_SIZEBOX ) Style |= WS_SIZEBOX|WS_MAXIMIZEBOX  ;
	if ( FF & WN_MENU ) Style |= WS_SYSMENU ;  
	if ( FF & WN_HSCROLL ) Style |= WS_HSCROLL ;
	if ( FF & WN_VSCROLL ) Style |= WS_VSCROLL ; 
	
/*	
	
	Style = WS_POPUP|WS_VISIBLE;
	
	if ( ( FF & WN_NOBORDER ) == 0 ) Style |= WS_BORDER ;
	if ( ( FF & WN_NOCAPTION )== 0 ) Style |= WS_CAPTION ;
	if ( FF & WN_MINIMIZE ) Style |= WS_MINIMIZE ;                
	if ( FF & WN_MINBOX ) Style |= WS_OVERLAPPED|WS_MINIMIZEBOX ;
	if ( FF & WN_MAXBOX ) Style |= WS_OVERLAPPED|WS_MAXIMIZEBOX ;
	if ( FF & WN_SIZEBOX ) Style |= WS_OVERLAPPED|WS_SIZEBOX|WS_MAXIMIZEBOX  ;
	if ( FF & WN_MENU ) Style |= WS_OVERLAPPED|WS_SYSMENU ;  
	if ( FF & WN_HSCROLL ) Style |= WS_HSCROLL ;
	if ( FF & WN_VSCROLL ) Style |= WS_VSCROLL ; 
*/	
	
	ShowWindow(hwndx,SW_HIDE);
	SetWindowLong(hwndx,GWL_STYLE,Style);
	ShowWindow(hwndx,SW_SHOW);
	UpdateWindow(hwndx);

  //$BB not needed
	//SetFocus(hwndx);

	MMset(m,0,0);
//	MMechostr(1,"end windowstyle\n");
	

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowStyle end");
#endif
//***********************************

	return 0;
}





/****************************************************************************/ 
/*                                                                          */ 
/*    int GRTopWindow ( mmachine m ) ;                                      */ 
/*                                                                          */ 
/*      Apporte une fenetre au premier plan                                 */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRTopWindow ( mmachine m ) 
{
    int s ;
    PtrObjVoid O ;
    PtrObjWindow W ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRTopWindow");
#endif
//***********************************

    s = MMpull(m);
    if ( s!= NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        W = ( PtrObjWindow ) MMstart(m,(O->Buffer>>1));
        BringWindowToTop ( W->WHandler ) ;
        SetActiveWindow ( W->WHandler ) ;
        SetForegroundWindow ( W->WHandler ) ;
    }

    s = MMpush(m,s);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRTopWindow end");
#endif
//***********************************

    return s ;
}


// $BLG: v4.6a7 - Add
// Source code from GRTopWindow
// **************************************************************************
// int GRTopMostWindow(mmachine m);
// Gčre le plan d'affectation d'une fenetre:
// - 0: Bottom
// - 1: Not TopMost (just below TopMost windows)
// - 2: Top
// - 3: TopMost (Top and stays above)
// **************************************************************************
int GRTopMostWindow(mmachine m)
{
  // Focus
  int fcs;
  // Level
  int lvl;
  // Window
  int win;
  PtrObjVoid O;
  PtrObjWindow W;
  // Flags
  UINT flags;

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRTopMostWindow");
#endif
//***********************************

	fcs = MMpull(m)>>1;
	lvl = MMpull(m)>>1;
  win = MMpull(m);
  if ((win != NIL) && (lvl >= 0) && (lvl <= 3) && (fcs >= 0) && (fcs <= 1))
  {
      O = (PtrObjVoid) MMstart(m, (win>>1));
      W = (PtrObjWindow) MMstart(m, (O->Buffer>>1));
      
      if ((fcs == 1) && (lvl != 0))
      	flags = SWP_NOMOVE | SWP_NOSIZE;
      else
      	flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE;
      
      if (lvl == 0)
      	SetWindowPos(W->WHandler, HWND_BOTTOM, 0, 0, 0, 0, flags);
      else if (lvl == 1)
      	SetWindowPos(W->WHandler, HWND_NOTOPMOST, 0, 0, 0, 0, flags);
      else if (lvl == 2)
      	SetWindowPos(W->WHandler, HWND_TOP, 0, 0, 0, 0, flags);
      else
      	SetWindowPos(W->WHandler, HWND_TOPMOST, 0, 0, 0, 0, flags);
  }

  win = MMpush(m, win);

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRTopMostWindow end");
#endif
//***********************************

  return win;
}



//$BLG - v5.21: Add
// **************************************************************************
// int CALLBACK BLG_EnumChildProc_AX(HWND hwndChild, LPARAM hwnd) 
// To retrieve ActiveX window real handler
// **************************************************************************
int CALLBACK BLG_EnumChildProc_AX(HWND hwndChild, LPARAM hwnd) 
{ 
  //This function can only be called once as a Scol ActiveX hosting Window contains only the ActiveX real Window. So, we are sure we get right hwnd.
  *((HWND *)hwnd) = hwndChild;
  return 0;
}


//$BLG - v5.21: Add
// **************************************************************************
// int GRClickWindow ( mmachine m ) ;
// envoit un click ŕ une fenętre
// **************************************************************************
int GRClickWindow(mmachine m)
{
	int win, wax, x, y, but;
	int ret;
	PtrObjVoid OW, OX;
	PtrObjWindow W, X;
	HWND hwndAX;
	
	HWND fthr, chld, fcs;
	int fthr_l, fthr_t, chld_l, chld_t;
	POINT pt0, pt1;
	PWINDOWINFO pwi;
	UINT msgDn, msgUp;
	
	TCHAR lpClassName[256];

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRClickWindow");
#endif
//***********************************

	but = MTOI(MMpull(m));
	y 	= MTOI(MMpull(m));
	x 	= MTOI(MMpull(m));
	wax = MMpull(m);
	win = MMpull(m);
MMechostr(0, "_ClickWindow\n");	
	if (win != NIL)
	{
MMechostr(0,"win\n");
		OW = (PtrObjVoid) MMstart(m, (win>>1));
    W = (PtrObjWindow) MMstart(m, (OW->Buffer>>1));
    
    if (wax != NIL)
    {
MMechostr(0,"wax\n");
    	OX = (PtrObjVoid) MMstart(m, (wax>>1));
    	X = (PtrObjWindow) MMstart(m, (OX->Buffer>>1));
    	EnumChildWindows((X->WHandler), (BLG_EnumChildProc_AX), (long)(&hwndAX));
    }
    
    pt1.x = pt0.x = x;
		pt1.y = pt0.y = y;
		
		fthr = W->WHandler;
		fcs = SetActiveWindow(fthr);
		
		pwi = (PWINDOWINFO)malloc(sizeof(WINDOWINFO));
		GetWindowInfo(fthr, pwi);
		fthr_l = pwi->rcWindow.left;
		fthr_t = pwi->rcWindow.top;
		
		chld = NULL;
		
		while (chld != fthr)
		{
MMechostr(0,"while\n");
			chld = ChildWindowFromPoint(fthr, pt1);
			if (chld != fthr)
			{
				GetWindowInfo(chld, pwi);
				chld_l = pwi->rcWindow.left;
				chld_t = pwi->rcWindow.top;
				pt1.x = pt0.x - (chld_l - fthr_l);
				pt1.y = pt0.y - (chld_t - fthr_t);
				fthr = chld;
				chld = (HWND)(-1);
			}
		}
		
		SetActiveWindow(chld);
		
		if (but == MB_LBUTTON)
		{
			msgDn = WM_LBUTTONDOWN;
			msgUp = WM_LBUTTONUP;
		}
		else if (but == MB_MBUTTON)
		{
			msgDn = WM_MBUTTONDOWN;
			msgUp = WM_MBUTTONUP;
		}
		else
		{
			msgDn = WM_RBUTTONDOWN;
			msgUp = WM_RBUTTONUP;
		}
		
		GetClassName(chld, lpClassName, 256);
		/*
		MMechostr(0,"> %s\n", (char *)lpClassName);
		if (!strcmp(lpClassName, "GenericClass2D"))								//ObjWin
			MMechostr(0,"ObjWin\n");
		else if (!strcmp(lpClassName, "NoBackgroundClass2D"))			//ObjContainer
			MMechostr(0,"ObjContainer\n");
		else
			MMechostr(0,"Control, other...\n");
		*/
		
		//- chld gets a click event
		//- if chld isn't an ObjWin nor an ObjContainer, we trigger an unclick for interactivity (click/unclick button for example)
		//- furthermore, if chld is an ActiveX window, we do all this twice to ensure the click (result ok 19/20, instead of 1/20 without that)
		
		SendMessage(chld, WM_SETCURSOR, (WPARAM)(0), (LPARAM)(MAKELONG(HTCLIENT, msgDn)));
		SendMessage(chld, msgDn, (WPARAM)(msgDn), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
		
		if ((strcmp(lpClassName, "GenericClass2D"))	&& (strcmp(lpClassName, "NoBackgroundClass2D")))
		{
MMechostr(0,"if\n");
			SendMessage(chld, WM_SETCURSOR, (WPARAM)(0), (LPARAM)(MAKELONG(HTCLIENT, msgUp)));
			SendMessage(chld, msgUp, (WPARAM)(msgUp), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
	    
	    if (wax != NIL)
	    	if (chld == hwndAX)
				{
MMechostr(0,"hwndAX\n");
					SendMessage(chld, msgDn, (WPARAM)(msgDn), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
					SendMessage(chld, msgUp, (WPARAM)(msgUp), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
				}
		}
    
    W->hwndChldClckd = chld;
    W->iChldClckdX = pt1.x;
    W->iChldClckdY = pt1.y;
    W->iChldClckdB = but;
    W->hwndLastClckd = chld;
    
    SetActiveWindow(fcs);
			
		free(pwi);
    
	}
	
	ret = MMpush(m, win);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRClickWindow");
#endif
//***********************************
	
	return ret;
	
}



//$BLG - v5.21: Add
// **************************************************************************
// int GRUnClickWindow ( mmachine m ) ;
// envoit un unclick ŕ une fenętre
// **************************************************************************
int GRUnClickWindow(mmachine m)
{
	int win, wax, x, y, but;
	int ret;
	PtrObjVoid OW, OX;
	PtrObjWindow W, X;
	HWND hwndAX;
	
	HWND fthr, chld, fcs;
	int fthr_l, fthr_t, chld_l, chld_t;
	POINT pt0, pt1;
	PWINDOWINFO pwi;
	UINT /*msgDn,*/ msgUp;

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRUnClickWindow");
#endif
//***********************************

	but = MTOI(MMpull(m));
	y 	= MTOI(MMpull(m));
	x 	= MTOI(MMpull(m));
	wax = MMpull(m);
	win = MMpull(m);
	
	if (win != NIL)
	{
		OW = (PtrObjVoid) MMstart(m, (win>>1));
    W = (PtrObjWindow) MMstart(m, (OW->Buffer>>1));
    
    if (wax != NIL)
    {
    	OX = (PtrObjVoid) MMstart(m, (wax>>1));
    	X = (PtrObjWindow) MMstart(m, (OX->Buffer>>1));
    	EnumChildWindows((X->WHandler), (BLG_EnumChildProc_AX), (long)(&hwndAX));
    }
    
    pt1.x = pt0.x = x;
		pt1.y = pt0.y = y;
		
		fthr = W->WHandler;
		fcs = SetActiveWindow(fthr);
		
		pwi = (PWINDOWINFO)malloc(sizeof(WINDOWINFO));
		GetWindowInfo(fthr, pwi);
		fthr_l = pwi->rcWindow.left;
		fthr_t = pwi->rcWindow.top;
		
		chld = NULL;
		
		while (chld != fthr)
		{
			chld = ChildWindowFromPoint(fthr, pt1);
			if (chld != fthr)
			{
				GetWindowInfo(chld, pwi);
				chld_l = pwi->rcWindow.left;
				chld_t = pwi->rcWindow.top;
				pt1.x = pt0.x - (chld_l - fthr_l);
				pt1.y = pt0.y - (chld_t - fthr_t);
				fthr = chld;
				chld = (HWND)(-1);
			}
		}
		
		SetActiveWindow(chld);
		
		if (but == MB_LBUTTON)
		{
			msgUp = WM_LBUTTONUP;
		}
		else if (but == MB_MBUTTON)
		{
			msgUp = WM_MBUTTONUP;
		}
		else
		{
			msgUp = WM_RBUTTONUP;
		}
		
		//- chld gets an unclick event 
		//- if chld is an ObjWin or an ObjContainer, this is their sole unclick event.
		//- other controls get a secondary unclick as they got their unclick during click event.
		//- ActiveX controls get an additionnal unclick event.
		
		SendMessage(chld, WM_SETCURSOR, (WPARAM)(0), (LPARAM)(MAKELONG(HTCLIENT, msgUp)));
		SendMessage(chld, msgUp, (WPARAM)(msgUp), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
		
		
    if (wax != NIL)
    	if (chld == hwndAX)
			{
				SendMessage(chld, msgUp, (WPARAM)(msgUp), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
			}
		
    
    W->hwndChldClckd = NULL;
    
    SetActiveWindow(fcs);
			
		free(pwi);
    
	}
	
	ret = MMpush(m, win);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRUnClickWindow");
#endif
//***********************************
	
	return ret;
	
}



//$BLG - v5.21: Add
// **************************************************************************
// int GRDblClickWindow ( mmachine m ) ;
// envoit un dblclick ŕ une fenętre
// **************************************************************************
int GRDblClickWindow(mmachine m)
{
	int win, wax, x, y, but;
	int ret;
	PtrObjVoid OW, OX;
	PtrObjWindow W, X;
	HWND hwndAX;
	
	HWND fthr, chld, fcs;
	int fthr_l, fthr_t, chld_l, chld_t;
	POINT pt0, pt1;
	PWINDOWINFO pwi;
	UINT msgDC;

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRDblClickWindow");
#endif
//***********************************

	but = MTOI(MMpull(m));
	y 	= MTOI(MMpull(m));
	x 	= MTOI(MMpull(m));
	wax = MMpull(m);
	win = MMpull(m);
	
	if (win != NIL)
	{
		OW = (PtrObjVoid) MMstart(m, (win>>1));
    W = (PtrObjWindow) MMstart(m, (OW->Buffer>>1));
    
    if (wax != NIL)
    {
    	OX = (PtrObjVoid) MMstart(m, (wax>>1));
    	X = (PtrObjWindow) MMstart(m, (OX->Buffer>>1));
    	EnumChildWindows((X->WHandler), (BLG_EnumChildProc_AX), (long)(&hwndAX));
    }
    
    pt1.x = pt0.x = x;
		pt1.y = pt0.y = y;
		
		fthr = W->WHandler;
		fcs = SetActiveWindow(fthr);
		
		pwi = (PWINDOWINFO)malloc(sizeof(WINDOWINFO));
		GetWindowInfo(fthr, pwi);
		fthr_l = pwi->rcWindow.left;
		fthr_t = pwi->rcWindow.top;
		
		chld = NULL;
		
		while (chld != fthr)
		{
			chld = ChildWindowFromPoint(fthr, pt1);
			if (chld != fthr)
			{
				GetWindowInfo(chld, pwi);
				chld_l = pwi->rcWindow.left;
				chld_t = pwi->rcWindow.top;
				pt1.x = pt0.x - (chld_l - fthr_l);
				pt1.y = pt0.y - (chld_t - fthr_t);
				fthr = chld;
				chld = (HWND)(-1);
			}
		}
		
		SetActiveWindow(chld);
		
		if (but == MB_LBUTTON)
		{
			msgDC = WM_LBUTTONDBLCLK;
		}
		else if (but == MB_MBUTTON)
		{
			msgDC = WM_MBUTTONDBLCLK;
		}
		else
		{
			msgDC = WM_RBUTTONDBLCLK;
		}
		
		//- chld gets a dblclick event
		//- ActiveX controls get an additionnal dblclick event.
		
		SendMessage(chld, WM_SETCURSOR, (WPARAM)(0), (LPARAM)(MAKELONG(HTCLIENT, msgDC)));
		SendMessage(chld, msgDC, (WPARAM)(msgDC), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
    
    if (wax != NIL)
    	if (chld == hwndAX)
			{
				SendMessage(chld, msgDC, (WPARAM)(msgDC), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
			}
    
    SetActiveWindow(fcs);
			
		free(pwi);
    
	}
	
	ret = MMpush(m, win);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRDblClickWindow");
#endif
//***********************************
	
	return ret;
	
}


//$BLG - v5.21: Add
// **************************************************************************
// int GRMouseMoveWindow ( mmachine m ) ;
// envoit un mouse move ŕ une fenętre
// **************************************************************************
int GRMouseMoveWindow(mmachine m)
{
	int win, wax, x, y, but;
	int ret;
	PtrObjVoid OW, OX;
	PtrObjWindow W, X;
	HWND hwndAX;
	
	HWND fthr, chld/*, fcs*/;
	int fthr_l, fthr_t, chld_l, chld_t;
	POINT pt0, pt1;
	PWINDOWINFO pwi;
	//UINT msgDn, msgUp;
	
	//TCHAR lpClassName[256];

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRMouseMoveWindow");
#endif
//***********************************

	but = MTOI(MMpull(m));
	y 	= MTOI(MMpull(m));
	x 	= MTOI(MMpull(m));
	wax = MMpull(m);
	win = MMpull(m);
	
	if (win != NIL)
	{
		OW = (PtrObjVoid) MMstart(m, (win>>1));
    W = (PtrObjWindow) MMstart(m, (OW->Buffer>>1));
    
    if (wax != NIL)
    {
    	OX = (PtrObjVoid) MMstart(m, (wax>>1));
    	X = (PtrObjWindow) MMstart(m, (OX->Buffer>>1));
    	EnumChildWindows((X->WHandler), (BLG_EnumChildProc_AX), (long)(&hwndAX));
    }
    
    pt1.x = pt0.x = x;
		pt1.y = pt0.y = y;
		
		fthr = W->WHandler;
		//fcs = SetActiveWindow(fthr);
		
		pwi = (PWINDOWINFO)malloc(sizeof(WINDOWINFO));
		GetWindowInfo(fthr, pwi);
		fthr_l = pwi->rcWindow.left;
		fthr_t = pwi->rcWindow.top;
		
		chld = NULL;
		
		while (chld != fthr)
		{
			chld = ChildWindowFromPoint(fthr, pt1);
			if (chld != fthr)
			{
				GetWindowInfo(chld, pwi);
				chld_l = pwi->rcWindow.left;
				chld_t = pwi->rcWindow.top;
				pt1.x = pt0.x - (chld_l - fthr_l);
				pt1.y = pt0.y - (chld_t - fthr_t);
				fthr = chld;
				chld = (HWND)(-1);
			}
		}
		
		//Removed following
		//What was intended was to be able to perform moving with button pushed
		//However, this produces disgraceful scintillating on 3D window because
		//of focus changes
		/*
		SetActiveWindow(chld);
		
		if (but == MB_LBUTTON)
		{
			msgDn = WM_LBUTTONDOWN;
			msgUp = WM_LBUTTONUP;
		}
		else if (but == MB_MBUTTON)
		{
			msgDn = WM_MBUTTONDOWN;
			msgUp = WM_MBUTTONUP;
		}
		else if (but == MB_RBUTTON)
		{
			msgDn = WM_RBUTTONDOWN;
			msgUp = WM_RBUTTONUP;
		}
		
		GetClassName(chld, lpClassName, 256);
		
		//- chld gets a click event
		//- if chld isn't an ObjWin nor an ObjContainer, we trigger an unclick for interactivity (click/unclick button for example)
		//- furthermore, if chld is an ActiveX window, we do all this twice to ensure the click (result ok 19/20, instead of 1/20 without that)
		
		if ((!strcmp(lpClassName, "GenericClass2D")) && (!strcmp(lpClassName, "NoBackgroundClass2D")))
		{
			SendMessage(chld, WM_MOUSEMOVE, 0, (LPARAM)(MAKELONG(pt1.x, pt1.y)));
		}
		else
		{
			MMechostr(0,"> Mov ");
			if ((chld == W->hwndChldClckd) && (but == W->iChldClckdB))
			{
				MMechostr (0,"%d",W->iChldClckdX);
				
				//First try
				//SendMessage(chld, WM_SETCURSOR, (WPARAM)(chld), (LPARAM)(MAKELONG(HTCLIENT, msgDn)));
				//SendMessage(chld, msgDn, (WPARAM)(msgDn), (LPARAM)(MAKELONG(W->iChldClckdX, W->iChldClckdY)));
				//if (chld == hwndAX) SendMessage(chld, msgDn, (WPARAM)(msgDn), (LPARAM)(MAKELONG(W->iChldClckdX, W->iChldClckdY)));
				
				//SendMessage(chld, WM_SETCURSOR, (WPARAM)(chld), (LPARAM)(MAKELONG(HTCLIENT, WM_MOUSEMOVE)));
				//SendMessage(chld, WM_MOUSEMOVE, (WPARAM)(but), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
				//if (chld == hwndAX) SendMessage(chld, WM_MOUSEMOVE, (WPARAM)(but), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
				
				//SendMessage(chld, WM_SETCURSOR, (WPARAM)(chld), (LPARAM)(MAKELONG(HTCLIENT, msgUp)));
				//SendMessage(chld, msgUp, (WPARAM)(msgUp), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
				//if (chld == hwndAX) SendMessage(chld, msgUp, (WPARAM)(msgUp), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
				
				//Second try
				SendMessage(chld, WM_MOUSEACTIVATE, (WPARAM)(W->WHandler), (LPARAM)(MAKELONG(HTCLIENT, WM_MOUSEMOVE)));
				SendMessage(chld, WM_SETCURSOR, (WPARAM)(chld), (LPARAM)(MAKELONG(HTCLIENT, msgDn)));
				SendMessage(chld, msgDn, (WPARAM)(but), (LPARAM)(MAKELONG(W->iChldClckdX, W->iChldClckdY)));
				//SendMessage(chld, WM_MOUSEACTIVATE, (WPARAM)(W->WHandler), (LPARAM)(MAKELONG(HTCLIENT, WM_MOUSEMOVE)));
				SendMessage(chld, WM_SETCURSOR, (WPARAM)(chld), (LPARAM)(MAKELONG(HTCLIENT, WM_MOUSEMOVE)));
				
				SendMessage(chld, WM_MOUSEMOVE, (WPARAM)(but), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
				
				SendMessage(chld, WM_SETCURSOR, (WPARAM)(chld), (LPARAM)(MAKELONG(HTCLIENT, msgUp)));
				SendMessage(chld, msgUp, (WPARAM)(but), (LPARAM)(MAKELONG(pt1.x, pt1.y)));
				
				W->iChldClckdX = pt1.x;
    		W->iChldClckdY = pt1.y;
    		MMechostr (0," %d <\n",W->iChldClckdX);
			}
			else
			{
				SendMessage(chld, WM_MOUSEMOVE, 0, (LPARAM)(MAKELONG(pt1.x, pt1.y)));
				if (chld == hwndAX) SendMessage(chld, WM_MOUSEMOVE, 0, (LPARAM)(MAKELONG(pt1.x, pt1.y)));
			}
		}
    
    SetActiveWindow(fcs);
    */
		
		//SendMessage(chld, WM_SETCURSOR, (WPARAM)(chld), (LPARAM)(MAKELONG(HTCLIENT, WM_MOUSEMOVE)));
		SendMessage(chld, WM_MOUSEMOVE, 0, (LPARAM)(MAKELONG(pt1.x, pt1.y)));
		
		free(pwi);
    
	}
	
	ret = MMpush(m, win);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRMouseMoveWindow");
#endif
//***********************************
	
	return ret;
	
}


//$BLG - v5.21: Add
// **************************************************************************
// int GRKeyDownWindow ( mmachine m ) ;
// envoit un keydown ŕ une fenętre
// **************************************************************************
int GRKeyDownWindow(mmachine m)
{
	int win, wax, vkey, key;
	int ret;
	PtrObjVoid OW, OX;
	PtrObjWindow W, X;
	HWND hwndAX;
	
	HWND fthr, chld, fcs, fchld;
	
	POINT pnt;
	int p;
	PtrObjVoid OF;
  PtrObjWindow WF;
  

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRKeyDownWindow");
#endif
//***********************************

	vkey 	= MTOI(MMpull(m));
	key 	= MTOI(MMpull(m));
	wax 	= MMpull(m);
	win 	= MMpull(m);
	
	MMechostr(0,"key:%d vkey:%d\n",key,vkey);
	
	if (win != NIL)
	{
		OW = (PtrObjVoid) MMstart(m, (win>>1));
    W = (PtrObjWindow) MMstart(m, (OW->Buffer>>1));
    
    if (wax != NIL)
    {
    	OX = (PtrObjVoid) MMstart(m, (wax>>1));
    	X = (PtrObjWindow) MMstart(m, (OX->Buffer>>1));
    	EnumChildWindows((X->WHandler), (BLG_EnumChildProc_AX), (long)(&hwndAX));
    }
		
		fthr = W->WHandler;
		fcs = SetActiveWindow(fthr);
		
		p = OBJfindTH(m, OBJTYPWINDOW, (int)fcs);
    if (p == NIL) 
    {
    	MMpush(m, win);
    	return 1;
    }
    p = MMfetch(m, p, OFFOBJMAG);
    OF = (PtrObjVoid) MMstart(m, p>>1);
    WF = (PtrObjWindow) MMstart(m, OF->Buffer>>1);
      
		pnt.x = WF->iChldClckdX;
		pnt.y = WF->iChldClckdY;
		fchld = ChildWindowFromPointEx(fcs, pnt, CWP_ALL);		// DMSwin -> win on "Zone View"
		fchld = ChildWindowFromPointEx(fchld, pnt, CWP_ALL);	// win on "Zone View" -> child
		fchld = ChildWindowFromPointEx(fchld, pnt, CWP_ALL);  // child -> OpenGL

		chld = W->hwndLastClckd;
		if (chld != NULL)
		{
			SetActiveWindow(chld);
			SendMessage(chld, WM_KEYDOWN, (WPARAM)(vkey), (LPARAM)(MAKELONG(1, key)));
			SendMessage(chld, WM_CHAR, (WPARAM)(vkey), (LPARAM)(MAKELONG(1, key)));
			SendMessage(chld, WM_KEYUP, (WPARAM)(vkey), (LPARAM)(MAKELONG(1, key+0xC000)));
			MMechostr(0,"ML: %h\n",MAKELONG(1, key+0xC000));
    }
    
    SetActiveWindow(fcs);
		if (fchld != fcs)
			SetFocus(fchld);
    
	}
	
	ret = MMpush(m, win);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRKeyDownWindow");
#endif
//***********************************
	
	return ret;
	
}



//$BLG - v5.21: Add
// **************************************************************************
// int GRKeyUpWindow ( mmachine m ) ;
// envoit un keyup ŕ une fenętre
// **************************************************************************
int GRKeyUpWindow(mmachine m)
{
	int win, wax, key;
	int ret;
	PtrObjVoid OW, OX;
	PtrObjWindow W, X;
	HWND hwndAX;
	
	HWND fthr, chld, fcs, fchld;
	
	POINT pnt;
	int p;
	PtrObjVoid OF;
  PtrObjWindow WF;

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRKeyUpWindow");
#endif
//***********************************

	key	= MTOI(MMpull(m));
	wax = MMpull(m);
	win = MMpull(m);
	
	MMechostr(0,"key:%d vkey:%d shift:%d\n",key,MapVirtualKey(key,1),GetKeyState(VK_SHIFT)&128); //MAPVK_VSC_TO_VK
	
	if (win != NIL)
	{
		OW = (PtrObjVoid) MMstart(m, (win>>1));
    W = (PtrObjWindow) MMstart(m, (OW->Buffer>>1));
    
    if (wax != NIL)
    {
    	OX = (PtrObjVoid) MMstart(m, (wax>>1));
    	X = (PtrObjWindow) MMstart(m, (OX->Buffer>>1));
    	EnumChildWindows((X->WHandler), (BLG_EnumChildProc_AX), (long)(&hwndAX));
    }
		
		fthr = W->WHandler;
		fcs = SetActiveWindow(fthr);
		
		p = OBJfindTH(m, OBJTYPWINDOW, (int)fcs);
    if (p == NIL) 
    {
    	MMpush(m, win);
    	return 1;
    }
    p = MMfetch(m, p, OFFOBJMAG);
    OF = (PtrObjVoid) MMstart(m, p>>1);
    WF = (PtrObjWindow) MMstart(m, OF->Buffer>>1);
      
		pnt.x = WF->iChldClckdX;
		pnt.y = WF->iChldClckdY;
		fchld = ChildWindowFromPointEx(fcs, pnt, CWP_ALL);
		fchld = ChildWindowFromPointEx(fchld, pnt, CWP_ALL);
		fchld = ChildWindowFromPointEx(fchld, pnt, CWP_ALL);
		
		chld = W->hwndLastClckd;
		if (chld != NULL)
		{
			SetActiveWindow(chld);
			SendMessage(chld, WM_KEYUP, (WPARAM)(MapVirtualKey(key, 1)), (LPARAM)(MAKELONG(1, key+0xC000))); //MAPVK_VSC_TO_VK
		}
    
    SetActiveWindow(fcs);
    if (fchld != fcs)
			SetFocus(fchld);

	}
	
	ret = MMpush(m, win);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRKeyUpWindow");
#endif
//***********************************
	
	return ret;
	
}



/****************************************************************************/ 
/*                                                                          */ 
/*  int GRSetWindowMinSize ( mmachine m ) ;                                 */ 
/*                                                                          */ 
/*  Correspond a la fonction scol ObjWin _SETwindowMinSize(ObjWin,I,I)      */ 
/*  laquelle fixe la taille minimale d'une fenetre via les bords resisable  */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRSetWindowMinSize ( mmachine m )
{
    int s ,w , h ;
    PtrObjVoid O ;
    PtrObjWindow W ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowMinSize");
#endif
//***********************************

    h = MMpull(m)>>1 ;
    w = MMpull(m)>>1 ;
    s = MMpull(m) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        W = ( PtrObjWindow ) MMstart(m,(O->Buffer>>1));
        W->MinW = min (W->MaxW,w ) ;
        W->MinH = min (W->MaxH,h ) ;
    }

    s = MMpush(m,s) ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowMinSize end");
#endif
//***********************************

    return s ;
}




/****************************************************************************/ 
/*                                                                          */ 
/*  int GRSetWindowMaxSize ( mmachine m ) ;                                 */ 
/*                                                                          */ 
/*  Corerspond a la fonction scol ObjWin _SETwindowMaxSize(ObjWin,I,I)      */ 
/*                                                                          */ 
/*  Laquelle fixe la taille maximale atteignable avec les bords resizable   */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRSetWindowMaxSize ( mmachine m )
{
    int s , w , h ;
    PtrObjVoid O ;
    PtrObjWindow W ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowMaxSize");
#endif
//***********************************

    h = MMpull(m) >> 1 ;
    w = MMpull(m) >> 1 ;
    s = MMpull(m) ;

    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        W = ( PtrObjWindow ) MMstart(m,(O->Buffer>>1)) ;
        W->MaxW = max ( W->MinW , w ) ;
        W->MaxH = max ( W->MinH , h ) ;
    }

    s = MMpush(m,s) ;

 
//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowMaxSize end");
#endif
//***********************************

    return s ;
}



/****************************************************************************/ 
/*                                                                          */ 
/*  int GRSetWindowIcon ( mmachine m ) ;                                    */ 
/*                                                                          */ 
/*  Corerspond a la fonction scol ObjWin _SETwindowIcon(ObjWin,P)           */ 
/*                                                                          */ 
/*  Laquelle change l'icon de la fenetre                                    */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRSetWindowIcon ( mmachine m )
{
    int s, p;
    PtrObjVoid O ;
    PtrObjWindow W ;
    char Name [ 8000 ] ;   
    HICON hIcon1;
    HICON hIcon2;

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowIcon");
#endif
//***********************************
    MMechostr(0, "_SETwindowIcon in");
    p = MMpull(m) ;
    s = MMpull(m) ;

    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        W = ( PtrObjWindow ) MMstart(m,(O->Buffer>>1)) ;
        
        strcpy ( Name , ( char * ) MMstart(m, (p>>1)+1) ) ;

        hIcon1 = (HICON) LoadImage( (HINSTANCE)SCgetExtra("this_inst"), Name, IMAGE_ICON,
        GetSystemMetrics(SM_CXSMICON),
        GetSystemMetrics(SM_CYSMICON),
        LR_LOADFROMFILE);
        
        hIcon2 = (HICON) LoadImage( (HINSTANCE)SCgetExtra("this_inst"), Name, IMAGE_ICON,
        GetSystemMetrics(SM_CXICON),
        GetSystemMetrics(SM_CYICON),
        LR_LOADFROMFILE);

        SendMessage ( W->WHandler , WM_SETICON , ICON_SMALL, ( LPARAM ) hIcon1 );
        SendMessage ( W->WHandler , WM_SETICON , ICON_BIG, ( LPARAM ) hIcon2 );
    }

    s = MMpush ( m ,s ) ;
    MMechostr(0, "_SETwindowIcon out");

//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRSetWindowIcon end");
#endif
//***********************************

    return s ;
}


/****************************************************************************/ 
/*                                                                          */ 
/*      fun GREnableWindow ( mmachine m ) ;                                 */ 
/*                                                                          */ 
/*      Fonction generique correspondant aux fonction _ENABLExxx(Obj,I)->Obj*/ 
/*  laquelle enable disable les objets fenetres, boutons, etc               */ 
/*                                                                          */ 
/****************************************************************************/ 

int GREnableWindow ( mmachine m )
{
    int s , etat ;
    PtrObjVoid O ;
    HWND HW ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGREnableWindow");
#endif
//***********************************

    etat = MMpull(m)>>1 ;
    s = MMpull(m) ; 
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1));
        switch ( O->Type >> 1 )
        {
        case OBJ_TYPE_WINDOW :
                HW = (( PtrObjWindow ) MMstart(m, (O->Buffer>>1) ) ) ->WHandler ;
                break ;

             
        case OBJ_TYPE_EDIT_TEXT :
        case OBJ_TYPE_TEXT :
        case OBJ_TYPE_EDIT_LINE :
        case OBJ_TYPE_RICH_TEXT :

                HW = (( PtrObjText ) MMstart(m, (O->Buffer>>1) )) -> WHandler ;
                break ;
        case OBJ_TYPE_CHECK_BOX :
        case OBJ_TYPE_PUSHBUTTON :

                HW = (( PtrObjButton ) MMstart(m,( O->Buffer>>1) )) ->WHandler ;
                break ;

        case OBJ_TYPE_LIST_BOX :
        case OBJ_TYPE_COMBO_BOX :

                HW = (( PtrObjCombo ) MMstart(m,( O->Buffer>>1) )) -> WHandler ;
                break ;

        case OBJ_TYPE_PUSH_BUTTON_BITMAP :

                HW = (( PtrObjPushButtonBitmap ) MMstart(m,( O->Buffer>>1) )) -> WHandler ;
                break ;

        case OBJ_TYPE_TREE :

                HW =  ((PtrObjTree ) MMstart(m,(O->Buffer>>1)))->WHandler ;
                break ;

        case OBJ_TYPE_LISTTAB :

                HW = ((PtrObjListTab ) MMstart(m,(O->Buffer>>1)))->WHandler ;
                break ;

        default : return MMpush(m,s) ;        
        }

        MMechostr(MSKDEBUG,"'ENABLE winn %d etat %d\r\n",HW,etat);
        if ( etat == 0 ) EnableWindow ( HW , FALSE ) ; else EnableWindow ( HW , TRUE ) ;
    }    
        
    

    s = MMpush(m,s ) ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGREnableWindow end");
#endif
//***********************************

    return s ;
}



/****************************************************************************/ 
/*                                                                          */ 
/*      int GRClearWindow ( mmachine m ) ;                                  */ 
/*                                                                          */ 
/*      Correspond a la fonction scol ObjWin _CLRwindow ( ObjWin )          */ 
/*      laquelle efface le background d'une fenetre                         */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRClearWindow ( mmachine m )
{
    int s ;
    PtrObjVoid O ;
    PtrObjWindow W ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRClearWindow");
#endif
//***********************************

    s = MMpull(m) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        W = ( PtrObjWindow ) MMstart(m,(O->Buffer>>1)) ;

        SendMessage ( W->WHandler , WM_ERASEBKGND , (WPARAM ) GetDC ( W->WHandler ), ( LPARAM ) 0 );
    }

    s = MMpush ( m ,s ) ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRClearWindow end");
#endif
//***********************************

    return s ;
}


/****************************************************************************/ 
/*                                                                          */ 
/*      int GRGetBkColor ( mmachine m ) ;                                   */ 
/*                                                                          */ 
/*  correspond al a fonction window I _GETbkColor ( Objxxx )                */ 
/*                                                                          */ 
/*      Recupere la couleur par default des elements de fenetres            */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRGetBkColor ( mmachine m )
{

    int s , i ;
    PtrObjVoid O ;
    HWND H ;
    HBRUSH HB ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRGetBkColor");
#endif
//***********************************

    s = MMpull(m) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        s = O->Buffer >> 1  ;
        H = NULL ;
        switch (O->Type >> 1)
        {
            case OBJ_TYPE_WINDOW :
                H = (( PtrObjWindow ) ( MMstart(m,s) )) -> WHandler ;
                break ;
        }

        if (H == NULL) i = NIL ;
        else
        {
            HB = ( HBRUSH ) GetClassLong ( H , GCL_HBRBACKGROUND ) ;
        }
    } else i = NIL ;

    s = MMpush(m,i<<1);


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRGetBkColor end");
#endif
//***********************************

    return i ;
}
   

int GRGetSysColor ( mmachine m )
{
    int i ;

    i = MMpull(m)>>1 ;

    return MMpush(m,GetSysColor (COLOR_BACKGROUND+i)<<1) ;
}



/****************************************************************************/ 
/*                                                                          */ 
/*  int GRCreateScrollWindow ( mmachine m )                                 */ 
/*                                                                          */ 
/*  correspond a la fonction _CRscrollWindow ( Chn channel , ObjWin parent  */ 
/*      I x , I y , I w , I h , I wcli , I hcli , I flag, I flagcli ,       */ 
/*      S title )   -> [ ObjWin ObjWin ]                                    */ 
/*                                                                          */ 
/*  laquelle cree une fenetre avec ascenseur                                */ 
/*                                                                          */ 
/****************************************************************************/ 


int GRCreateScrollWindow ( mmachine m )
{
    char Name [ 33000 ] ;    
    int s , flag , wc , hc , w , h , x , y;
    int l , s2 , res ;
    PtrObjVoid O , OP;
    PtrObjWindow Wnd , PW ;
    HWND Parent , HW ;


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRCreateScrollWindow");
#endif
//***********************************
        
    /*************** test si channel == NIL *********************************/ 
    if ( MMget(m,10) == NIL ) 
    {
        MMechostr (1,"_CRwindow : channel is NIL\n");
        m->pp += 10;
        MMset(m,0,NIL);
        return 0;
    }

    /************* lecture nom de la fenetre parent *************************/ 
    s = MMpull(m) ;
    //$BLG - 4.6a4
    //Didn't remove the (SCOL) part of the name, as this is a Child Window which should not display its title
    if ( s == NIL ) strcpy ( Name , "(SCOL)" ) ;
    else sprintf(Name,"(SCOL) %s",( char * ) (MMstart(m, (s>>1)+1))) ;           

    /***************** lecture fenetre parent *******************************/ 
    
    flag    = MMpull(m) >> 1 ;
    hc      = MMpull(m) >> 1 ;
    wc      = MMpull(m) >> 1 ;
    h       = MMpull(m) >> 1 ;
    w       = MMpull(m) >> 1 ;

	// $BB
	// >> 1 do not divise the x y position by 2 !
    y       = MMpull(m) ;
    x       = MMpull(m) ;
	
    /*********** creation fenetre parent ************************************/ 
    l = ( sizeof ( struct ObjVoid ) + 3 ) >> 2 ;        
    s = MMmallocCLR(m,l,TYPETAB) ;
    if ( s == NIL )
    {
        MMechostr(MSKDEBUG,"(ERROR) _CRscrollWindow : out of memory \n" ) ;
        return MERRMEM ;
    }               
    if ( MMpush ( m,(s<<1)+1 )) return MERRMEM ;
    /* on remet s sur la pile au cas ou le malloc suivant */
    /* causerait un GC */

     /* creation de la zone memoire pour les donnees propres aux fenetres */
    l = ( sizeof ( struct ObjWindow ) + 3 ) >> 2 ;
        
    s2 = MMmalloc (m,l,TYPEBUF);
    if ( s2 == NIL )
    {
        MMechostr(MSKDEBUG,"(ERROR) _CRscrollWindow : out of memory \n" ) ;
        return MERRMEM ;
    }               

    Wnd = ( PtrObjWindow ) MMstart(m, s2 ) ;
    s = MMpull(m) ;
    O = ( PtrObjVoid ) MMstart(m, (s >> 1) ) ;

    /* initialisation de la structure fenetre */ 
    O -> Type             = OBJ_TYPE_WINDOW << 1  ;        
    Wnd -> Flags          = flag ;
    Wnd -> TailleH        = h ;
    Wnd -> TailleW        = w ;
    Wnd -> PosY           = y ;
    Wnd -> PosX           = x ;
    Wnd -> MinW           = 32 ;
    Wnd -> MinH           = 32 ;
    Wnd -> MaxW           = 8000 ;
    Wnd -> MaxH           = 8000 ;
    Wnd -> Child          = NULL ;
    Wnd -> Cursor         = NULL ;
    if ( Wnd->PosX == NIL ) Wnd->PosX = CW_USEDEFAULT ; else Wnd->PosX >>= 1 ;
    if ( Wnd->PosY == NIL ) Wnd->PosY = CW_USEDEFAULT ; else Wnd->PosY >>= 1 ;
    O -> Father           = MMpull(m) ;
    O -> Tab              = NIL ;
    O->Buffer = ( s2 << 1 ) + 1 ;
         
    /* recuperation du handler window du parent, si parent il y a */ 
    if ( O -> Father == NIL ) Parent = NULL ;
    else
    {
        OP = ( PtrObjVoid ) MMstart(m, (O->Father>>1) ) ;
        /* verifie que le pere est bien de type Fenetre */                          
        PW = ( PtrObjWindow ) MMstart(m,(OP->Buffer >> 1)) ;
        Parent = PW->WHandler ;
    }

    /* creation de la ressource */ 
     
    HW = NewWindow ( Wnd , Name , Parent ) ;
    if ( ! HW )
    {
        MMechostr (1,"(ERROR) _CRscrollWindow : Windows failed in creating object. Check values\n");
        MMset(m,0,NIL);
        return 0 ;
    }
    Wnd->WHandler = HW  ;           

    if ( DefaultFont != NULL && ( Wnd->Flags & WN_GROUP )!=0 ) 
       SendMessage ( HW , WM_SETFONT , ( WPARAM ) DefaultFont , ( LPARAM ) TRUE ) ;  
   
    /* affichage de la fenetre */ 
    if ( Wnd->Flags & WN_HIDE ) { ShowWindow ( HW , SW_HIDE ); MMechostr(MSKDEBUG,"Window %d HIDDEN2\n",HW);}
    else if ( Wnd->Flags & WN_MINIMIZE )ShowWindow ( HW , SW_MINIMIZE ) ;
    else
    {
        ShowWindow( HW , SW_SHOW) ; 
        if (Wnd->Flags & WN_NOCURSOR ) SetFocus ( HW ) ;
    }
    UpdateWindow( HW );
    BringWindowToTop (HW ) ;
 
    MMpush(m,MMget(m,0)) ;  /* dedouble le channel pour le deuxieme objet */ 
    MMpush(m,s) ;
    res = OBJcreate(m,OBJTYPWINDOW,(int)HW,OBJTYPWINDOW,(int)Parent) ;

    /* pile = fenetre 1 - channel */ 
    /******* creation de la fenetre fille **********************************/     
    l = ( sizeof ( struct ObjVoid ) + 3 ) >> 2 ;        
    s = MMmallocCLR(m,l,TYPETAB) ;
    if ( s == NIL )
    {
        MMechostr(MSKDEBUG,"(ERROR) _CRscrollWindow : out of memory \n" ) ;
        return MERRMEM ;
    }               
    if ( MMpush ( m,(s<<1)+1 )) return MERRMEM ;
    /* on remet s sur la pile au cas ou le malloc suivant */
    /* causerait un GC */

     /* creation de la zone memoire pour les donnees propres aux fenetres */
    l = ( sizeof ( struct ObjWindow ) + 3 ) >> 2 ;
        
    s2 = MMmalloc (m,l,TYPEBUF);
    if ( s2 == NIL )
    {
        MMechostr(MSKDEBUG,"(ERROR) _CRscrollWindow : out of memory \n" ) ;
        return MERRMEM ;
    }               

    Wnd = ( PtrObjWindow ) MMstart(m, s2 ) ;
    s = MMpull(m) ;
    O = ( PtrObjVoid ) MMstart(m, (s >> 1) ) ;

    /* initialisation de la structure fenetre */ 
    O -> Type             = OBJ_TYPE_WINDOW << 1  ;        
    Wnd -> Flags          = WN_CHILD|WN_NOBORDER;
    Wnd -> TailleH        = hc ;
    Wnd -> TailleW        = wc ;
    Wnd -> PosY           = 0 ;
    Wnd -> PosX           = 0 ;
    Wnd -> MinW           = 32 ;
    Wnd -> MinH           = 32 ;
    Wnd -> MaxW           = 8000 ;
    Wnd -> MaxH           = 8000 ;
    Wnd -> Cursor         = NULL ;
    if ( Wnd->PosX == NIL ) Wnd->PosX = CW_USEDEFAULT ; else Wnd->PosX >>= 1 ;
    if ( Wnd->PosY == NIL ) Wnd->PosY = CW_USEDEFAULT ; else Wnd->PosY >>= 1 ;
    O -> Father           = MMpull(m) ;
    O -> Tab              = NIL ;
    O->Buffer = ( s2 << 1 ) + 1 ;
         
    /* recuperation du handler window du parent, si parent il y a */ 
    if ( O -> Father == NIL ) Parent = NULL ;
    else
    {
        OP = ( PtrObjVoid ) MMstart(m, (O->Father>>1) ) ;
        /* verifie que le pere est bien de type Fenetre */                          
        PW = ( PtrObjWindow ) MMstart(m,(OP->Buffer >> 1)) ;
        Parent = PW->WHandler ;        
    }
    /* creation de la ressource */ 
     
    HW = NewWindow ( Wnd , Name , Parent ) ;
    if ( ! HW )
    {
        MMechostr (1,"(ERROR) _CRscrollWindow : Windows failed in creating object. Check values\n");
        MMset(m,0,NIL);
        return 0 ;
    }
    Wnd->WHandler = HW  ;           
    PW->Child = HW ;
    SCOLremakeScroll ( HW ) ;

   if ( DefaultFont != NULL && ( Wnd->Flags & WN_GROUP )!=0 ) 
       SendMessage ( HW , WM_SETFONT , ( WPARAM ) DefaultFont , ( LPARAM ) TRUE ) ;  
   
    /* affichage de la fenetre */ 
    if ( Wnd->Flags & WN_HIDE ) { ShowWindow ( HW , SW_HIDE ); MMechostr(MSKDEBUG,"Window %d HIDDEN3\n",HW);}
    else if ( Wnd->Flags & WN_MINIMIZE )ShowWindow ( HW , SW_MINIMIZE ) ;
    else
    {
        ShowWindow( HW , SW_SHOW) ; 
        if (Wnd->Flags & WN_NOCURSOR ) SetFocus ( HW ) ;
    }
    UpdateWindow( HW );
    BringWindowToTop (HW ) ;
      
    MMpush(m,s) ;
    res = OBJcreate(m,OBJTYPWINDOW,(int)HW,OBJTYPWINDOW,(int)Parent) ;
    s = MMpull(m);
    O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;

    MMpushNoGC(m,O->Father);
    MMpush(m,s);
   
    MMpush(m,4) ;
    res = MBdeftab ( m ) ;
      
      


//***********************************
#if DEBUG_LIB2DOS
_DEBUG_INFO (0, "\nGRCreateScrollWindow end");
#endif
//***********************************
    return res ; 
}

int GRFullScreenWindow( mmachine m )
{
	MMpull(m);
	MMpull(m);
	MMpull(m);
	return MMpush(m,NIL);
}

int GRDesktopWindow( mmachine m )
{
	MMpull(m);
	return MMpush(m,NIL);
}
