OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
applicat.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1991, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of class TApplication. This defines the basic behavior
7/// for ObjectWindows applications.
8//----------------------------------------------------------------------------
9
10#include <owl/pch.h>
11#include <owl/applicat.h>
12#include <owl/framewin.h>
13#include <owl/docmanag.h>
14#include <owl/appdict.h>
15#include <owl/messageb.h>
16#include <owl/window.rh>
17#include <owl/tooltip.h>
18#include "tracewnd.h"
19#include <vector>
20
21#if defined(OWL_SUPPORT_BWCC)
22# include <owl/private/bwcc.h>
23#endif
24
25
26#if defined(BI_MULTI_THREAD_RTL)
27# include <owl/thread.h>
28#endif
29
30using namespace std;
31
32#if defined(__BORLANDC__)
33# pragma option -w-ccc // Disable "Condition is always true/false"
34# pragma option -w-inl // Disable warning in standard library.
35#endif
36
37namespace owl {
39} // OWL namespace
40
41
42namespace owl {
43
44/// \addtogroup internal
45/// @{
46
47
48/////////////////////////////////////////////////////
49/// global definitions for both modules if sectioning
50struct TEnumInfo {
51 HWND ModalWnd; ///< The window being made modal if needed
52 short Count; ///< Count of windows in Wnds below
53 HWND* Wnds; ///< list of windows that were disabled
54 WNDPROC* PrevWndProc;//
55};
56
57//////////////////////////////////////////////////////////////////////////////////
58// Multithread support
59//
60class TWaitHook{
61 public:
62 TWaitHook();
63 ~TWaitHook();
64
65 void SetCursor(TCursor* cursor, TAutoDelete = AutoDelete);
66
67 private:
68 void FreeCursors();
69 void SetWaitCursor();
70
71 private:
72 TEnumInfo Subclass;
73 TEnumInfo* LastStackTop;
74 uint Count;
75 uint HideCaretCount;
76 TCursor* Cursor;
77 bool DeleteOnClose;
78
79 TResult WaitWndMethod(HWND, TMsgId, TParam1, TParam2);
80 TResult DefWndProc(HWND, TMsgId, TParam1, TParam2);
81
82 public:
83 static LRESULT CALLBACK WaitWndProc(HWND, UINT, WPARAM, LPARAM);
84};
85
86//
87struct TEnumInfoStr
89: public TLocalObject
90#endif
91{
92
93 TEnumInfoStr():Info(nullptr),Hook(nullptr),Top(nullptr)
94 {
95 }
96 ~TEnumInfoStr()
97 {
98 }
99
100 TEnumInfo* GetInfo() { return Info; }
101 void SetInfo(TEnumInfo* info) { Info = info; }
102
103 TEnumInfo* Info;
104 TWaitHook* Hook;
105 TWaitCursor* Top;
106
107#if defined(BI_MULTI_THREAD_RTL)
108 TMRSWSection Lock;
109#endif
110};
111//
112//
113static TEnumInfoStr& GetEnumInfo();
114
115//
116//
117//
118#if !defined(BI_MULTI_THREAD_RTL)
119struct TApplicatData {
120#else
121struct TApplicatData : public TLocalObject {
122#endif
123 TApplicatData();
124 ~TApplicatData();
125
126 TMessageBox OwlMsgBox;
127
128#if defined(BI_MULTI_THREAD_RTL)
129 TMRSWSection Lock;
130#endif
131};
132
133//
134static TApplicatData& GetApplicatData();
135
136//
137//
138//
139#if defined(BI_MULTI_THREAD_RTL) //TMRSWSection::TLock lock(GetEnumInfo().Lock);
140#define LOCKENUMINFO(l,s) TMRSWSection::TLock __lock(l,s)
141#else
142#define LOCKENUMINFO(l,s)
143#endif
144
145//
146//
147//
148#if defined(BI_MULTI_THREAD_RTL) //GetApplicatData().Lock,true
149#define LOCKAPPLDATA(l,s) TMRSWSection::TLock __lock(l,s)
150#else
151#define LOCKAPPLDATA(l,s)
152#endif
153
154/// @}
155
156
158
159// System Menu command "Diagnostic Window".
160// This system command is present in debug builds only, i.e. when either of the symbols __TRACE and
161// __WARN is defined. For more details, see EvSysCommand where the ScmTrace command is handled.
162//
163const auto ScmTrace = 0xFEC0;
164
165// -----------------------------------------------------------------------------
166static int
167OWLDefaultMsgBox(HWND wnd, LPCTSTR text, LPCTSTR caption, uint type)
168{
170 return ::MessageBoxEx(wnd, text, caption, type, app ? app->GetLangId() : LangNeutral);
171}
172// -----------------------------------------------------------------------------
173TApplicatData::TApplicatData()
174: OwlMsgBox(OWLDefaultMsgBox)
175{
176}
177// -----------------------------------------------------------------------------
178TApplicatData::~TApplicatData()
179{
180}
181
182//////////////////////////////////////////////////////////////////////////////////////////////////
183// multithread support
184//
185static
186TApplicatData& GetApplicatData()
187{
188//#if defined(BI_MULTI_THREAD_RTL)
189// static TProcessContainer<TApplicatData> __ApplData;
190//#else
191 static TApplicatData __ApplData;
192//#endif
193 return __ApplData;
194}
195//
196static
197TEnumInfoStr& GetEnumInfo()
198{
199//#if defined(BI_MULTI_THREAD_RTL)
200// static TProcessContainer<TEnumInfoStr> __EnumInfo;
201//#else
202 static TEnumInfoStr __EnumInfo;
203//#endif
204 return __EnumInfo;
205}
206
207// -----------------------------------------------------------------------------
208//
209// Static members for initialization of app prior to initial construction
210//
211HINSTANCE TApplication::InitHInstance;
212HINSTANCE TApplication::InitHPrevInstance;
213int TApplication::InitCmdShow;
214
215
216// -----------------------------------------------------------------------------
217_OWLFUNC(TMessageBox)
218SetDefMessageBox(TMessageBox newMsgBox)
219{
220 TApplicatData& data = GetApplicatData();
221 LOCKAPPLDATA(data.Lock,true);
222 TMessageBox msgBox = data.OwlMsgBox;
223 data.OwlMsgBox = newMsgBox;
224 return msgBox;
225}
226// -----------------------------------------------------------------------------
227_OWLFUNC(int)
228OWLMessageBox(HWND wnd, const tstring& text, const tstring& caption, uint type)
229{
230 return OWLMessageBox(wnd, text.c_str(), caption.c_str(), type);
231}
232// -----------------------------------------------------------------------------
233_OWLFUNC(int)
235{
236 // If no parent is supplied need to use task modal to disable all toplevel
237 // windows in this task.
238 //
239 if (!wnd && !(type & MB_SYSTEMMODAL))
241
242 LPCTSTR _caption = caption; // Older compilers like Borland C++ 5.5 do not allow assigning new value to caption
243 if (_caption == nullptr)
245 return (GetApplicatData().OwlMsgBox)(wnd, text, _caption, type);
246}
247// -----------------------------------------------------------------------------
248_OWLFUNC(int)
249OWLMessageBox(TWindow* wnd, TResId resId, const tstring& caption, uint type, TModule* module)
250{
251 return OWLMessageBox(wnd, resId, caption.c_str(), type, module);
252}
253// -----------------------------------------------------------------------------
254_OWLFUNC(int)
255OWLMessageBox(TWindow* wnd, TResId resId, LPCTSTR caption, uint type, TModule* module)
256{
257 TModule& m = module ? *module : wnd && wnd->GetModule() ? *wnd->GetModule() : GetGlobalModule();
258 tstring text = m.LoadString(resId.GetInt());
259 LPCTSTR _caption = caption; // Older compilers like Borland C++ 5.5 do not allow assigning new value to caption
260 if (_caption == nullptr && wnd && wnd->GetApplication())
261 _caption = wnd->GetApplication()->GetName();
262
263 HWND h = wnd ? wnd->GetHandle() : static_cast<HWND>(nullptr);
264 return OWLMessageBox(h, text, _caption, type);
265}
266
267// -----------------------------------------------------------------------------
268//
269/// Gets WinMain's 3rd param.
270//
271tstring&
272TApplication::GetInitCmdLine()
273{
274 static tstring InitCmdLine;
275 return InitCmdLine;
276};
277
278//
279/// Constructor for use in OwlMain(). Gets members from statics set earlier by
280/// a call to InitWinMainParams() in Owl's WinMain.
281//
282/// Creates a new TApplication object named name. You can use owl::Module to specify the
283/// global module pointer that points to this application. The appDict parameter
284/// specifies which dictionary this application will insert itself into. To override
285/// the default ObjectWindows TAppDictionary object, pass a pointer to a
286/// user-supplied appDict object.
287//
288TApplication::TApplication(LPCTSTR name, TModule*& module, TAppDictionary* appDict)
289:
290 TModule(name, InitHInstance, GetInitCmdLine()),
291 TMsgThread(TMsgThread::Current),
292 // Copy over values that were stashed in static members before this instance
293 // was constructed.
294 //
295 hPrevInstance(InitHPrevInstance), nCmdShow(InitCmdShow),
296 DocManager(nullptr), MainWindow(nullptr),
297 LangId(LangUserDefault),
298 Tooltip(nullptr),
299 CmdLine(GetInitCmdLine()),
300 WaitCount(0),
301 WaitHandles(nullptr),
304#endif
307#endif
308 CurrentEvent(),
309 CurrentException(),
310 CondemnedWindows(nullptr),
311 Dictionary(appDict ? appDict : &(OWLGetAppDictionary()))
312{
313 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication constructing @") << (void*)this);
314
315 Dictionary->Add(this);
316 module = this;
317
318 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication constructed @") << (void*)this);
319}
320
321//
322/// String-aware overload
323//
325 :
326 TModule(name, InitHInstance, GetInitCmdLine()),
327 TMsgThread(TMsgThread::Current),
328 // Copy over values that were stashed in static members before this instance
329 // was constructed.
330 //
331 hPrevInstance(InitHPrevInstance), nCmdShow(InitCmdShow),
332 DocManager(nullptr), MainWindow(nullptr),
333 LangId(LangUserDefault),
334 Tooltip(nullptr),
335 CmdLine(GetInitCmdLine()),
336 WaitCount(0),
337 WaitHandles(nullptr),
340#endif
343#endif
344 CurrentEvent(),
345 CurrentException(),
346 CondemnedWindows(nullptr),
347 Dictionary(appDict ? appDict : &(OWLGetAppDictionary()))
348{
349 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication constructing @") << (void*)this);
350
351 Dictionary->Add(this);
352 module = this;
353
354 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication constructed @") << (void*)this);
355}
356
357//
358/// Constructor for use in user defined WinMain() when all the args are
359/// available
360//
361/// Creates a TApplication object with the application name (name), the application
362/// instance handle (instance), the previous application instance handle
363/// (prevInstance), the command line invoked (cmdLine), and the main window show
364/// flag (cmdShow). The appDict parameter specifies which dictionary this
365/// application will insert itself into. To override the default ObjectWindows
366/// TAppDictionary object, pass a pointer to a user-supplied appDict object.
367///
368/// If you want to create your own WinMain, use this constructor because it provides
369/// access to the various arguments provided by WinMain. You can use module to to
370/// specify the global module pointer that points to this application.
371//
373 (
377 const tstring& cmdLine,
378 int cmdShow,
379 TModule*& module,
381 )
382:
384 TMsgThread(TMsgThread::Current),
385 hPrevInstance(prevInstance), nCmdShow(cmdShow),
386 DocManager(nullptr), MainWindow(nullptr),
387 LangId(LangUserDefault),
388 Tooltip(nullptr),
389 CmdLine(cmdLine),
390 WaitCount(0),
391 WaitHandles(nullptr),
394#endif
397#endif
398 CurrentEvent(),
399 CurrentException(),
400 CondemnedWindows(nullptr),
401 Dictionary(appDict ? appDict : &(OWLGetAppDictionary()))
402{
403 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication constructing @") << (void*)this);
404
405 Dictionary->Add(this);
406 module = this;
407
408 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication constructed @") << (void*)this);
409}
410
411//
412/// String-aware overload
413//
415(
416 const tstring& name,
419 const tstring& cmdLine,
420 int cmdShow,
421 TModule*& module,
423)
424 :
426 TMsgThread(TMsgThread::Current),
427 hPrevInstance(prevInstance), nCmdShow(cmdShow),
428 DocManager(nullptr), MainWindow(nullptr),
429 LangId(LangUserDefault),
430 Tooltip(nullptr),
431 CmdLine(cmdLine),
432 WaitCount(0),
433 WaitHandles(nullptr),
436#endif
439#endif
440 CurrentEvent(),
441 CurrentException(),
442 CondemnedWindows(nullptr),
443 Dictionary(appDict ? appDict : &(OWLGetAppDictionary()))
444{
445 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication constructing @") << (void*)this);
446
447 Dictionary->Add(this);
448 module = this;
449
450 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication constructed @") << (void*)this);
451}
452
453//
454/// ~TApplication destroys the TApplication object.
455//
457{
458 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication destructing @") << (void*)this);
459
460 DeleteCondemned();
461
462#if defined(OWL_SUPPORT_CTL3D)
463 // Unregister ourselves from the Ctl3d DLL if it is loaded.
464 //
465 if (Ctl3dModule) {
466 Ctl3dModule->Unregister(*this);
467 delete Ctl3dModule;
468 }
469#endif
470#if defined(OWL_SUPPORT_BWCC)
471 // Unregister ourselves from the BWCC DLL if it is loaded.
472 if (BWCCModule) {
473 BWCCModule->IntlTerm();
474 delete BWCCModule;
475 }
476#endif
477
478 // Delete the main window if still present, may be destroyed but not deleted
479 // Set MainWindow to 0 first to prevent it from calling ::PostQuitMessage
480 //
481 TWindow* mainWindow = SetMainWindow(nullptr);
482 if (mainWindow) {
483 mainWindow->Destroy();
484 delete mainWindow;
485 delete Tooltip; // if SetMainWindow(0) need manually delete Tooltip
486 }
487
488 delete DocManager;
489
490 // Remove this app from the application dictionary that it is in
491 //
492 Dictionary->Remove(this);
493
494 TRACEX(OwlApp, OWL_CDLEVEL, _T("TApplication destructed @") << (void*)this);
495}
496
497
498//
499/// Displays a message in a modal pop-up dialog box.
500///
501/// By default, this function simply forwards to the eponymous Windows API function. However, a
502/// custom message box can be installed by calling \ref SetDefMessageBox.
503///
504/// \note If \p wnd is null, the \p type flag MB_TASKMODAL is automatically applied unless already
505/// set (or MB_SYSTEMMODAL is specified). Setting MB_TASKMODAL ensures that all other windows in
506/// the application are disabled during message display.
507///
508/// \note <br />The \p type flag MB_TASKMODAL requires a null window handle. If a non-null handle
509/// is passed along with this flag, the default message box will ignore it and behave as if
510/// MB_APPLMODAL (default) was passed. In debug builds, a diagnostic warning is generated.
511///
512/// \sa <a href="https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-messagebox" target="_blank">
513/// ::%MessageBox</a>, TWindow::MessageBox, SetDefMessageBox
514//
515int
517{
518 IFDIAG(const auto fun = to_tstring(__func__));
519
520 // Unless specified, set the caption to this application's name.
521 //
522 const auto caption = caption_ ? caption_ : GetName();
523
524 // If no handle is supplied, we need to use MB_TASKMODAL to disable all top-level windows.
525 //
526 const auto needTaskModal = !(type & (MB_TASKMODAL | MB_SYSTEMMODAL)) && !wnd;
527 if (needTaskModal)
529
531 << _T(": NULL handle without either MB_TASKMODAL or MB_SYSTEMMODAL is not allowed;")
532 << _T("Applying MB_TASKMODAL."));
533
534 WARNX(OwlApp, wnd && (type & MB_TASKMODAL), 0, fun
535 << _T(": MB_TASKMODAL with non-null handle behaves like MB_APPLMODAL (the default); ")
536 << _T("Use NULL handle for task-modal behaviour."));
537
538#if defined(OWL_SUPPORT_BWCC)
539 // Use the BWCC message box if BWCC is enabled
540 //
541 if (BWCCEnabled() && GetBWCCModule()) {
542 return GetBWCCModule()->MessageBox( wnd, text, caption, type);
543 }
544 else
545#endif
546 // Otherwise, 3d-ize the message box if ctl3d is enabled
547 //
548#if defined(OWL_SUPPORT_CTL3D)
549 {
551 int retValue = (GetApplicatData().OwlMsgBox)(wnd, text, caption, type);
553 return retValue;
554 }
555#else
556 return (GetApplicatData().OwlMsgBox)(wnd, text, caption, type);
557#endif
558}
559
560//
561/// Handle initialization for the first executing instance of the OWL
562/// application. Under Win32, every app instance is treated as the first.
563//
564/// Derived classes can override this to perform app initialization, or they
565/// can use the derived class constructor.
566//
567/// The following sample program calls InitApplication the first time an instance of
568/// the program begins.
569/// \code
570/// class TTestApp : public TApplication {
571/// public:
572/// TTestApp(): TApplication("Instance Tester")
573/// { strcpy(WindowTitle, "Additional Instance");}
574/// protected:
575/// char WindowTitle[20];
576/// void InitApplication() { strcpy(WindowTitle, "First Instance"); }
577/// void InitMainWindow() { MainWindow = new TFrameWindow(0, WindowTitle); }
578/// };
579/// static TTestApp App;
580/// \endcode
581//
582void
584{
585 TRACEX(OwlApp, 1, _T("TApplication::InitApplication() called @") << (void*)this);
586}
587
588
589//
590/// Performs each instance initialization necessary for the application. Unlike
591/// InitApplication(), which is called for the first instance of an application,
592/// InitInstance is called whether or not there are other executing instances of the
593/// application. InitInstance calls InitMainWindow(), and then creates and shows the
594/// main window element by TWindow::Create and TWindow::Show. If the main window
595/// cannot be created, a TXInvalidMainWindow exception is thrown.
596//
597/// \note If you redefine this member function, be sure to explicitly call
598/// TApplication::InitInstance.
599//
600void
602{
604
605 TRACEX(OwlApp, 1, _T("TApplication::InitInstance() called @") << (void*)this);
606
608
609 if (MainWindow) {
610 MainWindow->SetFlag(wfMainWindow);
611 MainWindow->Create();
612
613#if defined(__TRACE) || defined(__WARN)
614
615 TSystemMenu sysMenu{MainWindow->GetHandle()};
616 if (sysMenu.IsOK())
617 {
618 sysMenu.AppendMenu(MF_SEPARATOR);
619 sysMenu.AppendMenu(MF_STRING, ScmTrace, _T("Diagnostic Window"));
620 }
621
622#endif
623
624 MainWindow->ShowWindow(nCmdShow);
625 }
626 else
628}
629
630
631//
632/// Initialize the application's main window. Derived classes should override
633/// this to construct, initialize and set the main window using SetMainWindow().
634//
635/// By default, InitMainWindow constructs a generic TFrameWindow object with the
636/// name of the application as its caption. You can redefine InitMainWindow to
637/// construct a useful main window object of TFrameWindow (or a class derived from
638/// TFrameWindow) and store it in MainWindow. The main window must be a top-level
639/// window; that is, it must be derived from TFrameWindow. A typical use is
640/// \code
641/// virtual void TMyApp_InitMainWindow(){
642/// SetMainWindow(TMyWindow(nullptr, Caption));
643/// }
644/// \endcode
645/// InitMainWindow can be overridden to create your own custom window.
646//
647void
652
653
654//
655/// Handle termination for each executing instance of the application. Called
656/// at the end of a Run() with the final return status.
657//
658int
660{
661 TRACEX(OwlApp, 1, _T("TApplication::TermInstance() called @") << (void*)this);
662
663#if defined(__TRACE) || defined(__WARN)
664
665 // If open, destroy the Diagnostic Window.
666 // See ProcessAppMsg, where the window is created.
667 //
670
671#endif
672
673 return TMsgThread::TermInstance(status);
674}
675
676//
677/// Set (or reset) the main window. Return, but do not destroy the previous
678/// main window.
679//
682{
683 if (MainWindow) {
684 MainWindow->ClearFlag(wfMainWindow);
685 uint32 style = MainWindow->GetExStyle();
686 if (style & WS_EX_APPWINDOW)
687 MainWindow->SetExStyle(style & ~WS_EX_APPWINDOW);
688 if(Tooltip && Tooltip->GetParentO()==MainWindow)
689 Tooltip->SetParent(nullptr);
690 }
691
692 TFrameWindow* oldMainWindow = MainWindow;
693 MainWindow = window;
694
695 if (MainWindow) {
696 MainWindow->SetFlag(wfMainWindow);
697 uint32 style = MainWindow->GetExStyle();
698 if (!(style & WS_EX_APPWINDOW))
699 MainWindow->SetExStyle(style | WS_EX_APPWINDOW);
700 // set new parent only if MainWindow created
701 if(Tooltip && Tooltip->GetParentO()==nullptr && MainWindow->GetHandle())
702 Tooltip->SetParent(MainWindow);
703 }
704 return oldMainWindow;
705}
706
707//
708/// Smart-pointer-aware overload.
709//
710auto TApplication::SetMainWindow(std::unique_ptr<TFrameWindow> f) -> std::unique_ptr<TFrameWindow>
711{
712 auto old = std::unique_ptr<TFrameWindow>{SetMainWindow(f.get())};
713 f.release(); // We took ownership.
714 return old;
715}
716
717//
718/// Set (or resets) the document manager, return the previous one if present
719//
722{
723 TDocManager* oldDocManager = DocManager;
724 DocManager = docManager;
725 return oldDocManager;
726}
727
728//
729/// Smart-pointer-aware overload.
730//
731auto TApplication::SetDocManager(std::unique_ptr<TDocManager> d) -> std::unique_ptr<TDocManager>
732{
733 auto old = std::unique_ptr<TDocManager>{SetDocManager(d.get())};
734 d.release(); // We took ownership.
735 return old;
736}
737
738#if defined(BI_MULTI_THREAD_RTL)
739//
740/// BI_MULTI_THREAD_RTL only: Overrides TEventHandler::Dispatch() to handle
741/// multi-thread synchonization.
742//
744{
745 TApplication::TQueueLock lock(*this);
747}
748#endif
749
750//
751/// Run this application, return when application terminates
752//
753/// Initialize instances, create and display their main window (calls
754/// InitApplication for the first executing instance and calls InitInstance for
755/// all instances). Run the application's message loop. Each of the virtual
756/// functions called are expected to throw an exception if there is an error.
757///
758/// Exceptions are propagated out of this function, but the message queue is still
759/// flushed and TermInstance called in the event of an exception.
760//
761int
763{
764 try
765 {
766 if (!MainWindow)
767 {
768 if (!hPrevInstance)
770 InitInstance();
771 }
772 LoopRunning = true;
773 int status = MessageLoop();
774 FlushQueue();
775 LoopRunning = false;
776 return TermInstance(status);
777 }
778 catch (...)
779 {
780 FlushQueue();
781 LoopRunning = false;
782 TermInstance(-1);
783 throw;
784 }
785}
786
787//
788/// Start this application and return immediately. Used for component DLLs
789//
790/// Initializes instances, creating and displaying their main window (calls
791/// InitApplication for the first executing instance and calls InitInstance for
792/// all instances). Each of the virtual functions called are expected to throw
793/// an exception if there is an error. Any exceptions are handled and converted
794/// to an error code which is then returned. Returns 0 on success.
795/// Does not run message loop.
796//
797int
799{
800 int status = 0;
801 try {
802 if (!hPrevInstance)
804 InitInstance();
805 }
806 catch (TXOwl& x) {status = x.Unhandled(this, 0);}
807 catch (TXBase& x) {status = Error(x, 0);}
808 catch (...) {status = -1;}
809 return status;
810}
811
812//
813/// Operates the application's message loop, which runs during the lifetime of the
814/// application. MessageLoop queries for messages. If one is received, it processes
815/// it by calling ProcessAppMsg. If the query returns without a message, MessageLoop
816/// calls IdleAction to perform some processing during the idle time.
817///
818/// MessageLoop calls PumpWaitingMessages to get and dispatch waiting messages.
819/// MessageLoop can be broken if BreakMessageLoop is set by EndModal.
820//
821int
823{
824 long idleCount = 0;
826 while (!BreakMessageLoop)
827 {
828 try
829 {
830 if (!IdleAction(idleCount++))
831 {
832 DWORD r = MsgWaitForMultipleObjects(WaitCount, WaitHandles, FALSE, INFINITE, QS_ALLINPUT);
833 if (r >= WAIT_OBJECT_0 && r < WAIT_OBJECT_0 + WaitCount)
834 ObjectSignaled(WaitHandles[r - WAIT_OBJECT_0], false);
835 else if (r >= WAIT_ABANDONED_0 && r < WAIT_ABANDONED_0 + WaitCount)
836 ObjectSignaled(WaitHandles[r - WAIT_ABANDONED_0], true);
837 }
839 idleCount = 0;
840 ResumeThrow();
841 }
842 catch (...)
843 {
844 BreakMessageLoop = true;
846 throw;
847 }
848 }
849 BreakMessageLoop = false;
850 return MessageLoopResult;
851}
852
853//
854/// Called each time there are no messages in the queue. Idle count is
855/// incremented each time, & zeroed when messages are pumped. Return
856/// whether or not more processing needs to be done.
857//
858/// Default behavior is to give the main window an opportunity to do idle
859/// processing by invoking its IdleAction() member function when
860/// "idleCount" is 0
861//
862bool
864{
865 TRACEX(OwlApp, 1, _T("TApplication::IdleAction() called @") << (void*)this <<
866 _T(" idleCount ") << idleCount);
867 bool more = false;
868 if (MainWindow)
869 more = MainWindow->IdleAction(idleCount);
870
871#if defined(__TRACE) || defined(__WARN)
872
873 // If open, let the Diagnostic Window process diagnostics.
874 // See TApplication::ProcessAppMsg, where the window is opened (or closed).
875 //
876 const auto diagIdleAction = [](long idleCount)
877 {
878 LOCKAPPLDATA(GetApplicatData().Lock, true);
879 bool more = false;
880 const auto t = TTraceWindow::GetInstance();
881 if (t && t->IdleAction(idleCount))
882 more = true;
883 return more;
884 };
886 more = true;
887
888#endif
889
890 return more;
891}
892
893//
894/// Called for each message that is pulled from the queue, to perform all
895/// translation & dispatching.
896///
897/// Return true to drop out of pump
898//
899bool
901{
902 // Let the app preprocess the message. If it is not eaten, then translate
903 // it, & dispatch it. If no HWND, then first find/dispatch it directly
904 // to the app (for PostAppMessage() functionality)
905 //
906 if (!ProcessAppMsg(msg)) {
908 if (!msg.hwnd) {
909 TEventInfo cmdEventInfo(msg.message, static_cast<uint>(msg.wParam));
910 if (Find(cmdEventInfo)) {
911 Dispatch(cmdEventInfo, msg.wParam, msg.lParam);
912 return true;
913 }
914 else {
915 TEventInfo eventInfo(msg.message);
916 if (Find(eventInfo)) {
917 Dispatch(eventInfo, msg.wParam, msg.lParam);
918 return true;
919 }
920 }
921 }
923 DeleteCondemned();
924 ResumeThrow();
925 }
926 return false;
927}
928
929//
930/// Called after each message is pulled from the queue, and before it is
931/// dispatched. Return true if the message was handled completely here.
932//
933/// Checks for any special processing that is required for modeless dialog box,
934/// accelerator, and MDI accelerator messages. Calls the virtual
935/// TWindow::PreProcessMsg function of the window receiving the message. If your
936/// application does not create modeless dialog boxes, does not respond to
937/// accelerators, and is not an MDI application, you can improve performance by
938/// overriding this member function to return false.
939//
940bool
942{
943 // Check if this message might be worth relaying to the tooltip window
944 //
945 if (Tooltip && Tooltip->IsWindow()) {
946 if (msg.hwnd == *MainWindow || MainWindow->IsChild(msg.hwnd)) {
947 if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST) {
948 Tooltip->RelayEvent(msg);
949 }
950 }
951 }
952
953 // Start with the window that the event was destined for and allow it
954 // and its parent (and its parent...) an opportunity to preprocess the
955 // event
956 //
957 for (HWND hWnd = msg.hwnd; hWnd; hWnd = ::GetParent(hWnd)) {
958 // NT seems very picky about calls to ::GetWindowThreadProcessId
959 // with the HWND of the desktop. Hence we'll abort this loop
960 // when encountering the desktop. Specially useful when dealing with
961 // DropDown[List] ComboBoxes thunked by OWL when hit the ComboLBox
962 // window which is parented to the Desktop.
963 //
964 static HWND deskTopHwnd = ::GetDesktopWindow();
965 if (hWnd == deskTopHwnd)
966 break;
967
968 TWindow* win = GetWindowPtr(hWnd);
969
970 if (win && win->PreProcessMsg(msg))
971 return true;
972 }
973
974 return false;
975}
976
978{
979 bool exists = false;
980 int index;
981
982 if (WaitHandles)
983 {
984 for (int i = 0; i < static_cast<int>(WaitCount); i++) //JJH added static_cast
985 if (WaitHandles[i] == handle)
986 {
987 exists = true;
988 index = i;
989 }
990 }
991
992 if (wait)
993 {
994 if (!exists)
995 {
996 LPHANDLE newHandles = new HANDLE[WaitCount + 1];
997 for (int i = 0; i < static_cast<int>(WaitCount); i++) //JJH added static_cast
998 newHandles[i] = WaitHandles[i];
999 delete[] WaitHandles;
1000 WaitHandles = newHandles;
1001 WaitHandles[WaitCount] = handle;
1002 WaitCount++;
1003 }
1004 }
1005 else
1006 {
1007 if (exists)
1008 {
1009 if (WaitCount == 1)
1010 {
1011 delete[] WaitHandles;
1012 WaitHandles = nullptr;
1013 WaitCount = 0;
1014 }
1015 else
1016 {
1017 LPHANDLE newHandles = new HANDLE[WaitCount - 1];
1018
1019 int i;
1020 for (i = 0; i < index; i++)
1021 newHandles[i] = WaitHandles[i];
1022 for (i = index + 1; i < static_cast<int>(WaitCount); i++) //JJH added static_cast
1023 newHandles[i-1] = WaitHandles[i];
1024 delete[] WaitHandles;
1025 WaitHandles = newHandles;
1026 WaitCount--;
1027 }
1028 }
1029 }
1030}
1031
1032//
1033/// Stores the given exception so that it can be rethrown later by a call to ResumeThrow.
1034/// Calls PostQuitMessage to break the application message loop, thus ensuring that the
1035/// application will not linger in a corrupt state.
1036//
1037void
1039{
1040 TRACEX(OwlApp, 0, _T("TApplication::SuspendThrow: Suspending exception and posting quit-message."));
1041 CurrentException = e;
1043}
1044
1045//
1046/// Rethrows the suspended exception stored by a previous call to SuspendThrow.
1047/// Otherwise, if no exception has been suspended, does nothing.
1048//
1049void
1051{
1052 if (CurrentException == nullptr) return;
1053
1054 TRACEX(OwlApp, 0, _T("TApplication::ResumeThrow: Rethrowing suspended exception."));
1055 exception_ptr e = CurrentException;
1056 CurrentException = exception_ptr(); // clear
1058}
1059
1060
1061//
1062/// If TApplication's message loop is not used, this function should be called after
1063/// each message is dispatched
1064//
1065void
1067{
1068 DeleteCondemned();
1069 ResumeThrow();
1070
1071 MSG msg;
1072 if (!::PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE))
1073 IdleAction(0);
1074}
1075
1076
1077//
1078//
1079//
1080void
1082{
1083 if (!Tooltip) {
1084 // To circumvent this scenario, we'll look for a window which is fairly
1085 // stable/rooted as owner of the tooltip. Ideally, we'll get the
1086 // application's main window.
1087 //
1088 TWindow* tipParent = MainWindow;
1089 if(!MainWindow->GetHandle())
1090 tipParent = nullptr;
1091 // Create and initialize tooltip
1092 //
1094 }
1095 else {
1096 if (Tooltip->GetHandle())
1097 Tooltip->Activate(enable);
1098 }
1099}
1100
1101//
1102/// Set tooltip . Assume we now own the ToolTip
1103//
1104void
1106{
1107 // Cleanup; via Condemned list if tooltip was created
1108 //
1109 if (Tooltip) {
1110 if (Tooltip->GetHandle())
1111 Tooltip->SendMessage(WM_CLOSE);
1112 else
1113 delete Tooltip;
1114 }
1115
1116 // Store new tooltip and create if necessary
1117 // Create only if MainWindows already created
1118 Tooltip = tooltip;
1119 if (Tooltip && !Tooltip->GetHandle() &&
1120 MainWindow && MainWindow->GetHandle()) {
1121 if(!Tooltip->GetParentO())
1122 Tooltip->SetParent(MainWindow);
1123 // Make sure tooltip is disabled so it does not take input focus
1124 Tooltip->ModifyStyle(0,WS_DISABLED);
1125 Tooltip->Create();
1126 }
1127}
1128
1129//
1130/// Does internal processing of system menu messages.
1131/// In particular, it handles the command "Diagnostic Window" on the system menu in debug builds.
1132//
1133void TApplication::EvSysCommand([[maybe_unused]] uint cmd, const TPoint&)
1134{
1135
1136#if defined(__TRACE) || defined(__WARN)
1137
1138 // If the user selects ScmTrace ("Diagnostic Window") from the main window's system menu,
1139 // then create the Diagnostic Window, if it does not already exist, or destroy it, if it does.
1140 // See InitInstance, where the menu item is created for the debug build.
1141 // See IdleAction, where diagnostic messages are processed.
1142 // See TermInstance, where the window is closed on exit.
1143 //
1144 switch (cmd & 0xFFF0)
1145 {
1146 case ScmTrace:
1147 {
1148 LOCKAPPLDATA(GetApplicatData().Lock, false);
1151 else
1152 {
1153 const auto t = TTraceWindow::GetInstance(true);
1154 t->Create();
1155 t->ShowWindow(SW_SHOWNORMAL);
1156 }
1157 return;
1158 }
1159 }
1160
1161 // Update the checkmark on the system menu command "Diagnostic Window".
1162 //
1163 if (cmd & (SC_KEYMENU | SC_MOUSEMENU))
1164 if (const auto w = GetMainWindow())
1165 if (const auto h = w->GetHandle())
1166 {
1168 TSystemMenu{h}.CheckMenuItem(ScmTrace, MF_BYCOMMAND | c);
1169 }
1170
1171#endif
1172
1173 if (const auto m = GetMainWindow())
1174 m->DefaultProcessing();
1175}
1176
1177//
1178/// Close down main window if application receives a CM_EXIT command.
1179//
1180void
1181TApplication::CmExit()
1182{
1183 TFrameWindow* frame = GetMainWindow();
1184 if (frame) {
1185 frame->SendMessage(WM_CLOSE);
1186 DeleteCondemned();
1187 }
1188}
1189
1190//
1191/// Overrides TEventHandler::Find.
1192/// If a DocManager has been installed, TDocManager::Find is called first to give it an opportunity
1193/// to handle the event.
1194///
1195/// \note Since TApplication needs a custom implementation of Find, the common implementation
1196/// provided by the response table macros can not be used. For that reason, the response table for
1197/// TApplication is implemented explicitly within this function.
1198//
1199auto TApplication::Find(TEventInfo& eventInfo, TEqualOperator equal) -> bool
1200{
1201 const auto r = DocManager ? DocManager->Find(eventInfo, equal) : false;
1202 if (r) return true;
1203
1204#if OWL_NEW_RESPONSE_TABLE
1205
1206 using TEntry = TResponseTableEntry;
1207
1208#else
1209
1210 using TEntry = TResponseTableEntry<TApplication>;
1211 using TMyPMF = TResponseTableEntry<TApplication>::PMF; // Needed for the reponse table macros.
1212
1213#endif
1214
1215 using TMyClass = TApplication; // Needed for the reponse table macros.
1216 static const TEntry entries[] =
1217 {
1219 EV_COMMAND(CM_EXIT, CmExit),
1220 {} // Sentinel is required.
1221 };
1222 eventInfo.Object = reinterpret_cast<TGeneric*>(this);
1223 return SearchEntries(reinterpret_cast<const TGenericTableEntry*>(entries), eventInfo, equal) ||
1225}
1226
1227//
1228/// Determine whether the application can be closed.
1229/// Makes sure the MainWindow can close & doc manager can close.
1230//
1231/// Returns true if it is OK for the application to close. By default, CanClose
1232/// calls the CanClose member function of its main window and returns true if both
1233/// the main window and the document manager (TDocManager) can be closed. If any of
1234/// the CanClose functions return false, the application does not close.
1235///
1236/// This member function is seldom redefined; closing behavior is usually redefined
1237/// in the main window's CanClose member function, if needed.
1238//
1239bool
1241{
1243 return (!MainWindow || MainWindow->CanClose())
1244 && (!DocManager ||!DocManager->Find(eventInfo)
1245 || DocManager->Dispatch(eventInfo, 0, 0));
1246}
1247
1248//
1249/// Called by the main window to provide an oportunity to preprocess the main
1250/// window's menubar before it is installed.
1251/// Normally delegated to the doc manager to install a file menu as needed
1252//
1253void
1255{
1257 if (DocManager && DocManager->Find(eventInfo)) {
1258 DocManager->Dispatch(eventInfo, TParam1(hMenubar), 0);
1259 MainWindow->DrawMenuBar();
1260 }
1261}
1262
1263//
1264/// Condemns the given window to be deleted the at the next available safe time.
1265///
1266/// Appends the window to the list of condemned windows.
1267///
1268/// \note Condemned windows should be removed (see TApplication::Uncondemn) if they are destructed
1269/// in the mean time through some other mechanism (i.e. stack, aggregate, etc).
1270///
1271/// \note It is assumed that the condemned window was constructed using `new`. If it was
1272/// constructed by other means, do not pass it to this function. Instead ensure it is destructed in
1273/// the appropriate way.
1274///
1275/// \note While it in previous versions of OWLNext was unsafe for a window in the process of
1276/// destruction to condemn other windows (e.g. child or buddy), it is now safe to do so.
1277///
1278/// \note If the window is already in the list of condemned windows, the function does nothing.
1279//
1280void
1282{
1283 PRECONDITION(win);
1284 TRACEX(OwlApp, 1, _T("Condemning window @") << (void*)win << *win);
1285
1286 // Insert the new window to be deleted at the end of the list.
1287 //
1288 if (!CondemnedWindows)
1289 {
1290 CondemnedWindows = win; // Simply set head.
1291 }
1292 else
1293 {
1294 // Find end of list (while also checking for redundant condemnation).
1295 //
1296 TWindow* eol = nullptr;
1297 for (TWindow* w = CondemnedWindows; w; eol = w, w = w->Next())
1298 if (w == win)
1299 {
1300 WARNX(OwlApp, true, 0, _T("TApplication::Condemn: Redundant condemnation, win: ") << *win);
1301 return; // Ignore redundant condemnation.
1302 }
1303 CHECK(eol && !eol->Next());
1304 eol->SetNext(win); // Update end of list.
1305 }
1306 win->SetParent(nullptr); // NOTE: Must be called before SetNext(nullptr), since it assumes the sibling list is circular.
1307 win->SetNext(nullptr); // Terminate list of condemned windows.
1308}
1309
1310//
1311/// Removes the given window from the list of condemned windows.
1312/// If the given window is not in the list of condemned windows, the function does nothing.
1313//
1314void
1316{
1317 if (win && CondemnedWindows) {
1318 TWindow* w = nullptr;
1319 if (CondemnedWindows != win)
1320 for (w = CondemnedWindows; w->Next() != win; w = w->Next())
1321 if (!w->Next())
1322 return;
1323
1324 TRACEX(OwlApp, 1, _T("Uncondemning window @") << (void*)win << *win);
1325 if (w)
1326 w->SetNext(win->Next());
1327 else
1328 CondemnedWindows = win->Next();
1329 }
1330}
1331
1332//
1333/// Deletes all entries in the list of condemned windows.
1334///
1335/// If new additions to the list of condemned windows are made in the process of deleting the
1336/// condemned windows, these additions are also deleted, and so on, until the list of condemned
1337/// windows is empty.
1338///
1339/// \note It is assumed that the condemned windows were constructed using `new`, as each entry is
1340/// destructed using `delete`.
1341//
1342void
1343TApplication::DeleteCondemned()
1344{
1345 // Note that deleting a condemned window will cause its destructor to be called, which may call
1346 // TApplication::Condemn as part of the destruction (e.g. condemning its children or a buddy).
1347 // The original code did not support this, as it simply walked the linked list while deleting the
1348 // nodes, thereby possibly crashing or ignoring additions to the list while traversing it. For
1349 // more robust code, we now copy the condemned windows into a temporary vector, then clear the
1350 // list (ready for additions), and finally delete the condemned windows collected in the vector.
1351 // In case there were additions while deleting, we repeat this sequence until the condemned list
1352 // is empty.
1353 //
1354 do
1355 {
1356 auto c = vector<TWindow*>{};
1357 while (CondemnedWindows)
1358 {
1359 const auto next = CondemnedWindows->Next();
1360 c.push_back(CondemnedWindows);
1361 CondemnedWindows = next;
1362 }
1363 for (const auto w : c)
1364 {
1365 TRACEX(OwlApp, 1, _T("Deleting condemned window @") << w << *w);
1366 delete w;
1367 }
1368 }
1369 while (CondemnedWindows);
1370}
1371
1372
1373
1374//
1375/// Constructs a TXInvalidMainWindow object with a default IDS_INVALIDMAINWINDOW
1376//
1382
1385{
1386 return new TXInvalidMainWindow(*this);
1387}
1388
1389//
1390/// Throws the exception object. Throw must be implemented in any class derived from
1391/// TXOwl.
1392//
1393void
1395{
1396 throw *this;
1397}
1398
1399//
1400/// Throws a TXInvalidMainWindow exception.
1401//
1402void
1407
1408
1409//
1410/// Enum[Thread/Task]Windows callback. Counts or disables given window based on
1411/// whether or not window list has been allocated yet.
1412//
1413static bool CALLBACK
1414disableWnds(HWND hWnd, TEnumInfo * ei)
1415{
1416 if (!(::GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)) {
1417 if (hWnd != ei->ModalWnd && ::IsWindowEnabled(hWnd)) {
1418 if (!ei->Wnds) {
1419 ei->Count++; // no buffer yet, we are just counting
1420 }
1421 else {
1422 *(ei->Wnds++) = hWnd;
1423 ::EnableWindow(hWnd, false);
1424 }
1425 }
1426 }
1427 return true;
1428}
1429
1430//
1431/// Terminate the modal state initiated by BeginModal. Needs topmost ei block,
1432/// and cleans the block up as needed inorder to be safe to be called twice.
1433//
1434static void termModal(TEnumInfo& ei)
1435{
1436 // Re-enable window(s) that are disabled in BeginModal()
1437 //
1438 if (ei.Wnds) {
1439 for (HWND* hWnd = ei.Wnds; *hWnd; hWnd++)
1440 ::EnableWindow(*hWnd, true);
1441 delete[] ei.Wnds;
1442 ei.Wnds = nullptr;
1443 }
1444 else {
1445 if (ei.ModalWnd && IsWindow(ei.ModalWnd)) {
1446 ::EnableWindow(ei.ModalWnd, true);
1447 ei.ModalWnd = nullptr;
1448 }
1449 }
1450}
1451
1452//
1453/// Called to begin a modal window's modal message loop. After determining which
1454/// window to disable, BeginModal saves the current status of the window, disables
1455/// the window, calls MessageLoop, and then reenables the window when the message
1456/// loop is finished. The flags determine how BeginModal treats the window. flags
1457/// can be one of the following values:
1458///
1459/// - \c \b MB_APPLMODAL The window to be disabled (which is usually an ancestor of the
1460/// modal window) is identified by window. If window is 0, no window is disabled.
1461/// - \c \b MB_SYSTEMMODAL The window to become system modal is identified by window.
1462/// - \c \b MB_TASKMODAL All top-level windows are disabled, and window is ignored.
1463///
1464/// BeginModal returns -1 if an error occurs.
1465//
1466int
1468{
1469 // lock enuminfo if multithreading
1470 TEnumInfo ei = { nullptr, 0, nullptr, nullptr};
1471 TEnumInfo* lastStackTop;
1472 {
1473 TEnumInfoStr& data = GetEnumInfo();
1474 LOCKENUMINFO(data.Lock, false); // Y.B. do we have do lock here ?????????
1475 lastStackTop = data.GetInfo(); // Keep last stackTop to restore later
1476 data.SetInfo(&ei); // Point stackTop to topmost ei
1477 }
1478
1479 // The concept of SYSTEM MODAL applies only to the 16-bit environment of
1480 // Windows. The semantics of TASKMODAL is the closest to SYSMODAL in
1481 // 32-bit - specially in relation to the meaning of the 'window' parameter.
1482 // So we'll coerce SYSTEM MODAL to TASK MODAL
1483 //
1484 if (flags & MB_SYSTEMMODAL) {
1485 flags &= ~MB_SYSTEMMODAL;
1486 flags |= MB_TASKMODAL;
1487 }
1488
1489 // Check modal state
1490 //
1491 if (flags & MB_TASKMODAL) {
1492 LOCKENUMINFO(GetEnumInfo().Lock, false); // lock data
1493 // Save the window to make modal
1494 //
1495 if (window)
1496 ei.ModalWnd = window->GetHandle();
1497
1498 // Count windows to disable
1499 //
1501 TParam2(static_cast<TEnumInfo *>(&ei))))
1502 return -1;
1503
1504 // Allocate list of windows to disable, disable windows that are
1505 // enabled and then stuff them into the list.
1506 //
1507 HWND* hWnds = ei.Wnds = new HWND[ei.Count + 1];
1508 memset(ei.Wnds, 0, sizeof(TModule::THandle)*(ei.Count + 1));
1509
1510 EnumThreadWindows(GetCurrentThreadId(), reinterpret_cast<WNDENUMPROC>(disableWnds),
1511 TParam2(reinterpret_cast<TEnumInfo *>(&ei)));
1512
1513 ei.Wnds = hWnds; // Restore alloc'd pointer since enumerator bumps it
1514 }
1515
1516 else if (window) {
1517
1518 // In MB_APPMODAL mode, we simply disable the window specified
1519 //
1520 ei.ModalWnd = window->GetHandle(); // Remember who to re-enable later
1521 CHECK(ei.ModalWnd);
1522 window->EnableWindow(false);
1523 }
1524
1525 // Enter message loop, saving & restoring the current status & getting the
1526 // returned result.
1527 //
1528 int result;
1529 try {
1530 result = MessageLoop();
1531 }
1532 catch (...) {
1533 TEnumInfoStr& data = GetEnumInfo();
1534 LOCKENUMINFO(data.Lock, false);
1535 termModal(ei);
1536 data.SetInfo(lastStackTop);
1537 throw;
1538 }
1539
1540 {
1541 TEnumInfoStr& data = GetEnumInfo();
1542 LOCKENUMINFO(data.Lock, false);
1543 data.SetInfo(lastStackTop);
1544 termModal(ei); // Just in case termModal was missed in EndModal
1545 }
1546
1547 // Return the result from the modal window's EndModal call
1548 //
1549 return result;
1550}
1551
1552//
1553/// Cause the current modal message loop to break and have it return a result
1554/// Re-enable the disabled windows here, if the EnumInfo is available.
1555//
1556void
1558{
1559 MessageLoopResult = result;
1560 BreakMessageLoop = true;
1561 TEnumInfoStr& data = GetEnumInfo();
1562 if (data.GetInfo()){
1563 LOCKENUMINFO(data.Lock, false);
1564 termModal(*data.GetInfo());
1565 }
1566}
1567
1568//----------------------------------------------------------------------------
1569#if defined(OWL_SUPPORT_BWCC)
1570
1571#if !defined(BWCCVERSION) // solely foe WARNX
1572#define BWCCVERSION 0x0200 // version 2.00
1573#endif
1574
1575//
1576/// Loads and registers either BWCC.DLL if you are running 16-bit applications or
1577/// BWCC32.DLL if you are running 32-bit applications.
1578/// To disable BWCC, set enable to false.
1579/// Library is not free'd on disable to reduce re-loads if enabling on the fly
1580/// \note BWCC is now obsolete and should be used only for backward compatibility
1581void
1582TApplication::EnableBWCC(bool enable, uint language)
1583{
1584 if (enable) {
1585 if (!BWCCModule) {
1586 try {
1587 BWCCModule = new TBwccDll();
1588 BWCCModule->IntlInit(language);
1589 BWCCModule->Register(GetHandle());
1590
1591 WARNX(OwlApp, BWCCModule->GetVersion() < BWCCVERSION, 0, \
1592 _T("Old version of BWCC DLL found"));
1593 }
1594 catch (...) {
1595 TRACEX(OwlApp, 0, _T("Unable to create instance of TBwccDll"));
1596 return;
1597 }
1598 }
1599 }
1600 BWCCOn = enable;
1601}
1602
1603#endif //#if defined(OWL_SUPPORT_BWCC)
1604//----------------------------------------------------------------------------
1605#if defined(OWL_SUPPORT_CTL3D)
1606
1607//
1608/// Enables or disables the use of the CTL3D DLL. If enable is true, EnableCtl3d
1609/// loads and registers the CTL3D.DLL if it is not already enabled.
1610/// \note Usage of Ctl3d is now obsolete and should be used only for backward compatibility
1611//
1612void
1613TApplication::EnableCtl3d(bool enable)
1614{
1615 // As per Article Q125684 of Microsoft Development Library:
1616 // "If major version is 4 or greater, the application should not
1617 // implement CTL3D".
1618 // 'How to Use CTL3D Under the Windows 95 Operating System'
1619 //
1620 if (TSystem::GetMajorVersion() >= 4)
1621 return;
1622
1623 // Load the Ctl3d DLL if needed & register our instance
1624 //
1625 if (enable) {
1626 if (!Ctl3dModule) {
1627 try {
1628 Ctl3dModule = new TCtl3dDll();
1629 Ctl3dModule->Register(*this);
1630 }
1631 catch (...) {
1632 TRACEX(OwlApp, 0, _T("Unable to create instance of TCtl3dDll"));
1633 return;
1634 }
1635 }
1636 }
1637 Ctl3dOn = enable;
1638}
1639
1640//
1641/// Enable or disable Ctl3d's use of auto-subclassing.
1642//
1643/// Caller should turn on autosubclassing before creating a non-owl dialog to
1644/// make it 3d, & turn it off immediatly after.
1645///
1646/// Enables or disables CTL3D's use of autosubclassing if CTL3D is already enabled
1647/// using Ctl3dEnabled. If autosubclassing is enabled, any non-ObjectWindows dialog
1648/// boxes have a 3-D effect. The common dialog classes and TDocManager use this
1649/// function both to turn on autosubclassing before creating a non-ObjectWindows
1650/// dialog box to make it three-dimensional and to turn off autosubclassing
1651/// immediately after the dialog box is destroyed.
1652//
1653void
1654TApplication::EnableCtl3dAutosubclass(bool enable) const
1655{
1656 if (Ctl3dEnabled()) {
1657 if (enable) {
1658 Ctl3dModule->Register(*this);
1659 Ctl3dModule->AutoSubclass(*this);
1660 }
1661 else {
1662 Ctl3dModule->Unregister(*this);
1663 }
1664 }
1665}
1666
1667#endif //#if defined(OWL_SUPPORT_CTL3D)
1668//----------------------------------------------------------------------------
1669#if defined(OWL_SUPPORT_BWCC)
1670
1671//
1672/// Predefined DLLs that TApplication knows how to find.
1673//
1674 const tchar BwccDllName[] = _T("BWCC32.DLL");
1675
1676//
1677/// Load the BWCC DLL dynamically.
1678/// Bind the member functions to the exported functions.
1679//
1680/// This is how TApplication::EnableBWCC uses TBwccDll:
1681/// \code
1682/// if (!BWCCModule) {
1683/// try {
1684/// BWCCModule = new TBwccDll();
1685/// BWCCModule->IntlInit(language);
1686/// BWCCModule->Register(GetHandle());
1687///
1688/// WARNX(OwlApp, BWCCModule->GetVersion() < BWCCVERSION, 0, \\
1689/// _T("Old version of BWCC DLL found"));
1690/// }
1691/// catch (...) {
1692/// TRACEX(OwlApp, 0, _T("Unable to create instance of TBwccDll"));
1693/// return;
1694/// }
1695/// \endcode
1696//
1697TBwccDll::TBwccDll()
1698:
1699 TModule(BwccDllName, true, true, false), // shouldLoad, mustLoad and !addToList
1700
1701 IntlInit(*this, "BWCCIntlInit"),
1702 Register(*this, "BWCCRegister"),
1703 IntlTerm(*this, "BWCCIntlTerm"),
1704
1705 SpecialLoadDialog(*this, "SpecialLoadDialog"),
1706 MangleDialog(*this, "MangleDialog"),
1707 DefDlgProc(*this, "BWCCDefDlgProc"),
1708 DefGrayDlgProc(*this, "BWCCDefGrayDlgProc"),
1709 DefWindowProc(*this, "BWCCDefWindowProc"),
1710 DefMDIChildProc(*this, "BWCCDefMDIChildProc"),
1711 MessageBox(*this, "BWCCMessageBox"),
1712 GetPattern(*this, "BWCCGetPattern"),
1713 GetVersion(*this, "BWCCGetVersion")
1714{
1715}
1716
1717#endif //#if defined(OWL_SUPPORT_BWCC)
1718//----------------------------------------------------------------------------
1719#if defined(OWL_SUPPORT_CTL3D)
1720
1721//
1722/// Predefined DLLs that TApplication knows how to find.
1723//
1724 const tchar Ctl3dDllName[] = _T("CTL3D32.DLL");
1725
1726//
1727/// Load the Ctl3d DLL dynamically.
1728/// Bind the member functions to the exported functions.
1729//
1730TCtl3dDll::TCtl3dDll()
1731:
1732 TModule(Ctl3dDllName, true, true, false), // shouldLoad, mustLoad and !addToList
1733
1734 Register(*this, "Ctl3dRegister"),
1735 Unregister(*this, "Ctl3dUnregister"),
1736 AutoSubclass(*this, "Ctl3dAutoSubclass"),
1737 CtlColorEx(*this, "Ctl3dCtlColorEx"),
1738 SubclassDlg(*this, "Ctl3dSubclassDlg"),
1739 SubclassDlgEx(*this, "Ctl3dSubclassDlgEx"),
1740 GetVer(*this, "Ctl3dGetVer"),
1741 Enabled(*this, "Ctl3dEnabled"),
1742 ColorChange(*this, "Ctl3dColorChange"),
1743 SubclassCtl(*this, "Ctl3dSubclassCtl"),
1744 DlgFramePaint(*this, "Ctl3dDlgFramePaint"),
1745 WinIniChange(*this, "Ctl3dWinIniChange")
1746{
1747}
1748
1749#endif //#if defined(OWL_SUPPORT_CTL3D)
1750//----------------------------------------------------------------------------
1751
1752#if OWL_PERSISTENT_STREAMS
1753
1754// Broken apart: IMPLEMENT_STREAMABLE1(TApplication, TModule);
1755// to replace the ctor
1756//
1757IMPLEMENT_STREAMABLE_CLASS(TApplication);
1758IMPLEMENT_STREAMER(TApplication);
1759IMPLEMENT_STREAMABLE_POINTER(TApplication)
1760
1761//
1762// IMPLEMENT_STREAMABLE_CTOR1(TApplication, TModule), plus TMsgThread init
1763//
1765:
1766 TModule(streamableInit),
1767 TMsgThread(TMsgThread::Current)
1768{
1769}
1770
1771//
1772//
1773//
1774void*
1775TApplication::Streamer::Read(ipstream& is, uint32 /*version*/) const
1776{
1777 TApplication* o = GetObject();
1778 if (o != owl::Module)
1779 is >> *owl::Module; // set reference to OWL module
1780 return o;
1781}
1782
1783//
1784//
1785//
1786void
1787TApplication::Streamer::Write(opstream& os) const
1788{
1789 TApplication* o = GetObject();
1790 if (o != owl::Module)
1791 os << *owl::Module; // write out reference to OWL module, no data written
1792}
1793
1794#else
1795
1797
1798#endif
1799
1800//----------------------------------------------------------------------------
1801
1802// TWaitCursor data
1803
1804inline bool FilterWindow (HWND hWnd){
1805 return !::IsWindowEnabled (hWnd) || !::IsWindowVisible (hWnd);
1806}
1807//
1808/// Enum[Thread/Task]Windows callback. Counts or subclasses given window based on
1809/// whether or not window list has been allocated yet.
1810//
1811static bool CALLBACK
1812subclassWnds(HWND hWnd, TEnumInfo * ei)
1813{
1814 if (!FilterWindow (hWnd)) {
1815 if (!ei->Wnds) {
1816 ei->Count++; // no buffer yet, we are just counting
1817 }
1818 else {
1819 *(ei->Wnds++) = hWnd;
1820 *(ei->PrevWndProc++) = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(TWaitHook::WaitWndProc)));
1821 }
1822 }
1823 return true;
1824}
1825//
1826enum{
1830//
1831TWaitHook::TWaitHook()
1832:
1833 LastStackTop(nullptr),
1834 HideCaretCount(0),
1835 Cursor(nullptr),
1836 DeleteOnClose(false)
1837{
1838 memset(&Subclass,0,sizeof(Subclass));
1839
1840 TEnumInfoStr& data = GetEnumInfo();
1841 LastStackTop = data.GetInfo(); // Keep last stackTop to restore later
1842 data.SetInfo(&Subclass); // Point stackTop to topmost ei
1843
1844 // Count windows to subclass
1845 //
1846 if (!::EnumThreadWindows(GetCurrentThreadId(), reinterpret_cast<WNDENUMPROC>(subclassWnds),
1847 TParam2(reinterpret_cast<TEnumInfo *>(&Subclass))))
1848 return;
1849
1850 // Allocate list of windows to disable, disable windows that are
1851 // enabled and then stuff them into the list.
1852 //
1853 HWND* hWnds = Subclass.Wnds = new HWND[Subclass.Count + 1];
1854 WNDPROC* fProc = Subclass.PrevWndProc = new WNDPROC[Subclass.Count + 1];
1855 memset(Subclass.Wnds, 0, sizeof(HWND)*(Subclass.Count + 1));
1856 memset(Subclass.PrevWndProc, 0, sizeof(WNDPROC)*(Subclass.Count + 1));
1857
1858 EnumThreadWindows(GetCurrentThreadId(), reinterpret_cast<WNDENUMPROC>(subclassWnds),
1859 TParam2(reinterpret_cast<TEnumInfo *>(&Subclass)));
1860
1861 Subclass.Wnds = hWnds; // Restore alloc'd pointer since enumerator bumps it
1862 Subclass.PrevWndProc = fProc; // Restore alloc'd pointer
1863
1864 HideCaret(nullptr);
1865 HideCaretCount = 1;
1866 Cursor = new TCursor(::LoadCursor(nullptr, IDC_WAIT));
1867 DeleteOnClose = true;
1868 SetWaitCursor();
1869}
1870//
1871TWaitHook::~TWaitHook()
1872{
1873 for (int i = 0; i < Subclass.Count; i++)
1874 ::SetWindowLongPtr(Subclass.Wnds[i], GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(Subclass.PrevWndProc[i]));
1875
1876 delete [] Subclass.Wnds;
1877 delete [] Subclass.PrevWndProc;
1878
1879 while(HideCaretCount--)
1880 ShowCaret(nullptr);
1881
1882 TPoint pt;
1883 ::GetCursorPos(&pt);
1884 ::SetCursorPos(pt.x, pt.y);
1885
1886 GetEnumInfo().SetInfo(LastStackTop); // Restore stackttop
1887
1888 FreeCursors();
1889}
1890//
1891void TWaitHook::FreeCursors()
1892{
1893 if(DeleteOnClose)
1894 delete Cursor;
1895 Cursor = nullptr;
1896}
1897//
1898void TWaitHook::SetCursor(TCursor* cursor, TAutoDelete del)
1899{
1900 FreeCursors();
1901 Cursor = cursor;
1902 DeleteOnClose = del == AutoDelete;
1903}
1904//
1905void TWaitHook::SetWaitCursor()
1906{
1907 ::SetCursor(*Cursor);
1908}
1909//
1910LRESULT CALLBACK TWaitHook::WaitWndProc(HWND wnd, UINT msg, WPARAM param1, LPARAM param2)
1911{
1912 return GetEnumInfo().Hook->WaitWndMethod(wnd, msg, param1, param2);
1913}
1914//
1915TResult TWaitHook::WaitWndMethod(HWND wnd, TMsgId msg, TParam1 param1, TParam2 param2)
1916{
1918 switch (msg){
1919 case WM_SETCURSOR:
1920 SetWaitCursor();
1921 return TRUE;
1922
1923 case WM_MOUSEACTIVATE:
1924 hTopMostWindow = reinterpret_cast<HWND>(param1);
1925
1926 if (hTopMostWindow == wnd)
1927 return MA_ACTIVATEANDEAT;
1928
1929 return ::DefWindowProc(wnd, msg, param1, param2);
1930
1931 case WM_SETFOCUS:
1932 DefWndProc (wnd, msg, param1, param2);
1933 HideCaret(nullptr);
1934 ++HideCaretCount;
1935 return 0;
1936 }
1937
1938 if ((msg >= WM_KEYFIRST && msg <= WM_KEYLAST) ||
1939 (msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) ||
1940 (msg >= WM_NCMOUSEFIRST && msg <= WM_NCMOUSELAST))
1941 {
1942 return 0; // ::DefWindowProc (wnd, msg, param1, param2);
1943 }
1944 return DefWndProc (wnd, msg, param1, param2);
1945}
1946//
1947TResult TWaitHook::DefWndProc(HWND wnd, TMsgId msg, TParam1 param1, TParam2 param2)
1948{
1949 for(int i = 0; i < static_cast<int>(Subclass.Count); i++){
1950 if (Subclass.Wnds[i] == wnd)
1951 return CallWindowProc(Subclass.PrevWndProc[i], wnd, msg, param1, param2);
1952 }
1953 PRECONDITION(0);
1954 return 0;
1955}
1956
1957//----------------------------------------------------------------------------
1958//
1959/// Changes the cursor to cursor. If TAutoDelete is set to AutoDelete the cursor
1960/// resource is deleted when the wait cursor is destoryed.
1961//
1962void TWaitCursor::SetCursor(TCursor* cursor, TAutoDelete del)
1963{
1964 TEnumInfoStr& data = GetEnumInfo();
1965 LOCKENUMINFO(data.Lock, false);
1966 if(data.Hook)
1967 data.Hook->SetCursor(cursor,del);
1968}
1969
1970//----------------------------------------------------------------------------
1971
1972//
1973/// Called by the constructors to add this cursor into the applications chain.
1974//
1975void TWaitCursor::Init()
1976{
1977 TEnumInfoStr& data = GetEnumInfo();
1978 LOCKENUMINFO(data.Lock, false);
1979 Next = data.Top;
1980 data.Top = this;
1981 if(!Next){
1982 PRECONDITION(data.Hook == 0);
1983 data.Hook = new TWaitHook;
1984 }
1985}
1986//
1987/// Restores the previous cursor.
1988//
1989TWaitCursor::~TWaitCursor()
1990{
1991 TEnumInfoStr& data = GetEnumInfo();
1992 LOCKENUMINFO(data.Lock, false);
1993
1994 const auto ok = data.Top == this; // Must be destructed in reverse order.
1995 WARN(!ok, _T("TWaitCursor::~TWaitCursor: Terminating due to failed precondition."));
1996 if (!ok) terminate();
1997
1998 if(data.Top){
1999 data.Top = Next;
2000 if(!Next){
2001 delete data.Hook;
2002 data.Hook = nullptr;
2003 }
2004 }
2005}
2006//
2007/// Restores old state of cursor.
2008//
2009void TWaitCursor::Restore()
2010{
2011 TEnumInfoStr& data = GetEnumInfo();
2012 LOCKENUMINFO(data.Lock, false);
2013
2014 delete data.Hook;
2015 data.Hook = nullptr;
2016 data.Top = nullptr;
2017}
2018//----------------------------------------------------------------------------
2019//
2020/// Sends text to the applications TMessageBar::SetHintText function if it has one.
2021//
2022void TWaitCursor::Message(const tstring& msg)
2023{
2024 TEnumInfoStr& data = GetEnumInfo();
2025 LOCKENUMINFO(data.Lock, true);
2026 if(data.Top == this && data.Hook){
2028 if(!app)
2029 return;
2030
2031 TFrameWindow* frame= app->GetMainWindow();
2032 if (frame){
2035 if(messageBar){
2036 messageBar->SetHintText(msg);
2037 messageBar->UpdateWindow();
2038 }
2039 }
2040 }
2041}
2042//-----------------------------------------------------------------------------
2043//
2044TLangModule::TLangModule(const tstring& prefix, const TApplication& appl)
2045:
2046 Prefix(prefix),
2047 Module(nullptr),
2048 Application(&const_cast<TApplication&>(appl)),
2049 LangId(static_cast<unsigned short>(-1)) //JJH added static_cast
2050{
2051 SetLanguage(appl.GetLangId());
2052}
2053//-----------------------------------------------------------------------------
2055{
2056 if(Module && Module != Application)
2057 delete Module;
2058}
2059//-----------------------------------------------------------------------------
2061{
2063
2064 tchar szLocName[10];
2066 if(retval)
2067 mname += szLocName;
2068 else
2069 mname += _T("ENU");
2070 mname += _T(".DLL");
2071 TModule* module = new TModule(mname.c_str(),true, false, true); // shouldLoad, !mustLoad and addToList
2072 if(module->GetHandle() <= HINSTANCE(HINSTANCE_ERROR)){
2073 delete module;
2075 locname += _T("ENU.DLL");
2076 module = new TModule(locname.c_str(),true, false, true); // shouldLoad, !mustLoad and addToList
2077 if(module->GetHandle() > HINSTANCE(HINSTANCE_ERROR))
2078 mname = locname;
2079 else{
2080 delete module;
2081 module = Application;
2082 }
2083 }
2084 if(Module && Module != Application)
2085 delete Module;
2086 Module = module;
2087
2088 // init LangId
2090 if(pProc)
2091 pProc();
2092}
2093//-----------------------------------------------------------------------------
2094//-----------------------------------------------------------------------------
2095
2096} // OWL namespace
2097//===============================================================================
2098
2099
Definition of class TAppDictionary.
Definition of class TApplication.
Legacy support for Borland Windows Custom Controls (BWCC)
#define CHECK(condition)
Definition checks.h:239
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define WARN(condition, message)
Definition checks.h:273
#define PRECONDITION(condition)
Definition checks.h:227
#define IFDIAG(a)
Definition checks.h:418
#define TRACEX(group, level, message)
Definition checks.h:263
#define DIAG_DEFINE_GROUP_INIT(f, g, e, l)
Definition checks.h:429
TAppDictionary implementation for DLLs only.
Definition appdict.h:30
TApplication * GetApplication(uint pid=0)
Looks up and returns the application associated with a given process ID.
Definition appdict.cpp:192
void Remove(TApplication *app)
Searches for the dictionary entry using the specified application (app).
Definition appdict.cpp:218
void Add(TApplication *app, uint pid=0)
Adds an application object (app) and corresponding process ID to this dictionary.
Definition appdict.cpp:205
Derived from TModule and TMsgThread and virtually derived from TEventHandler, TApplication acts as an...
Definition applicat.h:141
virtual bool ProcessAppMsg(MSG &msg)
Called after each message is pulled from the queue, and before it is dispatched.
Definition applicat.cpp:941
virtual void PreProcessMenu(HMENU hMenubar)
Called by the main window to provide an oportunity to preprocess the main window's menubar before it ...
virtual void ObjectSignaled(HANDLE, bool)
Definition applicat.h:236
void ResumeThrow()
Rethrows the suspended exception stored by a previous call to SuspendThrow.
auto TermInstance(int status) -> int override
Handle termination for each executing instance of the application.
Definition applicat.cpp:659
void SetTooltip(TTooltip *tooltip)
Assigns tooltip.
int MessageBox(HWND wnd, const tstring &text, const tstring &caption=tstring(), uint type=MB_OK) const
Definition applicat.h:774
virtual void WaitOnObject(HANDLE handle, bool wait)
Definition applicat.cpp:977
virtual void EnableTooltip(bool enable=true)
auto IdleAction(long idleCount) -> bool override
Called each time there are no messages in the queue.
Definition applicat.cpp:863
void PostDispatchAction()
Call this function after each msg dispatch if TApplication's message loop is not used.
void SuspendThrow(std::exception_ptr)
Stores the given exception so that it can be rethrown later by a call to ResumeThrow.
int BeginModal(TWindow *window, int flags=MB_APPLMODAL)
Called to begin a modal window's modal message loop.
auto MessageLoop() -> int override
Operates the application's message loop, which runs during the lifetime of the application.
Definition applicat.cpp:822
TWindow * GetWindowPtr(HWND hWnd) const
Get the TWindow pointer belonging to this app given an hWnd.
Definition applicat.h:665
virtual void InitApplication()
Handle initialization for the first executing instance of the OWL application.
Definition applicat.cpp:583
TFrameWindow * SetMainWindow(TFrameWindow *window)
Set (or reset) the main window.
Definition applicat.cpp:681
auto Run() -> int override
Run this application, return when application terminates.
Definition applicat.cpp:762
auto Find(TEventInfo &, TEqualOperator=nullptr) -> bool override
Overrides TEventHandler::Find.
virtual void InitMainWindow()
Initialize the application's main window.
Definition applicat.cpp:648
auto ProcessMsg(MSG &) -> bool override
Called for each message that is pulled from the queue, to perform all translation & dispatching.
Definition applicat.cpp:900
void Condemn(TWindow *win)
Condemns the given window to be deleted the at the next available safe time.
virtual bool CanClose()
Determine whether the application can be closed.
TApplication(LPCTSTR name=nullptr, TModule *&=owl::Module, TAppDictionary *=nullptr)
Constructor for use in OwlMain().
Definition applicat.cpp:288
virtual int Start() noexcept
Start this application and return immediately. Used for component DLLs.
Definition applicat.cpp:798
void InitInstance() override
Performs each instance initialization necessary for the application.
Definition applicat.cpp:601
~TApplication() override
~TApplication destroys the TApplication object.
Definition applicat.cpp:456
TFrameWindow * GetMainWindow()
Return the current main window.
Definition applicat.h:592
TDocManager * SetDocManager(TDocManager *docManager)
Set (or resets) the document manager, return the previous one if present.
Definition applicat.cpp:721
void EndModal(int result)
Cause the current modal message loop to break and have it return a result Re-enable the disabled wind...
void Uncondemn(TWindow *win)
Removes the given window from the list of condemned windows.
TCursor, derived from TGdiBase, represents the GDI cursor object class.
Definition gdiobjec.h:730
TDocManager creates a document manager object that manages the list of current documents and register...
Definition docmanag.h:100
A nested class, TEventInfo provides specific information about the type of message sent,...
Definition eventhan.h:170
virtual bool Find(TEventInfo &info, TEqualOperator op=0)
Searches the list of response table entries looking for a match.
Definition eventhan.cpp:371
TResult Dispatch(TEventInfo &info, TParam1, TParam2=0)
Takes the message data from TEventInfo's Msg data member and dispatches it to the correct event-handl...
Definition eventhan.cpp:396
Derived from TWindow, TFrameWindow controls such window-specific behavior as keyboard navigation and ...
Definition framewin.h:96
auto IdleAction(long idleCount) -> bool override
Overrides TWindow's virtual function.
Definition framewin.cpp:293
void SetLanguage(const TLangId &langId)
TApplication * Application
Definition applicat.h:552
virtual ~TLangModule()
void(* InitLanguage)()
Definition applicat.h:537
TModule * Module
Definition applicat.h:551
Derived from TGadgetWindow, TMessageBar implements a message bar with one text gadget as wide as the ...
Definition messageb.h:36
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:78
TMsgThread implements basic behavior for threads that own message queues, including mutex locking for...
Definition msgthred.h:45
bool BreakMessageLoop
Message loop is broken via WM_QUIT.
Definition msgthred.h:106
virtual void InitInstance()
Handles initialization for each executing instance of the message thread.
Definition msgthred.cpp:189
virtual int TermInstance(int status)
Handles termination for each executing instance of the message thread.
Definition msgthred.cpp:202
bool LoopRunning
Track if the loop is running.
Definition msgthred.h:110
int MessageLoopResult
Return value from message loop.
Definition msgthred.h:107
void FlushQueue()
Flushes all real messages from the message queue.
Definition msgthred.cpp:147
bool PumpWaitingMessages()
The inner message loop.
Definition msgthred.cpp:123
TPoint is a support class, derived from tagPOINT.
Definition geometry.h:87
A template class, TResponseTableEntry lets you define a pattern for entries into a response table.
Definition eventhan.h:217
static uint GetMajorVersion()
Definition system.cpp:81
TSystemMenu creates a system menu object that then becomes the existing system menu.
Definition menu.h:175
TTooltip encapsulates a tooltip window - i.e.
Definition tooltip.h:175
void RelayEvent(MSG &)
Passes a mouse message to the tooltip control for processing.
Definition tooltip.h:524
void Activate(bool activate=true)
Set state of tooltip.
Definition tooltip.h:394
static void DestroyInstance()
Definition tracewnd.cpp:150
static auto GetInstance(bool shouldCreateIfNeccessary=false) -> TTraceWindow *
Definition tracewnd.cpp:143
TWindow, derived from TEventHandler and TStreamableBase, provides window-specific behavior and encaps...
Definition window.h:414
void SetNext(TWindow *next)
Sets the next window in the sibling list.
Definition window.h:1762
virtual void SetParent(TWindow *newParent)
Sets the parent for the specified window by setting Parent to the specified new Parent window object.
Definition window.cpp:738
virtual bool EnableWindow(bool enable)
Allows the given window to receive input from the keyboard of mouse.
Definition window.h:2172
void DrawMenuBar()
DrawMenuBar redraws the menu bar.
Definition window.h:3313
virtual bool PreProcessMsg(MSG &msg)
Called from TApplication::ProcessAppMsg() to give the window an opportunity to perform preprocessing ...
Definition window.cpp:644
virtual bool Create()
Creates the window interface element to be associated with this ObjectWindows interface element.
Definition window.cpp:2399
void SetFlag(uint mask)
Sets the specified TWindow wfXxxx constant flags (for example wfAlias, wfTransfer,...
Definition window.h:1783
TWindow * GetParentO() const
Return the OWL's parent for this window.
Definition window.h:2006
uint32 SetExStyle(uint32 style)
Sets the extra style bits of the window.
Definition window.cpp:3583
bool IsWindow() const
Returns true if an HWND is being used.
Definition window.h:2040
bool IsChild(HWND hWnd) const
Returns true if the window is a child window or a descendant window of this window.
Definition window.h:3176
uint32 GetExStyle() const
Gets the extra style bits of the window.
Definition window.cpp:3575
bool ModifyStyle(uint32 offBits, uint32 onBits, uint swpFlags=0)
Modifies the style bits of the window.
Definition window.cpp:3591
virtual bool CanClose()
Use this function to determine if it is okay to close a window.
Definition window.cpp:2795
void ClearFlag(uint mask)
Clears the specified TWindow wfXxxx constant flags (for example wfAlias, wfTransfer,...
Definition window.h:1790
TWindow * Next()
Returns a pointer to the next sibling window in the window's sibling list.
Definition window.h:1755
virtual bool ShowWindow(int cmdShow)
Displays this TWindow in a given state.
Definition window.cpp:3713
TResult SendMessage(TMsgId, TParam1=0, TParam2=0) const
Sends a message (msg) to a specified window or windows.
Definition window.cpp:3288
HWND GetHandle() const
Returns the handle of the window.
Definition window.h:2020
auto ChildWithId(int id) const -> const TWindow *
Definition window.h:681
Derived from xmsg, TXBase is the base class for ObjectWindows and ObjectComponents exception-handling...
Definition exbase.h:41
A nested class, TXInvalidMainWindow describes an exception that results from an invalid Window.
Definition applicat.h:498
TXInvalidMainWindow * Clone()
TXInvalidMainWindow()
Constructs a TXInvalidMainWindow object with a default IDS_INVALIDMAINWINDOW.
static void Raise()
Throws a TXInvalidMainWindow exception.
void Throw()
Throws the exception object.
TXOwl is root class of the ObjectWindows exception hierarchy.
Definition except.h:38
#define _T(x)
Definition cygwin.h:51
#define WM_OWLCANCLOSE
Definition dispatch.h:4109
#define WM_OWLPREPROCMENU
Definition dispatch.h:4108
Definition of class TDocManager.
Definition of class TFrameWindow.
#define IMPLEMENT_STREAMABLE_POINTER(cls)
Definition objstrm.h:1596
TAutoDelete
Flag for Handle ctors to control Handle deletion in dtor.
Definition gdibase.h:70
#define IMPLEMENT_STREAMABLE_CLASS(cls)
Definition objstrm.h:1573
#define IMPLEMENT_STREAMABLE1(cls, base1)
Definition objstrm.h:1725
StreamableInit
Definition objstrm.h:98
#define IMPLEMENT_STREAMER(cls)
Definition objstrm.h:1641
@ AutoDelete
Definition gdibase.h:70
@ streamableInit
Definition objstrm.h:98
virtual int Unhandled(TModule *appModule, uint promptResId)
Per-exception class unhandled-handler, will default to the per-module unhandled-handler.
Definition except.cpp:155
#define LOCKAPPLDATA(l, s)
Definition applicat.cpp:151
#define LOCKENUMINFO(l, s)
Definition applicat.cpp:142
THandle GetHandle() const
Return the instance handle of the library module represented by the TModule obect.
Definition module.h:1236
LPCTSTR GetName() const
Returns the name of the module.
Definition module.h:1227
FARPROC GetProcAddress(TNarrowResId) const
Returns the entry-point address of the specified exported function if found, otherwise returns NULL.
Definition module.h:1284
virtual int Error(TXBase &x, uint captionResId, uint promptResId=0)
Replaceable exception handler; may be redefined to process OWL exceptions if canResume is false,...
Definition module.cpp:522
@ wfMainWindow
This frame window is the main window.
Definition window.h:63
Definition of class TMessageBar.
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
@ WM_NCMOUSELAST
@ WM_NCMOUSEFIRST
UINT TMsgId
Message ID type.
Definition dispatch.h:53
bool FilterWindow(HWND hWnd)
int OWLMessageBox(HWND wnd, const tstring &text, const tstring &caption, uint type)
Definition applicat.cpp:228
EV_WM_SYSCOMMAND
Definition floatfra.cpp:26
unsigned long uint32
Definition number.h:34
owl::uint16 TLangId
Holds a language ID, a predefined number that represents a base language and dialect.
Definition lclstrng.h:26
char tchar
Definition defs.h:77
LPARAM TParam2
Second parameter type.
Definition dispatch.h:55
int(* TMessageBox)(HWND wnd, LPCTSTR text, const LPCTSTR caption, uint type)
Definition applicat.h:57
WPARAM TParam1
First parameter type.
Definition dispatch.h:54
const TLangId LangNeutral
Definition lclstrng.h:32
const TLangId LangUserDefault
Definition lclstrng.h:31
TModule * Module
Definition global.cpp:34
TAppDictionary & OWLGetAppDictionary()
Global exported TAppDictionary in Owl.
Definition appdict.cpp:35
OWL_DIAGINFO
Definition animctrl.cpp:14
const int IDW_STATUSBAR
Definition messageb.h:25
LRESULT TResult
Result type.
Definition dispatch.h:52
std::string tstring
Definition defs.h:79
unsigned int uint
Definition number.h:25
auto to_tstring(const T &v) -> tstring
Definition defs.h:82
const auto ScmTrace
Definition applicat.cpp:163
#define OWL_CDLEVEL
Definition defs.h:171
#define OWL_INI
Definition defs.h:170
#define _OWLFUNC(p)
Definition defs.h:341
#define TYPESAFE_DOWNCAST(object, toClass)
Definition defs.h:269
Definition of the TTooltip class and helper objects.
Definition of private class TTraceWindow.
#define EV_COMMAND(id, method)
Response table entry for a menu/accelerator/push button message.
Definition windowev.h:171
#define WS_EX_APPWINDOW
Definition wsysinc.h:63