5#include "Stroika/Foundation/StroikaPreComp.h"
12#include "Stroika/Frameworks/Led/Platform/Windows_FileRegistration.h"
13#include "Stroika/Frameworks/Led/StdDialogs.h"
16#include "LedLineItDocFrame.h"
17#include "LedLineItDocument.h"
18#include "LedLineItInPlaceFrame.h"
19#include "LedLineItMainFrame.h"
20#include "LedLineItView.h"
24#include "LedLineItApplication.h"
27using namespace Stroika::Frameworks::Led;
29#define STD_EXCEPT_CATCHER(APP) \
30 catch (CMemoryException * e) \
32 (APP).HandleBadAllocException (); \
35 catch (CException * e) \
37 (APP).HandleMFCException (e); \
42 (APP).HandleBadAllocException (); \
44 catch (const system_error&) \
46 (APP).HandleUnknownException (); \
48 catch (TextInteractor::BadUserInput&) \
50 (APP).HandleBadUserInputException (); \
54 (APP).HandleUnknownException (); \
57class SimpleLedTemplate :
public CMultiDocTemplate {
59 SimpleLedTemplate (
const char* daStr)
60 : CMultiDocTemplate (IDR_MAINFRAME, RUNTIME_CLASS (LedLineItDocument), RUNTIME_CLASS (LedLineItDocFrame), RUNTIME_CLASS (LedLineItView))
62 m_strDocStrings = daStr;
65 virtual void LoadTemplate ()
override
67 CMultiDocTemplate::LoadTemplate ();
70 if (m_hMenuShared != NULL) {
72 tmp.Attach (m_hMenuShared);
73#if qSupportSyntaxColoring
74 FixupFontMenu (tmp.GetSubMenu (2)->GetSubMenu (7));
76 FixupFontMenu (tmp.GetSubMenu (2)->GetSubMenu (6));
83 CDocument* OpenDocumentFile (LPCTSTR lpszPathName, BOOL bMakeVisible)
89 CDocument* pDocument = CreateNewDocument ();
90 if (pDocument == NULL) {
91 TRACE (traceAppMsg, 0,
"CDocTemplate::CreateNewDocument returned NULL.\n");
92 AfxMessageBox (AFX_IDP_FAILED_TO_CREATE_DOC);
95 ASSERT_VALID (pDocument);
98 BOOL bAutoDelete = pDocument->m_bAutoDelete;
99 pDocument->m_bAutoDelete = FALSE;
100 CFrameWnd* pFrame = CreateNewFrame (pDocument, NULL);
101 pDocument->m_bAutoDelete = bAutoDelete;
102 if (pFrame == NULL) {
103 AfxMessageBox (AFX_IDP_FAILED_TO_CREATE_DOC);
107 ASSERT_VALID (pFrame);
109 if (lpszPathName == NULL) {
111 SetDefaultTitle (pDocument);
115 pDocument->m_bEmbedded = TRUE;
117 if (!pDocument->OnNewDocument ()) {
119 TRACE (traceAppMsg, 0,
"CDocument::OnNewDocument returned FALSE.\n");
120 pFrame->DestroyWindow ();
130 if (!pDocument->OnOpenDocument (lpszPathName)) {
131 TRACE (traceAppMsg, 0,
"CDocument::OnOpenDocument returned FALSE.\n");
134 pDocument->SetPathName (lpszPathName);
137 InitialUpdateFrame (pFrame, pDocument, bMakeVisible);
141 pDocument->OnCloseDocument ();
148inline SDKString GetLongPathName (
const SDKString& pathName)
150 TCHAR szPath[_MAX_PATH];
151 Require (pathName.length () < _MAX_PATH);
152 Characters::CString::Copy (szPath, Memory::NEltsOf (szPath), pathName.c_str ());
153 WIN32_FIND_DATA fileData;
154 HANDLE hFind = ::FindFirstFile (szPath, &fileData);
155 if (hFind != INVALID_HANDLE_VALUE) {
156 TCHAR* lastSlash = ::_tcsrchr (szPath,
'\\');
157 if (lastSlash == NULL) {
163 Characters::CString::Cat (szPath, Memory::NEltsOf (szPath), _T (
"\\"));
165 Characters::CString::Cat (szPath, Memory::NEltsOf (szPath), fileData.cFileName);
166 VERIFY (::FindClose (hFind));
171class LedLineItDocManager :
public CDocManager {
173 using inherited = CDocManager;
176 LedLineItDocManager ()
182 virtual void OnFileOpen ()
override
186 if (LedLineItDocument::DoPromptOpenFileName (&fileName, &codePage)) {
187 OpenDocumentFile (fileName, codePage);
192 virtual BOOL DoPromptFileName (::CString& , UINT , DWORD , BOOL , CDocTemplate* )
override
199 CDocument* OpenDocumentFile (LPCTSTR lpszFileName, CodePage codePage)
201 Assert (LedLineItDocument::sHiddenDocOpenArg == kIGNORECodePage);
205 CDocument* untitledDoc = NULL;
208 POSITION tp = GetFirstDocTemplatePosition ();
210 CDocTemplate* t = GetNextDocTemplate (tp);
212 POSITION dp = t->GetFirstDocPosition ();
214 CDocument* doc = t->GetNextDoc (dp);
219 if (not doc->IsModified () and doc->GetPathName ().GetLength () == 0) {
230 LedLineItDocument::sHiddenDocOpenArg = codePage;
231 CDocument* doc = inherited::OpenDocumentFile (GetLongPathName (lpszFileName).c_str (), TRUE);
232 LedLineItDocument::sHiddenDocOpenArg = kIGNORECodePage;
234 if (untitledDoc != NULL) {
235 untitledDoc->OnCloseDocument ();
240 LedLineItDocument::sHiddenDocOpenArg = kIGNORECodePage;
244 virtual CDocument* OpenDocumentFile (LPCTSTR lpszFileName)
override
246 return OpenDocumentFile (lpszFileName, kAutomaticallyGuessCodePage);
250const char kAppName[] =
"LedLineIt";
257LedLineItApplication theApp;
262static const CLSID clsid = {0xfc00620, 0x28bd, 0x11cf, {0x89, 0x9c, 0x0, 0xaa, 0x0, 0x58, 0x3, 0x25}};
264BEGIN_MESSAGE_MAP (LedLineItApplication, CWinApp)
265ON_COMMAND (ID_APP_ABOUT, OnAppAbout)
266ON_COMMAND (ID_FILE_NEW, OnFileNew)
267ON_COMMAND (ID_FILE_OPEN, OnFileOpen)
268ON_COMMAND (ID_FILE_PRINT_SETUP, OnFilePrintSetup)
269ON_COMMAND (kToggleAutoIndentOptionCmd, OnToggleAutoIndentOptionCommand)
270ON_UPDATE_COMMAND_UI (kToggleAutoIndentOptionCmd, OnToggleAutoIndentOptionUpdateCommandUI)
271ON_COMMAND (kToggleTreatTabAsIndentCharOptionCmd, OnToggleTreatTabAsIndentCharOptionCommand)
272ON_UPDATE_COMMAND_UI (kToggleTreatTabAsIndentCharOptionCmd, OnToggleTreatTabAsIndentCharOptionUpdateCommandUI)
273ON_COMMAND (kToggleUseSmartCutNPasteCmdID, OnToggleSmartCutNPasteOptionCommand)
274ON_UPDATE_COMMAND_UI (kToggleUseSmartCutNPasteCmdID, OnToggleSmartCutNPasteOptionUpdateCommandUI)
275#if qSupportSyntaxColoring
276ON_COMMAND_RANGE (kNoSyntaxColoringCmd, kVBSyntaxColoringCmd, OnSyntaxColoringOptionCommand)
277ON_UPDATE_COMMAND_UI_RANGE (kNoSyntaxColoringCmd, kVBSyntaxColoringCmd, OnSyntaxColoringOptionUpdateCommandUI)
279ON_COMMAND (cmdChooseDefaultFontDialog, OnChooseDefaultFontCommand)
280ON_COMMAND (kGotoLedLineItWebPageCmdID, OnGotoLedLineItWebPageCommand)
281ON_COMMAND (kCheckForUpdatesWebPageCmdID, OnCheckForUpdatesWebPageCommand)
282ON_COMMAND (kGotoSophistsWebPageCmdID, OnGotoSophistsWebPageCommand)
285LedLineItApplication* LedLineItApplication::sThe = NULL;
287LedLineItApplication::LedLineItApplication ()
289#if qIncludeBasicSpellcheckEngine
293 fOleTemplateServer ()
295 Require (sThe == NULL);
299LedLineItApplication::~LedLineItApplication ()
301 Require (sThe ==
this);
305LedLineItApplication& LedLineItApplication::Get ()
311BOOL LedLineItApplication::InitInstance ()
313 SetRegistryKey (_T (
"Sophist Solutions, Inc."));
316 if (!AfxOleInit ()) {
317 AfxMessageBox (IDP_OLE_INIT_FAILED);
323 LedLineItMainFrame* pFrame =
new LedLineItMainFrame ();
324 if (not pFrame->LoadFrame (IDR_MAINFRAME)) {
329 pFrame->DragAcceptFiles ();
333 CCommandLineInfo cmdInfo;
334 ParseCommandLine (cmdInfo);
339 Enable3dControlsStatic ();
342 LoadStdProfileSettings (9);
344 Assert (m_pDocManager == NULL);
345 m_pDocManager =
new LedLineItDocManager ();
347 AddDocTemplateForString (
"LedLineIt\n\nLedLineIt\n\n.ledtext\nLedLineIt.Document\nLedLineIt Document",
true);
351 RegisterShellFileTypes (
true);
355 fOleTemplateServer.UpdateRegistry (OAT_INPLACE_SERVER);
356 COleObjectFactory::UpdateRegistryAll ();
358#if qIncludeBasicSpellcheckEngine && qStroika_Foundation_Debug_AssertionsChecked
360 SpellCheckEngine_Basic::RegressionTest ();
362 fSpellCheckEngine = make_shared<SpellCheckEngine_Basic_Simple> ();
363#if qStroika_Foundation_Common_Platform_Windows
367 TCHAR defaultPath[MAX_PATH + 1];
368 Verify (::SHGetSpecialFolderPath (NULL, defaultPath, CSIDL_FLAG_CREATE | CSIDL_PERSONAL,
true));
369 fSpellCheckEngine->SetUserDictionary (SDKString{defaultPath} + Led_SDK_TCHAROF (
"\\My LedLineIt Dictionary.txt"));
374#if qStroika_Foundation_Common_Platform_Windows
376 class MyRegistrationHelper :
public Win32UIFileAssociationRegistrationHelper {
378 using inherited = Win32UIFileAssociationRegistrationHelper;
381 MyRegistrationHelper ()
382 : inherited (::AfxGetResourceHandle ())
387 virtual bool CheckUserSaysOKToUpdate ()
const override
390 if (o.GetCheckFileAssocsAtStartup ()) {
391 Led_StdDialogHelper_UpdateWin32FileAssocsDialog dlg (::AfxGetResourceHandle (), ::GetActiveWindow ());
392 dlg.fAppName = Led_SDK_TCHAROF (
"LedLineIt!");
393 dlg.fTypeList = Led_SDK_TCHAROF (
".txt,.bat");
394 dlg.fKeepChecking =
true;
395 bool result = dlg.DoModal ();
396 o.SetCheckFileAssocsAtStartup (dlg.fKeepChecking);
404 MyRegistrationHelper fileAssocHelper;
405 SDKString txtDocIcon = Win32UIFileAssociationInfo::kNoChange;
406 SDKString batDocIcon = Win32UIFileAssociationInfo::kNoChange;
407 fileAssocHelper.Add (Win32UIFileAssociationInfo (Led_SDK_TCHAROF (
".txt"), Led_SDK_TCHAROF (
"txtfile"), Led_SDK_TCHAROF (
"Text Document"),
408 Win32UIFileAssociationInfo::kNoChange, Led_SDK_TCHAROF (
"$EXE$ \"%1\"")));
409 fileAssocHelper.Add (Win32UIFileAssociationInfo (Led_SDK_TCHAROF (
".bat"), Led_SDK_TCHAROF (
"batfile"),
410 Led_SDK_TCHAROF (
"MS-DOS Batch File"), Win32UIFileAssociationInfo::kNoChange,
411 Led_SDK_TCHAROF (
"$EXE$ \"%1\""), Win32UIFileAssociationInfo::kNoChange));
412 fileAssocHelper.DoIt ();
417 if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated) {
420 COleTemplateServer::RegisterAll ();
428 m_pMainWnd->ShowWindow (m_nCmdShow);
431 if (not ProcessShellCommand (cmdInfo)) {
438void LedLineItApplication::WinHelpInternal ([[maybe_unused]] DWORD_PTR dwData, [[maybe_unused]] UINT nCmd)
441 TCHAR directoryName[_MAX_PATH];
442 Verify (::GetModuleFileName (m_hInstance, directoryName, _MAX_PATH));
445 LPTSTR lpszExt = _tcsrchr (directoryName,
'\\');
446 ASSERT (lpszExt != NULL);
447 ASSERT (*lpszExt ==
'\\');
448 *(lpszExt + 1) =
'\0';
450 Characters::CString::Cat (directoryName, Memory::NEltsOf (directoryName), _T (
"LedLineItDocs\\"));
456 (void)::ShellExecute (NULL, _T (
"open"), _T (
"index.htm"), NULL, directoryName, SW_SHOWNORMAL);
459BOOL LedLineItApplication::PumpMessage ()
462 return inherited::PumpMessage ();
464 STD_EXCEPT_CATCHER (*
this);
468void LedLineItApplication::HandleMFCException (CException* )
noexcept
471 HandleUnknownException ();
474void LedLineItApplication::HandleBadAllocException () noexcept
477 CDialog errorDialog (kBadAllocExceptionOnCmdDialogID);
478 errorDialog.DoModal ();
485void LedLineItApplication::HandleBadUserInputException () noexcept
488#if qStroika_Foundation_Common_Platform_Windows
489 CDialog errorDialog (kBadUserInputExceptionOnCmdDialogID);
490 errorDialog.DoModal ();
492 HandleUnknownException ();
500void LedLineItApplication::HandleUnknownException () noexcept
503 CDialog errorDialog (kUnknownExceptionOnCmdDialogID);
504 errorDialog.DoModal ();
511void LedLineItApplication::AddDocTemplateForString (
const char* tmplStr,
bool connectToServer)
513 SimpleLedTemplate* pDocTemplate =
new SimpleLedTemplate (tmplStr);
514 pDocTemplate->SetContainerInfo (IDR_CNTR_INPLACE);
515 pDocTemplate->SetServerInfo (IDR_SRVR_EMBEDDED, IDR_SRVR_INPLACE, RUNTIME_CLASS (LedLineItInPlaceFrame));
516 AddDocTemplate (pDocTemplate);
517 if (connectToServer) {
522 fOleTemplateServer.ConnectTemplate (clsid, pDocTemplate,
true);
528void LedLineItApplication::OnAppAbout ()
530 class MyAboutBox :
public Led_StdDialogHelper_AboutBox {
532 using inherited = Led_StdDialogHelper_AboutBox;
535 MyAboutBox (HINSTANCE hInstance, HWND parentWnd)
536 : inherited (hInstance, parentWnd)
541 virtual BOOL OnInitDialog ()
override
543 BOOL result = inherited::OnInitDialog ();
547 const CoordinateType kPictWidth = 437;
548 const CoordinateType kPictHeight = 273;
549 const CoordinateType kButHSluff = 17;
550 const CoordinateType kButVSluff = 19;
553 ::GetWindowRect (GetHWND (), &windowRect);
559 ::GetClientRect (GetHWND (), &clientRect);
560 ncWidth = AsLedRect (windowRect).GetWidth () - AsLedRect (clientRect).GetWidth ();
561 ncHeight = AsLedRect (windowRect).GetHeight () - AsLedRect (clientRect).GetHeight ();
563 ::MoveWindow (GetHWND (), windowRect.left, windowRect.top, kPictWidth + ncWidth, kPictHeight + ncHeight,
false);
568 HWND w = ::GetDlgItem (GetHWND (), kLedStdDlg_AboutBox_VersionFieldID);
570 const int kVERWidth = 230;
571 ::MoveWindow (w, kPictWidth / 2 - kVERWidth / 2, 32, kVERWidth, 16,
false);
573#define kUNICODE_NAME_ADORNER L" [UNICODE]"
575#define kUNICODE_NAME_ADORNER " [Internal UNICODE]"
577 ::SetWindowText (w, _T (qLed_ShortVersionString) kUNICODE_NAME_ADORNER _T (
" (") _T (__DATE__) _T (
")"));
582 HWND w = ::GetDlgItem (GetHWND (), kLedStdDlg_AboutBox_InfoLedFieldID);
584 ::MoveWindow (w, 15, 159, 142, 17,
false);
585 w = ::GetDlgItem (GetHWND (), kLedStdDlg_AboutBox_LedWebPageFieldID);
587 ::MoveWindow (w, 227, 159, 179, 17,
false);
592 HWND w = ::GetDlgItem (GetHWND (), IDOK);
595 ::GetWindowRect (w, &tmp);
596 ::MoveWindow (w, kButHSluff, kPictHeight - AsLedRect (tmp).GetHeight () - kButVSluff, AsLedRect (tmp).GetWidth (),
597 AsLedRect (tmp).GetHeight (),
false);
600 ::SetWindowText (GetHWND (), _T (
"About LedLineIt!"));
606 virtual void OnClickInInfoField ()
override
609 Led_URLManager::Get ().Open (
"mailto:info-led@sophists.com");
614 inherited::OnClickInInfoField ();
617 virtual void OnClickInLedWebPageField ()
override
620 Led_URLManager::Get ().Open (MakeSophistsAppNameVersionURL (
"/Led/LedLineIt/", kAppName));
625 inherited::OnClickInLedWebPageField ();
628 MyAboutBox dlg (m_hInstance, AfxGetMainWnd ()->m_hWnd);
632void LedLineItApplication::OnGotoLedLineItWebPageCommand ()
634 Led_URLManager::Get ().Open (MakeSophistsAppNameVersionURL (
"/Led/LedLineIt/", kAppName));
637void LedLineItApplication::OnCheckForUpdatesWebPageCommand ()
639 Led_URLManager::Get ().Open (MakeSophistsAppNameVersionURL (
"/Led/CheckForUpdates.asp", kAppName));
642void LedLineItApplication::OnGotoSophistsWebPageCommand ()
644 Led_URLManager::Get ().Open (MakeSophistsAppNameVersionURL (
"/", kAppName));
647void LedLineItApplication::OnToggleAutoIndentOptionCommand ()
650 o.SetAutoIndent (not o.GetAutoIndent ());
653void LedLineItApplication::OnToggleTreatTabAsIndentCharOptionUpdateCommandUI (CCmdUI* pCmdUI)
657 pCmdUI->SetCheck (Options{}.GetTreatTabAsIndentChar ());
660void LedLineItApplication::OnToggleTreatTabAsIndentCharOptionCommand ()
663 o.SetTreatTabAsIndentChar (not o.GetTreatTabAsIndentChar ());
666void LedLineItApplication::OnToggleAutoIndentOptionUpdateCommandUI (CCmdUI* pCmdUI)
670 pCmdUI->SetCheck (Options{}.GetAutoIndent ());
673void LedLineItApplication::OnToggleSmartCutNPasteOptionCommand ()
676 o.SetSmartCutAndPaste (not o.GetSmartCutAndPaste ());
677 UpdateViewsForPrefsChange ();
680void LedLineItApplication::OnToggleSmartCutNPasteOptionUpdateCommandUI (CCmdUI* pCmdUI)
684 pCmdUI->SetCheck (Options{}.GetSmartCutAndPaste ());
687#if qSupportSyntaxColoring
688void LedLineItApplication::OnSyntaxColoringOptionCommand (UINT cmdNum)
692 case kNoSyntaxColoringCmd:
693 o.SetSyntaxColoringOption (Options::eSyntaxColoringNone);
695 case kCPlusPlusSyntaxColoringCmd:
696 o.SetSyntaxColoringOption (Options::eSyntaxColoringCPlusPlus);
698 case kVBSyntaxColoringCmd:
699 o.SetSyntaxColoringOption (Options::eSyntaxColoringVB);
704 UpdateViewsForPrefsChange ();
707void LedLineItApplication::OnSyntaxColoringOptionUpdateCommandUI (CCmdUI* pCmdUI)
711 switch (pCmdUI->m_nID) {
712 case kNoSyntaxColoringCmd:
713 pCmdUI->SetCheck (Options{}.GetSyntaxColoringOption () == Options::eSyntaxColoringNone);
715 case kCPlusPlusSyntaxColoringCmd:
716 pCmdUI->SetCheck (Options{}.GetSyntaxColoringOption () == Options::eSyntaxColoringCPlusPlus);
718 case kVBSyntaxColoringCmd:
719 pCmdUI->SetCheck (Options{}.GetSyntaxColoringOption () == Options::eSyntaxColoringVB);
727void LedLineItApplication::OnChooseDefaultFontCommand ()
732 (void)::memset (&lf, 0,
sizeof (lf));
734 Characters::CString::Copy (lf.lfFaceName, Memory::NEltsOf (lf.lfFaceName), fsp.GetFontNameSpecifier ().fName);
735 Assert (::_tcslen (lf.lfFaceName) < sizeof (lf.lfFaceName));
737 lf.lfWeight = (fsp.GetStyle_Bold ()) ? FW_BOLD : FW_NORMAL;
738 lf.lfItalic = (fsp.GetStyle_Italic ());
739 lf.lfUnderline = (fsp.GetStyle_Underline ());
740 lf.lfStrikeOut = (fsp.GetStyle_Strikeout ());
742 lf.lfHeight = fsp.PeekAtTMHeight ();
744 FontDlgWithNoColorNoStyles dlog (&lf);
745 if (dlog.DoModal () == IDOK) {
750void LedLineItApplication::UpdateViewsForPrefsChange ()
752 bool smartCutNPaste = Options{}.GetSmartCutAndPaste ();
755 POSITION tp = GetFirstDocTemplatePosition ();
757 CDocTemplate* t = GetNextDocTemplate (tp);
759 POSITION dp = t->GetFirstDocPosition ();
761 CDocument* doc = t->GetNextDoc (dp);
763 POSITION vp = doc->GetFirstViewPosition ();
765 CView* v = doc->GetNextView (vp);
767 LedLineItView* lv =
dynamic_cast<LedLineItView*
> (v);
769 lv->SetSmartCutAndPasteMode (smartCutNPaste);
770#if qSupportSyntaxColoring
771 lv->ResetSyntaxColoringTable ();
779BOOL LedLineItApplication::ProcessShellCommand (CCommandLineInfo& rCmdInfo)
786#if !qNo_argc_argv_MacrosSupported
787 if (rCmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen) {
788 for (
int i = 1; i < __argc; ++i) {
789 LPCTSTR pszParam = __targv[i];
790 if (pszParam[0] ==
'-' || pszParam[0] ==
'/') {
795 if (not m_pDocManager->OpenDocumentFile (pszParam)) {
801 HANDLE h = ::CreateFile (rCmdInfo.m_strFileName, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
802 if (h == INVALID_HANDLE_VALUE) {
803 POSITION p = m_pDocManager->GetFirstDocTemplatePosition ();
804 CDocTemplate* pTemplate = (CDocTemplate*)m_pDocManager->GetNextDocTemplate (p);
806 CDocument* newDoc = pTemplate->OpenDocumentFile (NULL);
807 if (newDoc != NULL) {
810 newDoc->SetPathName (pszParam,
false);
811 newDoc->SetTitle (newDoc->GetTitle () + Led_SDK_TCHAROF (
" {new}"));
825 return inherited::ProcessShellCommand (rCmdInfo);
827 STD_EXCEPT_CATCHER (*
this);
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
basic_string< SDKChar > SDKString