#include "xheaders.h"

#include XFrameWindow_i
#include XResourceLibrary_i
#include XMessageBox_i
#include XResource_i
#include XRect_i
#include XString_i
#include XFrame_i
#include XColor_i
#include XComboBox_i
#include XMultiLineEdit_i
#include XSlider_i
#include XEntryField_i
#include XCheckBox_i
#include XPushButton_i
#include XGraphicButton_i
#include XScrollBar_i
#include XSpinButton_i
#include XListBox_i
#include XCircularSlider_i
#include XGroupBox_i
#include XStaticBitmap_i
#include XStaticIcon_i
#include XStaticText_i
#include XStaticFrame_i
#include XValueSet_i
#include XRadioButton_i
#include XMenuBar_i
#include XFrameWindow_i
#include XContainerControl_i
#include XProcess_i
#include XControlEvent_i
#include XMediaWindow_i
#include XDragHandler_i
#include XDragEvent_i
#include XMouseHandler_i
#include XDefaultHandler_i
#include XMouseEvent_i
#include XContainerEvent_i
#include XContainerHandler_i
#include XKeyboardHandler_i
#include XKeyboardEvent_i
#include XScrollWindow_i
#include XContainerDragEvent_i
#include XContainerEditEvent_i
#include XItemDrawHandler_i
#include XItemDrawEvent_i
#include XBackgroundDrawEvent_i
#include XBackgroundDrawHandler_i
#include XStyleHandler_i

#include <stdlib.h>
#include <string.h>

LONG MAXX =0;
LONG MAXY;
SHORT cxDlgFrame;
SHORT cyDlgFrame;
SHORT cxBorder;
SHORT cyBorder;
SHORT cxSizeBorder;
SHORT cySizeBorder;


long int XFrameWindow::defaultStyle = FRM_TITLEBAR | FRM_SYSMENU | FRM_SIZEBORDER | FRM_MINBUTTON | FRM_MAXBUTTON | FRM_TASKLIST;
long int XFrameWindow::defaultDialogStyle = FRM_TITLEBAR | FRM_SYSMENU | FRM_DIALOGBORDER;
long int XFrameWindow::defaultClientStyle = FRM_BORDER;


