using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Resources; using IO = System.IO; using System.Windows.Forms; using System.Windows; using System.Windows.Interop; using Yaulw.Process; using Diag = System.Diagnostics; namespace Yaulw.File { /// /// CHM Help File Wrapper /// public class CHMFile { #region Private Members /// /// The Full File Name and Path to the CHM File /// private string _FileNameNPath = ""; /// /// The File Stream that created the CHM File (if used) /// private IO.Stream _FileStream = null; /// /// Internally we keep track of each Form to Help Context ID /// private Dictionary s_FormContextMap = new Dictionary(); #endregion #region Construction /// /// Construct a CHMFile object with the specified chm file /// /// a full path to a valid chm file public CHMFile(string FileNameNPath) { if (!String.IsNullOrEmpty(FileNameNPath) && IO.File.Exists(FileNameNPath) && (IO.Path.GetExtension(FileNameNPath).ToLower() == "chm")) _FileNameNPath = FileNameNPath; else throw new ArgumentException("Invalid chm File or File does not exist"); } /// /// Construct a CHMFile object from the specified stream (will construct a chm file in /// a temporary location from the specified stream) /// /// stream to construct the chm file from /// The name of the application (will be used when creating the .chm file) /// if true, will force a new file to be written out, false will only write file if not exists public CHMFile(IO.Stream stream, string ApplicationName, bool ForceNewFile) { if (stream != null && !String.IsNullOrEmpty(ApplicationName)) { _FileStream = stream; _FileNameNPath = IO.Path.GetTempPath() + ApplicationName + ".chm"; EnsureCHMFileExistance(ForceNewFile); } else throw new ArgumentNullException("Resource can not be null. ApplicationName can not be empty"); } #endregion #region Public Consts /// /// Legacy MFC View Context offset /// public const int MNU = 0x10000; /// /// Legacy MFC Dialog Context offset /// public const int DLG = 0x20000; #endregion #region Public Methods /// /// Attaches the HelpRequest Handler as well as shows the HelpButton on the CaptionBar /// /// WinForm to Attach Help Button to /// the Help Topic Context Id to attach to the specified WinForm public void AttachHelpCaptionButtonToWinForm(Form form, int dwContextId) { // Set the HelpButton to be displayed form.MinimizeBox = false; form.MaximizeBox = false; form.HelpButton = true; // add the form / contextID to the map s_FormContextMap[form] = (int)dwContextId; // Subscribe to the Help Requested Handler form.HelpRequested += new HelpEventHandler(form_HelpRequested); // Subscribe to the Destroyed Event Handler *to remove the form from the list* form.HandleDestroyed += new EventHandler(form_HandleDestroyed); } /// /// Launch CHM Help /// public void LaunchHelp() { int bHelpIsAlreadyRunning_Pid = 0; Diag.Process[] ps = ProcessW.AllRunningProcessesOf("hh", false, true); if (ps != null && ps.Length >= 1) { foreach (Diag.Process p in ps) { string ProcessName = ""; string CommandLine = ""; ProcessW.GetCommandLineArgumentsForProcessPID(p.Id, out ProcessName, out CommandLine); if (CommandLine.Contains(_FileNameNPath)) { bHelpIsAlreadyRunning_Pid = p.Id; break; } } } // No need to launch a second time if (bHelpIsAlreadyRunning_Pid != 0) { // Set Focus IntPtr hWnd = Yaulw.Win32.Functions.GetFirstTopLevelWindowForProcess(bHelpIsAlreadyRunning_Pid); if (hWnd != IntPtr.Zero) Yaulw.Win32.User32.SetActiveWindow(hWnd); } else { // Launch EnsureCHMFileExistance(false); PStarter.StartProcess(PStartInfo.CreateProcess(_FileNameNPath, "", "", false, System.Diagnostics.ProcessWindowStyle.Normal, true), false, false); } } /// /// Launch CHM Help /// /// form which will be the parent of the CHM File public void LaunchHelp(Form form) { if (form != null) { Control control = Control.FromHandle(form.Handle); if (control != null) { EnsureCHMFileExistance(false); Help.ShowHelp(control, _FileNameNPath); } } } /// /// aunch CHM Help /// /// Window which will be the parent for the CHM file public void LaunchHelp(Window window) { if (window != null) { Control control = Control.FromHandle(GetHandleForWPFWindow(window)); if (control != null) { EnsureCHMFileExistance(false); Help.ShowHelp(control, _FileNameNPath); } } } /// /// Launch CHM Help for the specified Context /// /// form which will be the parent of the CHM File /// Context Id to launch chm file with public void LaunchHelp(Form form, int dwContextId) { if (form != null) { Control control = Control.FromHandle(form.Handle); if (control != null) { EnsureCHMFileExistance(false); Help.ShowHelp(control, _FileNameNPath, HelpNavigator.TopicId, dwContextId.ToString()); } } } /// /// aunch CHM Help for the specified Context /// /// Window which will be the parent for the CHM file /// Context Id to launch chm file with public void LaunchHelp(Window window, int dwContextId) { if (window != null) { EnsureCHMFileExistance(false); Help.ShowHelp(null, _FileNameNPath, HelpNavigator.TopicId, dwContextId.ToString()); } } #endregion #region Private WinForm Help Event Handlers /// /// Handle HelpRequests /// private void form_HelpRequested(object sender, HelpEventArgs hlpevent) { Form form = sender as Form; if (form != null) { int dwContextId = s_FormContextMap[form]; Help.ShowHelp(form, _FileNameNPath, HelpNavigator.TopicId, dwContextId.ToString()); } } /// /// Handle Form Destroys /// private void form_HandleDestroyed(object sender, EventArgs e) { Form form = sender as Form; if (form != null) s_FormContextMap.Remove(form); } #endregion #region Private Helpers /// /// Creates the CHMFile from the stream (if a stream was used) /// /// true to force re-creation of the file, false otherwise private void EnsureCHMFileExistance(bool ForceCreationOfFile) { if (_FileStream != null) { if (ForceCreationOfFile || !IO.File.Exists(_FileNameNPath)) { using (IO.FileStream fs = new IO.FileStream(_FileNameNPath, IO.FileMode.Create)) { using (IO.BinaryWriter writer = new IO.BinaryWriter(fs)) { // Read from the Resource Byte[] streamData = new Byte[_FileStream.Length]; _FileStream.Read(streamData, 0, streamData.Length); // Write to File writer.Write(streamData); writer.Close(); } } } } } /// /// Uses the InteropHelper to get the Handle of a WPF Window /// /// a WPF Window /// an hWnd for the specified WPF Window private IntPtr GetHandleForWPFWindow(Window window) { WindowInteropHelper InteropHelper = new WindowInteropHelper(window); return InteropHelper.Handle; } #endregion } }