288 lines
9.9 KiB
C#
288 lines
9.9 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// CHM Help File Wrapper
|
|
/// </summary>
|
|
public class CHMFile
|
|
{
|
|
#region Private Members
|
|
|
|
/// <summary>
|
|
/// The Full File Name and Path to the CHM File
|
|
/// </summary>
|
|
private string _FileNameNPath = "";
|
|
|
|
/// <summary>
|
|
/// The File Stream that created the CHM File (if used)
|
|
/// </summary>
|
|
private IO.Stream _FileStream = null;
|
|
|
|
/// <summary>
|
|
/// Internally we keep track of each Form to Help Context ID
|
|
/// </summary>
|
|
private Dictionary<Form, int> s_FormContextMap = new Dictionary<Form, int>();
|
|
|
|
#endregion
|
|
|
|
#region Construction
|
|
|
|
/// <summary>
|
|
/// Construct a CHMFile object with the specified chm file
|
|
/// </summary>
|
|
/// <param name="FileNameNPath">a full path to a valid chm file</param>
|
|
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");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Construct a CHMFile object from the specified stream (will construct a chm file in
|
|
/// a temporary location from the specified stream)
|
|
/// </summary>
|
|
/// <param name="stream">stream to construct the chm file from</param>
|
|
/// <param name="ApplicationName">The name of the application (will be used when creating the .chm file)</param>
|
|
/// <param name="ForceNewFile">if true, will force a new file to be written out, false will only write file if not exists</param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Legacy MFC View Context offset
|
|
/// </summary>
|
|
public const int MNU = 0x10000;
|
|
|
|
/// <summary>
|
|
/// Legacy MFC Dialog Context offset
|
|
/// </summary>
|
|
public const int DLG = 0x20000;
|
|
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Attaches the HelpRequest Handler as well as shows the HelpButton on the CaptionBar
|
|
/// </summary>
|
|
/// <param name="form">WinForm to Attach Help Button to</param>
|
|
/// <param name="dwContextId">the Help Topic Context Id to attach to the specified WinForm</param>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Launch CHM Help
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Launch CHM Help
|
|
/// </summary>
|
|
/// <param name="form">form which will be the parent of the CHM File</param>
|
|
public void LaunchHelp(Form form)
|
|
{
|
|
if (form != null)
|
|
{
|
|
Control control = Control.FromHandle(form.Handle);
|
|
if (control != null)
|
|
{
|
|
EnsureCHMFileExistance(false);
|
|
Help.ShowHelp(control, _FileNameNPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// aunch CHM Help
|
|
/// </summary>
|
|
/// <param name="window">Window which will be the parent for the CHM file</param>
|
|
public void LaunchHelp(Window window)
|
|
{
|
|
if (window != null)
|
|
{
|
|
Control control = Control.FromHandle(GetHandleForWPFWindow(window));
|
|
if (control != null)
|
|
{
|
|
EnsureCHMFileExistance(false);
|
|
Help.ShowHelp(control, _FileNameNPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Launch CHM Help for the specified Context
|
|
/// </summary>
|
|
/// <param name="form">form which will be the parent of the CHM File</param>
|
|
/// <param name="dwContextId">Context Id to launch chm file with</param>
|
|
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());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// aunch CHM Help for the specified Context
|
|
/// </summary>
|
|
/// <param name="window">Window which will be the parent for the CHM file</param>
|
|
/// <param name="dwContextId">Context Id to launch chm file with</param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Handle HelpRequests
|
|
/// </summary>
|
|
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());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle Form Destroys
|
|
/// </summary>
|
|
private void form_HandleDestroyed(object sender, EventArgs e)
|
|
{
|
|
Form form = sender as Form;
|
|
if (form != null)
|
|
s_FormContextMap.Remove(form);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Helpers
|
|
|
|
/// <summary>
|
|
/// Creates the CHMFile from the stream (if a stream was used)
|
|
/// </summary>
|
|
/// <param name="ForceCreationOfFile">true to force re-creation of the file, false otherwise</param>
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Uses the InteropHelper to get the Handle of a WPF Window
|
|
/// </summary>
|
|
/// <param name="window">a WPF Window</param>
|
|
/// <returns>an hWnd for the specified WPF Window</returns>
|
|
private IntPtr GetHandleForWPFWindow(Window window)
|
|
{
|
|
WindowInteropHelper InteropHelper = new WindowInteropHelper(window);
|
|
return InteropHelper.Handle;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|