// File:        WNT_Window.cxx
// Created:     
// Author:      
// Modifications: PLOTNIKOV Eugeny at July 1998 (BUC60286)
//                TCL              at October 2000 (G002) 
//                new method SetBackground(CString aName)
// Copyright:   Matra Datavision 1998

#define TEST    //GG_021297
//              Protects window position when center is wrong

#define K4      //GG_090198
//              DoMapping implementation

#define G004    //GG 28/01/00 Add gama correction computation before dumping
//              an image.
//                GG 07/03/00 Add MMSize() method

#include <WNT_Window.ixx>

#include <stdio.h>
extern "C" void _debug_break ( char* );
//************************************************************************//
//***//
// callback function to manage window's background
extern LRESULT CALLBACK WNT_WndProc (
                         HWND, UINT, WPARAM, LPARAM
                        );
//***//
#define SELECT_PALETTE(hDC)                                  \
 HPALETTE hOldPal;                                           \
                                                             \
  if ( myExtraData.hPal  ) {                                 \
                                                             \
   hOldPal = SelectPalette ( hDC, myExtraData.hPal, FALSE ); \
                                                             \
   if (  RealizePalette ( hDC )  )                           \
                                                             \
    UpdateColors ( hDC );                                    \
                                                             \
  }  // end if
//***//
#define UNSELECT_PALETTE(hDC)            \
 if ( myExtraData.hPal )                 \
                                         \
  SelectPalette ( hDC, hOldPal, FALSE );

HBITMAP LoadImageFromFile (  Handle( WNT_GraphicDevice )&, char*, HDC = NULL  );

//***//
//************************* Constructor **********************************//
//***//
WNT_Window :: WNT_Window (
               const Handle( WNT_GraphicDevice )& aDevice,
               const Standard_CString             aTitle,
               const Handle( WNT_WClass )&        aClass,
               const WNT_Dword&                   aStyle,
               const Quantity_Parameter           Xc,
               const Quantity_Parameter           Yc,
               const Quantity_Parameter           aWidth,
               const Quantity_Parameter           aHeight,
               const Quantity_NameOfColor         aBackColor,
               const Aspect_Handle&               aParent,
               const Aspect_Handle&               aMenu,
               const Standard_Address             aClientStruct
                  ) : Aspect_Window ( aDevice ), myWClass ( aClass ) {

 int   x, y, w, h, px, py, pw, ph;
 DWORD dwStyle = aStyle;
 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );

 if ( Xc < 0. || Xc > 1. || Yc < 0. || Yc > 1. || aWidth <= 0. || aHeight <= 0. )

  Aspect_WindowDefinitionError :: Raise ( "Coordinate(s) out of range" );

 ZeroMemory (  &myExtraData, sizeof ( WNT_WindowData )  );

 if ( aParent ) {

  RECT r;
  GetClientRect (  ( HWND )aParent, &r  );
  pw = r.right;
  ph = r.bottom;  

 } else

  dev -> DisplaySize ( pw, ph );

 w  = ( int )(  aWidth  * Min ( pw, ph )  );
 h  = ( int )(  aHeight * Min ( pw, ph )  ); 

#ifdef TEST
 if( Xc > 0. ) px = ( int )(  Xc * ( Quantity_Parameter )pw  );
 else px = w/2;
 if( Yc > 0. ) py = ( int )(  ( 1. - Yc ) * ( Quantity_Parameter )ph );
 else py = h/2;
#else
 px = ( int )(  Xc * ( Quantity_Parameter )pw  );
 py = ( int )(  ( 1. - Yc ) * ( Quantity_Parameter )ph );