MRESULT HandleDefault( XWindow * w, ULONG msg, MPARAM mp1, MPARAM mp2, BOOL& handled)
{
  SHORT i;

  handled = TRUE;
  switch( msg )
    {
       case WM_PRESPARAMCHANGED:
         {
             handled = FALSE;
             for(i=0; i < w->handlers; i++)
                {
                  if( w->regHandlers[i]->GetID() == OOL_STYLEHANDLER)
                     {
                        XStyleHandler * d = (XStyleHandler*) w->regHandlers[i];
                        XEvent evn((LONG) mp1);
                        if( d->HandleEvent( &evn) == TRUE)
                           handled = TRUE;
                        return (MRESULT) handled;
                     }
                }
           }
           break;
       case CM_PAINTBACKGROUND:
          {
             handled = FALSE;
             for(i=0; i < w->handlers; i++)
                {
                  if( w->regHandlers[i]->GetID() == OOL_BACKDRAWHANDLER)
                     {
                        XBackgroundDrawHandler * d = (XBackgroundDrawHandler*) w->regHandlers[i];
                        XBackgroundDrawEvent dev( msg);
                        if( d->HandleEvent( &dev) == TRUE)
                           handled = TRUE;
                        return (MRESULT) handled;
                     }
                }
           }
           break;
       case WM_DRAWITEM:
          {
             handled = FALSE;
             for(i=0; i < w->handlers; i++)
                {
                  if( w->regHandlers[i]->GetID() == OOL_ITMDRAWHANDLER)
                     {
                        XItemDrawHandler * d = (XItemDrawHandler*) w->regHandlers[i];
                        XItemDrawEvent dev( msg, mp1, mp2);
                        if( d->HandleEvent( &dev) == TRUE)
                           handled = TRUE;
                        return (MRESULT) handled;
                     }
                }
           }
           break;
       case WM_BUTTON1DOWN:
       case WM_BUTTON1DBLCLK:
       case WM_BUTTON1CLICK:
       case WM_BUTTON1UP:
       case WM_BUTTON2DOWN:
       case WM_BUTTON2DBLCLK:
       case WM_BUTTON2CLICK:
       case WM_BUTTON2UP:
       case WM_BUTTON3DOWN:
       case WM_BUTTON3DBLCLK:
       case WM_BUTTON3CLICK:
       case WM_BUTTON3UP:
       case WM_BEGINDRAG:
       case WM_MOUSEMOVE:
          {
             handled = FALSE;
             for(i=0; i < w->handlers; i++)
                {
                  if( w->regHandlers[i]->GetID() == OOL_MOUSEHANDLER)
                     {
                        XMouseHandler * d = (XMouseHandler*) w->regHandlers[i];
                        XMouseEvent dev( msg, mp1, mp2);
                        d->HandleEvent( &dev);
                        break;
                     }
                }
           }
           break;
       case WM_CHAR:
           {
             handled = FALSE;
             for(i=0; i < w->handlers; i++)
                {
                  if( w->regHandlers[i]->GetID() == OOL_KEYBHANDLER)
                     {
                        XKeyboardHandler * d = (XKeyboardHandler*) w->regHandlers[i];
//                        XKeyboardEvent dev( SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), CHAR4FROMMP(mp1));
                        XKeyboardEvent dev( SHORT1FROMMP(mp2), SHORT1FROMMP(mp1), CHAR4FROMMP(mp1));
                        if( d->HandleEvent( &dev) == TRUE)
                           handled = FALSE;
                        else
                           handled = TRUE;
                        break;
                     }
                }
           }
           break;
       case DM_DISCARDOBJECT:
       case DM_ENDCONVERSATION:
          {
             char className[5];
             WinQueryClassName(w->GetHandle(), 5, (PCH) className);
             className[0] = ' ';
             SHORT classtype = atol( className );
             XContainerControl  * cd = NULL;
             if( classtype == 37)
                {
                   cd = (XContainerControl*) w;
                   w = w->QueryWindow(QW_PARENT);
                   if(!(w))
                      return FALSE;
                }
             for(i=0; i < w->handlers; i++)
                {
                  if( w->regHandlers[i]->GetID() == OOL_DRAGHANDLER)
                     {
                        XDragHandler * d = (XDragHandler*) w->regHandlers[i];
                        XDragEvent dev(msg, mp1);
                        d->HandleEvent( &dev);
                        return MRFROM2SHORT( dev.accept, dev.operation);
                     }

                  if( w->regHandlers[i]->GetID() == OOL_CONTAINERHANDLER)
                     {
                        XContainerHandler * d = (XContainerHandler*) w->regHandlers[i];
                        if(msg == DM_DISCARDOBJECT)
                           {
                              XContainerDragEvent dev( cd, NULL, NULL);
                              dev.dragInfo = (PDRAGINFO) mp1;
                              dev.window = cd;
                              dev.windowID = WinQueryWindowUShort( cd->GetHandle(), QWS_ID);
                              dev.eventID = msg;
                              d->HandleEvent( &dev);
                           }
                        else
                           {
                              XContainerEvent dev( cd, mp1, mp2);
                              dev.eventID = msg;
                              handled = TRUE;
                              return (MRESULT) d->HandleEvent( &dev);
                           }
                     }
                }
          }
          return FALSE;
       case DM_DROP:
       case DM_DRAGOVER:
          {
             for(i=0; i < w->handlers; i++)
                {
                  if( w->regHandlers[i]->GetID() == OOL_DRAGHANDLER)
                     {
                        XDragHandler * d = (XDragHandler*) w->regHandlers[i];
                        XDragEvent dev(msg, mp1);
                        d->HandleEvent( &dev);
                        return MRFROM2SHORT( dev.accept, dev.operation);
                     }
                }
             handled = FALSE;
          }
          return FALSE;
       case WM_MOVE:
          handled = FALSE;  //neu
          w->DoMove();
          break;
       case WM_SIZE:
          w->DoSize();
          handled = FALSE;
          return 0;
       case WM_DESTROY:
          return 0;
       case WM_FOCUSCHANGE:
          w->FocusChanged( SHORT1FROMMP(mp2));
          handled = FALSE;
          break;
       case WM_PAINT:
            w->Draw();
            handled = FALSE;
            break;
       default:
          {
             handled = FALSE;
             for(i=0; i < w->handlers; i++)
                {
                  if( w->regHandlers[i]->GetID() == OOL_DEFAULTHANDLER)
                     {
                        XDefaultHandler * d = (XDefaultHandler*) w->regHandlers[i];
                        d->HandleEvent( msg, mp1, mp2);
//                        return (MRESULT) handled;
                     }
                }
           }
           handled = FALSE;
           break;
    }
  return FALSE;
}


void XFrameWindow :: DoControl( XControlEvent*)
{
}

