DocManager.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. #region Using directives
  2. using System;
  3. using System.Windows.Forms;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Globalization;
  7. using System.Runtime.Serialization;
  8. using System.Runtime.Serialization.Formatters.Binary;
  9. using Microsoft.Win32;
  10. using System.Security;
  11. #endregion
  12. // Using: in the end of this file.
  13. namespace DocToolkit
  14. {
  15. #region Class DocManager
  16. /// <summary>
  17. /// Document manager. Makes file-related operations:
  18. /// open, new, save, updating of the form title,
  19. /// registering of file type for Windows Shell.
  20. /// Built using the article:
  21. /// Creating Document-Centric Applications in Windows Forms
  22. /// by Chris Sells
  23. /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms09182003.asp
  24. /// </summary>
  25. public class DocManager
  26. {
  27. #region Events
  28. public event SaveEventHandler SaveEvent;
  29. public event LoadEventHandler LoadEvent;
  30. public event OpenFileEventHandler OpenEvent;
  31. public event EventHandler ClearEvent;
  32. public event EventHandler DocChangedEvent;
  33. #endregion
  34. #region Members
  35. private string fileName = "";
  36. private bool dirty = false;
  37. private Form frmOwner;
  38. private string newDocName;
  39. private string fileDlgFilter;
  40. private string registryPath;
  41. private bool updateTitle;
  42. private const string registryValue = "Path";
  43. private string fileDlgInitDir = ""; // file dialog initial directory
  44. #endregion
  45. #region Enum
  46. /// <summary>
  47. /// Enumeration used for Save function
  48. /// </summary>
  49. public enum SaveType
  50. {
  51. Save,
  52. SaveAs
  53. }
  54. #endregion
  55. #region Constructor
  56. /// <summary>
  57. /// Initialization
  58. /// </summary>
  59. /// <param name="data"></param>
  60. public DocManager(DocManagerData data)
  61. {
  62. frmOwner = data.FormOwner;
  63. frmOwner.Closing += OnClosing;
  64. updateTitle = data.UpdateTitle;
  65. newDocName = data.NewDocName;
  66. fileDlgFilter = data.FileDialogFilter;
  67. registryPath = data.RegistryPath;
  68. if (!registryPath.EndsWith("\\"))
  69. registryPath += "\\";
  70. registryPath += "FileDir";
  71. // attempt to read initial directory from registry
  72. RegistryKey key = Registry.CurrentUser.OpenSubKey(registryPath);
  73. if (key != null)
  74. {
  75. string s = (string)key.GetValue(registryValue);
  76. if (!Empty(s))
  77. fileDlgInitDir = s;
  78. }
  79. }
  80. #endregion
  81. #region Public functions and Properties
  82. /// <summary>
  83. /// Dirty property (true when document has unsaved changes).
  84. /// </summary>
  85. public bool Dirty
  86. {
  87. get
  88. {
  89. return dirty;
  90. }
  91. set
  92. {
  93. dirty = value;
  94. SetCaption();
  95. }
  96. }
  97. /// <summary>
  98. /// Open new document
  99. /// </summary>
  100. /// <returns></returns>
  101. public bool NewDocument()
  102. {
  103. if (!CloseDocument())
  104. return false;
  105. SetFileName("");
  106. if (ClearEvent != null)
  107. {
  108. // raise event to clear document contents in memory
  109. // (this class has no idea how to do this)
  110. ClearEvent(this, new EventArgs());
  111. }
  112. Dirty = false;
  113. return true;
  114. }
  115. /// <summary>
  116. /// Close document
  117. /// </summary>
  118. /// <returns></returns>
  119. public bool CloseDocument()
  120. {
  121. if (!this.dirty)
  122. return true;
  123. DialogResult res = MessageBox.Show(
  124. frmOwner,
  125. "Save changes?",
  126. Application.ProductName,
  127. MessageBoxButtons.YesNoCancel,
  128. MessageBoxIcon.Exclamation);
  129. switch (res)
  130. {
  131. case DialogResult.Yes: return SaveDocument(SaveType.Save);
  132. case DialogResult.No: return true;
  133. case DialogResult.Cancel: return false;
  134. default: Debug.Assert(false); return false;
  135. }
  136. }
  137. /// <summary>
  138. /// Open document
  139. /// </summary>
  140. /// <param name="newFileName">
  141. /// Document file name. Empty - function shows Open File dialog.
  142. /// </param>
  143. /// <returns></returns>
  144. public bool OpenDocument(string newFileName)
  145. {
  146. // Check if we can close current file
  147. if (!CloseDocument())
  148. return false;
  149. // Get the file to open
  150. if (Empty(newFileName))
  151. {
  152. OpenFileDialog openFileDialog1 = new OpenFileDialog();
  153. openFileDialog1.Filter = fileDlgFilter;
  154. openFileDialog1.InitialDirectory = fileDlgInitDir;
  155. DialogResult res = openFileDialog1.ShowDialog(frmOwner);
  156. if (res != DialogResult.OK)
  157. return false;
  158. newFileName = openFileDialog1.FileName;
  159. fileDlgInitDir = new FileInfo(newFileName).DirectoryName;
  160. }
  161. // Read the data
  162. try
  163. {
  164. using (Stream stream = new FileStream(
  165. newFileName, FileMode.Open, FileAccess.Read))
  166. {
  167. // Deserialize object from text format
  168. IFormatter formatter = new BinaryFormatter();
  169. if (LoadEvent != null) // if caller subscribed to this event
  170. {
  171. SerializationEventArgs args = new SerializationEventArgs(
  172. formatter, stream, newFileName);
  173. // raise event to load document from file
  174. LoadEvent(this, args);
  175. if (args.Error)
  176. {
  177. // report failure
  178. if (OpenEvent != null)
  179. {
  180. OpenEvent(this,
  181. new OpenFileEventArgs(newFileName, false));
  182. }
  183. return false;
  184. }
  185. // raise event to show document in the window
  186. if (DocChangedEvent != null)
  187. {
  188. DocChangedEvent(this, new EventArgs());
  189. }
  190. }
  191. }
  192. }
  193. // Catch all exceptions which may be raised from this code.
  194. // Caller is responsible to handle all other exceptions
  195. // in the functions invoked by LoadEvent and DocChangedEvent.
  196. catch (ArgumentNullException ex) { return HandleOpenException(ex, newFileName); }
  197. catch (ArgumentOutOfRangeException ex) { return HandleOpenException(ex, newFileName); }
  198. catch (ArgumentException ex) { return HandleOpenException(ex, newFileName); }
  199. catch (SecurityException ex) { return HandleOpenException(ex, newFileName); }
  200. catch (FileNotFoundException ex) { return HandleOpenException(ex, newFileName); }
  201. catch (DirectoryNotFoundException ex) { return HandleOpenException(ex, newFileName); }
  202. catch (PathTooLongException ex) { return HandleOpenException(ex, newFileName); }
  203. catch (IOException ex) { return HandleOpenException(ex, newFileName); }
  204. // Clear dirty bit, cache the file name and set the caption
  205. Dirty = false;
  206. SetFileName(newFileName);
  207. if (OpenEvent != null)
  208. {
  209. // report success
  210. OpenEvent(this, new OpenFileEventArgs(newFileName, true));
  211. }
  212. // Success
  213. return true;
  214. }
  215. /// <summary>
  216. /// Save file.
  217. /// </summary>
  218. /// <param name="type"></param>
  219. /// <returns></returns>
  220. public bool SaveDocument(SaveType type)
  221. {
  222. // Get the file name
  223. string newFileName = this.fileName;
  224. SaveFileDialog saveFileDialog1 = new SaveFileDialog();
  225. saveFileDialog1.Filter = fileDlgFilter;
  226. if ((type == SaveType.SaveAs) ||
  227. Empty(newFileName))
  228. {
  229. if (!Empty(newFileName))
  230. {
  231. saveFileDialog1.InitialDirectory = Path.GetDirectoryName(newFileName);
  232. saveFileDialog1.FileName = Path.GetFileName(newFileName);
  233. }
  234. else
  235. {
  236. saveFileDialog1.InitialDirectory = fileDlgInitDir;
  237. saveFileDialog1.FileName = newDocName;
  238. }
  239. DialogResult res = saveFileDialog1.ShowDialog(frmOwner);
  240. if (res != DialogResult.OK)
  241. return false;
  242. newFileName = saveFileDialog1.FileName;
  243. fileDlgInitDir = new FileInfo(newFileName).DirectoryName;
  244. }
  245. // Write the data
  246. try
  247. {
  248. using (Stream stream = new FileStream(
  249. newFileName, FileMode.Create, FileAccess.Write))
  250. {
  251. // Serialize object to text format
  252. IFormatter formatter = new BinaryFormatter();
  253. if (SaveEvent != null) // if caller subscribed to this event
  254. {
  255. SerializationEventArgs args = new SerializationEventArgs(
  256. formatter, stream, newFileName);
  257. // raise event
  258. SaveEvent(this, args);
  259. if (args.Error)
  260. return false;
  261. }
  262. }
  263. }
  264. catch (ArgumentNullException ex) { return HandleSaveException(ex, newFileName); }
  265. catch (ArgumentOutOfRangeException ex) { return HandleSaveException(ex, newFileName); }
  266. catch (ArgumentException ex) { return HandleSaveException(ex, newFileName); }
  267. catch (SecurityException ex) { return HandleSaveException(ex, newFileName); }
  268. catch (FileNotFoundException ex) { return HandleSaveException(ex, newFileName); }
  269. catch (DirectoryNotFoundException ex) { return HandleSaveException(ex, newFileName); }
  270. catch (PathTooLongException ex) { return HandleSaveException(ex, newFileName); }
  271. catch (IOException ex) { return HandleSaveException(ex, newFileName); }
  272. // Clear the dirty bit, cache the new file name
  273. // and the caption is set automatically
  274. Dirty = false;
  275. SetFileName(newFileName);
  276. // Success
  277. return true;
  278. }
  279. /// <summary>
  280. /// Assosciate file type with this program in the Registry
  281. /// </summary>
  282. /// <param name="data"></param>
  283. /// <returns>true - OK, false - failed</returns>
  284. public bool RegisterFileType(
  285. string fileExtension,
  286. string progId,
  287. string typeDisplayName)
  288. {
  289. try
  290. {
  291. string s = String.Format(CultureInfo.InvariantCulture, ".{0}", fileExtension);
  292. // Register custom extension with the shell
  293. using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(s))
  294. {
  295. // Map custom extension to a ProgID
  296. key.SetValue(null, progId);
  297. }
  298. // create ProgID key with display name
  299. using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(progId))
  300. {
  301. key.SetValue(null, typeDisplayName);
  302. }
  303. // register icon
  304. using (RegistryKey key =
  305. Registry.ClassesRoot.CreateSubKey(progId + @"\DefaultIcon"))
  306. {
  307. key.SetValue(null, Application.ExecutablePath + ",0");
  308. }
  309. // Register open command with the shell
  310. string cmdkey = progId + @"\shell\open\command";
  311. using (RegistryKey key =
  312. Registry.ClassesRoot.CreateSubKey(cmdkey))
  313. {
  314. // Map ProgID to an Open action for the shell
  315. key.SetValue(null, Application.ExecutablePath + " \"%1\"");
  316. }
  317. // Register application for "Open With" dialog
  318. string appkey = "Applications\\" +
  319. new FileInfo(Application.ExecutablePath).Name +
  320. "\\shell";
  321. using (RegistryKey key =
  322. Registry.ClassesRoot.CreateSubKey(appkey))
  323. {
  324. key.SetValue("FriendlyCache", Application.ProductName);
  325. }
  326. }
  327. catch (ArgumentNullException ex)
  328. {
  329. return HandleRegistryException(ex);
  330. }
  331. catch (SecurityException ex)
  332. {
  333. return HandleRegistryException(ex);
  334. }
  335. catch (ArgumentException ex)
  336. {
  337. return HandleRegistryException(ex);
  338. }
  339. catch (ObjectDisposedException ex)
  340. {
  341. return HandleRegistryException(ex);
  342. }
  343. catch (UnauthorizedAccessException ex)
  344. {
  345. return HandleRegistryException(ex);
  346. }
  347. return true;
  348. }
  349. #endregion
  350. #region Other Functions
  351. /// <summary>
  352. /// Hanfle exception from RegisterFileType function
  353. /// </summary>
  354. /// <param name="ex"></param>
  355. /// <returns></returns>
  356. private bool HandleRegistryException(Exception ex)
  357. {
  358. Trace.WriteLine("Registry operation failed: " + ex.Message);
  359. return false;
  360. }
  361. /// <summary>
  362. /// Save initial directory to the Registry
  363. /// </summary>
  364. /// <param name="sender"></param>
  365. /// <param name="e"></param>
  366. private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
  367. {
  368. RegistryKey key = Registry.CurrentUser.CreateSubKey(registryPath);
  369. key.SetValue(registryValue, fileDlgInitDir);
  370. }
  371. /// <summary>
  372. /// Set file name and change owner's caption
  373. /// </summary>
  374. /// <param name="fileName"></param>
  375. private void SetFileName(string fileName)
  376. {
  377. this.fileName = fileName;
  378. SetCaption();
  379. }
  380. /// <summary>
  381. /// Set owner form caption
  382. /// </summary>
  383. private void SetCaption()
  384. {
  385. if (!updateTitle)
  386. return;
  387. frmOwner.Text = string.Format(
  388. CultureInfo.InvariantCulture,
  389. "{0} - {1}{2}",
  390. Application.ProductName,
  391. Empty(this.fileName) ? newDocName : Path.GetFileName(this.fileName),
  392. this.dirty ? "*" : "");
  393. }
  394. /// <summary>
  395. /// Handle exception in OpenDocument function
  396. /// </summary>
  397. /// <param name="ex"></param>
  398. /// <param name="fileName"></param>
  399. /// <returns></returns>
  400. private bool HandleOpenException(Exception ex, string fileName)
  401. {
  402. MessageBox.Show(frmOwner,
  403. "Open File operation failed. File name: " + fileName + "\n" +
  404. "Reason: " + ex.Message,
  405. Application.ProductName);
  406. if (OpenEvent != null)
  407. {
  408. // report failure
  409. OpenEvent(this, new OpenFileEventArgs(fileName, false));
  410. }
  411. return false;
  412. }
  413. /// <summary>
  414. /// Handle exception in SaveDocument function
  415. /// </summary>
  416. /// <param name="ex"></param>
  417. /// <param name="fileName"></param>
  418. /// <returns></returns>
  419. private bool HandleSaveException(Exception ex, string fileName)
  420. {
  421. MessageBox.Show(frmOwner,
  422. "Save File operation failed. File name: " + fileName + "\n" +
  423. "Reason: " + ex.Message,
  424. Application.ProductName);
  425. return false;
  426. }
  427. /// <summary>
  428. /// Helper function - test if string is empty
  429. /// </summary>
  430. /// <param name="s"></param>
  431. /// <returns></returns>
  432. static bool Empty(string s)
  433. {
  434. return s == null || s.Length == 0;
  435. }
  436. #endregion
  437. }
  438. #endregion
  439. #region Delegates
  440. public delegate void SaveEventHandler(object sender, SerializationEventArgs e);
  441. public delegate void LoadEventHandler(object sender, SerializationEventArgs e);
  442. public delegate void OpenFileEventHandler(object sender, OpenFileEventArgs e);
  443. #endregion
  444. #region Class SerializationEventArgs
  445. /// <summary>
  446. /// Serialization event arguments.
  447. /// Used in events raised from DocManager class.
  448. /// Class contains information required to load/save file.
  449. /// </summary>
  450. public class SerializationEventArgs : System.EventArgs
  451. {
  452. private IFormatter formatter;
  453. private Stream stream;
  454. private string fileName;
  455. private bool errorFlag;
  456. public SerializationEventArgs(IFormatter formatter, Stream stream,
  457. string fileName)
  458. {
  459. this.formatter = formatter;
  460. this.stream = stream;
  461. this.fileName = fileName;
  462. errorFlag = false;
  463. }
  464. public bool Error
  465. {
  466. get
  467. {
  468. return errorFlag;
  469. }
  470. set
  471. {
  472. errorFlag = value;
  473. }
  474. }
  475. public IFormatter Formatter
  476. {
  477. get
  478. {
  479. return formatter;
  480. }
  481. }
  482. public Stream SerializationStream
  483. {
  484. get
  485. {
  486. return stream;
  487. }
  488. }
  489. public string FileName
  490. {
  491. get
  492. {
  493. return fileName;
  494. }
  495. }
  496. }
  497. #endregion
  498. #region Class OpenFileEventArgs
  499. /// <summary>
  500. /// Open file event arguments.
  501. /// Used in events raised from DocManager class.
  502. /// Class contains name of file and result of Open operation.
  503. /// </summary>
  504. public class OpenFileEventArgs : System.EventArgs
  505. {
  506. private string fileName;
  507. private bool success;
  508. public OpenFileEventArgs(string fileName, bool success)
  509. {
  510. this.fileName = fileName;
  511. this.success = success;
  512. }
  513. public string FileName
  514. {
  515. get
  516. {
  517. return fileName;
  518. }
  519. }
  520. public bool Succeeded
  521. {
  522. get
  523. {
  524. return success;
  525. }
  526. }
  527. }
  528. #endregion
  529. #region class DocManagerData
  530. /// <summary>
  531. /// Class used for DocManager class initialization
  532. /// </summary>
  533. public class DocManagerData
  534. {
  535. public DocManagerData()
  536. {
  537. frmOwner = null;
  538. updateTitle = true;
  539. newDocName = "Untitled";
  540. fileDlgFilter = "All Files (*.*)|*.*";
  541. registryPath = "Software\\Unknown";
  542. }
  543. private Form frmOwner;
  544. private bool updateTitle;
  545. private string newDocName;
  546. private string fileDlgFilter;
  547. private string registryPath;
  548. public Form FormOwner
  549. {
  550. get
  551. {
  552. return frmOwner;
  553. }
  554. set
  555. {
  556. frmOwner = value;
  557. }
  558. }
  559. public bool UpdateTitle
  560. {
  561. get
  562. {
  563. return updateTitle;
  564. }
  565. set
  566. {
  567. updateTitle = value;
  568. }
  569. }
  570. public string NewDocName
  571. {
  572. get
  573. {
  574. return newDocName;
  575. }
  576. set
  577. {
  578. newDocName = value;
  579. }
  580. }
  581. public string FileDialogFilter
  582. {
  583. get
  584. {
  585. return fileDlgFilter;
  586. }
  587. set
  588. {
  589. fileDlgFilter = value;
  590. }
  591. }
  592. public string RegistryPath
  593. {
  594. get
  595. {
  596. return registryPath;
  597. }
  598. set
  599. {
  600. registryPath = value;
  601. }
  602. }
  603. };
  604. #endregion
  605. }
  606. #region Using
  607. /*
  608. Using:
  609. 1. Write class which implements program-specific tasks. This class keeps some data,
  610. knows to draw itself in the form window, and implements ISerializable interface.
  611. Example:
  612. [Serializable]
  613. public class MyTask : ISerializable
  614. {
  615. // class members
  616. private int myData;
  617. // ...
  618. public MyTask()
  619. {
  620. // ...
  621. }
  622. public void Draw(Graphics g, Rectangle r)
  623. {
  624. // ...
  625. }
  626. // other functions
  627. // ...
  628. // Serialization
  629. // This function is called when file is loaded
  630. protected GraphicsList(SerializationInfo info, StreamingContext context)
  631. {
  632. myData = info.GetInt32("myData");
  633. // ...
  634. }
  635. // Serialization
  636. // This function is called when file is saved
  637. public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
  638. {
  639. info.AddValue("myData", myData);
  640. // ...
  641. }
  642. }
  643. Add member of this class to the form:
  644. private MyClass myClass;
  645. 2. Add the DocManager member to the owner form:
  646. private DocManager docManager;
  647. 3. Add DocManager message handlers to the owner form:
  648. private void docManager_ClearEvent(object sender, EventArgs e)
  649. {
  650. // DocManager executed New command
  651. // Clear here myClass or create new empty instance:
  652. myClass = new MyClass();
  653. Refresh();
  654. }
  655. private void docManager_DocChangedEvent(object sender, EventArgs e)
  656. {
  657. // DocManager reports that document was changed (loaded from file)
  658. Refresh();
  659. }
  660. private void docManager_OpenEvent(object sender, OpenFileEventArgs e)
  661. {
  662. // DocManager reports about successful/unsuccessful Open File operation
  663. // For example:
  664. if ( e.Succeeded )
  665. // add e.FileName to MRU list
  666. else
  667. // remove e.FileName from MRU list
  668. }
  669. private void docManager_LoadEvent(object sender, SerializationEventArgs e)
  670. {
  671. // DocManager asks to load document from supplied stream
  672. try
  673. {
  674. myClass = (MyClass)e.Formatter.Deserialize(e.SerializationStream);
  675. }
  676. catch ( catch possible exceptions here )
  677. {
  678. // report error
  679. e.Error = true;
  680. }
  681. }
  682. private void docManager_SaveEvent(object sender, SerializationEventArgs e)
  683. {
  684. // DocManager asks to save document to supplied stream
  685. try
  686. {
  687. e.Formatter.Serialize(e.SerializationStream, myClass);
  688. }
  689. catch ( catch possible exceptions here )
  690. {
  691. // report error
  692. e.Error = true;
  693. }
  694. }
  695. 4. Initialize docManager member in the form initialization code:
  696. DocManagerData data = new DocManagerData();
  697. data.FormOwner = this;
  698. data.UpdateTitle = true;
  699. data.FileDialogFilter = "MyProgram files (*.mpf)|*.mpf|All Files (*.*)|*.*";
  700. data.NewDocName = "Untitled.mpf";
  701. data.RegistryPath = "Software\\MyCompany\\MyProgram";
  702. docManager = new DocManager(data);
  703. docManager.SaveEvent += docManager_SaveEvent;
  704. docManager.LoadEvent += docManager_LoadEvent;
  705. docManager.OpenEvent += docManager_OpenEvent;
  706. docManager.DocChangedEvent += docManager_DocChangedEvent;
  707. docManager.ClearEvent += docManager_ClearEvent;
  708. docManager.NewDocument();
  709. // Optionally - register file type for Windows Shell
  710. bool result = docManager.RegisterFileType("mpf", "mpffile", "MyProgram File");
  711. 5. Call docManager functions when necessary. For example:
  712. // File is dropped into the window;
  713. // Command line parameter is handled.
  714. public void OpenDocument(string file)
  715. {
  716. docManager.OpenDocument(file);
  717. }
  718. // User Selected File - Open command.
  719. private void CommandOpen()
  720. {
  721. docManager.OpenDocument("");
  722. }
  723. // User selected File - Save command
  724. private void CommandSave()
  725. {
  726. docManager.SaveDocument(DocManager.SaveType.Save);
  727. }
  728. // User selected File - Save As command
  729. private void CommandSaveAs()
  730. {
  731. docManager.SaveDocument(DocManager.SaveType.SaveAs);
  732. }
  733. // User selected File - New command
  734. private void CommandNew()
  735. {
  736. docManager.NewDocument();
  737. }
  738. 6. Optionally: test for unsaved data in the form Closing event:
  739. private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  740. {
  741. if ( ! docManager.CloseDocument() )
  742. e.Cancel = true;
  743. }
  744. 7. Optionally: handle command-line parameters in the main function:
  745. [STAThread]
  746. static void Main(string[] args)
  747. {
  748. // Check command line
  749. if( args.Length > 1 )
  750. {
  751. MessageBox.Show("Incorrect number of arguments. Usage: MyProgram.exe [file]", "MyProgram");
  752. return;
  753. }
  754. // Load main form, taking command line into account
  755. MainForm form = new MainForm();
  756. if ( args.Length == 1 )
  757. form.OpenDocument(args[0]); // OpenDocument calls docManager.OpenDocument
  758. Application.Run(form);
  759. }
  760. */
  761. #endregion