@@ -601,6 +601,25 @@ void CPlugin::ExecutePluginScript (const char * sName,
601
601
602
602
} // end of CPlugin::ExecutePluginScript
603
603
604
+ void RemoveTrailingBackslash (CString& str);
605
+
606
+ // function prototypes needed for folder browsing
607
+
608
+ int __stdcall BrowseCallbackProc (
609
+ HWND hwnd,
610
+ UINT uMsg,
611
+ LPARAM lParam,
612
+ LPARAM lpData
613
+ );
614
+
615
+ // The field below is needed to initialise the browse directory dialog
616
+ // with the initial directory
617
+
618
+ extern CString strStartingDirectory;
619
+
620
+ // flag not in my version of the API
621
+ #define BIF_NEWDIALOGSTYLE 0x00000040
622
+
604
623
bool CPlugin::SaveState (const bool bScripted)
605
624
{
606
625
@@ -623,6 +642,83 @@ bool bError = true;
623
642
if (m_pDoc->m_strWorldID .IsEmpty ())
624
643
return true ;
625
644
645
+ // sigh ... check plugin state folder exists
646
+
647
+ CFileStatus status;
648
+ CString strError;
649
+ CString strFolder = strFilename;
650
+ RemoveTrailingBackslash (strFolder); // trailing slash not wanted, thanks
651
+
652
+ if (!CFile::GetStatus (strFolder, status))
653
+ {
654
+ strError = " does not exist" ;
655
+ }
656
+ else
657
+ { // file exists, is it a writable folder?
658
+ if ((status.m_attribute & CFile::directory) == 0 )
659
+ strError = " is not a directory" ;
660
+ else if ((status.m_attribute & CFile::readOnly) == 1 )
661
+ strError = " is not writable" ;
662
+ } // end of checking for save state folder
663
+
664
+ // if some error, alert the media
665
+ if (!strError.IsEmpty ())
666
+ {
667
+ ::AfxMessageBox ((LPCTSTR) CFormat (" The plugins 'save state' folder:\r\n\r\n "
668
+ " %s\r\n\r\n "
669
+ " %s. Please click OK and then browse for it, or create it." ,
670
+ (LPCTSTR) strFilename,
671
+ (LPCTSTR) strError),
672
+ MB_ICONSTOP);
673
+
674
+ // BROWSE FOR STATE FOLDER
675
+
676
+ // Gets the Shell's default allocator
677
+ LPMALLOC pMalloc;
678
+ if (::SHGetMalloc (&pMalloc) == NOERROR)
679
+ {
680
+ char pszBuffer[MAX_PATH];
681
+ BROWSEINFO bi;
682
+ LPITEMIDLIST pidl;
683
+
684
+ // Get help on BROWSEINFO struct - it's got all the bit settings.
685
+ bi.hwndOwner = NULL ;
686
+ bi.pidlRoot = NULL ;
687
+ bi.pszDisplayName = pszBuffer;
688
+ bi.lpszTitle = " Folder for saving plugin state files" ;
689
+ bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
690
+
691
+ // if possible, let them create one
692
+ if (!bWine)
693
+ bi.ulFlags |= BIF_NEWDIALOGSTYLE | BIF_EDITBOX; // requires CoInitialize
694
+
695
+ bi.lpfn = BrowseCallbackProc;
696
+ bi.lParam = 0 ;
697
+ strStartingDirectory = App.m_strPluginsDirectory ; // really should be under plugins directory
698
+
699
+ // This next call issues the dialog box.
700
+ if ((pidl = ::SHBrowseForFolder (&bi)) != NULL )
701
+ {
702
+ if (::SHGetPathFromIDList (pidl, pszBuffer))
703
+ {
704
+ App.m_strDefaultStateFilesDirectory = pszBuffer;
705
+ App.m_strDefaultStateFilesDirectory += " \\ " ;
706
+ strFilename = App.m_strDefaultStateFilesDirectory ;
707
+ // save back to database
708
+ App.SaveGlobalsToDatabase ();
709
+
710
+ }
711
+
712
+ // Free the PIDL allocated by SHBrowseForFolder.
713
+ pMalloc->Free (pidl);
714
+ }
715
+ // Release the shell's allocator.
716
+ pMalloc->Release ();
717
+ }
718
+
719
+ } // end of no save state folder
720
+
721
+
626
722
ExecutePluginScript (ON_PLUGIN_SAVE_STATE, m_dispid_plugin_save_state);
627
723
628
724
strFilename += m_pDoc->m_strWorldID ; // world ID
0 commit comments