MRESULT HandleFrameDefault( XFrameWindow * w, ULONG msg, MPARAM mp1, MPARAM mp2, BOOL& handled)
{
   handled = TRUE;

   switch( msg )
      {
         case WM_PAINT:
            w->Draw();
            handled = FALSE;
            break;

/*
        case WM_MENUEND:
           {
              XMenu * m = (XMenu*) WinQueryWindowULong( (HWND) mp2, 0);
              if(m )
                 {
                    if(m->IsPopup())
                       {
                          delete m;
                          WinSetWindowULong( (HWND) mp2, 0, 0);
                       }
                 }
           }
           return 0;
*/
        case WM_INITMENU:
          {
             XMenu * menu = (XMenu*) WinQueryWindowPtr( (HWND) mp2, 0);
             w->InitMenu( menu );
             handled = FALSE;
          }
          return 0;
       case WM_CONTROL:
          switch( SHORT2FROMMP(mp1) )
             {
                case CN_ENTER:
                case CN_CONTEXTMENU:
                case CN_DRAGOVER:
                case CN_INITDRAG:
                case CN_DROP:
                case CN_BEGINEDIT:
                case CN_EMPHASIS:
                case CN_ENDEDIT:
                   {
                      SHORT i, ms = SHORT2FROMMP(mp1);
                      for(i=0; i < w->handlers; i++)
                        {
                           if( w->regHandlers[i]->GetID() == OOL_CONTAINERHANDLER)
                             {
                                XContainerHandler * d = (XContainerHandler*) w->regHandlers[i];
                                if( ms == CN_DRAGOVER || ms == CN_DROP )
                                   {
                                      XContainerDragEvent dev( w, mp1, mp2);
                                      d->HandleEvent( &dev);
                                      return MRFROM2SHORT( dev.accept, dev.operation);
                                   }
                                if( ms == CN_BEGINEDIT || ms == CN_ENDEDIT )
                                   {
                                       XContainerEditEvent dev(w, mp1, mp2);
                                       if( d->HandleEvent( &dev) == TRUE)
                                          handled = TRUE;
                                       return 0;
                                   }
                                else
                                   {
                                       XContainerEvent dev(w, mp1, mp2);
                                       if( d->HandleEvent( &dev) == TRUE)
                                          handled = TRUE;
                                       return 0;
                                   }
                             }
                        }
                   }
                   break;
                default:
                   {
                      //XControl * c = (XControl*) w->GetWindow( SHORT1FROMMP(mp1));
                      XControlEvent e(w, mp1, mp2);
                      handled = FALSE;
                   }
             }
          return 0;
       case WM_CLOSE:
          if( w->QueryForClose() == TRUE)
             delete w;
          return 0;
       case MEDIA_NOTIFY:
          {
             XControlEvent evn( SHORT2FROMMP(mp1));
             w->DoControl( &evn);
          }
          return 0;
       case WM_COMMAND:
          w->DoCommand( SHORT1FROMMP(mp1));
          return 0;
       case WM_HELP:
          if( SHORT1FROMMR( WinSendMsg( WinQueryHelpInstance(w->frame), HM_DISPLAY_HELP , MPFROM2SHORT( WinQueryWindowUShort(WinQueryFocus(HWND_DESKTOP), QWS_ID), NULL), MPFROMSHORT(HM_RESOURCEID))) != 0)
             {
               if( w->dlgHandle )
                  WinSendMsg( WinQueryHelpInstance(w->frame), HM_DISPLAY_HELP , MPFROM2SHORT( WinQueryWindowUShort(w->dlgHandle, QWS_ID), NULL), MPFROMSHORT(HM_RESOURCEID));
               else
                  WinSendMsg( WinQueryHelpInstance(w->frame), HM_DISPLAY_HELP , MPFROM2SHORT( WinQueryWindowUShort(w->winhandle, QWS_ID), NULL), MPFROMSHORT(HM_RESOURCEID));
             }
          return 0;
       case WM_SIZE:
          if( w->dlgHandle )
             WinSetWindowPos( w->dlgHandle, 0, 0,0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_SIZE);
          w->DoSize();
          return 0;
        default:
           handled = FALSE;
           break;
     }
  return HandleDefault( w, msg, mp1, mp2, handled);
}


MRESULT EXPENTRY WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
   XFrameWindow * w;

   if(msg == WM_CREATE )
     {
        w = (XFrameWindow*) mp1;
        WinSetWindowPtr( hwnd, 0, w);
        mp1 = NULL;
        return WinDefWindowProc( hwnd, msg, mp1, mp2);
     }
   else
      w = ( XFrameWindow*) WinQueryWindowPtr(hwnd, 0);

   if( w)
      {
         if(w->enabled == FALSE && msg != WM_PAINT && msg != WM_CONTROLPOINTER && msg != WM_DRAWITEM && msg != WM_ERASEBACKGROUND && msg != WM_QUERYBORDERSIZE)
            return 0;
         w->HandleMessage( msg, mp1, mp2);
         BOOL handeld = FALSE;
         MRESULT mr = HandleFrameDefault( w, msg, mp1, mp2, handeld);
         if( handeld )
            return mr;
         return WinDefWindowProc( hwnd, msg, mp1, mp2);
      }
   else
      return WinDefWindowProc( hwnd, msg, mp1, mp2);
}


