5#include "Stroika/Foundation/StroikaPreComp.h"
13#include "Stroika/Frameworks/Led/Platform/Windows_FileRegistration.h"
14#include "Stroika/Frameworks/Led/StdDialogs.h"
17#include "LedLineItDocFrame.h"
18#include "LedLineItDocument.h"
19#include "LedLineItInPlaceFrame.h"
20#include "LedLineItMainFrame.h"
21#include "LedLineItView.h"
25#include "LedLineItApplication.h"
29using Memory::MakeSharedPtr;
31using namespace Stroika::Frameworks::Led;
33#define STD_EXCEPT_CATCHER(APP) \
34 catch (CMemoryException * e) \
36 (APP).HandleBadAllocException (); \
39 catch (CException * e) \
41 (APP).HandleMFCException (e); \
46 (APP).HandleBadAllocException (); \
48 catch (const system_error&) \
50 (APP).HandleUnknownException (); \
52 catch (TextInteractor::BadUserInput&) \
54 (APP).HandleBadUserInputException (); \
58 (APP).HandleUnknownException (); \
61class SimpleLedTemplate :
public CMultiDocTemplate {
63 SimpleLedTemplate (
const char* daStr)
64 : CMultiDocTemplate (IDR_MAINFRAME, RUNTIME_CLASS (LedLineItDocument), RUNTIME_CLASS (LedLineItDocFrame), RUNTIME_CLASS (LedLineItView))
66 m_strDocStrings = daStr;
69 virtual void LoadTemplate ()
override
71 CMultiDocTemplate::LoadTemplate ();
74 if (m_hMenuShared != NULL) {
76 tmp.Attach (m_hMenuShared);
77#if qSupportSyntaxColoring
78 FixupFontMenu (tmp.GetSubMenu (2)->GetSubMenu (7));
80 FixupFontMenu (tmp.GetSubMenu (2)->GetSubMenu (6));
87 CDocument* OpenDocumentFile (LPCTSTR lpszPathName, BOOL bMakeVisible)
93 CDocument* pDocument = CreateNewDocument ();
94 if (pDocument == NULL) {
95 TRACE (traceAppMsg, 0,
"CDocTemplate::CreateNewDocument returned NULL.\n");
96 AfxMessageBox (AFX_IDP_FAILED_TO_CREATE_DOC);
99 ASSERT_VALID (pDocument);
102 BOOL bAutoDelete = pDocument->m_bAutoDelete;
103 pDocument->m_bAutoDelete = FALSE;
104 CFrameWnd* pFrame = CreateNewFrame (pDocument, NULL);
105 pDocument->m_bAutoDelete = bAutoDelete;
106 if (pFrame == NULL) {
107 AfxMessageBox (AFX_IDP_FAILED_TO_CREATE_DOC);
111 ASSERT_VALID (pFrame);
113 if (lpszPathName == NULL) {
115 SetDefaultTitle (pDocument);
119 pDocument->m_bEmbedded = TRUE;
121 if (!pDocument->OnNewDocument ()) {
123 TRACE (traceAppMsg, 0,
"CDocument::OnNewDocument returned FALSE.\n");
124 pFrame->DestroyWindow ();
134 if (!pDocument->OnOpenDocument (lpszPathName)) {
135 TRACE (traceAppMsg, 0,
"CDocument::OnOpenDocument returned FALSE.\n");
138 pDocument->SetPathName (lpszPathName);
141 InitialUpdateFrame (pFrame, pDocument, bMakeVisible);
145 pDocument->OnCloseDocument ();
152inline SDKString GetLongPathName (
const SDKString& pathName)
154 TCHAR szPath[_MAX_PATH];
155 Require (pathName.length () < _MAX_PATH);
156 Characters::CString::Copy (szPath, std::size (szPath), pathName.c_str ());
157 WIN32_FIND_DATA fileData;
158 HANDLE hFind = ::FindFirstFile (szPath, &fileData);
159 if (hFind != INVALID_HANDLE_VALUE) {
160 TCHAR* lastSlash = ::_tcsrchr (szPath,
'\\');
161 if (lastSlash == NULL) {
167 Characters::CString::Cat (szPath, std::size (szPath), _T (
"\\"));
169 Characters::CString::Cat (szPath, std::size (szPath), fileData.cFileName);
170 VERIFY (::FindClose (hFind));
175class LedLineItDocManager :
public CDocManager {
177 using inherited = CDocManager;
180 LedLineItDocManager ()
186 virtual void OnFileOpen ()
override
190 if (LedLineItDocument::DoPromptOpenFileName (&fileName, &codePage)) {
191 OpenDocumentFile (fileName, codePage);
196 virtual BOOL DoPromptFileName (::CString& , UINT , DWORD , BOOL , CDocTemplate* )
override
203 CDocument* OpenDocumentFile (LPCTSTR lpszFileName, CodePage codePage)
205 Assert (LedLineItDocument::sHiddenDocOpenArg == kIGNORECodePage);
209 CDocument* untitledDoc = NULL;
212 POSITION tp = GetFirstDocTemplatePosition ();
214 CDocTemplate* t = GetNextDocTemplate (tp);
216 POSITION dp = t->GetFirstDocPosition ();
218 CDocument* doc = t->GetNextDoc (dp);
223 if (not doc->IsModified () and doc->GetPathName ().GetLength () == 0) {
234 LedLineItDocument::sHiddenDocOpenArg = codePage;
235 CDocument* doc = inherited::OpenDocumentFile (GetLongPathName (lpszFileName).c_str (), TRUE);
236 LedLineItDocument::sHiddenDocOpenArg = kIGNORECodePage;
238 if (untitledDoc != NULL) {
239 untitledDoc->OnCloseDocument ();
244 LedLineItDocument::sHiddenDocOpenArg = kIGNORECodePage;
248 virtual CDocument* OpenDocumentFile (LPCTSTR lpszFileName)
override
250 return OpenDocumentFile (lpszFileName, kAutomaticallyGuessCodePage);
254const char kAppName[] =
"LedLineIt";
261LedLineItApplication theApp;
266static const CLSID clsid = {0xfc00620, 0x28bd, 0x11cf, {0x89, 0x9c, 0x0, 0xaa, 0x0, 0x58, 0x3, 0x25}};
268BEGIN_MESSAGE_MAP (LedLineItApplication, CWinApp)
269ON_COMMAND (ID_APP_ABOUT, OnAppAbout)
270ON_COMMAND (ID_FILE_NEW, OnFileNew)
271ON_COMMAND (ID_FILE_OPEN, OnFileOpen)
272ON_COMMAND (ID_FILE_PRINT_SETUP, OnFilePrintSetup)
273ON_COMMAND (kToggleAutoIndentOptionCmd, OnToggleAutoIndentOptionCommand)
274ON_UPDATE_COMMAND_UI (kToggleAutoIndentOptionCmd, OnToggleAutoIndentOptionUpdateCommandUI)
275ON_COMMAND (kToggleTreatTabAsIndentCharOptionCmd, OnToggleTreatTabAsIndentCharOptionCommand)
276ON_UPDATE_COMMAND_UI (kToggleTreatTabAsIndentCharOptionCmd, OnToggleTreatTabAsIndentCharOptionUpdateCommandUI)
277ON_COMMAND (kToggleUseSmartCutNPasteCmdID, OnToggleSmartCutNPasteOptionCommand)
278ON_UPDATE_COMMAND_UI (kToggleUseSmartCutNPasteCmdID, OnToggleSmartCutNPasteOptionUpdateCommandUI)
279#if qSupportSyntaxColoring
280ON_COMMAND_RANGE (kNoSyntaxColoringCmd, kVBSyntaxColoringCmd, OnSyntaxColoringOptionCommand)
281ON_UPDATE_COMMAND_UI_RANGE (kNoSyntaxColoringCmd, kVBSyntaxColoringCmd, OnSyntaxColoringOptionUpdateCommandUI)
283ON_COMMAND (cmdChooseDefaultFontDialog, OnChooseDefaultFontCommand)
284ON_COMMAND (kGotoLedLineItWebPageCmdID, OnGotoLedLineItWebPageCommand)
285ON_COMMAND (kCheckForUpdatesWebPageCmdID, OnCheckForUpdatesWebPageCommand)
286ON_COMMAND (kGotoSophistsWebPageCmdID, OnGotoSophistsWebPageCommand)
289LedLineItApplication* LedLineItApplication::sThe = NULL;
291LedLineItApplication::LedLineItApplication ()
293#if qIncludeBasicSpellcheckEngine
297 fOleTemplateServer ()
299 Require (sThe == NULL);
303LedLineItApplication::~LedLineItApplication ()
305 Require (sThe ==
this);
309LedLineItApplication& LedLineItApplication::Get ()
315BOOL LedLineItApplication::InitInstance ()
317 SetRegistryKey (_T (
"Sophist Solutions, Inc."));
320 if (!AfxOleInit ()) {
321 AfxMessageBox (IDP_OLE_INIT_FAILED);
327 LedLineItMainFrame* pFrame =
new LedLineItMainFrame ();
328 if (not pFrame->LoadFrame (IDR_MAINFRAME)) {
333 pFrame->DragAcceptFiles ();
337 CCommandLineInfo cmdInfo;
338 ParseCommandLine (cmdInfo);
343 Enable3dControlsStatic ();
346 LoadStdProfileSettings (9);
348 Assert (m_pDocManager == NULL);
349 m_pDocManager =
new LedLineItDocManager ();
351 AddDocTemplateForString (
"LedLineIt\n\nLedLineIt\n\n.ledtext\nLedLineIt.Document\nLedLineIt Document",
true);
355 RegisterShellFileTypes (
true);
359 fOleTemplateServer.UpdateRegistry (OAT_INPLACE_SERVER);
360 COleObjectFactory::UpdateRegistryAll ();
362#if qIncludeBasicSpellcheckEngine && qStroika_Foundation_Debug_AssertionsChecked
364 SpellCheckEngine_Basic::RegressionTest ();
366 fSpellCheckEngine = MakeSharedPtr<SpellCheckEngine_Basic_Simple> ();
367#if qStroika_Foundation_Common_Platform_Windows
371 TCHAR defaultPath[MAX_PATH + 1];
372 Verify (::SHGetSpecialFolderPath (NULL, defaultPath, CSIDL_FLAG_CREATE | CSIDL_PERSONAL,
true));
373 fSpellCheckEngine->SetUserDictionary (SDKString{defaultPath} + Led_SDK_TCHAROF (
"\\My LedLineIt Dictionary.txt"));
378#if qStroika_Foundation_Common_Platform_Windows
380 class MyRegistrationHelper :
public Win32UIFileAssociationRegistrationHelper {
382 using inherited = Win32UIFileAssociationRegistrationHelper;
385 MyRegistrationHelper ()
386 : inherited (::AfxGetResourceHandle ())
391 virtual bool CheckUserSaysOKToUpdate ()
const override
394 if (o.GetCheckFileAssocsAtStartup ()) {
395 Led_StdDialogHelper_UpdateWin32FileAssocsDialog dlg (::AfxGetResourceHandle (), ::GetActiveWindow ());
396 dlg.fAppName = Led_SDK_TCHAROF (
"LedLineIt!");
397 dlg.fTypeList = Led_SDK_TCHAROF (
".txt,.bat");
398 dlg.fKeepChecking =
true;
399 bool result = dlg.DoModal ();
400 o.SetCheckFileAssocsAtStartup (dlg.fKeepChecking);
408 MyRegistrationHelper fileAssocHelper;
409 SDKString txtDocIcon = Win32UIFileAssociationInfo::kNoChange;
410 SDKString batDocIcon = Win32UIFileAssociationInfo::kNoChange;
411 fileAssocHelper.Add (Win32UIFileAssociationInfo (Led_SDK_TCHAROF (
".txt"), Led_SDK_TCHAROF (
"txtfile"), Led_SDK_TCHAROF (
"Text Document"),
412 Win32UIFileAssociationInfo::kNoChange, Led_SDK_TCHAROF (
"$EXE$ \"%1\"")));
413 fileAssocHelper.Add (Win32UIFileAssociationInfo (Led_SDK_TCHAROF (
".bat"), Led_SDK_TCHAROF (
"batfile"),
414 Led_SDK_TCHAROF (
"MS-DOS Batch File"), Win32UIFileAssociationInfo::kNoChange,
415 Led_SDK_TCHAROF (
"$EXE$ \"%1\""), Win32UIFileAssociationInfo::kNoChange));
416 fileAssocHelper.DoIt ();
421 if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated) {
424 COleTemplateServer::RegisterAll ();
432 m_pMainWnd->ShowWindow (m_nCmdShow);
435 if (not ProcessShellCommand (cmdInfo)) {
442void LedLineItApplication::WinHelpInternal ([[maybe_unused]] DWORD_PTR dwData, [[maybe_unused]] UINT nCmd)
445 TCHAR directoryName[_MAX_PATH];
446 Verify (::GetModuleFileName (m_hInstance, directoryName, _MAX_PATH));
449 LPTSTR lpszExt = _tcsrchr (directoryName,
'\\');
450 ASSERT (lpszExt != NULL);
451 ASSERT (*lpszExt ==
'\\');
452 *(lpszExt + 1) =
'\0';
454 Characters::CString::Cat (directoryName, std::size (directoryName), _T (
"LedLineItDocs\\"));
460 (void)::ShellExecute (NULL, _T (
"open"), _T (
"index.htm"), NULL, directoryName, SW_SHOWNORMAL);
463BOOL LedLineItApplication::PumpMessage ()
466 return inherited::PumpMessage ();
468 STD_EXCEPT_CATCHER (*
this);
472void LedLineItApplication::HandleMFCException (CException* )
noexcept
475 HandleUnknownException ();
478void LedLineItApplication::HandleBadAllocException () noexcept
481 CDialog errorDialog (kBadAllocExceptionOnCmdDialogID);
482 errorDialog.DoModal ();
489void LedLineItApplication::HandleBadUserInputException () noexcept
492#if qStroika_Foundation_Common_Platform_Windows
493 CDialog errorDialog (kBadUserInputExceptionOnCmdDialogID);
494 errorDialog.DoModal ();
496 HandleUnknownException ();
504void LedLineItApplication::HandleUnknownException () noexcept
507 CDialog errorDialog (kUnknownExceptionOnCmdDialogID);
508 errorDialog.DoModal ();
515void LedLineItApplication::AddDocTemplateForString (
const char* tmplStr,
bool connectToServer)
517 SimpleLedTemplate* pDocTemplate =
new SimpleLedTemplate (tmplStr);
518 pDocTemplate->SetContainerInfo (IDR_CNTR_INPLACE);
519 pDocTemplate->SetServerInfo (IDR_SRVR_EMBEDDED, IDR_SRVR_INPLACE, RUNTIME_CLASS (LedLineItInPlaceFrame));
520 AddDocTemplate (pDocTemplate);
521 if (connectToServer) {
526 fOleTemplateServer.ConnectTemplate (clsid, pDocTemplate,
true);
532void LedLineItApplication::OnAppAbout ()
534 class MyAboutBox :
public Led_StdDialogHelper_AboutBox {
536 using inherited = Led_StdDialogHelper_AboutBox;
539 MyAboutBox (HINSTANCE hInstance, HWND parentWnd)
540 : inherited (hInstance, parentWnd)
545 virtual BOOL OnInitDialog ()
override
547 BOOL result = inherited::OnInitDialog ();
551 const CoordinateType kPictWidth = 437;
552 const CoordinateType kPictHeight = 273;
553 const CoordinateType kButHSluff = 17;
554 const CoordinateType kButVSluff = 19;
557 ::GetWindowRect (GetHWND (), &windowRect);
563 ::GetClientRect (GetHWND (), &clientRect);
564 ncWidth = AsLedRect (windowRect).GetWidth () - AsLedRect (clientRect).GetWidth ();
565 ncHeight = AsLedRect (windowRect).GetHeight () - AsLedRect (clientRect).GetHeight ();
567 ::MoveWindow (GetHWND (), windowRect.left, windowRect.top, kPictWidth + ncWidth, kPictHeight + ncHeight,
false);
572 HWND w = ::GetDlgItem (GetHWND (), kLedStdDlg_AboutBox_VersionFieldID);
574 const int kVERWidth = 230;
575 ::MoveWindow (w, kPictWidth / 2 - kVERWidth / 2, 32, kVERWidth, 16,
false);
577#define kUNICODE_NAME_ADORNER L" [UNICODE]"
579#define kUNICODE_NAME_ADORNER " [Internal UNICODE]"
581 ::SetWindowText (w, _T (qLed_ShortVersionString) kUNICODE_NAME_ADORNER _T (
" (") _T (__DATE__) _T (
")"));
586 HWND w = ::GetDlgItem (GetHWND (), kLedStdDlg_AboutBox_InfoLedFieldID);
588 ::MoveWindow (w, 15, 159, 142, 17,
false);
589 w = ::GetDlgItem (GetHWND (), kLedStdDlg_AboutBox_LedWebPageFieldID);
591 ::MoveWindow (w, 227, 159, 179, 17,
false);
596 HWND w = ::GetDlgItem (GetHWND (), IDOK);
599 ::GetWindowRect (w, &tmp);
600 ::MoveWindow (w, kButHSluff, kPictHeight - AsLedRect (tmp).GetHeight () - kButVSluff, AsLedRect (tmp).GetWidth (),
601 AsLedRect (tmp).GetHeight (),
false);
604 ::SetWindowText (GetHWND (), _T (
"About LedLineIt!"));
610 virtual void OnClickInInfoField ()
override
613 Led_URLManager::Get ().Open (
"mailto:info-led@sophists.com");
618 inherited::OnClickInInfoField ();
621 virtual void OnClickInLedWebPageField ()
override
624 Led_URLManager::Get ().Open (MakeSophistsAppNameVersionURL (
"/Led/LedLineIt/", kAppName));
629 inherited::OnClickInLedWebPageField ();
632 MyAboutBox dlg (m_hInstance, AfxGetMainWnd ()->m_hWnd);
636void LedLineItApplication::OnGotoLedLineItWebPageCommand ()
638 Led_URLManager::Get ().Open (MakeSophistsAppNameVersionURL (
"/Led/LedLineIt/", kAppName));
641void LedLineItApplication::OnCheckForUpdatesWebPageCommand ()
643 Led_URLManager::Get ().Open (MakeSophistsAppNameVersionURL (
"/Led/CheckForUpdates.asp", kAppName));
646void LedLineItApplication::OnGotoSophistsWebPageCommand ()
648 Led_URLManager::Get ().Open (MakeSophistsAppNameVersionURL (
"/", kAppName));
651void LedLineItApplication::OnToggleAutoIndentOptionCommand ()
654 o.SetAutoIndent (not o.GetAutoIndent ());
657void LedLineItApplication::OnToggleTreatTabAsIndentCharOptionUpdateCommandUI (CCmdUI* pCmdUI)
661 pCmdUI->SetCheck (Options{}.GetTreatTabAsIndentChar ());
664void LedLineItApplication::OnToggleTreatTabAsIndentCharOptionCommand ()
667 o.SetTreatTabAsIndentChar (not o.GetTreatTabAsIndentChar ());
670void LedLineItApplication::OnToggleAutoIndentOptionUpdateCommandUI (CCmdUI* pCmdUI)
674 pCmdUI->SetCheck (Options{}.GetAutoIndent ());
677void LedLineItApplication::OnToggleSmartCutNPasteOptionCommand ()
680 o.SetSmartCutAndPaste (not o.GetSmartCutAndPaste ());
681 UpdateViewsForPrefsChange ();
684void LedLineItApplication::OnToggleSmartCutNPasteOptionUpdateCommandUI (CCmdUI* pCmdUI)
688 pCmdUI->SetCheck (Options{}.GetSmartCutAndPaste ());
691#if qSupportSyntaxColoring
692void LedLineItApplication::OnSyntaxColoringOptionCommand (UINT cmdNum)
696 case kNoSyntaxColoringCmd:
697 o.SetSyntaxColoringOption (Options::eSyntaxColoringNone);
699 case kCPlusPlusSyntaxColoringCmd:
700 o.SetSyntaxColoringOption (Options::eSyntaxColoringCPlusPlus);
702 case kVBSyntaxColoringCmd:
703 o.SetSyntaxColoringOption (Options::eSyntaxColoringVB);
708 UpdateViewsForPrefsChange ();
711void LedLineItApplication::OnSyntaxColoringOptionUpdateCommandUI (CCmdUI* pCmdUI)
715 switch (pCmdUI->m_nID) {
716 case kNoSyntaxColoringCmd:
717 pCmdUI->SetCheck (Options{}.GetSyntaxColoringOption () == Options::eSyntaxColoringNone);
719 case kCPlusPlusSyntaxColoringCmd:
720 pCmdUI->SetCheck (Options{}.GetSyntaxColoringOption () == Options::eSyntaxColoringCPlusPlus);
722 case kVBSyntaxColoringCmd:
723 pCmdUI->SetCheck (Options{}.GetSyntaxColoringOption () == Options::eSyntaxColoringVB);
731void LedLineItApplication::OnChooseDefaultFontCommand ()
736 (void)::memset (&lf, 0,
sizeof (lf));
738 Characters::CString::Copy (lf.lfFaceName, std::size (lf.lfFaceName), fsp.GetFontNameSpecifier ().fName);
739 Assert (::_tcslen (lf.lfFaceName) < sizeof (lf.lfFaceName));
741 lf.lfWeight = (fsp.GetStyle_Bold ()) ? FW_BOLD : FW_NORMAL;
742 lf.lfItalic = (fsp.GetStyle_Italic ());
743 lf.lfUnderline = (fsp.GetStyle_Underline ());
744 lf.lfStrikeOut = (fsp.GetStyle_Strikeout ());
746 lf.lfHeight = fsp.PeekAtTMHeight ();
748 FontDlgWithNoColorNoStyles dlog (&lf);
749 if (dlog.DoModal () == IDOK) {
754void LedLineItApplication::UpdateViewsForPrefsChange ()
756 bool smartCutNPaste = Options{}.GetSmartCutAndPaste ();
759 POSITION tp = GetFirstDocTemplatePosition ();
761 CDocTemplate* t = GetNextDocTemplate (tp);
763 POSITION dp = t->GetFirstDocPosition ();
765 CDocument* doc = t->GetNextDoc (dp);
767 POSITION vp = doc->GetFirstViewPosition ();
769 CView* v = doc->GetNextView (vp);
771 LedLineItView* lv =
dynamic_cast<LedLineItView*
> (v);
773 lv->SetSmartCutAndPasteMode (smartCutNPaste);
774#if qSupportSyntaxColoring
775 lv->ResetSyntaxColoringTable ();
783BOOL LedLineItApplication::ProcessShellCommand (CCommandLineInfo& rCmdInfo)
790#if !qNo_argc_argv_MacrosSupported
791 if (rCmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen) {
792 for (
int i = 1; i < __argc; ++i) {
793 LPCTSTR pszParam = __targv[i];
794 if (pszParam[0] ==
'-' || pszParam[0] ==
'/') {
799 if (not m_pDocManager->OpenDocumentFile (pszParam)) {
805 HANDLE h = ::CreateFile (rCmdInfo.m_strFileName, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
806 if (h == INVALID_HANDLE_VALUE) {
807 POSITION p = m_pDocManager->GetFirstDocTemplatePosition ();
808 CDocTemplate* pTemplate = (CDocTemplate*)m_pDocManager->GetNextDocTemplate (p);
810 CDocument* newDoc = pTemplate->OpenDocumentFile (NULL);
811 if (newDoc != NULL) {
814 newDoc->SetPathName (pszParam,
false);
815 newDoc->SetTitle (newDoc->GetTitle () + Led_SDK_TCHAROF (
" {new}"));
829 return inherited::ProcessShellCommand (rCmdInfo);
831 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