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
88#if defined(BI_MULTI_THREAD_RTL)
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)
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)
234OWLMessageBox(HWND wnd, LPCTSTR text, LPCTSTR caption, uint type)
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))
240 type |= MB_TASKMODAL;
241
242 LPCTSTR _caption = caption; // Older compilers like Borland C++ 5.5 do not allow assigning new value to caption
243 if (_caption == nullptr)
244 _caption = OWLGetAppDictionary().GetApplication(0)->GetName();
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()),
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),
302#if defined(OWL_SUPPORT_BWCC)
303 BWCCOn(false),BWCCModule(0),
304#endif
305#if defined(OWL_SUPPORT_CTL3D)
306 Ctl3dOn(false),Ctl3dModule(0),
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()),
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),
338#if defined(OWL_SUPPORT_BWCC)
339 BWCCOn(false), BWCCModule(0),
340#endif
341#if defined(OWL_SUPPORT_CTL3D)
342 Ctl3dOn(false), Ctl3dModule(0),
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 (
374 LPCTSTR name,
375 HINSTANCE instance,
376 HINSTANCE prevInstance,
377 const tstring& cmdLine,
378 int cmdShow,
379 TModule*& module,
380 TAppDictionary* appDict
381 )
382:
383 TModule(name, instance, cmdLine),
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),
392#if defined(OWL_SUPPORT_BWCC)
393 BWCCOn(false),BWCCModule(0),
394#endif
395#if defined(OWL_SUPPORT_CTL3D)
396 Ctl3dOn(false),Ctl3dModule(0),
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,
417 HINSTANCE instance,
418 HINSTANCE prevInstance,
419 const tstring& cmdLine,
420 int cmdShow,
421 TModule*& module,
422 TAppDictionary* appDict
423)
424 :
425 TModule(name, instance, cmdLine),
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),
434#if defined(OWL_SUPPORT_BWCC)
435 BWCCOn(false), BWCCModule(0),
436#endif
437#if defined(OWL_SUPPORT_CTL3D)
438 Ctl3dOn(false), Ctl3dModule(0),
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
516TApplication::MessageBox(HWND wnd, LPCTSTR text, LPCTSTR caption_, uint type) const
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)
528 type |= MB_TASKMODAL;
529
530 WARNX(OwlApp, needTaskModal, 1, fun
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 {
550 EnableCtl3dAutosubclass(true);
551 int retValue = (GetApplicatData().OwlMsgBox)(wnd, text, caption, type);
552 EnableCtl3dAutosubclass(false);
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//
743TResult TApplication::Dispatch(TEventInfo& info, TParam1 p1, TParam2 p2)
744{
745 TApplication::TQueueLock lock(*this);
746 return TEventHandler::Dispatch(info, p1, p2);
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 };
885 if (diagIdleAction(idleCount))
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)) {
907 ::TranslateMessage(&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 }
922 ::DispatchMessage(&msg);
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
977void TApplication::WaitOnObject(HANDLE handle, bool wait)
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;
1042 ::PostQuitMessage(-1);
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
1057 rethrow_exception(e);
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 //
1093 SetTooltip(new TTooltip(tipParent));
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 {
1167 const auto c = TTraceWindow::GetInstance() ? MF_CHECKED : MF_UNCHECKED;
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) ||
1224 TEventHandler::Find(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{
1242 TEventInfo eventInfo(WM_OWLCANCLOSE);
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{
1256 TEventInfo eventInfo(WM_OWLPREPROCMENU);
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//
1378:
1379 TXOwl(IDS_INVALIDMAINWINDOW)
1380{
1381}
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 //
1500 if (!EnumThreadWindows(GetCurrentThreadId(), (WNDENUMPROC)disableWnds,
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//
1760
1761//
1762// IMPLEMENT_STREAMABLE_CTOR1(TApplication, TModule), plus TMsgThread init
1763//
1765:
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{
1827 WM_NCMOUSEFIRST = WM_NCMOUSEMOVE,
1828 WM_NCMOUSELAST = WM_NCMBUTTONDBLCLK
1829};
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{
1917 HWND hTopMostWindow;
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//
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//
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//
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//
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){
2033 TMessageBar* messageBar =
2035 if(messageBar){
2036 messageBar->SetHintText(msg);
2037 messageBar->UpdateWindow();
2038 }
2039 }
2040 }
2041}
2042//-----------------------------------------------------------------------------
2043//
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{
2062 tstring mname = Prefix;
2063
2064 tchar szLocName[10];
2065 int retval = ::GetLocaleInfo(langId,LOCALE_SABBREVLANGNAME, 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;
2074 tstring locname = Prefix;
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
2089 InitLanguage pProc = (InitLanguage)Module->GetProcAddress("InitLanguage");
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
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
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 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.
TLangId GetLangId() const
Returns identifier of language used by application.
Definition applicat.h:673
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
TCursor(HCURSOR handle, TAutoDelete autoDelete=NoAutoDelete)
Creates a TCursor object and sets the Handle data member to the given borrowed handle.
Definition cursor.cpp:24
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
bool(*) TEqualOperator(const TGenericTableEntry &, const TEventInfo &)
Definition eventhan.h:193
bool SearchEntries(const TGenericTableEntry *entries, TEventInfo &info, TEqualOperator op)
Low-level response table search function.
Definition eventhan.cpp:431
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
TFrameWindow()
< String-aware overload
Definition framewin.cpp:152
void SetLanguage(const TLangId &langId)
TApplication * Application
Definition applicat.h:552
virtual ~TLangModule()
TModule * Module
Definition applicat.h:551
TLangModule(const tstring &prefix, const TApplication &appl)
void(*) InitLanguage()
Definition applicat.h:537
bool IsOK() const
Returns true if the menu has a valid handle.
Definition menu.h:333
bool AppendMenu(uint flags, TMenuItem newItem=static_cast< unsigned int >(-1), LPCTSTR newStr=nullptr)
Adds a text menu item to the end of the menu.
Definition menu.h:342
Derived from TGadgetWindow, TMessageBar implements a message bar with one text gadget as wide as the ...
Definition messageb.h:36
virtual void SetHintText(LPCTSTR text)
Sets the hint text displayed on the messagebar.
Definition messageb.cpp:113
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
virtual int Run()
Runs this message thread, returns when the message queue quits.
Definition msgthred.cpp:164
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
virtual int MessageLoop()
Retrieves and processes messages from the thread's message queue using PumpWaitingMessages() until Br...
Definition msgthred.cpp:61
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
TMsgThread(TCurrent)
Attaches to the current running thread.
Definition msgthred.cpp:28
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
void(T::*) PMF()
Type for a generic member function that responds to notification messages.
Definition eventhan.h:222
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
TTooltip(TWindow *parent, bool alwaysTip=true, TModule *module=nullptr)
Constructor for Ttooltip.
Definition tooltip.cpp:388
static void DestroyInstance()
Definition tracewnd.cpp:150
static auto GetInstance(bool shouldCreateIfNeccessary=false) -> TTraceWindow *
Definition tracewnd.cpp:143
~TWaitCursor()
Restores the previous cursor.
void Restore()
Restores old state of cursor.
void Message(const tstring &text)
Sends text to the applications TMessageBar::SetHintText function if it has one.
void SetCursor(TCursor *cursor, TAutoDelete=AutoDelete)
Changes the cursor to cursor.
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
virtual bool PreProcessMsg(MSG &msg)
Called from TApplication::ProcessAppMsg() to give the window an opportunity to perform preprocessing ...
Definition window.cpp:644
virtual void Destroy(int retVal=0)
Destroys an MS-Windows element associated with the TWindow.
Definition window.cpp:2160
TResult DefaultProcessing()
Handles default processing of events, which includes continued processing of menu/accelerators comman...
Definition window.cpp:852
void UpdateWindow()
Updates the client area of the specified window by immediately sending a WM_PAINT message.
Definition window.h:2901
TWindow * Next()
Returns a pointer to the next sibling window in the window's sibling list.
Definition window.h:1755
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
ipstream, a specialized input stream derivative of pstream, is the base class for reading (extracting...
Definition objstrm.h:391
Base class for writing streamable objects.
Definition objstrm.h:480
#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
TResponseTableEntry< TGeneric > TGenericTableEntry
Definition eventhan.h:144
StreamableInit
Definition objstrm.h:98
#define IMPLEMENT_STREAMER(cls)
Definition objstrm.h:1641
@ AutoDelete
Definition gdibase.h:70
@ streamableInit
Definition objstrm.h:98
TXOwl(const tstring &msg, uint resId=0)
An OWL exception with a given message for displaying and an unsigned Id that can be used for identifi...
Definition except.cpp:123
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
int LoadString(uint id, TCHAR *buf, int maxChars) const
Loads a string resource identified by id into the buffer pointed to by buff.
Definition module.cpp:586
TModule(const tstring &name, bool shouldLoad=true, bool mustLoad=true, bool addToList=true)
Constructs a TModule object that is used as an alias for a DLL.
Definition module.cpp:308
HINSTANCE THandle
TModule encapsulates an HINSTANCE.
Definition module.h:82
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
TMessageBox SetDefMessageBox(TMessageBox)
Definition applicat.cpp:218
UINT TMsgId
Message ID type.
Definition dispatch.h:53
bool FilterWindow(HWND hWnd)
int(*) TMessageBox(HWND wnd, LPCTSTR text, const LPCTSTR caption, uint type)
Definition applicat.h:57
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
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
@ WM_NCMOUSELAST
@ WM_NCMOUSEFIRST
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
DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlApp, 1, 0)
auto to_tstring(const T &v) -> tstring
Definition defs.h:82
IMPLEMENT_STREAMABLE1(TApplication, TModule)
EV_COMMAND(IDOK, CmOkCancel)
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 WS_EX_APPWINDOW
Definition wsysinc.h:63