MRESULT EXPENTRY DProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
  XFrameWindow * w = (XFrameWindow*) WinQueryWindowPtr(hwnd, 0);

  if(w )
   {
      if( w->enabled == FALSE && msg != WM_PAINT && msg != WM_CONTROLPOINTER && msg != WM_DRAWITEM && msg != WM_ERASEBACKGROUND && msg != WM_QUERYBORDERSIZE)
         return 0;

      BOOL handeld = FALSE;
      MRESULT mr = HandleFrameDefault( w, msg, mp1, mp2, handeld);
      if( handeld )
         return mr;
   }
  return WinDefDlgProc(hwnd, msg, mp1, mp2);
}


/*DOC
CLASS XFrameWindow
FUNCTION Activate
GROUP display a window
REMARKS The window will be activated.
Parameters: -
*/
void XFrameWindow :: Activate( void )
{
   WinSetActiveWindow( HWND_DESKTOP, frame);
}



/*
LONG XFrameWindow :: GetClientHandle( void )
{
  return (LONG) (dlgHandle ? dlgHandle : winhandle );
}
*/

/*DOC
CLASS XFrameWindow
FUNCTION ~XFrameWindow
GROUP constructors/destructors
REMARKS Destructors of windows are called automaticaly when the window is closed.
The destructor of XFrameWindow calles the destructor of every client window, meus and
toolbars. Also the destructors of handlers (derived classes of XHandler) which are
attached with it are called. If the last XFrameWindow of a process is closed, the process
will terminate.
If you want to close a window yourself, destruct the window with delete.

Parameters: -
*/
XFrameWindow :: ~XFrameWindow()
{
   HWND hwnd;
   HENUM enumWindow;

   if(lockingWin)
     {
        lockingWin->enabled = TRUE;
        lockingWin->Enable();
        lockingWin = NULL;
     }

   WinSetWindowPtr( frameWin->winhandle, 0, NULL);
   WinSetWindowPtr( winhandle, 0, NULL);

   hwnd = WinWindowFromID(frame, FID_MENU);
   XMenuBar * m = (XMenuBar*) WinQueryWindowPtr( hwnd, 0);
   if( m )
      delete m;

   if(dlgHandle )
      {
         enumWindow = WinBeginEnumWindows(dlgHandle);
         while( (hwnd = WinGetNextWindow( enumWindow)) != 0)
            {
                XWindow * w = (XWindow *) WinQueryWindowPtr( hwnd, 0);
                if( w )
                   delete w;
            };
         WinEndEnumWindows( enumWindow);
         WinDismissDlg( dlgHandle, 1);
         WinDestroyWindow( dlgHandle );
      };

   enumWindow = WinBeginEnumWindows(winhandle);
   char str[5];
   while( (hwnd = WinGetNextWindow( enumWindow)) != NULLHANDLE)
      {
         XWindow * w = (XWindow *) WinQueryWindowPtr( hwnd, 0);
         if(w && w!=this)
            {
              WinQueryClassName( hwnd, 5, (PCH) str);
              if( strcmp(str, "#1") == 0)
                 {
                    XFrame * f = (XFrame*) w;
                    if(f->frame)
                       delete f->frame;
                    else
                       delete f;
                 }
              else
                  delete w;
            }
      };
   WinEndEnumWindows( enumWindow);

   XProcess * p = (XProcess*) WinQueryWindowULong( winhandle, 4);
   p->RemoveWindow( this ); //test

   delete frameWin;

   if(clientWindow)
      delete clientWindow;

   WinDestroyWindow( frame );
}


/*DOC
CLASS XFrameWindow
FUNCTION InitMenu
GROUP displaying a window
REMARKS If a menu must be initialized this function is called. If you
want to setup the menu dynamicaly, override this function.

Parameters:   XMenu * theMenu
*/
void XFrameWindow :: InitMenu( XMenu *)
{ ;}


/*DOC
CLASS XFrameWindow
FUNCTION DoCommand
GROUP user input
REMARKS If the user selected a menuitem (from XMenuBar or XPopupMenu) if the
user pressed a button of a toolbar which is attached to it the framewindow, this function
is called. To get the ID of the action the user requested, override this function.

Parameters:   LONG theCommandID    the ID of the menuitem/toolbar-button
*/
void XFrameWindow :: DoCommand( LONG)
{ ;}


/*DOC
CLASS XFrameWindow
FUNCTION Draw
GROUP drawing a window
REMARKS This function is called if a window or a part of it must be redrawn.
If you use a window which is not created from a resource template or you dontīt
have set a client with SetClient(), you must override this function and call
FillBackground().
Parameters: -
*/
void XFrameWindow :: Draw ( void )
{ ;}


/*DOC
CLASS XFrameWindow
FUNCTION GetHandle
REMARKS GetHandle returns the window-handle defined by the operating system. The handle is different
from the ID of the window and the pointers used by the OOL. In XFrameWindow the function returns:
1. if you have set a client window with function SetClient() the handle of the client
2. if the XFrameWindow displays a resource-defined window, the resource window handle is returned
3. on default, the handle of the client-rect is returned

Parameters:    -
Returns:       OOL_WINDOWHANDLE  theSystemHandle
*/
OOL_WINDOWHANDLE XFrameWindow :: GetHandle()
{
  if( clientWindow )
     return clientWindow->winhandle;
  return dlgHandle ? dlgHandle : winhandle;
}