#endif

 if ( px - w / 2 < 0 )

  w = ( int )( 2 * px );

 if ( px + w / 2 > pw )

  w = ( int )(  2 * ( pw - px )  );

 if ( py - h / 2 < 0 )

  h = ( int )( 2 * py );

 if ( py + h / 2 > ph )

  h = ( int )(  2 * ( ph - py )  );

 x = ( int )( px - w / 2 );
 y = ( int )( py - h / 2 ); 

 if (  aParent && !( aStyle & WS_CHILD )  )

  dwStyle |= WS_CHILD | WS_CLIPSIBLINGS;

 else if (  !aParent && !( aStyle & WS_CLIPCHILDREN )  )

  dwStyle |= WS_CLIPCHILDREN;

 myHWindow = CreateWindow (
              myWClass -> Name (),                    // window's class name
              aTitle,                                 // window's name
              dwStyle,                                // window's style
              x, y, w, h,                             // window's coordinates
              ( HWND )aParent,                        // window's parent
              ( HMENU )aMenu,                         // window's menu
              ( HINSTANCE)myWClass -> Instance (),    // application's instance
              aClientStruct                           // pointer to
             );                                       //   CLIENTCREATESTRUCT

 if ( !myHWindow )

  Aspect_WindowDefinitionError :: Raise ( "Unable to create window" );

 myDoubleBuffer  = Standard_False;               
 myHPixmap       = 0;
 myHParentWindow = aParent;
 myWndProc       = myWClass -> WndProc ();
 myHParentWindow = aParent;

 SetBackground ( aBackColor );
#ifndef _WIN64
 SetWindowLong (  ( HWND )myHWindow, GWL_WNDPROC,  ( LONG )WNT_WndProc   );
#else
 SetWindowLong (  ( HWND )myHWindow, GWLP_WNDPROC,  ( LONG )WNT_WndProc   );
#endif
 myUsrData = ( Standard_Integer )SetWindowLong (  
#ifndef _WIN64
                                  ( HWND )myHWindow, GWL_USERDATA, ( LONG )&myExtraData
#else
                                  ( HWND )myHWindow, GWLP_USERDATA, ( LONG )&myExtraData
#endif
                                 );

 aXLeft   = x;
 aYTop    = y;
 aXRight  = x + w;
 aYBottom = y + h;

 myExtraData.WNT_Window_Ptr  = ( void* )this;
 myExtraData.hPal            = ( HPALETTE )dev -> HPalette ();

 myImages = new WNT_ImageManager ( this );
 myFormat = WNT_TOI_XWD;

}  // end constructor
//***//
//************************* Constructor **********************************//
//***//
WNT_Window :: WNT_Window (
               const Handle( WNT_GraphicDevice )& aDevice,
               const Aspect_Handle&               aHandle,
               const Quantity_NameOfColor         aBackColor
              ) : Aspect_Window ( aDevice ) {

 doCreate ( aDevice, aHandle, aBackColor );

}  // end constructor
//***//
//************************* Constructor **********************************//
//***//
WNT_Window :: WNT_Window (
               const Handle( WNT_GraphicDevice )& aDevice,
               const Standard_Integer             aPart1,
               const Standard_Integer             aPart2,
               const Quantity_NameOfColor         aBackColor
              ) : Aspect_Window ( aDevice ) {

 Aspect_Handle aHandle = ( Aspect_Handle )(  ( aPart1 << 16 ) + aPart2  );

 doCreate ( aDevice, aHandle, aBackColor );

}  // end constructor
//***//
//***************************** Destroy **********************************//
//***//
void WNT_Window :: Destroy () {

 if ( MyHBackground ) DeleteObject ( MyHBackground );  // delete background brush
 if ( myHPixmap     ) DeleteObject ( myHPixmap     );  // . . . and double buffer pixmap if exists

 if ( myHWindow ) {
 
  if ( myUsrData != -1 )
  
#ifndef _WIN64
   SetWindowLong (  ( HWND )myHWindow, GWL_USERDATA, ( LONG )myUsrData  );
#else
   SetWindowLong (  ( HWND )myHWindow, GWLP_USERDATA, ( LONG )myUsrData  );
#endif

  if ( myWndProc != NULL )
  
#ifndef _WIN64
   SetWindowLong (  ( HWND )myHWindow, GWL_WNDPROC, ( LONG )myWndProc  );
#else
   SetWindowLong (  ( HWND )myHWindow, GWLP_WNDPROC, ( LONG )myWndProc  );
#endif

  if (  !( myExtraData.dwFlags & WDF_FOREIGN )  )
  
   DestroyWindow (  ( HWND )myHWindow  );

 }  // end if

}  // end WNT_Window :: Destroy
//***//
//************************ SetBackground (1) *****************************//
//***//
void WNT_Window :: SetBackground ( const Aspect_Background& Background ) {

 SetBackground (  Background.Color ().Name ()  );

}  // end WNT_Window :: SetBackground
//***//
//************************ SetBackground (2) *****************************//
//***//
void WNT_Window :: SetBackground ( const Quantity_NameOfColor BackColor ) {

 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );

 if ( MyHBackground )
   DeleteObject ( MyHBackground );

 MyBackground.SetColor ( BackColor );
 MyHBackground = CreateSolidBrush (
                  dev -> SetColor (  MyBackground.Color ()  )
                 ); 

}  // end WNT_Window :: SetBackground
//***//
//************************ SetBackground (3) *****************************//
//***//
void WNT_Window :: SetBackground ( const Aspect_Handle& aBackPixmap ) {

 Aspect_Handle bitmap = CreatePatternBrush (  ( HBITMAP )aBackPixmap  );

 if( bitmap ) {
   if ( MyHBackground ) DeleteObject ( MyHBackground );
   MyHBackground = bitmap;
   MyBackgroundImage.Clear();
   MyBackgroundFillMethod = Aspect_FM_NONE;
 }

}  // end WNT_Window :: SetBackground
//***//
//************************ SetBackground (4) *****************************//
//***//
Standard_Boolean WNT_Window::SetBackground( const Standard_CString aName,
                                const Aspect_FillMethod aMethod ) {
 Standard_Boolean status = Standard_False; 

 if( !aName ) return Standard_False;

 Handle( WNT_GraphicDevice ) gdev =  
     *( ( Handle_WNT_GraphicDevice * )& MyGraphicDevice );
 if ( MyHBackground )
   DeleteObject( MyHBackground );
 MyHBackground = 0;

 HBITMAP hBmp = LoadImageFromFile( gdev, aName );

 if( hBmp ) {
   status = Standard_True;
   MyBackgroundImage = aName;
   MyBackgroundFillMethod = aMethod;
   MyHBackground = CreatePatternBrush(  hBmp  );
 }

 return status;
}  // end WNT_Window :: SetBackground
    //***//
