
Added a new parameter to SaveSectionDocument and Error Handling Changed error handling for InvokeMember to throw an exception Added code to change the view to PrintMode when determining length
544 lines
17 KiB
C#
544 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
using Microsoft.Win32;
|
|
using System.Windows.Forms;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace LBWordLibrary
|
|
{
|
|
public partial class LBApplicationClass : LBComObject
|
|
{
|
|
/// <summary>
|
|
/// This gives the option of specifying Background = false to print in the foreground.
|
|
/// </summary>
|
|
/// <param name="Background">boolean BackGround
|
|
/// If true - document will be printed in the background
|
|
/// If false - document will be printed in the foreground</param>
|
|
public void PrintOut(Boolean Background)
|
|
{
|
|
InvokeMethod("PrintOut", Background, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
|
|
}
|
|
public void Quit(bool save)
|
|
{
|
|
InvokeMethod("Quit", save, Missing.Value, Missing.Value);
|
|
}
|
|
public bool VolianPDFInstalled
|
|
{
|
|
get
|
|
{
|
|
foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
|
|
if (printer == "VolianPDF Writer") return true;
|
|
return false;
|
|
}
|
|
}
|
|
public bool WordPDFExporterInstalled
|
|
{
|
|
get
|
|
{
|
|
// this is for ExportAsFixedFormat MSOffice AddIn
|
|
RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"Installer\Components\12B306B24E250DD428FC7016B6FB4BD8");
|
|
if (key != null)
|
|
{
|
|
key.Close();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
private bool CanCreatePDFFile(string pdfFileName)
|
|
{
|
|
System.IO.FileInfo file = new System.IO.FileInfo(pdfFileName);
|
|
if (!file.Exists) return true;
|
|
try
|
|
{
|
|
file.Delete();
|
|
return true;
|
|
}
|
|
catch (System.IO.IOException exio)
|
|
{
|
|
if (exio.Message.StartsWith("The process cannot access the file")) return false;
|
|
throw new Exception(string.Format("Cannot Delete PDF file {0}", pdfFileName), exio);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(string.Format("Cannot Delete PDF file {0}", pdfFileName), ex);
|
|
}
|
|
}
|
|
private string AvailableFileName(string pdfFileName)
|
|
{
|
|
if (CanCreatePDFFile(pdfFileName)) return pdfFileName;
|
|
string prefix = pdfFileName.Replace(".pdf", "");
|
|
for (int i = 1; i < 1000; i++)
|
|
{
|
|
string newname = string.Format("{0}_{1:000}.PDF", prefix, i);
|
|
if (CanCreatePDFFile(newname)) return newname;
|
|
}
|
|
throw new Exception("Cannot find a name to use");
|
|
}
|
|
public string CreatePDF(string pdfFileName, bool openPDF)
|
|
{
|
|
pdfFileName = CreatePDF(pdfFileName);
|
|
if (openPDF) OpenPDF(pdfFileName);
|
|
return pdfFileName;
|
|
}
|
|
static List<System.Diagnostics.Process> _AcrobatProcesses=new List<System.Diagnostics.Process>();
|
|
private static void OpenPDF(string pdfFileName)
|
|
{
|
|
_AcrobatProcesses.Add(System.Diagnostics.Process.Start(pdfFileName));
|
|
}
|
|
public static void ClosePDFs()
|
|
{
|
|
foreach(System.Diagnostics.Process proc in _AcrobatProcesses)
|
|
if (!proc.HasExited)
|
|
KillAndWait(proc);
|
|
}
|
|
private static void KillAndWait(System.Diagnostics.Process proc)
|
|
{
|
|
Console.WriteLine("{0:s.ffff} Killing Adobe", DateTime.Now);
|
|
DateTime tStart = DateTime.Now;
|
|
proc.Kill();
|
|
DateTime tEnd = DateTime.Now.AddMilliseconds(100);
|
|
while (DateTime.Now < tEnd)
|
|
{
|
|
Application.DoEvents();
|
|
}
|
|
Console.WriteLine("{0:yyyy-MM-dd HH:mm:ss.ffff} {1:yyyy-MM-dd HH:mm:ss.ffff} {2}", DateTime.Now, proc.ExitTime
|
|
,TimeSpan.FromTicks(proc.ExitTime.Ticks - tStart.Ticks).TotalMilliseconds);
|
|
}
|
|
public string CreatePDF(string pdfFileName)
|
|
{
|
|
pdfFileName = AvailableFileName(pdfFileName);
|
|
if (Convert.ToSingle(Version) >= 12.0F && WordPDFExporterInstalled)
|
|
return CreatePDF2007(pdfFileName);
|
|
else if (VolianPDFInstalled)
|
|
return CreatePDF2003BG(pdfFileName);
|
|
else
|
|
throw new Exception("No PDF Writer support installed for MS Word sections");
|
|
}
|
|
public string CreatePDF2003FG(string pdfFileName, bool openPDF)
|
|
{
|
|
pdfFileName = CreatePDF2003FG(pdfFileName);
|
|
if (openPDF) OpenPDF(pdfFileName);
|
|
return pdfFileName;
|
|
}
|
|
public string CreatePDF2003FG(string pdfFileName)
|
|
{
|
|
pdfFileName = AvailableFileName(pdfFileName);
|
|
if (!VolianPDFInstalled)
|
|
throw new Exception("VolianPDF Writer is not installed properly");
|
|
try
|
|
{
|
|
string printer = ActivePrinter;
|
|
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\VolianPDF Writer");
|
|
key.SetValue("OutputFile", pdfFileName, RegistryValueKind.String);
|
|
key.SetValue("BypassSaveAs", "1", RegistryValueKind.String);
|
|
key.Close();
|
|
ActivePrinter = "VolianPDF Writer";
|
|
PrintOut(false);
|
|
ActivePrinter = printer;
|
|
Registry.CurrentUser.DeleteSubKeyTree(@"Software\VolianPDF Writer");
|
|
return pdfFileName;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception("Error creating PDF - LBApplicationClass.CreatePDF2003FG", ex);
|
|
}
|
|
}
|
|
public string CreatePDF2003BG(string pdfFileName, bool openPDF)
|
|
{
|
|
pdfFileName = CreatePDF2003BG(pdfFileName);
|
|
if (openPDF) OpenPDF(pdfFileName);
|
|
return pdfFileName;
|
|
}
|
|
public string CreatePDF2003BG(string pdfFileName)
|
|
{
|
|
pdfFileName = AvailableFileName(pdfFileName);
|
|
if (!VolianPDFInstalled)
|
|
throw new Exception("VolianPDF Writer is not installed properly");
|
|
try
|
|
{
|
|
string printer = ActivePrinter;
|
|
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\VolianPDF Writer");
|
|
key.SetValue("OutputFile", pdfFileName, RegistryValueKind.String);
|
|
key.SetValue("BypassSaveAs", "1", RegistryValueKind.String);
|
|
key.Close();
|
|
ActivePrinter = "VolianPDF Writer";
|
|
PrintOut(true);
|
|
do
|
|
{
|
|
// Console.WriteLine("Background Printing Status = {0}", _MyApp.BackgroundPrintingStatus);
|
|
Application.DoEvents();
|
|
} while (BackgroundPrintingStatus == 1);
|
|
ActivePrinter = printer;
|
|
Registry.CurrentUser.DeleteSubKeyTree(@"Software\VolianPDF Writer");
|
|
return pdfFileName;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception("Error creating PDF - LBApplicationClass.CreatePDF2003BG", ex);
|
|
}
|
|
}
|
|
public string CreatePDF2007(string pdfFileName, bool openPDF)
|
|
{
|
|
pdfFileName = CreatePDF2007(pdfFileName);
|
|
if (openPDF) OpenPDF(pdfFileName);
|
|
return pdfFileName;
|
|
}
|
|
public string CreatePDF2007(string pdfFileName)
|
|
{
|
|
pdfFileName = AvailableFileName(pdfFileName);
|
|
if (!WordPDFExporterInstalled)
|
|
throw new Exception("MS Word PDF Exporter is not installed");
|
|
try
|
|
{
|
|
ActiveDocument.ExportAsFixedFormat(pdfFileName, LBWdExportFormat.wdExportFormatPDF);
|
|
return pdfFileName;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception("Error creating PDF - LBApplicationClass.CreatePDF2007", ex);
|
|
}
|
|
}
|
|
}
|
|
public partial class LBDocuments
|
|
{
|
|
public LBDocumentClass Open(string fileName, Boolean addToRecentFiles)
|
|
{
|
|
return Open(fileName, Missing.Value, Missing.Value, addToRecentFiles);
|
|
}
|
|
private LBDocumentClass Open(params object[] myParams)
|
|
{
|
|
return new LBDocumentClass(InvokeMethod("Open", myParams));
|
|
}
|
|
}
|
|
public partial class LBDocumentClass : LBComObject
|
|
{
|
|
public void SaveAs2000(string fileName)
|
|
{
|
|
if (fileName.ToUpper().EndsWith("DOC"))
|
|
SaveAs2000(fileName, LBWdSaveFormat.wdFormatDocument);
|
|
else if (fileName.ToUpper().EndsWith("RTF"))
|
|
SaveAs2000(fileName, LBWdSaveFormat.wdFormatRTF);
|
|
else
|
|
SaveAs2000(fileName);
|
|
}
|
|
public void SaveAs2000(params object[] myParams)
|
|
{
|
|
InvokeMethod("SaveAs2000", myParams);
|
|
}
|
|
public void SaveAs(string fileName)
|
|
{
|
|
if (fileName.ToUpper().EndsWith("DOC"))
|
|
SaveAs2(fileName, LBWdSaveFormat.wdFormatDocument, Missing.Value, Missing.Value, false);
|
|
else if (fileName.ToUpper().EndsWith("RTF"))
|
|
SaveAs2(fileName, LBWdSaveFormat.wdFormatRTF, Missing.Value, Missing.Value, false);
|
|
else if (fileName.ToUpper().EndsWith("TXT"))
|
|
SaveAs2(fileName, LBWdSaveFormat.wdFormatDOSText, Missing.Value, Missing.Value, false);
|
|
else if (fileName.ToUpper().EndsWith("DOCX"))
|
|
SaveAs2(fileName, LBWdSaveFormat.wdFormatXMLDocument, Missing.Value, Missing.Value, false);
|
|
else
|
|
SaveAs2(fileName, Missing.Value, Missing.Value, Missing.Value, false);
|
|
}
|
|
public void SaveAs2(params object[] myParams)
|
|
{
|
|
InvokeMethod("SaveAs", myParams);
|
|
}
|
|
public void SaveAs(string fileName, LBWdSaveFormat format)
|
|
{
|
|
SaveAs2(fileName, format, Missing.Value, Missing.Value, false);
|
|
}
|
|
public LBRange Range(int Start, int End)
|
|
{
|
|
return new LBRange(InvokeMethod("Range", Start, End));
|
|
}
|
|
/// <summary>
|
|
/// Length is Pages and Partial Pages
|
|
/// The integral part is the number of full pages
|
|
/// The decimal part is the size of the last page divided by 7200
|
|
/// (the first two digits should be the number of inches)
|
|
/// </summary>
|
|
public float Length
|
|
{
|
|
get
|
|
{
|
|
ActiveWindow.ActivePane.View.Type = LBWdViewType.wdPrintView;
|
|
ActiveWindow.View.Type = LBWdViewType.wdPrintView;
|
|
LBPages myPages = ActiveWindow.ActivePane.Pages;// Start with pages
|
|
float retval = (float)myPages.Count - 1;
|
|
LBRange myRange = Range();
|
|
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
|
|
float partial = (float) myRange.get_Information(LBWdInformation.wdVerticalPositionRelativeToPage);
|
|
partial += myRange.Font.Size;
|
|
retval += partial / 7200;
|
|
return retval;
|
|
}
|
|
}
|
|
public string Ascii
|
|
{
|
|
get
|
|
{
|
|
LBRange myRange = Range();
|
|
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
|
|
myRange.Start = 0;
|
|
return ReplaceSymbolCharacters(GetRangeText(myRange));
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Checks to see if the document contains symbol characters
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool HasSymbolCharacters
|
|
{
|
|
get
|
|
{
|
|
LBRange myRange = Range();
|
|
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
|
|
myRange.Start = 0;
|
|
string myText = GetRangeText(myRange);
|
|
return _RegFindSymbol.IsMatch(myText);
|
|
}
|
|
}
|
|
Regex _RegFindSymbol = new Regex("[\\uF000-\\uF0FF]+");
|
|
/// <summary>
|
|
/// FixSymbolCharacters - Fix any symbol characters in the document
|
|
/// </summary>
|
|
public void FixSymbolCharacters()
|
|
{
|
|
// Set up range object to be used to process text
|
|
LBRange myRange = Range();
|
|
myRange = myRange.GoTo(LBWdGoToItem.wdGoToPercent, LBWdGoToDirection.wdGoToLast, 100);
|
|
int end = myRange.End;
|
|
myRange.Start = 0;
|
|
string myText = GetRangeText(myRange);
|
|
MatchCollection problems = _RegFindSymbol.Matches(myText);
|
|
int offset = 0;
|
|
foreach (Match problem in problems)
|
|
{
|
|
myRange.Start = problem.Index + offset;
|
|
myRange.End = problem.Index + problem.Length + offset;
|
|
int newOffset = FindRangeOffset(myRange, problem, offset, end);
|
|
ReplaceSymbolCharacters(myRange);
|
|
offset = newOffset;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Get the Range Text with error handling. myRange.Text sometimes will get a null reference exception.
|
|
/// </summary>
|
|
/// <param name="myRange"></param>
|
|
/// <returns></returns>
|
|
internal static string GetRangeText(LBRange myRange)
|
|
{
|
|
string text="";
|
|
try
|
|
{
|
|
text = myRange.Text;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("{0} - {1}", ex.GetType().Name, ex.Message);
|
|
}
|
|
return text;
|
|
}
|
|
/// <summary>
|
|
/// Looks for the problem string and adjusts the range as necessary
|
|
/// </summary>
|
|
/// <param name="myRange"></param>
|
|
/// <param name="problem"></param>
|
|
/// <param name="offset"></param>
|
|
/// <param name="end"></param>
|
|
/// <returns></returns>
|
|
private int FindRangeOffset(LBRange myRange, Match problem, int offset, int end)
|
|
{
|
|
// try to find the string
|
|
string text = GetRangeText(myRange);
|
|
if (text != problem.Value)
|
|
{
|
|
// Get the entire text starting at the offset of the first match
|
|
myRange.Start = problem.Index + offset;
|
|
myRange.End = end;
|
|
text = GetRangeText(myRange);
|
|
while (!text.StartsWith(problem.Value))
|
|
{
|
|
int newStart = text.IndexOf(problem.Value);// Find the string if it is not at the beginning
|
|
myRange.Start += myRange.Start == newStart ? newStart + 1 : newStart; // adjust the starting location
|
|
text = GetRangeText(myRange);// get the text to check
|
|
}
|
|
myRange.End = myRange.Start + problem.Length; // assume that the end should be the start plus the length
|
|
text = GetRangeText(myRange);
|
|
while (text.Length < problem.Length) // If the result is too short increase the length
|
|
{
|
|
myRange.End += (problem.Length - text.Length);
|
|
text = GetRangeText(myRange);
|
|
}
|
|
}
|
|
return myRange.Start - problem.Index;
|
|
}
|
|
/// <summary>
|
|
/// ReplaceSymbolCharacters Replaces any symbol characters in the specified range
|
|
/// </summary>
|
|
/// <param name="myRange"></param>
|
|
private static void ReplaceSymbolCharacters(LBRange myRange)
|
|
{
|
|
try
|
|
{
|
|
string before = GetRangeText(myRange);
|
|
string updated = ReplaceSymbolCharacters(before);
|
|
myRange.Text = updated;
|
|
string after = GetRangeText(myRange);
|
|
if (after != updated) // If the Word text doesn't match try including a character before and after and do it again.
|
|
{
|
|
Console.WriteLine("'TryEntireRange Failed',{0},{1},'{2}','{3}','{4}'", myRange.Start, myRange.End, before, updated, after);
|
|
int end = myRange.End;
|
|
myRange.Start = myRange.Start - 1;
|
|
myRange.End = end + 1;
|
|
myRange.Text = ReplaceSymbolCharacters(GetRangeText(myRange));
|
|
Console.WriteLine("'TryEntireRange Failed',{0},{1},'{2}'", myRange.Start, myRange.End, GetRangeText(myRange));
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("'TryEntireRange Exception',{0},{1},'{2}'", myRange.Start, myRange.End, ex.Message);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// ReplaceSymbolCharacters processes the string returned and changes any symbols (0xF0??) to normal characters
|
|
/// </summary>
|
|
/// <param name="str"></param>
|
|
/// <returns></returns>
|
|
private static string ReplaceSymbolCharacters(string str)
|
|
{
|
|
StringBuilder results = new StringBuilder();
|
|
foreach (char c in str)
|
|
{
|
|
if ((c & 0xFF00) == 0xF000)
|
|
results.Append((char)(c & 0xFF));
|
|
else
|
|
results.Append((char)(c));
|
|
}
|
|
return results.ToString();
|
|
}
|
|
/// <summary>
|
|
/// Close the document
|
|
/// </summary>
|
|
/// <param name="SaveChanges">Save Changes</param>
|
|
public void Close(bool SaveChanges)
|
|
{
|
|
InvokeMethod("Close", SaveChanges, Missing.Value, Missing.Value);
|
|
}
|
|
}
|
|
public partial class LBFind
|
|
{
|
|
public void ReplaceAll()
|
|
{
|
|
this.Execute(Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
|
|
Missing.Value, Missing.Value, Missing.Value, Missing.Value, LBWdReplace.wdReplaceAll, Missing.Value,
|
|
Missing.Value, Missing.Value, Missing.Value);
|
|
}
|
|
}
|
|
public partial class LBFontClass : LBComObject
|
|
{
|
|
public int TextColor
|
|
{
|
|
get { return (int)GetProperty("Color"); }
|
|
set { SetProperty("Color", value); }
|
|
}
|
|
}
|
|
public partial class LBRange : LBComObject
|
|
{
|
|
public Object get_Information(LBWdInformation info)
|
|
{
|
|
return GetProperty("Information", info);
|
|
}
|
|
public LBRange GoTo(LBWdGoToItem What, LBWdGoToDirection Which, int Count)
|
|
{
|
|
return new LBRange(InvokeMethod("GoTo", What, Which, Count, Missing.Value));
|
|
}
|
|
}
|
|
public partial class LBSelection : LBComObject
|
|
{
|
|
public Object get_Information(LBWdInformation info)
|
|
{
|
|
return GetProperty("Information", info);
|
|
}
|
|
public int MoveStart(LBWdUnits Unit, int Count)
|
|
{
|
|
return InvokeMethod("MoveStart", Unit, Count) as int? ?? 0;
|
|
}
|
|
public int MoveEnd(LBWdUnits Unit, int Count)
|
|
{
|
|
return InvokeMethod("MoveEnd", Unit, Count) as int? ?? 0;
|
|
}
|
|
public int EndKey(LBWdUnits Unit, bool Extend)
|
|
{
|
|
return InvokeMethod("EndKey", Unit, Extend) as int? ?? 0;
|
|
}
|
|
public bool LastWasUpper
|
|
{
|
|
get
|
|
{
|
|
LBRange myRange = Range;
|
|
int start = myRange.Start - 1;
|
|
while (start >= 0)
|
|
{
|
|
myRange.Start = start;
|
|
myRange.End = start + 1;
|
|
string previous = LBDocumentClass.GetRangeText(myRange);
|
|
if (Regex.IsMatch(previous, "[A-Z]")) return true;
|
|
if (Regex.IsMatch(previous, "[a-z]")) return false;
|
|
start = start - 1;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
public partial class LBInlineShapes : LBComObjectList<LBInlineShapes, LBInlineShape> /* Collection */
|
|
{
|
|
public LBInlineShape AddPicture(string FileName, LBRange Range)
|
|
{
|
|
return new LBInlineShape(InvokeMethod("AddPicture", FileName, false, true, Range));
|
|
}
|
|
}
|
|
public partial class LBShapes : LBComObjectList<LBShapes, LBShape> /* Collection */
|
|
{
|
|
public LBShape AddPicture(string FileName, float Left, float Top, LBRange Anchor)
|
|
{
|
|
return new LBShape(InvokeMethod("AddPicture", FileName, false, true, Left, Top, Missing.Value, Missing.Value, Anchor));
|
|
}
|
|
public LBShape AddPicture(string FileName, float Left, float Top)
|
|
{
|
|
return new LBShape(InvokeMethod("AddPicture", FileName, false, true, Left, Top, Missing.Value, Missing.Value, Missing.Value));
|
|
}
|
|
}
|
|
public enum LBMsoTriState
|
|
{
|
|
msoCTrue = 1,
|
|
msoFalse = 0,
|
|
msoTriStateMixed = -2,
|
|
msoTriStateToggle = -3,
|
|
msoTrue = -1
|
|
}
|
|
//public partial class ProcessKiller
|
|
//{
|
|
// System.Diagnostics.Process _MyProcess;
|
|
// private bool _Exited = false;
|
|
// public ProcessKiller(System.Diagnostics.Process myProcess)
|
|
// {
|
|
// _MyProcess = myProcess;
|
|
// _MyProcess.Exited += new EventHandler(_MyProcess_Exited);
|
|
// _MyProcess.Kill();
|
|
// DateTime next = DateTime.Now.AddMilliseconds(200);
|
|
// while (DateTime.Now < next)
|
|
// Application.DoEvents();
|
|
// while (!_Exited)
|
|
// Application.DoEvents();
|
|
// }
|
|
// void _MyProcess_Exited(object sender, EventArgs e)
|
|
// {
|
|
// Console.WriteLine("Exited");
|
|
// _Exited = true;
|
|
// }
|
|
//}
|
|
}
|