/*DOC
CLASS XFrameWindow
FUNCTION Enable
GROUP displaying a window
REMARKS enables/disables a window for user-input

Parameters:    BOOL enable     enables/disables the window (default is TRUE)
*/
void XFrameWindow :: Enable( BOOL enable)
{
   WinEnableWindow(frame, enable);
}


/*DOC
CLASS XFrameWindow
FUNCTION EnableWindowUpdate
GROUP drawing a window
REMARKS This function can stop drawing the window contents until you allow drawing.
For complex windows there can be some performance-advantages.
WARNING: If you disable drawing of a window and attach a XToolBar to it, the position
and size of the toolbar can not set correctly.
Parameters:    BOOL enable    enable/disable window drawing (default is TRUE)
*/
void XFrameWindow :: EnableWindowUpdate ( BOOL enable )
{
   WinEnableWindowUpdate( winhandle, enable);
}


/*DOC
CLASS XFrameWindow
FUNCTION FillBackground
GROUP drawing a window
REMARKS FillBackground fills the background in the color you have set with
SetBackgroundColor (default is black). Usualy you call this function when
you have overridden Draw(). You donīt have to call this function if a resource defined
window is displayed or a window is set as client with SetClient().

Parameters: -
*/
void XFrameWindow :: FillBackground( void )
{
  RECTL rec;
  HPS hps = WinBeginPaint( winhandle, NULLHANDLE, &rec);
  GpiCreateLogColorTable( hps, LCOL_RESET, LCOLF_RGB, 0, 1, &backCol);
  WinFillRect(hps, &rec, (LONG) backCol);
  WinEndPaint( hps);
}


/*DOC
CLASS XFrameWindow
FUNCTION SetBackgroundColor
GROUP drawing a window
REMARKS With this function you set the color wich is used to fill the
background in FillBackground(). Default color is black.

Parameters: XColor * theNewColor
*/
void XFrameWindow :: SetBackgroundColor( XColor * col)
{
   memcpy(&backCol,col->color, 4);
   if( dlgHandle)
      WinSetPresParam( dlgHandle, PP_BACKGROUNDCOLOR, 4, &backCol);
}


/*DOC
CLASS XFrameWindow
FUNCTION GetText
GROUP text input/output
REMARKS

Parameters:    XString * theBuffer       theBuffer will contain the title of the window
Returns:       LONG                      the length of the text
*/
LONG XFrameWindow :: GetText( XString * buffer )
{
   SHORT r = WinQueryWindowTextLength( frame);
   WinQueryWindowText( frame, r+1, (PCH) buffer->GetBuffer( r + 1));
   buffer->ReleaseBuffer();
   return r;
}


/*DOC
CLASS XFrameWindow
FUNCTION Hide
GROUP display a window
REMARKS Hide the window
Parameters: -
*/
void XFrameWindow :: Hide(void)
{
   WinSetWindowPos(frame, 0,0,0,0,0, SWP_HIDE);
}


/*DOC
CLASS XFrameWindow
FUNCTION SetBottom
GROUP display a window
REMARKS Set the window to the bottom (in z-order)
Parameters: -
*/
void XFrameWindow :: SetBottom(void)
{
   WinSetWindowPos(frame, HWND_BOTTOM, 0,0,0,0, SWP_ZORDER);
}


/*DOC
CLASS XFrameWindow
FUNCTION SetIcon
REMARKS Set the icon which is displayed in the button of the system menu.

Parameters:    OOL_ICONHANDLE theNewIcon
*/
void XFrameWindow :: SetIcon( LONG iconHandle)
{
   WinSendMsg( frame, WM_SETICON, MPFROMP( iconHandle), 0);
}


/*DOC
CLASS XFrameWindow
FUNCTION SetText
GROUP text input/output
REMARKS Set the Text which is displayed in the titlebar

Parameters:    XString * theNewText
*/
void XFrameWindow :: SetText(const char * buffer)
{
   WinSetWindowText(frame, (PSZ) buffer);
}


/*DOC
CLASS XFrameWindow
FUNCTION SetTop
GROUP display a window
REMARKS Set the window to the top (in z-order)
Parameters: -
*/
void XFrameWindow :: SetTop(void)
{
   WinSetWindowPos(frame, HWND_TOP, 0,0,0,0, SWP_ZORDER);
}


/*DOC
CLASS XFrameWindow
FUNCTION Show
GROUP display a window
REMARKS Displayes a window. The window wil be activated an be shown at the topmost position
(in z-order). If the window is minimized the old position and size will be restored.
Parameters: -
*/
void XFrameWindow :: Show(void)
{
   WinSetWindowPos(frame, HWND_TOP,0,0,0,0, SWP_SHOW|SWP_ZORDER|SWP_ACTIVATE|SWP_RESTORE);
}