//************************ SetBackground (5) *****************************//
//***//
void WNT_Window::SetBackground( const Quantity_Color& color ) {

 const Handle( WNT_GraphicDevice )& dev = 
   Handle( WNT_GraphicDevice )::DownCast ( MyGraphicDevice );

 if ( MyHBackground )
   DeleteObject( MyHBackground );

 MyBackground.SetColor( color );
 MyHBackground = CreateSolidBrush( dev->SetColor( color ) ); 

}  // end WNT_Window :: SetBackground
//**************************** SetCursor *********************************//
//***//
void WNT_Window :: SetCursor ( const Aspect_Handle& aCursor ) const {

#ifndef _WIN64
 SetClassLong (  ( HWND )myHWindow, GCL_HCURSOR, ( LONG )aCursor  );
#else
 SetClassLong (  ( HWND )myHWindow, GCLP_HCURSOR, ( LONG )aCursor  );
#endif

}  // end WNT_Window :: SetCursor 
//***//
//**************************** SetIcon ***********************************//
//***//
void WNT_Window :: SetIcon (
                    const Aspect_Handle&   anIcon,
                    const Standard_CString aName
                   ) {

 if (  !myIcon.IsNull ()  )

  myIcon.Nullify ();

 myIcon = new WNT_Icon ( aName, anIcon, 0 );

}  // end WNT_Window :: SetIcon
//***//
//**************************** SetIconName *******************************//
//***//
void WNT_Window :: SetIconName ( const Standard_CString aName ) {

 myIcon -> SetName ( aName );

}  // end WNT_Window :: SetIconName
//***//
//************************** SetDoubleBuffer *****************************//
//***//
void WNT_Window :: SetDoubleBuffer ( const Standard_Boolean DBmode ) {

 if ( DBmode )

  if (  !BackingStore ()  )

   Aspect_WindowError :: Raise ( "Unable to set double buffer" );

  else {

   myDoubleBuffer   = Standard_True;
   myExtraData.hBmp     = ( HBITMAP )myHPixmap;

  }  // end else

 else {

  myDoubleBuffer   = Standard_False;
  myExtraData.hBmp = NULL;

 }  // end else
  
}  // end WNT_Window :: SetDoubleBuffer
//***//
//***************************** Flush ************************************//
//***//
void WNT_Window :: Flush () const {

 if ( myDoubleBuffer ) Restore ();

}  // end WNT_Window :: Flush
//***//
//***************************** IsMapped *********************************//
//***//
Standard_Boolean WNT_Window :: IsMapped () const {

 WINDOWPLACEMENT wp;

 wp.length = sizeof ( WINDOWPLACEMENT );
 GetWindowPlacement (  ( HWND )myHWindow, &wp  );

 return !(  wp.showCmd == SW_HIDE || wp.showCmd == SW_MINIMIZE );

}  // WNT_Window :: IsMapped
//***//
//***************************** Map (1) **********************************//
//***//
void WNT_Window :: Map () const {

 Map ( SW_SHOW );
 
}  // end WNT_Window :: Map
//***//
//***************************** Map (2) **********************************//
//***//
void WNT_Window :: Map ( const Standard_Integer aMapMode ) const {

 ShowWindow (  ( HWND )myHWindow, aMapMode  );
 UpdateWindow (  ( HWND )myHWindow  );
 
}  // end WNT_Window :: Map
//***//
//**************************** Unmap *************************************//
//***//
void WNT_Window :: Unmap () const {

 Map ( SW_HIDE );

}  // end WNT_Window :: Unmap
//***//
//**************************** DoResize **********************************//
//***//
Aspect_TypeOfResize WNT_Window :: DoResize () const {

 int                 mask = 0;
 Aspect_TypeOfResize mode = Aspect_TOR_UNKNOWN;
 WINDOWPLACEMENT     wp;  

 wp.length = sizeof ( WINDOWPLACEMENT );
 GetWindowPlacement (  ( HWND )myHWindow, &wp  );

 if ( wp.showCmd != SW_SHOWMINIMIZED ) {

  if (  Abs ( wp.rcNormalPosition.left   - aXLeft   ) > 2  ) mask |= 1;
  if (  Abs ( wp.rcNormalPosition.right  - aXRight  ) > 2  ) mask |= 2;
  if (  Abs ( wp.rcNormalPosition.top    - aYTop    ) > 2  ) mask |= 4;
  if (  Abs ( wp.rcNormalPosition.bottom - aYBottom ) > 2  ) mask |= 8;

  switch ( mask ) {

   case 0:

     mode = Aspect_TOR_NO_BORDER;

    break;  

   case 1:

     mode = Aspect_TOR_LEFT_BORDER;

    break;  

   case 2:

     mode = Aspect_TOR_RIGHT_BORDER;

    break;  

   case 4:

     mode = Aspect_TOR_TOP_BORDER;

    break;  

   case 5:

     mode = Aspect_TOR_LEFT_AND_TOP_BORDER;

    break;  

   case 6:

     mode = Aspect_TOR_TOP_AND_RIGHT_BORDER;

    break;  

   case 8:

     mode = Aspect_TOR_BOTTOM_BORDER;

    break;  

   case 9:

     mode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER;

    break;  

   case 10:

     mode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER;

    break;  

   default:

    break;  

  }  // end switch

  *(  ( Standard_Integer* )&aXLeft   ) = wp.rcNormalPosition.left;
  *(  ( Standard_Integer* )&aXRight  ) = wp.rcNormalPosition.right;
  *(  ( Standard_Integer* )&aYTop    ) = wp.rcNormalPosition.top;
  *(  ( Standard_Integer* )&aYBottom ) = wp.rcNormalPosition.bottom;

  if (  myDoubleBuffer  ) {
  
   DeleteObject ( myHPixmap );
   *(  ( Aspect_Handle* )&myHPixmap  ) = 0;
   
   if (  !BackingStore ()  )

    Aspect_WindowError :: Raise ( "WNT_Window::DoResize (): Unable to set double buffer" );

  }  // end if

 }  // end if

 return mode;

}  // end WNT_Window :: DoResize

