home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / APPLICAT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  18.5 KB  |  748 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   source\owl\applicat.cpp
  4. //   Implementation of class TApplication. This defines the basic behavior
  5. //   for ObjectWindows applications.
  6. //----------------------------------------------------------------------------
  7. #pragma hdrignore SECTION
  8. #include <owl\owlpch.h>
  9. #include <owl\applicat.h>
  10. #include <owl\framewin.h>
  11. #include <owl\docmanag.h>
  12.  
  13. #if defined(SECTION) && SECTION != 1
  14. DIAG_DECLARE_GROUP(OwlApp);        // General Application diagnostic group
  15. #endif
  16.  
  17. #if !defined(SECTION) || SECTION == 1
  18.  
  19. DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlApp, 1, 0);
  20.  
  21. //
  22. // Static members for initialization
  23. //
  24. HINSTANCE       TApplication::InitHInstance;
  25. HINSTANCE       TApplication::InitHPrevInstance;
  26. const char far* TApplication::InitCmdLine;
  27. int             TApplication::InitCmdShow;
  28.  
  29. //
  30. // Constructor for use in OwlMain(). Gets members from statics set earlier by
  31. // a call to InitWinMainParams() in Owl's WinMain.
  32. //
  33. TApplication::TApplication(const char far* name, TModule*& gModule)
  34.   : TModule(name, InitHInstance, InitCmdLine), XOwl(0),XState(0),DocManager(0)
  35.  
  36. {
  37.   //
  38.   // Copy over values that were stashed in static members before this instance
  39.   // was constructed.
  40.   //
  41.   hPrevInstance = InitHPrevInstance;
  42.   nCmdShow = InitCmdShow;
  43.  
  44.   MainWindow = 0;
  45.   HAccTable = 0;
  46.   BreakMessageLoop = FALSE;
  47.   BWCCOn = Ctl3dOn = FALSE;
  48.   BWCCModule = Ctl3dModule = 0;
  49.   CondemnedWindows = 0;
  50.  
  51.   AddApplicationObject(this);
  52.   gModule = this;
  53. }
  54.  
  55. //
  56. // Constructor for use in user defined WinMain() when all the args are
  57. // available
  58. //
  59. TApplication::TApplication(const char far* name,
  60.                            HINSTANCE       instance,
  61.                            HINSTANCE       prevInstance,
  62.                            const char far* cmdLine,
  63.                            int             cmdShow,
  64.                            TModule*&       gModule)
  65.   : TModule(name, instance, cmdLine), XOwl(0), XState(0), DocManager(0)
  66.  
  67. {
  68.   hPrevInstance = prevInstance;
  69.   nCmdShow = cmdShow;
  70.   MainWindow = 0;
  71.   HAccTable = 0;
  72.   BreakMessageLoop = FALSE;
  73.   BWCCOn = Ctl3dOn = FALSE;
  74.   BWCCModule = Ctl3dModule = 0;
  75.   CondemnedWindows = 0;
  76.   
  77.   AddApplicationObject(this);
  78.   gModule = this;
  79. }
  80.  
  81. TApplication::~TApplication()
  82. {
  83.   DeleteCondemned();
  84.   
  85.   //
  86.   // Unregister ourselves from the Ctl3d DLL and/or the BWCC DLL if they are
  87.   // loaded.
  88.   //
  89.   if (Ctl3dModule) {
  90.     BOOL FAR PASCAL(*Ctl3dUnregister)(HANDLE);
  91.     (FARPROC)Ctl3dUnregister = Ctl3dModule->GetProcAddress("Ctl3dUnregister");
  92.     if (Ctl3dUnregister)
  93.       Ctl3dUnregister(*this);
  94.     delete Ctl3dModule;
  95.   }
  96.   if (BWCCModule) {
  97.     BOOL FAR PASCAL(*bwccIntlTerm)(void);
  98.     (FARPROC)bwccIntlTerm = BWCCModule->GetProcAddress("BWCCIntlTerm");
  99.     if (bwccIntlTerm)
  100.       bwccIntlTerm();
  101.     delete BWCCModule;
  102.   }
  103.  
  104.   //
  105.   // Deletes main window if still present, may be destroyed but not deleted
  106.   // Sets MainWindow to 0 to prevent calling ::PostQuitMessage
  107.   //
  108.   TWindow* mainWindow = SetMainWindow(0);
  109.   if (mainWindow) {
  110.     mainWindow->Destroy();
  111.     delete mainWindow;
  112.   }
  113.  
  114.   delete (TStreamableBase*)DocManager;// cast to avoid ref to docmgr if not used
  115.  
  116.   //
  117.   // Remove ourselves from the application object list
  118.   //
  119.   DeleteApplicationObject();
  120.   delete XOwl;   // remove any exception copy
  121. }
  122.  
  123. //
  124. // handles initialization for the first executing instance of the OWL
  125. // application
  126. //
  127. void
  128. TApplication::InitApplication()
  129. {
  130. }
  131.  
  132. //
  133. // handles initialization for each executing instance of the OWL
  134. // application
  135. //
  136. // creates and displays the main window
  137. //
  138. void
  139. TApplication::InitInstance()
  140. {
  141.   InitMainWindow();
  142.  
  143.   if (MainWindow) {
  144.     MainWindow->SetFlag(wfMainWindow);
  145.     MainWindow->Create();
  146.     MainWindow->Show(nCmdShow);
  147.  
  148.   } else
  149.     THROW( TXInvalidMainWindow() );
  150. }
  151.  
  152. //
  153. // initialize the application's main window
  154. //
  155. // default main window title is the same as the applications
  156. //
  157. void
  158. TApplication::InitMainWindow()
  159. {
  160.   SetMainWindow(new TFrameWindow(0, GetName()));
  161. }
  162.  
  163. //
  164. // handles termination for each executing instance of the OWL
  165. // application
  166. //
  167. int
  168. TApplication::TermInstance(int status)
  169. {
  170.   return status;
  171. }
  172.  
  173. //
  174. // Sets (or resets) the main window. Returns, but does not destroy the
  175. // previous main window.
  176. //
  177. TFrameWindow*
  178. TApplication::SetMainWindow(TFrameWindow* window)
  179. {
  180.   if (MainWindow)
  181.     MainWindow->ClearFlag(wfMainWindow);
  182.   TFrameWindow* oldMainWindow = MainWindow;
  183.   MainWindow = window;
  184.   if (MainWindow)
  185.     MainWindow->SetFlag(wfMainWindow);
  186.   return oldMainWindow;
  187. }
  188.  
  189. //
  190. // Sets (or resets) the document manager, returns the previous one if present
  191. //
  192. TDocManager*
  193. TApplication::SetDocManager(TDocManager* docManager)
  194. {
  195.   TDocManager* oldDocManager = DocManager;
  196.   DocManager = docManager;
  197.   return oldDocManager;
  198. }
  199.  
  200. #if defined(__WIN32__)
  201. //
  202. // overrides TEventHandler::Dispatch() to handle multi-thread synchonization
  203. //
  204. LRESULT TApplication::Dispatch(TEventInfo& info, WPARAM wp, LPARAM lp)
  205. {
  206.   TApplication::TAppLock Lock(*this);
  207.   return TModule::Dispatch(info, wp, lp);
  208. }
  209.  
  210. int TApplication::TAppMutex::NotWIN32s =
  211.     (HIWORD(::GetVersion()) & 0x8000) == 0;
  212. #endif
  213.  
  214. //
  215. // default idle action is to forward the action to the main window.
  216. //
  217. BOOL
  218. TApplication::IdleAction(long idleCount)
  219. {
  220.   if (MainWindow)
  221.     return MainWindow->IdleAction(idleCount);
  222.   return 0;
  223. }
  224.  
  225. //
  226. // initializes instances, creating and displaying their main window (calls
  227. // InitApplication for the first executing instance and calls InitInstance for
  228. // all instances). Runs the application's message loop. Each of the virtual
  229. // functions called are expected to throw an exception if there is an error.
  230. //
  231. int
  232. TApplication::Run()
  233. {
  234.   int status;
  235.   TRY {
  236.     if (!hPrevInstance)
  237.       InitApplication();
  238.     InitInstance();
  239.     status = MessageLoop();
  240.   }
  241.   CATCH( (TXOwl& x) {status = x.Unhandled(this, 0);})
  242.   CATCH( (xmsg& x) {status = Error(x, 0);})
  243.   CATCH( (Bad_cast& x) {status = Error(xmsg(string(typeid(x).name())), 0);} )
  244.   CATCH( (Bad_typeid& x) {status = Error(xmsg(string(typeid(x).name())), 0);} )
  245.  
  246.   MSG msg;
  247.   while (::PeekMessage(&msg,0,0,0,PM_NOYIELD|PM_REMOVE)
  248.          && msg.message != WM_PAINT) ; // flush queue
  249.   return TermInstance(status);
  250. }
  251.  
  252. BOOL
  253. TApplication::ProcessAppMsg(MSG& msg)
  254. {
  255.   // start with the window that the event was destined for and allow it
  256.   // and its parent (and its parent...) an opportunity to preprocess the
  257.   // event
  258.   //
  259.   for (HWND hWnd = msg.hwnd; hWnd; hWnd = ::GetParent(hWnd)) {
  260.     TWindow*  win = GetWindowPtr(hWnd);
  261.  
  262.     if (win && win->PreProcessMsg(msg))
  263.       return TRUE;
  264.   }
  265.  
  266.   // for compatability with OWL 1.0, check the application's accelerator
  267.   // table if it is being used
  268.   //
  269.   // NOTE: we should only support this for one rev...
  270.   //
  271.   if (HAccTable && MainWindow)
  272.     return ::TranslateAccelerator(MainWindow->HWindow, HAccTable, &msg);
  273.  
  274.   return FALSE;
  275. }
  276.  
  277. //
  278. // Called after each message dispatch when TApplication's message loop is not
  279. // being used.
  280. //
  281. void
  282. TApplication::PostDispatchAction()
  283. {
  284.   DeleteCondemned();
  285.   ResumeThrow();
  286.   if (!::PeekMessage(0, 0, 0, 0, PM_NOREMOVE))
  287.     IdleAction(0);
  288. }
  289.  
  290. //
  291. // lowlevel message loop: retrieves and processes messages from the OWL
  292. // application's message queue until it is empty
  293. //
  294. // calls ProcessAppMsg() to allow special handling of the message
  295. //
  296. BOOL
  297. TApplication::PumpWaitingMessages()
  298. {
  299.   MSG  msg;
  300.   BOOL foundOne = FALSE;
  301.  
  302.   while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
  303.     foundOne = TRUE;
  304.     if (msg.message == WM_QUIT) {
  305.       BreakMessageLoop = TRUE;
  306.       MessageLoopResult = msg.wParam;
  307.       ::PostQuitMessage(msg.wParam);  // make sure all loops exit
  308.       break;
  309.     }
  310.  
  311.     if (!ProcessAppMsg(msg)) {
  312.       ::TranslateMessage(&msg);
  313.       ::DispatchMessage(&msg);
  314.       DeleteCondemned();
  315.       ResumeThrow();
  316.     }
  317.   }
  318.   return foundOne;
  319. }
  320.  
  321. void
  322. TApplication::SuspendThrow(xalloc& x)
  323. {
  324.   XString = x.why();
  325.   XSize   = x.requested();
  326.   XState |= xsAlloc;
  327. }
  328.  
  329. void
  330. TApplication::SuspendThrow(xmsg& x)
  331. {
  332.   XString = x.why();
  333.   XState |= xsMsg;
  334. }
  335.  
  336. void
  337. TApplication::SuspendThrow(TXOwl& x)
  338. {
  339.   delete XOwl;       // remove any previous exception
  340.   XOwl = x.Clone();
  341.   XState |= xsOwl;
  342. }
  343.  
  344. void
  345. TApplication::SuspendThrow(int flag)
  346. {
  347.   XState |= (flag & (xsBadCast | xsBadTypeid | xsUnknown));
  348. }
  349.  
  350. void
  351. TApplication::ResumeThrow()
  352. {
  353.   if (XState) {
  354.     if (XState & xsAlloc){
  355.       XState &= ~xsAlloc;
  356.       THROW( xalloc(XString,XSize) );
  357.     }
  358.     if (XState & xsMsg) {
  359.       XState &= ~xsMsg;
  360.       THROW( xmsg(XString) );
  361.     }
  362.     if (XState & xsUnknown) {
  363.       XState &= ~xsUnknown;
  364.       THROW( xmsg(string()) );
  365.     }
  366.     if (XState & xsBadCast) {
  367.       XState &= ~xsBadCast;
  368.       THROW( Bad_cast() );
  369.     }
  370.     if (XState & xsBadTypeid) {
  371.       XState &= ~xsBadTypeid;
  372.       THROW( Bad_typeid() );
  373.     }
  374.     if (XState & xsOwl) {
  375.       XState &= ~xsOwl;
  376.       XOwl->Throw();  // must be deleted later
  377.     }
  378.   }
  379. }
  380.  
  381. //
  382. // general message loop: retrieves and processes messages from the OWL
  383. // application's message queue until BreakMessageLoop becomes true
  384. //
  385. // calls IdleAction() when there are no messages
  386. //
  387. int
  388. TApplication::MessageLoop()
  389. {
  390.   long idleCount = 0;
  391.  
  392.   MessageLoopResult = 0;
  393.   while (!BreakMessageLoop) {
  394.     TRY {
  395.       if (!IdleAction(idleCount++))
  396.         ::WaitMessage();             // allow system to go idle
  397.       if (PumpWaitingMessages())     // pumps any waiting messages
  398.         idleCount = 0;
  399.     }
  400.     CATCH( (TXOwl& x) {
  401.       MessageLoopResult = x.Unhandled(this, IDS_OKTORESUME);
  402.       if (MessageLoopResult != 0) {
  403.         ::PostQuitMessage(MessageLoopResult);
  404.         break;
  405.       }
  406.     })
  407.     CATCH( (xmsg& x) {
  408.       MessageLoopResult = Error(x, 0, IDS_OKTORESUME);
  409.       if (MessageLoopResult != 0) {
  410.         ::PostQuitMessage(MessageLoopResult);
  411.         break;
  412.       }
  413.     })
  414.     CATCH( (Bad_cast& x) {
  415.       MessageLoopResult = Error(xmsg(string(typeid(x).name())), 0, IDS_OKTORESUME);
  416.       if (MessageLoopResult != 0) {
  417.         ::PostQuitMessage(MessageLoopResult);
  418.         break;
  419.       }
  420.     })
  421.     CATCH( (Bad_typeid& x) {
  422.       MessageLoopResult = Error(xmsg(string(typeid(x).name())), 0, IDS_OKTORESUME);
  423.       if (MessageLoopResult != 0) {
  424.         ::PostQuitMessage(MessageLoopResult);
  425.         break;
  426.       }
  427.     })
  428.   }
  429.   BreakMessageLoop = FALSE;
  430.   return MessageLoopResult;
  431. }
  432.  
  433. //
  434. // event handling simply defers to the DocManager if it has been installed
  435. //
  436. BOOL
  437. TApplication::Find(TEventInfo &eventInfo, TEqualOperator equal)
  438. {
  439.   return DocManager ? DocManager->Find(eventInfo, equal) : FALSE;
  440. }
  441.  
  442. //
  443. // determines whether the application can be closed
  444. // makes sure app can close & doc manager can close.
  445. //
  446. BOOL
  447. TApplication::CanClose()
  448. {
  449.   TEventInfo eventInfo(WM_OWLCANCLOSE);
  450.   return (!MainWindow || MainWindow->CanClose())
  451.       && (!DocManager ||!DocManager->Find(eventInfo)
  452.                       || DocManager->Dispatch(eventInfo, 0, 0));
  453. }
  454.  
  455. void
  456. TApplication::PreProcessMenu(HMENU fmenu)
  457. {
  458.   TEventInfo eventInfo(WM_OWLPREPROCMENU);
  459.   if (DocManager && DocManager->Find(eventInfo)) {
  460.     DocManager->Dispatch(eventInfo, (WPARAM)fmenu, 0);
  461.     MainWindow->DrawMenuBar();
  462.   }
  463. }
  464.  
  465. void
  466. TApplication::Condemn(TWindow* win)
  467. {
  468.   TRACEX(OwlApp, 1, "Condemning window: " << *win);
  469.   win->SetParent(0);
  470.   win->SetNext(CondemnedWindows);
  471.   CondemnedWindows = win;
  472. }
  473.  
  474. void
  475. TApplication::DeleteCondemned()
  476. {
  477.   while (CondemnedWindows) {
  478.     TRACEX(OwlApp, 1, "Deleting condemned window: " << *CondemnedWindows);
  479.     TWindow* next = CondemnedWindows->Next();
  480.     delete CondemnedWindows;
  481.     CondemnedWindows = next;
  482.   }
  483. }
  484.  
  485. TApplication::TXInvalidMainWindow::TXInvalidMainWindow()
  486.             : TXOwl(IDS_INVALIDMAINWINDOW)
  487. {
  488. }
  489.  
  490. TXOwl*
  491. TApplication::TXInvalidMainWindow::Clone()
  492. {
  493.   return new TXInvalidMainWindow(*this);
  494. }
  495.  
  496. void
  497. TApplication::TXInvalidMainWindow::Throw()
  498. {
  499.   THROW( *this );
  500. }
  501.  
  502. //----------------------------------------------------------------------------
  503. #endif
  504. #if !defined(SECTION) || SECTION == 2
  505.  
  506. struct TEnumInfo {
  507.   short     Count;
  508.   HWND far* Wnds;
  509. };
  510.  
  511. BOOL far _export _pascal
  512. DisableWnds(HWND wnd, TEnumInfo* info)
  513. {
  514.   if (!::GetWindowLong(wnd, GWL_STYLE) & WS_CHILD) {
  515.     if (!info->Wnds) {
  516.       if (::IsWindowEnabled(wnd))
  517.         info->Count++;  // no buffer yet, we are just counting
  518.  
  519.     } else if (::IsWindowEnabled(wnd)) {
  520.       *(info->Wnds++) = wnd;
  521.       ::EnableWindow(wnd, FALSE);
  522.     }
  523.   }
  524.   return TRUE;
  525. }
  526.  
  527. static void termModal(HWND* wnds, TWindow* w, int flags)
  528. {
  529.   //
  530.   // Re-enable window(s) that are disabled in BeginModal()
  531.   //
  532.   if (wnds) {
  533.     for (HWND* wnd = wnds; *wnd; wnd++)
  534.       ::EnableWindow(*wnd, TRUE);
  535.     delete wnds;
  536.  
  537.   } else if (!(flags & MB_SYSTEMMODAL))
  538.     if (w)
  539.       w->EnableWindow(TRUE);
  540. }
  541.  
  542. //
  543. // Go modal and enter a message loop until a quit message goes by.
  544. // the flag values determine how window is used:
  545. //   MB_APPLMODAL -   window is the owner to disable (if 0, none are disabled)
  546. //   MB_TASKMODAL -   window is ignored, all top level windows are disabled
  547. //   MB_SYSTEMMODAL - window is the window to make system modal
  548. // returns -1 on errors
  549. //
  550. int
  551. TApplication::BeginModal(TWindow* window, int flags)
  552. {
  553.   TEnumInfo ei = { 0, 0 };
  554.   HWND*     wnds = 0;
  555.  
  556.   // Set modal state
  557.   //
  558.   if (flags & MB_TASKMODAL) {
  559.  
  560.     // count windows to disable
  561.     //
  562.     #if defined(__WIN32__)
  563.       if (!EnumThreadWindows(GetCurrentThreadId(), (WNDENUMPROC)DisableWnds,
  564.                              (LPARAM)(TEnumInfo far*)&ei))
  565.         return -1;
  566.     #else
  567.       if (!EnumTaskWindows(GetCurrentTask(), (WNDENUMPROC)DisableWnds,
  568.                            (LPARAM)(TEnumInfo far*)&ei))
  569.         return -1;
  570.     #endif
  571.  
  572.     // Allocate list of windows to disable, disable windows that are
  573.     // enabled and then stuff them into the list.
  574.     //
  575.     ei.Wnds = wnds = new HWND[ei.Count + 1];
  576.     memset(wnds, 0, sizeof(HWND)*(ei.Count + 1));
  577.  
  578.     #if defined(__WIN32__)
  579.       EnumThreadWindows(GetCurrentThreadId(), (WNDENUMPROC)DisableWnds,
  580.                         (LPARAM)(TEnumInfo far*)&ei);
  581.     #else
  582.       EnumTaskWindows(GetCurrentTask(), (WNDENUMPROC)DisableWnds,
  583.                       (LPARAM)(TEnumInfo far*)&ei);
  584.     #endif
  585.   }
  586.   #if !defined(__WIN32__)
  587.     else if (flags & MB_SYSTEMMODAL)
  588.       window->SetSysModalWindow();
  589.   #endif
  590.   else if (window)
  591.       window->EnableWindow(FALSE);
  592.  
  593.   // Enter message loop, saving & restoring the current status & getting the
  594.   // returned result.
  595.   //
  596.   int result;
  597.   TRY {
  598.     result = MessageLoop();
  599.   }
  600.   CATCH( (...) {
  601.     termModal(wnds, window, flags);
  602.     RETHROW;
  603.   })
  604.   termModal(wnds, window, flags);
  605.  
  606.   // return the result from the model window EndModal call
  607.   //
  608.   return result;
  609. }
  610.  
  611. //
  612. // Cause the current modal message loop to break and have it return a result
  613. //
  614. void
  615. TApplication::EndModal(int result)
  616. {
  617.   MessageLoopResult = result;
  618.   BreakMessageLoop = TRUE;
  619. }
  620.  
  621. //----------------------------------------------------------------------------
  622. #endif
  623. #if !defined(SECTION) || SECTION == 3
  624.  
  625. //
  626. // Predefined DLLs that TApplication knows how to find.
  627. //
  628. #if defined(__WIN32__)
  629.   const char BwccDllName[]  = "BWCC32.DLL";
  630.   const char Ctl3dDllName[] = "CTL3D32.DLL";
  631. #else
  632.   const char BwccDllName[]  = "BWCC.DLL";
  633.   const char Ctl3dDllName[] = "CTL3DV2.DLL";
  634. #endif
  635.  
  636. //
  637. // Load the BWCC DLL if needed & set the BWCC on flag according to 'enable'
  638. // Library is not free'd on disable to reduce re-loads if enabling on the fly
  639. //
  640. void
  641. TApplication::EnableBWCC(BOOL enable, UINT language)
  642. {
  643.   if (enable) {
  644.     if (!BWCCModule) {
  645.       BWCCModule = new TModule(BwccDllName, TRUE);
  646.  
  647.       BOOL FAR PASCAL(*bwccIntlInit)(UINT);
  648.       (FARPROC)bwccIntlInit = BWCCModule->GetProcAddress("BWCCIntlInit");
  649.       if (bwccIntlInit)
  650.         bwccIntlInit(language);
  651.  
  652.       BOOL FAR PASCAL(*bwccRegister)(HINSTANCE);
  653.       (FARPROC)bwccRegister = BWCCModule->GetProcAddress("BWCCRegister");
  654.       if (bwccRegister)
  655.         bwccRegister(GetInstance());
  656.     }
  657.     BWCCOn = TRUE;
  658.  
  659.   } else
  660.     BWCCOn = FALSE;
  661. }
  662.  
  663. //
  664. // enable or disable the use of the CTL3D DLL. Loads it if needed.
  665. //
  666. void
  667. TApplication::EnableCtl3d(BOOL enable)
  668. {
  669.   //
  670.   // If we are running Win4.0 or greater, then ctl3d is unnecessary
  671.   //
  672.   if (LOBYTE(LOWORD(GetVersion())) >= 0x04)
  673.     return;
  674.  
  675.   //
  676.   // Load the Ctl3d DLL if needed & register our instance
  677.   //
  678.   if (enable) {
  679.     if (!Ctl3dModule) {
  680.       Ctl3dModule = new TModule(Ctl3dDllName, TRUE);
  681.       BOOL FAR PASCAL(*ctl3dRegister)(HANDLE);
  682.       (FARPROC)ctl3dRegister = Ctl3dModule->GetProcAddress("Ctl3dRegister");
  683.       if (ctl3dRegister)
  684.         ctl3dRegister(*this);
  685.       else {
  686.         delete Ctl3dModule;
  687.         Ctl3dModule = 0;
  688.         return;   // could not register--don't change Ctl3dOn flag
  689.       }
  690.     }
  691.   }
  692.   Ctl3dOn = enable;
  693. }
  694.  
  695. //
  696. // enable or disable CTL3D's use of auto-subclassing. Turn on autosubclassing
  697. // before creating a non-owl dialog to make it 3d, & turn it off immediatly
  698. // after.
  699. //
  700. void
  701. TApplication::EnableCtl3dAutosubclass(BOOL enable)
  702. {
  703.   if (Ctl3dEnabled()) {
  704.     if (enable) {
  705.       BOOL FAR PASCAL(*ctl3dRegister)(HANDLE);
  706.       (FARPROC)ctl3dRegister = Ctl3dModule->GetProcAddress("Ctl3dRegister");
  707.       if (ctl3dRegister) {
  708.         ctl3dRegister(*this);
  709.  
  710.         BOOL FAR PASCAL(*ctl3dAutoSubclass)(HANDLE);
  711.         (FARPROC)ctl3dAutoSubclass = Ctl3dModule->GetProcAddress("Ctl3dAutoSubclass");
  712.         if (ctl3dAutoSubclass)
  713.           ctl3dAutoSubclass(*this);
  714.       }
  715.       
  716.     } else {
  717.       BOOL FAR PASCAL(*Ctl3dUnregister)(HANDLE);
  718.       (FARPROC)Ctl3dUnregister = Ctl3dModule->GetProcAddress("Ctl3dUnregister");
  719.       if (Ctl3dUnregister)
  720.         Ctl3dUnregister(*this);
  721.     }
  722.   }
  723. }
  724. #endif
  725.  
  726. #if !defined(SECTION) || SECTION == 4
  727.  
  728. IMPLEMENT_STREAMABLE1(TApplication, TModule);
  729.  
  730. void*
  731. TApplication::Streamer::Read(ipstream& is, uint32 /*version*/) const
  732. {
  733.   TApplication* o = GetObject();
  734.   if (o != ::Module)
  735.     is >> *::Module;   // set reference to OWL module
  736.   return o;
  737. }
  738.  
  739. void
  740. TApplication::Streamer::Write(opstream& os) const
  741. {
  742.   TApplication* o = GetObject();
  743.   if (o != ::Module)
  744.     os << *::Module;    // write out reference to OWL module, no data written
  745. }
  746.  
  747. #endif  // SECTION
  748.