/*DOC
CLASS XFrameWindow
FUNCTION SetClient
REMARKS SetClient is used to set a window, for example a control like a XMultiLineEdit,
as a clientwindow of the XFrameWindow so sizing, moving and painting is automaticaly done.
Parameters: XWindow * theNewClient
*/
void XFrameWindow :: SetClient( XWindow * c)
{
   if(frameWin)
      frameWin->adds += 1;
   WinSetOwner( c->winhandle, frame);
   WinSetParent( c->winhandle, frame, FALSE);
   clientWindow = c;
   SWP swp;
   WinQueryWindowPos( winhandle, &swp);
   WinSetWindowPos( c->winhandle, 0, swp.x, swp.y, swp.cx, swp.cy, SWP_SIZE|SWP_MOVE|SWP_SHOW);
}


/*DOC
CLASS XFrameWindow
FUNCTION QueryProcess
REMARKS returns a pointer to the owning process (XApplication or XThread) of this window.
*/
XProcess * XFrameWindow :: QueryProcess( void )
{
   return (XProcess*) WinQueryWindowULong( winhandle, 4);
}


/*DOC
CLASS XFrameWindow
FUNCTION XFrameWindow
GROUP constructors/destructors
REMARKS construct a frame-window
Note that destructors of windows are called automaticaly when a window is closed! (see ~XFrameWindow)

Parameters: XResource * theResourceID   a XResource contains two informations, an ID and a pointer
                                        to a XResourceLibrary. If you want to create a window out of
                                        a resourcefile you must specify the ID (otherwise it can be zero)
                                        and the XResourceLibrary which contains the window-resource.
                                        The window which is created always belongs to the process who
                                        owns the resource library, so if you work with multiple processes
                                        every process must have its own resource library.
            char * theTitle             The title of the window which is displayed in the titlebar
            ULONG theStyleofWindow      You can specify the style of the window with the following defines,
                                        which can be or-ed:

                                           FRM_TITLEBAR     the window gets a titlebar
                                           FRM_SYSMENU      the window gets the system menu
                                           FRM_MINBUTTON    the titlebar get a button to minimize the window
                                           FRM_MAXBUTTON    the titlebar get a button to maximize the window

                                           FRM_CENTER       the window is created in the midle of the workplace

                                           FRM_SIZEBORDER   the windowsize can be changed by the user
                                           FRM_DIALOGBORDER the window gets a thick border
                                           FRM_BORDER       the window gets a thin border

                                           FRM_TASKLIST     the window is displayed in the tasklist

                                           FRM_NOMOVEWITHOWNER  the window dontīt move when the parent is moved
                                           FRM_ICON         the window get an icon wich is identified by theResourceID,
                                                            if the icon is not found in the resource-library, an error ocurses
                                           FRM_ACCELTABLE
                                           FRM_SYSMODAL     the window is displayed system-modal
                                           FRM_SCREENALIGN
                                           FRM_MOUSEALIGN
                                           FRM_HIDEBUTTON
                                           FRM_HIDEMAX
                                           FRM_AUTOICON


                                        there are three static member-variables for default styles

                                           long defaultStyle          default setting for a framewindow
                                           long defaultClientStyle    default setting for windows wich are displayed as a clientwindow of a framewindow
                                           long defaultDialogStyle    default setting for windows wich are displayed as a dialog

                                        Default is defaultStyle.
            XRect * theRectangle        On default a window is created with length and hight of zero. Windows
                                        which are created with an resource template get the size of the template.
                                        Default is NULL.
                                        If theRectangle is specified, the window gets the size of it.
            XFrameWindow * parent       If parent is specified the window is a client of the parent. The
                                        behavior depends on the styles you have set.
                                        Default is NULL.
            BOOL buildFromResource      If this variable is set OOL try to build the window with a resource
                                        template which is identified by theResourceID. If the template is
                                        not found, an error ocurses.
                                     Default is FALSE.
*/
XFrameWindow :: XFrameWindow( XResource * id,
                  const char * title,
                  ULONG style,
                  XRect * rec,
                  XFrameWindow * parent,
                  BOOL build)
{
   HWND client, p = parent ? parent->winhandle : HWND_DESKTOP;
   HAB hab = 0;
   HMODULE handler = 0;
   SHORT resId = 0;
   SWP swp;
   static BOOL frameRegistered = FALSE;
   LONG xRight = 0, yBottom = 0;

   memset( &swp, 0, sizeof(SWP));

   frame = 0;
   clientWindow = NULL;
   vert = horz = NULL;
   lockingWin = NULL;

   if(MAXX == 0)
      {
         MAXX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
         MAXY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
         cxDlgFrame = WinQuerySysValue( HWND_DESKTOP, SV_CXDLGFRAME);
         cyDlgFrame = WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME);
         cxBorder = WinQuerySysValue( HWND_DESKTOP, SV_CXBORDER);
         cyBorder = WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER);
         cxSizeBorder = WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER);
         cySizeBorder = WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER);
      }

   enabled = TRUE;
   dummy = 0;

   hab = id->library->proc->hab;
   handler = id->library->moduleHandle;
   resId = id->id;

   if( frameRegistered == FALSE)
     {
        frameRegistered = TRUE;
        if( WinRegisterClass( hab, (PSZ) "OOL_FRAMEWND", (PFNWP) WindowProc, CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT, 8) == FALSE)
            XMessageBox( "registration failed");
     }

   backCol = 0;
   dlgHandle = 0;

   FRAMECDATA fcmd;
   fcmd.cb = sizeof(fcmd);
   fcmd.flCreateFlags = style | FCF_NOBYTEALIGN;
   fcmd.hmodResources = handler;
   fcmd.idResources = resId;

   frame = WinCreateWindow(p, WC_FRAME, (PSZ) title, 0, 0, 0, 0, 0, p, HWND_TOP, resId, &fcmd, NULL);
   winhandle = WinCreateWindow(frame, (PSZ) "OOL_FRAMEWND", (PSZ) "", WS_CLIPCHILDREN, 0, 0, 0, 0, frame,
                         HWND_TOP, FID_CLIENT, this, NULL);

   if(frame==0)
      XMessageBox( "no framewindow", "debug");

   WinSetWindowULong( winhandle, 4, (LONG) id->library->proc);

   frameWin = new XFrame( this );