#ifdef K4
//***//
//**************************** DoMapping **********************************//
//***//
Standard_Boolean WNT_Window :: DoMapping () const {
// DO nothing on WNT.
  return Standard_True;
}
#endif
//***//
//**************************** Clear *************************************//
//***//
void WNT_Window :: Clear () const {

 RECT r;

 GetClientRect (  ( HWND )myHWindow, &r  );
 ClearArea ( r.right / 2, r.bottom / 2, r.right, r.bottom );

}  // end WNT_Window :: Clear
//***//
//**************************** ClearArea *********************************//
//***//
void WNT_Window :: ClearArea (
                    const Standard_Integer Xc,
                    const Standard_Integer Yc,
                    const Standard_Integer Width,
                    const Standard_Integer Height
                   ) const {

 RECT r;
 HDC  hDC = GetDC (  ( HWND )myHWindow  );

  r.left   = Xc - Width / 2;
  r.right  = r.left + Width;
  r.top    = Yc - Height / 2;
  r.bottom = r.top + Height;

  if ( myDoubleBuffer && myHPixmap ) {

   HDC hDCmem = CreateCompatibleDC ( hDC );

    SELECT_PALETTE( hDCmem );

     SelectObject ( hDCmem, myHPixmap );
     FillRect (  hDCmem, &r, ( HBRUSH )MyHBackground  );

        UNSELECT_PALETTE( hDCmem );

   DeleteDC ( hDCmem );

  } else {

   SELECT_PALETTE( hDC );

    FillRect (  hDC, &r, ( HBRUSH )MyHBackground  );

   UNSELECT_PALETTE( hDC );

  }  // end else

 ReleaseDC (  ( HWND )myHWindow, hDC  );

}  // end WNT_Window :: ClearArea
//***//
//**************************** Restore ***********************************//
//***//
void WNT_Window :: Restore () const {

 RECT r;

 if ( myHPixmap ) {

  GetClientRect (  ( HWND )myHWindow, &r  );
  RestoreArea (
   r.right / 2, r.bottom - r.bottom / 2, r.right, r.bottom
  );

 }  // end if

}  // end WNT_Window :: Restore
//***//
//************************* Restore Area *********************************//
//***//
void WNT_Window :: RestoreArea (
                    const Standard_Integer Xc,
                    const Standard_Integer Yc,
                    const Standard_Integer Width,
                    const Standard_Integer Height
                   ) const {

 HDC hDC, hDCmem;
 int x, y;

 if ( myHPixmap ) {

  hDC     = GetDC (  ( HWND )myHWindow  );
   hDCmem = CreateCompatibleDC ( hDC );

    x = Xc - Width / 2;
    y = Yc - Height / 2;

    SelectObject ( hDCmem, myHPixmap );
    BitBlt ( hDC, x, y, Width, Height, hDCmem, x, y, SRCCOPY );

   DeleteDC ( hDCmem );
  ReleaseDC (  ( HWND )myHWindow, hDC  );

 }  // end if

}  // end WNT_Window :: RestoreArea
//***//
//****************************** Dump ************************************//
//***//
Standard_Boolean
#ifdef G004
WNT_Window::Dump (const Standard_CString aFilename,
                 const Standard_Real aGammaValue ) const {
#else
WNT_Window :: Dump ( const Standard_CString aFilename ) const {
#endif

 RECT r;

 GetClientRect (  ( HWND )myHWindow, &r  );
 
 return DumpArea (
         aFilename, r.right / 2, r.bottom - r.bottom / 2,
         r.right, r.bottom
#ifdef G004
        ,aGammaValue
#endif
        );

}  // end WNT_Window :: Dump
//***//
//*************************** DumpArea ***********************************//
//***//
Standard_Boolean
#ifdef G004
WNT_Window::DumpArea (const Standard_CString aFilename, const Standard_Integer Xc , const Standard_Integer Yc, const Standard_Integer Width, const Standard_Integer Height, const Standard_Real aGammaValue) const {
#else
WNT_Window :: DumpArea (
                                const Standard_CString aFilename,
                                const Standard_Integer Xc,
                                const Standard_Integer Yc,
                                const Standard_Integer Width,
                                const Standard_Integer Height
                               ) const {
#endif

// *** Gamma correction must be implemented also under WNT ...

 RECT             r;
 Standard_Integer x, y;

 GetClientRect (  ( HWND )myHWindow, &r  );

 x = Xc - Width  / 2;
 y = Yc - Height / 2;

 return ( myDoubleBuffer ) ?
         myImages -> SaveBuffer ( aFilename, x, y, Width, Height ) :
                 myImages -> Save               ( aFilename, x, y, Width, Height );

}  // end WNT_Window :: DumpArea
//***//
//****************************** Load ************************************//
//***//
Standard_Boolean WNT_Window :: Load ( const Standard_CString aFilename ) const {

 RECT r;

 GetClientRect (  ( HWND )myHWindow, &r  );
 
 return LoadArea ( aFilename, r.right / 2, r.bottom / 2, r.right, r.bottom );

}  // end WNT_Window :: Load
//***//
//*************************** LoadArea ***********************************//
//***//
Standard_Boolean WNT_Window :: LoadArea (
                                const Standard_CString aFilename,
                                const Standard_Integer Xc,
                                const Standard_Integer Yc,
                                const Standard_Integer Width,
                                const Standard_Integer Height
                               ) const {

 Standard_Integer idx;
 Standard_Boolean status;

 status = (  idx = myImages -> Load ( aFilename )  ) ? Standard_True : Standard_False;

 if ( status ) myImages -> Draw ( idx, Xc, Yc, Width, Height );

 return status;

}  // end WNT_Window :: LoadArea
//***//
//*************************** BackingStore *******************************//
//***//
Standard_Boolean WNT_Window :: BackingStore () const {

 Standard_Boolean retVal = Standard_False;;
 HDC              hDC;
 RECT             r;

 if ( myHPixmap )

  retVal = Standard_True;

 else {

  hDC = GetDC (  ( HWND )myHWindow  );

   GetClientRect (  ( HWND )myHWindow, &r  );
   *(  ( Aspect_Handle* )&myHPixmap  ) = CreateCompatibleBitmap ( hDC, r.right, r.bottom );

   if ( myHPixmap ) {

    HDC hDCmem;

         hDCmem = CreateCompatibleDC ( hDC );

       SELECT_PALETTE( hDCmem );

            SelectObject ( hDCmem, myHPixmap );
        FillRect (  hDCmem, &r, ( HBRUSH )MyHBackground  );

       UNSELECT_PALETTE( hDCmem );

         DeleteDC ( hDCmem );

    retVal = Standard_True;

   }  // end if

  ReleaseDC (  ( HWND )myHWindow, hDC  );

 }  // end else

 return retVal;

}  // end WNT_Window :: BackingStore 
//***//
//******************************* Ratio **********************************//
//***//
Quantity_Ratio WNT_Window :: Ratio () const {

 RECT r;

 GetClientRect (  ( HWND )myHWindow, &r  );

 return ( Quantity_Ratio )(  ( Quantity_Ratio )r.right / ( Quantity_Ratio )r.bottom  );

}  // end WNT_Window :: Ratio
//***//
//**************************** Position (1) ******************************//
//***//
void WNT_Window :: Position (
                    Quantity_Parameter& X1, Quantity_Parameter& Y1,
                    Quantity_Parameter& X2, Quantity_Parameter& Y2
                   ) const {

 POINT ptl, ptr;
 RECT  pr, cr;
 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );

 if ( myHParentWindow )

  GetClientRect (  ( HWND )myHParentWindow, &pr  );

 else {

  int w, h;

  dev -> DisplaySize ( w, h );

  pr.right  = w;
  pr.bottom = h;

 }  // end else

 GetClientRect (  ( HWND )myHWindow, &cr  );

 ptl.x = ptl.y = 0;
 ClientToScreen (  ( HWND )myHWindow, &ptl  );
 cr.left = ptl.x;
 cr.top  = ptl.y;

 ptr.x = cr.right;
 ptr.y = cr.bottom;
 ClientToScreen (  ( HWND )myHWindow, &ptr  );
 cr.right  = ptr.x;
 cr.bottom = ptr.y;

 if ( myHParentWindow ) {
 
  ScreenToClient (      ( HWND )myHParentWindow, &ptl  );
  ScreenToClient (  ( HWND )myHParentWindow, &ptr  );
  cr.left   = ptl.x;
  cr.top    = ptl.y;
  cr.right  = ptr.x;
  cr.bottom     = ptr.y;
 
 }  // end if

 X1 = ( Quantity_Parameter )cr.left   / ( Quantity_Parameter )pr.right;
 X2 = ( Quantity_Parameter )cr.right  / ( Quantity_Parameter )pr.right;
 Y1 = 1. - ( Quantity_Parameter )cr.top    / ( Quantity_Parameter )pr.bottom;
 Y2 = 1. - ( Quantity_Parameter )cr.bottom / ( Quantity_Parameter )pr.bottom;

}  // end WNT_Window :: Position
//***//
//**************************** Position (2) ******************************//
//***//
void WNT_Window :: Position (
                    Standard_Integer& X1, Standard_Integer& Y1,
                    Standard_Integer& X2, Standard_Integer& Y2
                   ) const {

 POINT ptl, ptr;
 RECT  r;

 GetClientRect (  ( HWND )myHWindow, &r  );

 ptl.x = ptl.y = 0;
 ClientToScreen (  ( HWND )myHWindow, &ptl  );
 ptr.x = r.right;
 ptr.y = r.bottom;
 ClientToScreen (  ( HWND )myHWindow, &ptr  );

 if ( myHParentWindow ) {
 
  ScreenToClient (      ( HWND )myHParentWindow, &ptl  );
  ScreenToClient (  ( HWND )myHParentWindow, &ptr  );
 
 }  // end if

 X1 = ptl.x;
 X2 = ptr.x;
 Y1 = ptl.y;
 Y2 = ptr.y;

}  // end WNT_Window :: Position
//***//
//******************************* Size (1) *******************************//
//***//
void WNT_Window :: Size (
                    Quantity_Parameter& Width, Quantity_Parameter& Height
                   ) const {

 RECT pr, wr;
 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );
 
 if ( myHParentWindow )

  GetClientRect (  ( HWND )myHParentWindow, &pr  );

 else {

  int w, h;

  dev -> DisplaySize ( w, h );

  pr.right  = w;
  pr.bottom     = h;

 }  // end else

 GetClientRect (  ( HWND )myHWindow, &wr  );
 
 Width  = ( Quantity_Parameter )wr.right  / ( Quantity_Parameter )pr.right;
 Height = ( Quantity_Parameter )wr.bottom / ( Quantity_Parameter )pr.bottom;

}  // end WNT_Window :: Size
//***//
//******************************* Size (2) *******************************//
//***//
void WNT_Window :: Size (
                    Standard_Integer& Width, Standard_Integer& Height
                   ) const {

 RECT r;

 GetClientRect (  ( HWND )myHWindow, &r  );

 Width  = r.right;
 Height = r.bottom;

}  // end WNT_Window :: Size
//***//
//******************************* MMSize (1) *******************************//
//***//
void WNT_Window :: MMSize (
                    Standard_Real& Width, Standard_Real& Height
                   ) const {

 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );
 
 int w, h;
 dev -> DisplaySize ( w, h );
 Standard_Real mmw,mmh;
 dev -> DisplaySize ( mmw, mmh );
 Standard_Real mmratio = (mmw/w + mmh/h)/2.;

 RECT wr;
 GetClientRect (  ( HWND )myHWindow, &wr  );

 Width  = mmratio * wr.right; 
 Height = mmratio * wr.bottom;

}  // end WNT_Window :: MMSize
//***//
//**************************** Convert (1) *******************************//
//***//
Quantity_Parameter WNT_Window :: Convert (
                                  const Standard_Integer PV
                                 ) const {

 int w, h;
 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );

 dev -> DisplaySize ( w, h );

 return ( Quantity_Parameter )(  PV / Min ( w, h )  );

}  // end WNT_Window :: Convert
//***//
//**************************** Convert (2) *******************************//
//***//
Standard_Integer WNT_Window :: Convert (
                                const Quantity_Parameter DV
                               ) const {

 int w, h;
 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );

 dev -> DisplaySize ( w, h );

 return ( Standard_Integer )(  DV * Min ( w, h )  );
 
}  // end WNT_Window :: Convert
//***//
//**************************** Convert (3) *******************************//
//***//

