home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / OWL1.PAK / WINDOW.CPP < prev    next >
Text File  |  1995-08-29  |  19KB  |  615 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2.  
  3. /* --------------------------------------------------------
  4.   WINDOW.CPP
  5.   Defines type TWindow.  This defines the basic behavior
  6.   of all windows.
  7.   -------------------------------------------------------- */
  8.  
  9. #include <string.h>
  10. #include <alloc.h>
  11. #include "applicat.h"
  12. #include "window.h"
  13.  
  14. __link(RegScroller)
  15.  
  16. extern PTWindowsObject CreationWindow;
  17. extern PTWindowsObject DlgCreationWindow;
  18.  
  19. extern PTWindowsObject GetObjectPtr(HWND);
  20.  
  21. #ifdef WIN31
  22. extern long FAR PASCAL _export
  23.      InitWndProc(HWND, UINT, WPARAM, LPARAM);
  24. #endif
  25.  
  26. #ifdef WIN30
  27. extern LONG FAR PASCAL _export
  28.      InitWndProc(HWND_30, WORD, WORD, LONG);
  29. #endif
  30.  
  31. /* Constructor for a TWindow.  Initializes its data fields using passed
  32.   parameters and default values. */
  33. TWindow::TWindow(PTWindowsObject AParent, LPSTR ATitle, PTModule AModule)
  34.         : TWindowsObject(AParent, AModule)
  35. {
  36.   Title = _fstrdup(ATitle ? ATitle : "");
  37.   DefaultProc = (WNDPROC)DefWindowProc;
  38.   if ( !AParent )
  39.     Attr.Style = WS_OVERLAPPEDWINDOW;
  40.   else
  41.     if ( AParent->IsFlagSet(WB_MDIFRAME) )
  42.     {
  43.       /* Set WB_MDICHILD by default, change this if you want a
  44.          non-mdi child as a child of your TMDIFrame window. */
  45.       SetFlags(WB_MDICHILD, TRUE);
  46.       Attr.Style = WS_CLIPSIBLINGS;
  47.     }
  48.     else
  49.       Attr.Style = WS_VISIBLE;
  50.   Attr.ExStyle = 0;
  51.   Attr.X = CW_USEDEFAULT;
  52.   Attr.Y = 0;
  53.   Attr.W = CW_USEDEFAULT;
  54.   Attr.H = 0;
  55.   Attr.Param = NULL;
  56.   Attr.Menu = NULL;
  57.   Attr.Id = 0;
  58.   Scroller = NULL;
  59.   FocusChildHandle = 0;
  60. }
  61.  
  62. /* Constructor for a TWindow which is being used in a DLL as an alias
  63.    for a non-OWL window */
  64. TWindow::TWindow(HWND AnHWindow, PTModule AModule) :
  65.          TWindowsObject((PTWindowsObject)NULL, AModule)
  66. {
  67.   HWND HParent;
  68.   RECT WndRect;
  69.  
  70.   HWindow = AnHWindow;
  71.  
  72.   int TitleLength = GetWindowTextLength(AnHWindow);
  73.   if (TitleLength > -1)
  74.   {
  75.       Title = (LPSTR)farmalloc((unsigned long)TitleLength + 1);
  76.       Title[0] = '\0'; Title[TitleLength] = '\0';
  77.       GetWindowText(AnHWindow, Title, TitleLength+1);
  78.   }
  79.   else
  80.       Title = _fstrdup("");
  81.  
  82.   DefaultProc = (WNDPROC) SetWindowLong(AnHWindow, GWL_WNDPROC,
  83.                                           (DWORD)GetInstance());
  84.  
  85.   // Note that the following two lines are not guaranteed to exactly
  86.   // reconstruct the original Style and ExStyle values passed to
  87.   // CreateWindow or CreateWindowEx.  This is because some controls
  88.   // (e.g. EDIT) modify their style bits (e.g. WS_BORDER) when they
  89.   // are being created.
  90.  
  91.   Attr.Style = GetWindowLong(AnHWindow, GWL_STYLE);
  92.   Attr.ExStyle = GetWindowLong(AnHWindow, GWL_EXSTYLE);
  93.  
  94.   HParent = GetParent(AnHWindow);
  95.   GetWindowRect(AnHWindow, &WndRect);
  96.   Attr.H = WndRect.bottom - WndRect.top;
  97.   Attr.W = WndRect.right - WndRect.left;
  98.   if ( HParent && ((Attr.Style & WS_CHILD) == WS_CHILD) )
  99.     ScreenToClient(HParent, (LPPOINT)&WndRect);
  100.   Attr.X = WndRect.left;
  101.   Attr.Y = WndRect.top;
  102.   Attr.Param = NULL;
  103.   Attr.Menu = NULL;
  104.   Attr.Id = GetWindowWord(AnHWindow, GWW_ID);
  105.  
  106.   Scroller = NULL;
  107.   FocusChildHandle = 0;
  108.   SetFlags(WB_ALIAS, TRUE);
  109. }
  110.  
  111. /* Destructor for a TWindow.  Disposes of its Scroller if the TScroller
  112.   object was constructed. */
  113. TWindow::~TWindow()
  114. {
  115.   if ( Scroller )
  116.   {
  117.     delete Scroller;
  118.     Scroller = NULL;
  119.   }
  120.   if ( HIWORD(Attr.Menu) )
  121.     farfree(Attr.Menu);
  122. }
  123.  
  124. /* If Attr.Menu currently points to a string then free it. Set Attr.Menu to
  125.    the passed parameter. If the window has been created then load and
  126.    set the new menu and destroy the old one. The return value is FALSE
  127.    if SetMenu is called and fails, TRUE otherwise.  Note that this function
  128.    is declared virtual, but may be called from constructors of classes
  129.    derived from TWindow.  In C++, virtual functions called from constructors
  130.    are called as though they were non-virtual.  Care must be taken when
  131.    redefining AssignMenu in derived classes. */
  132. BOOL TWindow::AssignMenu(LPSTR MenuName)
  133. {
  134.   BOOL ReturnVal = TRUE;
  135.   HMENU NewHMenu;
  136.   HMENU OldHMenu;
  137.   LPSTR TempMenuName = NULL;    // handle case where MenuName==Attr.Menu
  138.  
  139.   if ( HIWORD(Attr.Menu) )
  140.       TempMenuName = Attr.Menu;
  141.  
  142.   if ( HIWORD(MenuName) )   // Not NULL and not an int in disguise
  143.     Attr.Menu = _fstrdup(MenuName);
  144.   else
  145.     Attr.Menu = MenuName;
  146.  
  147.   if (TempMenuName)
  148.       farfree(TempMenuName);
  149.  
  150.   if ( HWindow )
  151.   {
  152.     OldHMenu = GetMenu(HWindow);
  153.     NewHMenu = LoadMenu(GetModule()->hInstance, Attr.Menu);
  154.     ReturnVal = SetMenu(HWindow, NewHMenu);
  155.     if ( OldHMenu )
  156.       DestroyMenu(OldHMenu);
  157.   }
  158.   return ReturnVal;
  159. }
  160.  
  161. BOOL TWindow::AssignMenu(int MenuId)
  162. {
  163.   return AssignMenu((LPSTR)MAKEINTRESOURCE(MenuId));
  164. }
  165.  
  166.  
  167. /* Specifies registration attributes for the MS-Windows window
  168.    class of the TWindow, allowing instances of TWindow to be
  169.    registered.  Sets the fields of the passed WNDCLASS parameter
  170.    to the default attributes appropriate for a TWindow. */
  171. void TWindow::GetWindowClass(WNDCLASS& AWndClass)
  172. {
  173.   AWndClass.cbClsExtra        = 0;
  174.   AWndClass.cbWndExtra        = 0;
  175.   AWndClass.hInstance        = GetModule()->hInstance;
  176.   AWndClass.hIcon        = LoadIcon(0, IDI_APPLICATION);
  177.   AWndClass.hCursor        = LoadCursor(0, IDC_ARROW);
  178.   AWndClass.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);
  179.   AWndClass.lpszMenuName    = NULL;
  180.   AWndClass.lpszClassName    = GetClassName();
  181.   AWndClass.style        = CS_HREDRAW | CS_VREDRAW;
  182.   AWndClass.lpfnWndProc     = InitWndProc;
  183. }
  184.  
  185. /* Associates an MS-Windows interface element with the TWindow object,
  186.   after creating the interface element if not already created.  When
  187.   creating an element, uses the creation attributes previously set
  188.   in the Attr data field.  (Simply associates the TWindow with an
  189.   already-created interface element if the "FromResource" flag is set.)
  190.   If the TWindow could be successfully associated, calls SetupWindow and
  191.   returns True.  Association is not attempted if the TWindow's Status
  192.   data field is non-zero. */
  193. BOOL TWindow::Create()
  194. {
  195.     HWND HParent;
  196.     PTWindow TheMDIClient; // compiler doesn't know about TMDIClients yet
  197.     MDICREATESTRUCT CreateStruct;
  198.     WORD MenuOrId = 0;
  199.  
  200.   if (Status == 0)
  201.   {
  202.     DisableAutoCreate();
  203.     if ( Parent == NULL )
  204.       HParent = 0;
  205.     else
  206.       HParent = Parent->HWindow;
  207.     if ( !IsFlagSet(WB_FROMRESOURCE) )
  208.     {
  209.       if ( Register() )
  210.       {
  211.         CreationWindow = this;
  212.         TWindowsObject *TmpDlgCreationWindow = DlgCreationWindow;
  213.         /*  Set DlgCreationWindow to NULL so in InitWndProc we'll know
  214.             we're not being created from a resource */
  215.         DlgCreationWindow = NULL;
  216.         /* Create as MDI child if the WB_MDICHILD flag is set and Parent
  217.            has a Client */
  218.         if (IsFlagSet(WB_MDICHILD))
  219.         {
  220.         if ((TheMDIClient = (PTWindow)(Parent->GetClient())) != NULL)
  221.         {   // MDI child window
  222.                 DefaultProc = (WNDPROC)DefMDIChildProc;
  223.                 CreateStruct.szClass = GetClassName();
  224.                 CreateStruct.szTitle = Title;
  225.                 CreateStruct.hOwner = GetModule()->hInstance;
  226.                 CreateStruct.x = Attr.X; CreateStruct.y = Attr.Y;
  227.                 CreateStruct.cx = Attr.W; CreateStruct.cy = Attr.H;
  228.                 CreateStruct.style = Attr.Style;
  229.         CreateStruct.lParam = (LONG)Attr.Param;
  230.         
  231.         HWindow = (HWND)LOWORD(SendMessage(TheMDIClient->HWindow,
  232.             WM_MDICREATE, 0, (LPARAM)(&CreateStruct)));
  233.             }
  234.             else    // Parent doesn't have a client, error
  235.                 Status = EM_INVALIDWINDOW;
  236.         }
  237.         else    // Not an MDI child window
  238.         {
  239.           if ( Attr.Menu)
  240.         MenuOrId = (WORD)LoadMenu(GetModule()->hInstance,
  241.                                    Attr.Menu);
  242.           else
  243.             MenuOrId = Attr.Id;
  244.           HWindow = CreateWindowEx(Attr.ExStyle, GetClassName(),
  245.             Title, Attr.Style, Attr.X, Attr.Y, Attr.W,
  246.         Attr.H, HParent, (HMENU)MenuOrId , GetModule()->hInstance,
  247.         Attr.Param);
  248.         }
  249.         DlgCreationWindow = TmpDlgCreationWindow;
  250.       }
  251.     }
  252.     else /* Windows already created window */
  253.       HWindow = GetDlgItem(HParent, Attr.Id);
  254.     if ( HWindow )
  255.     {
  256.       if ( !GetObjectPtr(HWindow) ) // predefined Windows class
  257.       {
  258.         // Retrieve the Title
  259.         int TitleLength = GetWindowTextLength(HWindow);
  260.         if (TitleLength > -1)
  261.         {
  262.             Title = (char far*)farmalloc((unsigned long)TitleLength + 1);
  263.             Title[0] = '\0'; Title[TitleLength] = '\0';
  264.             GetWindowText(HWindow, Title, TitleLength+1);
  265.         }
  266.         else
  267.             Title = _fstrdup("");
  268.  
  269.         // Retrieve Attr.Style and Attr.ExStyle.
  270.  
  271.         // NOTE:  Some windows controls (e.g. EDIT) change the style bits
  272.         // (e.g. WS_BORDER) from their original values.  If we reset
  273.         // Attr.Style and Attr.ExStyle by extracting their values from
  274.         // Windows, we will lose some of the style bits we supplied
  275.         // in the CreateWindowEx call.  In the case of the ResourceId
  276.         // constructors, of course, we must retrieve these values.
  277.  
  278.         if ( IsFlagSet(WB_FROMRESOURCE) )
  279.         {
  280.         Attr.Style = GetWindowLong(HWindow, GWL_STYLE);
  281.         Attr.ExStyle = GetWindowLong(HWindow, GWL_EXSTYLE);
  282.         }
  283.  
  284.         // Retrieve Attr.X, Attr.Y, Attr.W and Attr.H
  285.         RECT WndRect;
  286.         GetWindowRect(HWindow, &WndRect);
  287.         Attr.H = WndRect.bottom - WndRect.top;
  288.         Attr.W = WndRect.right - WndRect.left;
  289.         if ( HParent && ((Attr.Style & WS_CHILD) == WS_CHILD) )
  290.           ScreenToClient(HParent, (LPPOINT)&WndRect);
  291.         Attr.X = WndRect.left;
  292.         Attr.Y = WndRect.top;
  293.  
  294.       SetFlags(WB_PREDEFINEDCLASS, TRUE);
  295.     DefaultProc =  (WNDPROC)SetWindowLong(HWindow, GWL_WNDPROC,
  296.                                           (DWORD)GetInstance());
  297.         SetupWindow();
  298.       }
  299.     }
  300.     else                              // HWindow == 0
  301.     {
  302.       if ( Attr.Menu )
  303.     DestroyMenu( HMENU( MenuOrId ));
  304.       Status = EM_INVALIDWINDOW;
  305.     }
  306.   }
  307.   return (Status == 0);
  308. }
  309.  
  310. /* Response method for an incoming WM_MDIACTIVATE message. Calls
  311.    ActivationResponse to provide a keyboard interface for the controls
  312.    of a window. */
  313. void TWindow::WMMDIActivate(TMessage& Msg)
  314. {
  315.   DefWndProc(Msg);
  316.   if ( Parent )
  317.     ((PTMDIFrame)Parent)->ActiveChild = (Msg.WParam ? this : NULL);
  318.   if ( !IsFlagSet(WB_ALIAS) )
  319.   {
  320.     ActivationResponse(Msg.WParam, IsIconic(HWindow));
  321.   }
  322. }
  323.  
  324. /* Calls TWindowsObject::ActivationResponse to enable or disable the
  325.    "keyboard handler". If the TWindow has requested keyboard handling
  326.    for its messages, saves the child with the focus if it is being
  327.    deactivated and restores the focus to this child when the TWindow
  328.    is reactivated. */
  329. void TWindow::ActivationResponse(WORD Activated, BOOL IsIconified)
  330. {
  331.   HWND CurrentFocus;
  332.  
  333.   TWindowsObject::ActivationResponse(Activated, IsIconified);
  334.   if ( IsFlagSet(WB_KBHANDLER) )
  335.   {
  336.     if ( Activated )
  337.     {
  338.       if ( FocusChildHandle && IsWindow(FocusChildHandle) &&
  339.              !IsIconified )
  340.       {
  341.         SetFocus(FocusChildHandle);
  342.         // Set to 0 so we won't reset focus if another activate comes
  343.         FocusChildHandle = 0;
  344.       }
  345.     }
  346.     else
  347.     {
  348.       CurrentFocus = GetFocus();
  349.       if ( !FocusChildHandle && CurrentFocus &&
  350.            IsChild(HWindow, CurrentFocus) )
  351.         FocusChildHandle = CurrentFocus;
  352.     }
  353.   }
  354. }
  355.  
  356. static BOOL HasStyle(void *P, void *Style)
  357. {
  358.   return ((PTWindowsObject)P)->HWindow &&
  359.     (GetWindowLong(((PTWindowsObject)P)->HWindow, GWL_STYLE) &
  360.        *(long *)Style) == *(long *)Style;
  361. }
  362.  
  363. /* Initializes ("sets up") the TWindow.  Called following a
  364.    successful association between an MS-Windows interface element
  365.    and a TWindow.  Calls TWindowsObject::SetupWindow to create windows
  366.    in child list. If keyboard handling has been requested and
  367.    FocusChildHandle has not been set, sets it to the first child.
  368.    Sets the focus to TWindows created as MDI children.  If the
  369.    TWindow has a TScroller object, calls the TScroller's
  370.    SetSBarRange to set the range of the TWindow's window scrollbars.
  371.    Can be redefined in descendant classes to perform additional
  372.    initialization. */
  373. void TWindow::SetupWindow()
  374. {
  375.   TWindowsObject::SetupWindow();
  376.  
  377.   if ( IsFlagSet(WB_KBHANDLER) && !FocusChildHandle )
  378.   {
  379.     long Style = WS_TABSTOP;
  380.     PTWindowsObject TmpWO;
  381.     TmpWO = FirstThat(HasStyle, &Style);
  382.     if ( !TmpWO ) // no child has WS_TABSTOP
  383.     {
  384.       Style = WS_CHILD;
  385.       TmpWO = FirstThat(HasStyle, &Style);
  386.     }
  387.     if ( TmpWO )
  388.       FocusChildHandle = TmpWO->HWindow;
  389.   }
  390.  
  391.   if ( IsFlagSet(WB_MDICHILD) )
  392.     SetFocus(HWindow);
  393.   if ( Scroller )
  394.     Scroller->SetSBarRange();
  395. }
  396.  
  397. void TWindow::WMCreate(TMessage& Msg)
  398. {
  399.   SetupWindow();
  400.   DefWndProc(Msg);
  401. }
  402.  
  403. /* Response method for an incoming WM_HSCROLL message.  If the
  404.    message is from a scrollbar control, calls DispatchScroll directly to
  405.    avoid calling TWindowsObject::WMHScroll so that GetWindowLong is
  406.    called only once. Else passes the message to the TWindow's Scroller
  407.    if it has been constructed, and calls DefWndProc. Assumes because of
  408.    a Windows bug that if the window has the scrollbar style, it will not
  409.    have scrollbar controls. */
  410. void TWindow::WMHScroll(TMessage& Msg)
  411. {
  412.   if ( !(GetWindowLong(HWindow, GWL_STYLE) & WS_HSCROLL) )
  413.     DispatchScroll(Msg);
  414.   else
  415.     if ( Scroller )
  416.       Scroller->HScroll(Msg.WParam, LOWORD(Msg.LParam));
  417.     else
  418.       DefWndProc(Msg);
  419. }
  420.  
  421. /* Response method for an incoming WM_VSCROLL message.  If the
  422.    message is from a scrollbar control, calls DispatchScroll directly to
  423.    avoid calling TWindowsObject::WMVScroll so that GetWindowLong is
  424.    called only once. Else passes the message to the TWindow's Scroller
  425.    if it has been constructed, and calls DefWndProc. Assumes because of
  426.    a Windows bug that if the window has the scrollbar style, it will not
  427.    have scrollbar controls. */
  428. void TWindow::WMVScroll(TMessage& Msg)
  429. {
  430.   if ( !(GetWindowLong(HWindow, GWL_STYLE) & WS_VSCROLL) )
  431.     DispatchScroll(Msg);
  432.   else
  433.     if ( Scroller )
  434.       Scroller->VScroll(Msg.WParam, LOWORD(Msg.LParam));
  435.     else
  436.       DefWndProc(Msg);
  437. }
  438.  
  439. /* Response method for an incoming WM_PAINT message. Calls Paint,
  440.   performing Windows-required paint setup and cleanup before and after.
  441.   (If the TWindow has a TScroller, also calls its BeginView and EndView
  442.   methods before and after call to Paint. */
  443. void TWindow::WMPaint(TMessage& Msg)
  444. {
  445.   PAINTSTRUCT PaintInfo;
  446.  
  447.   if ( IsFlagSet(WB_ALIAS) ) // use application-defined wndproc
  448.     DefWndProc(Msg);
  449.   else
  450.   {
  451.     BeginPaint(HWindow, &PaintInfo);
  452.     if ( Scroller )
  453.       Scroller->BeginView(PaintInfo.hdc, PaintInfo);
  454.     Paint(PaintInfo.hdc, PaintInfo);
  455.     if ( Scroller )
  456.       Scroller->EndView();
  457.     EndPaint(HWindow, &PaintInfo);
  458.   }
  459. }
  460.  
  461. /* Redraws the contents of the TWindow after a WMPaint message
  462.    is received. Placeholder for descendant object types to redefine. */
  463.  
  464. #ifdef WIN31
  465. void TWindow::Paint(HDC, PAINTSTRUCT _FAR &)
  466. { }
  467. #endif
  468.  
  469. #ifdef WIN30
  470. void TWindow::Paint(HDC_30, PAINTSTRUCT _FAR &)
  471. { }
  472. #endif
  473.  
  474. /* Response method for an incoming WM_SIZE message.  Calls the
  475.    SetPageSize and SetSBarRange methods of the TWindow's Scroller,
  476.    if it has been constructed. Also saves the normal size of the
  477.    window in Attr. */
  478. void TWindow::WMSize(TMessage& Msg)
  479. {
  480.   RECT WndRect;
  481.  
  482.   if ( Scroller && (Msg.WParam != SIZEICONIC) )
  483.   {
  484.     Scroller->SetPageSize();
  485.     Scroller->SetSBarRange();
  486.   }
  487.   if ( Msg.WParam == SIZENORMAL )
  488.   {
  489.     GetWindowRect(HWindow, &WndRect);
  490.     Attr.H = WndRect.bottom - WndRect.top;
  491.     Attr.W = WndRect.right - WndRect.left;
  492.   }
  493.   DefWndProc(Msg);
  494. }
  495.  
  496. /* Save the normal position of the window.  If IsIconic and IsZoomed
  497.    ignore the position since it does not reflect the normal state. */
  498. void TWindow::WMMove(TMessage& Msg)
  499. {
  500.   RECT WndRect;
  501.  
  502.   if ( !(IsIconic(HWindow) || IsZoomed(HWindow)) )
  503.   {
  504.     GetWindowRect(HWindow, &WndRect);
  505.     if ( ((GetWindowLong(HWindow, GWL_STYLE) & WS_CHILD) == WS_CHILD)
  506.             && Parent && Parent->HWindow )
  507.       ScreenToClient(Parent->HWindow, (LPPOINT)&WndRect);
  508.     Attr.X = WndRect.left;
  509.     Attr.Y = WndRect.top;
  510.   }
  511.   DefWndProc(Msg);
  512. }
  513.  
  514. /* Response method for an incoming WM_LBUTTONDOWN message.  If
  515.    the TWindow's Scroller has been constructed and if auto-scrolling
  516.    has been requested, captures mouse input, loops until a
  517.    WM_LBUTTONUP message comes in calling the Scroller's AutoScroll
  518.    method, and then releases capture on mouse input. */
  519. void TWindow::WMLButtonDown(TMessage& Msg)
  520. {
  521.   MSG LoopMsg;
  522.  
  523.   LoopMsg.message = 0;
  524.   if ( Scroller && Scroller->AutoMode )
  525.   {
  526.     SetCapture(HWindow);
  527.     while ( LoopMsg.message != WM_LBUTTONUP )
  528.     {
  529.       if ( PeekMessage(&LoopMsg, 0, 0, 0, PM_REMOVE) )
  530.       {
  531.         TranslateMessage(&LoopMsg);
  532.         DispatchMessage(&LoopMsg);
  533.       }
  534.       Scroller->AutoScroll();
  535.     }
  536.     ReleaseCapture();
  537.   }
  538.   DefWndProc(Msg);
  539. }
  540.  
  541. void *TWindow::read(ipstream& is)
  542. {
  543.   BOOL NameIsNumeric;
  544.   TWindowsObject::read(is);
  545.  
  546.   if ( IsFlagSet(WB_FROMRESOURCE) )
  547.   {
  548.     DefaultProc = (WNDPROC)DefWindowProc;
  549.     memset(&Attr, 0x0, sizeof (Attr));
  550.   }
  551.   else
  552.   {
  553.     is >> Attr.Style >> Attr.ExStyle
  554.        >> Attr.X >> Attr.Y >> Attr.W
  555.        >> Attr.H >> (long)(Attr.Param);
  556.  
  557.     if ( IsFlagSet(WB_MDICHILD) )
  558.       DefaultProc = (WNDPROC)DefMDIChildProc;
  559.     else
  560.       DefaultProc = (WNDPROC)DefWindowProc;
  561.   }
  562.   is >> Attr.Id;
  563.  
  564.   is >> NameIsNumeric;
  565.   if ( NameIsNumeric )
  566.     is >> (long)(Attr.Menu);
  567.   else
  568.     Attr.Menu= is.freadString();
  569.  
  570.   is >> Scroller;
  571.   if ( Scroller )
  572.     Scroller->Window = this;
  573.   FocusChildHandle = 0;
  574.   return this;
  575. }
  576.  
  577. /* Writes data of the TWindow to the passed opstream. Writes its
  578.    Scroller if constructed. */
  579. void TWindow::write(Ropstream os)
  580. {
  581.   long SaveStyle;
  582.   BOOL NameIsNumeric;
  583.   TWindowsObject::write(os);
  584.   if ( !IsFlagSet(WB_FROMRESOURCE) )
  585.   {
  586.     SaveStyle = Attr.Style & ~(WS_MINIMIZE | WS_MAXIMIZE);
  587.     if ( HWindow )
  588.       if ( IsIconic(HWindow) )
  589.         SaveStyle |= WS_MINIMIZE;
  590.       else
  591.         if ( IsZoomed(HWindow) )
  592.           SaveStyle |= WS_MAXIMIZE;
  593.     os << SaveStyle << Attr.ExStyle << Attr.X
  594.        << Attr.Y << Attr.W << Attr.H
  595.        << (long)(Attr.Param);
  596.   }
  597.   os << Attr.Id;
  598.  
  599.   NameIsNumeric = HIWORD(Attr.Menu) == NULL;
  600.   os << NameIsNumeric;
  601.   if ( NameIsNumeric )
  602.     os << (long)(Attr.Menu);
  603.   else
  604.     os.fwriteString(Attr.Menu);
  605.  
  606.   os << Scroller;
  607. }
  608.  
  609. PTStreamable TWindow::build()
  610. {
  611.   return new TWindow(streamableInit);
  612. }
  613.  
  614. TStreamableClass RegWindow("TWindow", TWindow::build, __DELTA(TWindow));
  615.