/*
   frameWin->frame = this;
   WinSetWindowULong( frame, QWL_USER, (LONG) frameWin);
*/
   if( build)
     {
        XWindow * du;
        XColor col(COL_PALEGRAY);
        SetBackgroundColor( &col);
        dlgHandle = WinLoadDlg( winhandle, winhandle, (PFNWP) DProc, id->library->moduleHandle, id->id, NULL);
        WinSetWindowPtr( dlgHandle, 0, this);

        HWND hwnd;
        char className[50];
        SHORT classtype;
        HENUM enumWindow = WinBeginEnumWindows(dlgHandle);

        while( (hwnd = WinGetNextWindow( enumWindow)) != 0)
          {
             WinQueryClassName(hwnd, 50, (PCH) className);
             className[0] = ' ';
             classtype = atol( className );
             switch ( classtype)
               {
                 case 1:                                                    //Frame
                    du = new XFrame( hwnd ); break;
                 case 2:                                                    //Combobox
                    du = new XComboBox( hwnd ); break;
                 case 3:                                                    //Button
                   {
                      ULONG style = WinQueryWindowULong( hwnd, QWL_STYLE);
                      if(style & BS_AUTOCHECKBOX)
                         du = new XCheckBox( hwnd );                        //CheckBox
                      else
                        {
                           if(style & BS_AUTORADIOBUTTON)                   //RadioButton
                              du = new XRadioButton( hwnd );
                           else
                              du = new XPushButton( hwnd );                 //PushButton
                        }
                    }
                    break;
                 case 4:                                                    //Menu
                   du = new XMenuBar( hwnd ); break;
                 case 5:                                                    //Static
                   {
                      ULONG style = WinQueryWindowULong( hwnd, QWL_STYLE);
                      if(style & SS_GROUPBOX)
                        du = new XGroupBox( hwnd );
                      if(style & SS_TEXT)
                        du = new XStaticText( hwnd );
                      if(style & SS_ICON)
                        du = new XStaticIcon( hwnd );
                      if(style & SS_BITMAP)
                        du = new XStaticBitmap( hwnd );
                    }
                    break;
                 case 6:                                                    //EntryField
                    du = new XEntryField( hwnd ); break;
                 case 7:                                                    //Listbox
                    du = new XListBox( hwnd ); break;
                 case 8:                                                    //ScrollBar
                    du = new XScrollBar( hwnd ); break;
                 case 10:                                                   //MLE
                    du = new XMultiLineEdit( hwnd ); break;
                 case 32:                                                   //SpinButton
                    du = new XSpinButton( hwnd ); break;
                 case 37:                                                   //Container
                    du = new XContainerControl( hwnd ); break;
                 case 38:                                                   //Slider
                    du = new XSlider( hwnd ); break;
                 case 39:                                                   //ValueSet
                    du = new XValueSet( hwnd ); break;
                 case 40:                                                   //Notebook
                    { }
                 case 64:                                                   //GraphicButton
                    du = new XGraphicButton( hwnd ); break;
                 case 65:                                                   //CircularSlider
                    du = new XCircularSlider( hwnd ); break;
             }
         }
       WinEndEnumWindows( enumWindow);

       SHORT x = 0, y = 0;

       if( style & FCF_TITLEBAR)
          y = WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR);
       if( style & FCF_DLGBORDER)
         {
            x = cxDlgFrame;
            y += cyDlgFrame;
         }
       if( style & FCF_SIZEBORDER)
         {
            x = cxBorder;
            y += cyBorder;
         }
       if( style & FCF_BORDER)
         {
            x = cxSizeBorder;
            y += cySizeBorder;
         }

       x += x;

       WinQueryWindowPos( dlgHandle, &swp);
       WinSetWindowPos( dlgHandle, 0, 0,0, 0, 0, SWP_MOVE|SWP_SHOW);
       swp.cx+=x;
       swp.cy+=y;

    }
   else
      {
         if( rec )
            {
               swp.cx = rec->GetWight();
               swp.cy = rec->GetHight();
            }
      }

   if( style & FRM_CENTER)
     {
         if(dlgHandle)
            {
               xRight = MAXX / 2 - swp.cx / 2;
               yBottom = MAXY / 2- swp.cy / 2;
            }
         else
            {
               if(rec)
                  {
                     xRight = MAXX / 2 - rec->GetWight() / 2;
                     yBottom = MAXY / 2- rec->GetHight() / 2;
                  }
            }
     }
   else
     {
         if( rec )
            {
               xRight = rec->GetX();
               yBottom = rec->GetY();
            }
      }

   WinSetWindowPos( frame, HWND_TOP, xRight, yBottom, swp.cx, swp.cy, SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);

   id->library->proc->AddWindow( this );
}


