/* Commands.cs
* © Andrey Bushman, 2014
* При необходимости закомментируйте или раскомментируйте обозначенные ниже
* символы компиляции соответственно Вашей версии AutoCAD.
* В коде определены следующие команды:
* - ThroughAttribute
* - ThroughAcedSetFunHelp
* - ThroughProcess
* - ThroughAcedHelp
*/
#define AUTOCAD
#define AUTOCAD_NEWER_THAN_2012
#define AUTOCAD_NEWER_THAN_2014
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
#if AUTOCAD
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Ap = Autodesk.AutoCAD.ApplicationServices;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Rt = Autodesk.AutoCAD.Runtime;
using Wn = Autodesk.AutoCAD.Windows;
#endif
[assembly: Rt.ExtensionApplication(typeof(Bushman.CAD.Samples.Help
.ExtensionApplication))]
[assembly: Rt.CommandClass(typeof(Bushman.CAD.Samples.Help.Commands))]
namespace Bushman.CAD.Samples.Help {
/// <summary>
/// Класс, в котором определён набор пользовательских команд AutoCAD
/// </summary>
public static class Commands {
#region PInvoke
#if AUTOCAD_NEWER_THAN_2012
const String fnc_location = "accore.dll";
#else
const String fnc_location = "acad.exe";
#endif
#if AUTOCAD_NEWER_THAN_2014
const String x86_Prefix = "_";
#else
const String x86_Prefix = "";
#endif
#region acedSetFunHelp
const String acedSetFunHelp_Name = "acedSetFunHelp";
[DllImport(fnc_location, CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = "acedSetFunHelp")]
private static extern Int32 acedSetFunHelp_x64(
String functionName,
String helpFile,
String helpTopic,
Int32 cmd);
[DllImport(fnc_location, CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = x86_Prefix + "acedSetFunHelp")]
private static extern Int32 acedSetFunHelp_x86(
String functionName,
String helpFile,
String helpTopic,
Int32 cmd);
internal static Int32 acedSetFunHelp(
String functionName,
String helpFile,
String helpTopic,
Int32 cmd) {
if(IntPtr.Size == 4)
return acedSetFunHelp_x86(functionName, helpFile, helpTopic, cmd);
else
return acedSetFunHelp_x64(functionName, helpFile, helpTopic, cmd);
}
#endregion // acedSetFunHelp
#region acedHelp
[DllImport(fnc_location, CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = "acedHelp")]
private static extern Int32 acedHelp_x64(
String helpFile,
String helpTopic,
Int32 cmd);
[DllImport(fnc_location, CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = x86_Prefix + "acedHelp")]
private static extern Int32 acedHelp_x86(
String helpFile,
String helpTopic,
Int32 cmd);
internal static Int32 acedHelp(
String helpFile,
String helpTopic,
Int32 cmd) {
if(IntPtr.Size == 4)
return acedHelp_x86(helpFile, helpTopic, cmd);
else
return acedHelp_x64(helpFile, helpTopic, cmd);
}
#endregion // acedHelp
#endregion // PInvoke
const String commandGroup = "Bushman";
const String throughAttribute = "ThroughAttribute";
internal const String throughAcedSetFunHelp = "ThroughAcedSetFunHelp";
internal const String throughAcedHelp = "ThroughAcedHelp";
const String throughProcess = "ThroughProcess";
const String helpPageExtension = ".htm";
const String chmFileName = "MyHelp.chm";
internal static readonly String asm_location = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location);
// Предположим, что файл справки хранится в том же каталоге, что и DLL.
internal static readonly String chmFileFullName = Path.Combine(
asm_location, chmFileName);
const String f1_msg = "\nНажмите клавишу F1 для открытия нужного " +
"раздела справочной системы.\n";
/// <summary>
/// Пример открытия нужного раздела справки при помощи нажатия клавиши
/// F1 в момент выполнения команды (регистрация через атрибуты метода).
/// </summary>
[Rt.CommandMethod(commandGroup, throughAttribute, null,
Rt.CommandFlags.Session, null, chmFileName, throughAttribute)]
public static void ThroughAttribute_Command() {
Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
if(null == doc) {
return;
}
doc.Editor.GetPoint(f1_msg);
}
/// <summary>
/// Пример открытия нужного раздела справки при помощи нажатия клавиши
/// F1 в момент выполнения команды (регистрация через функцию
/// acedSetFunHelp).
/// </summary>
[Rt.CommandMethod(commandGroup, throughAcedSetFunHelp,
Rt.CommandFlags.Session)]
public static void ThroughAcedSetFunHelp_Command() {
Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
if(null == doc) {
return;
}
doc.Editor.GetPoint(f1_msg);
}
/// <summary>
/// Пример открытия нужного раздела справки при помощи запуска внешнего
/// процесса с передачей ему необходимого параметра
/// </summary>
[Rt.CommandMethod(commandGroup, throughProcess, Rt.CommandFlags.Session)]
public static void ThroughProcess_Command() {
Process process = new Process();
String parameter = String.Format("mk:@MSITStore:{0}::/{1}{2}",
chmFileFullName.Replace(" ", "%20"), throughProcess, helpPageExtension);
ProcessStartInfo info = new ProcessStartInfo("hh", parameter);
process.StartInfo = info;
process.Start();
}
/// <summary>
/// Пример открытия нужного раздела справки при помощи нажатия клавиши
/// F1 в момент выполнения команды (регистрация через функцию
/// acedHelp).
/// </summary>
[Rt.CommandMethod(commandGroup, throughAcedHelp, Rt.CommandFlags.Session)]
public static void ThroughAcedHelp_Command() {
// Открываю тот же раздел справки, что и в команде создания процесса
Int32 result2 = Commands.acedHelp(Commands.chmFileFullName,
Commands.throughProcess, 0); // 5100
}
}
/// <summary>
/// Класс, реализующий интерфейс IExtensionApplication.
/// </summary>
public sealed class ExtensionApplication : Rt.IExtensionApplication {
/// <summary>
/// Код этого метода будет выполнен сразу после загрузки данной сборки.
/// </summary>
public void Initialize() {
Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
if(null == doc) {
cad.DocumentManager.DocumentActivated += DocumentActivated;
return;
}
WriteLoadingReport(doc);
}
void DocumentActivated(object sender, Ap.DocumentCollectionEventArgs e) {
cad.DocumentManager.DocumentActivated -= DocumentActivated;
Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
WriteLoadingReport(doc);
}
private static void WriteLoadingReport(Ap.Document doc) {
if(null == doc)
throw new ArgumentNullException("doc");
if(doc.IsDisposed)
throw new ArgumentException("doc.IsDisposed == true");
using(doc.LockDocument()) {
String format = String.Empty;
doc.Editor.WriteMessage("\nСборка \"{0}\" успешно загружена.\n",
Assembly.GetExecutingAssembly().Location);
if(File.Exists(Commands.chmFileFullName)) {
Int32 result = Commands.acedSetFunHelp(Commands.throughAcedSetFunHelp,
Commands.chmFileFullName, Commands.throughAcedSetFunHelp, 0); // 5100
format = "\nФайл \"{0}\" найден. Регистрация раздела справки " +
"выполнена.\n";
}
else
format = "\nФайл \"{0}\" не найден.\n";
doc.Editor.WriteMessage(format, Commands.chmFileFullName);
}
}
public void Terminate() { }
}
}