void WNT_Window :: Convert (
                    const Standard_Integer PX, const Standard_Integer PY,
                    Quantity_Parameter& DX, Quantity_Parameter& DY
                   ) const {

 int w, h;
 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );

 dev -> DisplaySize ( w, h );

 DX = ( Quantity_Parameter )PX / ( Quantity_Parameter )w;
 DY = 1. - ( Quantity_Parameter )PY / ( Quantity_Parameter )h;

}  // end WNT_Window :: Convert
//***//
//**************************** Convert (4) *******************************//
//***//
void WNT_Window :: Convert (
                    const Quantity_Parameter DX, const Quantity_Parameter DY,
                    Standard_Integer& PX, Standard_Integer& PY
                   ) const {

 int w, h;
 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );

 dev -> DisplaySize ( w, h );

 PX = ( Standard_Integer )(  DX * ( Quantity_Parameter )w           );
 PY = ( Standard_Integer )(  ( 1. - DY ) * ( Quantity_Parameter )h  );

}  // end WNT_Window :: Convert
//***//
//******************************* SetPos *********************************//
//***//
void WNT_Window :: SetPos (
                    const Standard_Integer X,  const Standard_Integer Y,
                    const Standard_Integer X1, const Standard_Integer Y1
                   ) {
                   
 aXLeft   = X;
 aYTop    = Y;
 aXRight  = X1;
 aYBottom = Y1;               
                   
}  // end WNT_Window :: SetPos
//***//
//*************************** SetOutputFormat ****************************//
//***//
void WNT_Window :: SetOutputFormat ( const WNT_TypeOfImage aFormat ) {

 myFormat = aFormat;
 myImages -> SetFormat ( aFormat );

}  // end WNT_Window :: SetOutputFormat
//***//
//**************************** SetFlags **********************************//
//***//
void WNT_Window :: SetFlags ( const Standard_Integer aFlags ) {

 myExtraData.dwFlags |= aFlags;

}  // end WNT_Window :: SetFlags
//***//
//*************************** ResetFlags *********************************//
//***//
void WNT_Window :: ResetFlags ( const Standard_Integer aFlags ) {

 myExtraData.dwFlags &= ~aFlags;

}  // end WNT_Window :: ResetFlags
//***//
//*************************** doCreate **********************************//
//***//
void WNT_Window :: doCreate (
                    const Handle( WNT_GraphicDevice )& aDevice,
                    const Aspect_Handle&               aHandle,
                    const Quantity_NameOfColor         aBackColor
                   ) {

 LONG            uData;
 WNDPROC         wProc;
 WINDOWPLACEMENT wp;

 const Handle( WNT_GraphicDevice )& dev = Handle( WNT_GraphicDevice ) ::
                                           DownCast ( MyGraphicDevice );

 ZeroMemory (  &myExtraData, sizeof ( WNT_WindowData )  );

 myHWindow        = aHandle;
 myHParentWindow  = GetParent (  ( HWND )aHandle  );
 myDoubleBuffer   = Standard_False;
 myHPixmap        = NULL;
#ifndef _WIN64
 wProc            = ( WNDPROC )GetWindowLong (  ( HWND )aHandle, GWL_WNDPROC  );
 uData            = GetWindowLong (  ( HWND )aHandle, GWL_USERDATA  );
#else
 wProc            = ( WNDPROC )GetWindowLong (  ( HWND )aHandle, GWLP_WNDPROC  );
 uData            = GetWindowLong (  ( HWND )aHandle, GWLP_USERDATA  );
#endif
 myUsrData        = -1;
 myWndProc        = NULL;

 if ( wProc != &WNT_WndProc ) {

  myWndProc = wProc;

  SetBackground ( aBackColor );

  myExtraData.WNT_Window_Ptr = ( void* )this;
  myExtraData.hPal           = ( HPALETTE )dev -> HPalette ();

  if (  uData != ( LONG )&myExtraData  )

#ifndef _WIN64
   myUsrData = SetWindowLong (  ( HWND )myHWindow, GWL_USERDATA, ( LONG )&myExtraData  );
#else
   myUsrData = SetWindowLong (  ( HWND )myHWindow, GWLP_USERDATA, ( LONG )&myExtraData  );
#endif

  if ( myWndProc != NULL )
  
#ifndef _WIN64
   SetWindowLong (  ( HWND )myHWindow, GWL_WNDPROC, ( LONG )WNT_WndProc  );
#else
   SetWindowLong (  ( HWND )myHWindow, GWLP_WNDPROC, ( LONG )WNT_WndProc  );
#endif

 }  // end if

 myExtraData.dwFlags = WDF_FOREIGN;

 myImages = new WNT_ImageManager ( this );
 myFormat = WNT_TOI_XWD;

 wp.length = sizeof ( WINDOWPLACEMENT );
 GetWindowPlacement (  ( HWND )myHWindow, &wp  );

 aXLeft   = wp.rcNormalPosition.left;
 aYTop    = wp.rcNormalPosition.top;
 aXRight  = wp.rcNormalPosition.right;
 aYBottom = wp.rcNormalPosition.bottom;

}  // end WNT_Window :: doCreate
//***//
//************************************************************************//