/*DOC
CLASS XFrameWindow
FUNCTION ShowModal
GROUP display a window
REMARKS ShowModal displays a window modal for another window which is specified in the first parameter,
that means that the user cannot perform any input with the specified window.
WARNING: you should only use this function for windows which are constructed with a resource template!
If you do so the operating system stops with executing the calling code until the window is closed,
otherwise the calling code is executed while the window is displayed.

Parameters: XFrameWindow * theOwnerWindow   the window which is disabled until this window is closed
*/
void XFrameWindow :: ShowModal( XFrameWindow * w )
{
   if(!w)
      return;

   lockingWin = w;
   w->Enable( FALSE);
   w->enabled = FALSE;

   if( dlgHandle)
      WinProcessDlg( dlgHandle);
}


/*DOC
CLASS XFrameWindow
FUNCTION SetSize
GROUP sizing of a window
REMARKS Set the size and/or position of a window

Parameters:    XRect * theNewSize
*/
void XFrameWindow :: SetSize( XRect * rect )
{
   WinSetWindowPos( frame, 0, rect->x, rect->y, rect->cx, rect->cy, SWP_SHOW|SWP_MOVE|SWP_SIZE);
}


/*DOC
CLASS XFrameWindow
FUNCTION GetSize
GROUP sizing of a window
REMARKS Get the size and position of a window

Parameters:    XRect * theSizeAndPosition
*/
void XFrameWindow :: GetSize( XRect * rect)
{
   SWP swp;
   WinQueryWindowPos( frame, &swp);
   rect->x = swp.x;
   rect->y = swp.y;
   rect->cx = swp.cx;
   rect->cy = swp.cy;
}


/*DOC
CLASS XFrameWindow
FUNCTION GetClientSize
GROUP sizing of a window
*/
void XFrameWindow :: GetClientSize( XRect * rect)
{
   XWindow :: GetSize( rect );
}


/*DOC
CLASS XFrameWindow
FUNCTION GetWindow
REMARKS With GetWindow you can get a pointer of a window wich is created when the XFrameWindow
is constructed with a resource template.
Also you can get a pointer to windows which are created dynamicaly if you have specified an
ID in the constructors of these windows. In this case you donīt need to store the pointers
in your program.

Parameters:    ULONG theWindowID      the ID of the client window
Returns:       XWindow * thePointer   the pointer to the window you have asked for. If you
                                      know the type of the window, you can make a typcast to
                                      the needed class.
*/
XWindow * XFrameWindow :: GetWindow( ULONG id )
{
   XWindow * win;
   HWND w = ( dlgHandle ? dlgHandle : winhandle);
   HWND hwnd = WinWindowFromID( w, id);
   win = (XWindow *) WinQueryWindowPtr( hwnd, 0);
   if( win )
      return win;
   if( clientWindow )
      {
         if( WinQueryWindowUShort(clientWindow->winhandle, QWS_ID) == id)
            return clientWindow;
      }
   return NULL;
}


/*DOC
CLASS XFrameWindow
FUNCTION QueryForClose
REMARKS If the user try to close a XFrameWindow this function is called. If you want
to check if the window can be closed or not or to perform a security-check (for example
with XMessageBox), override this function. This function is not called if you destroy
the window with delete.

Parameters:    -
Returns:       BOOL canBeClosed    return TRUE if the window can be closed, otherwise
                                   return FALSE
*/
BOOL XFrameWindow :: QueryForClose( void )
{
   return TRUE;
}

