Не открывается нужный раздел пользовательской справки по нажатию F1

Автор Тема: Не открывается нужный раздел пользовательской справки по нажатию F1  (Прочитано 44110 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
В прошлом не раз успешно регистрировал пользовательскую справку без каких-либо проблем. Видимо что-то подзабыл...

* AutoCAD 2009 SP3 x86 Enu
* AutoCAD 2015 x86 Enu

Ниже в примере, демонстрирующем проблему, определены три команды:
  • ThroughAttribute - регистрация справки для этой команды выполняется через атрибуты.
  • ThroughAcedSetFunHelp - регистрация справки для этой команды выполняется при помощи acedSetFunHelp.
  • ThroughProcess - эта команда создаёт новый процесс и в нём открывает нужный раздел справочной системы.

Во вложении находится соответствующий CHM файл для тестирования - его нужно положить в каталог сборки.

Из приведённых выше вариантов корректно работает только ThroughProcess. В остальных двух не происходит открытие нужного раздела пользовательского файла справочной системы при нажатии клавиши F1 во время выполнения команды: вместо этого открывается файл справки AutoCAD. Добавление каталога сборки в каталоги поиска так же результатов не дали.

Код - C# [Выбрать]
  1. /* Commands.cs
  2.  * © Andrey Bushman, 2014
  3.  * При необходимости закомментируйте или раскомментируйте обозначенные ниже
  4.  * символы компиляции соответственно Вашей версии AutoCAD.
  5.  * В коде определены следующие команды:
  6.  * -  ThroughAttribute
  7.  * -  ThroughAcedSetFunHelp
  8.  * -  ThroughProcess
  9.  */
  10.  
  11. #define AUTOCAD
  12. #define AUTOCAD_NEWER_THAN_2012
  13. #define AUTOCAD_NEWER_THAN_2014
  14.  
  15. using System;
  16. using System.Reflection;
  17. using System.Diagnostics;
  18. using System.IO;
  19. using System.Runtime.InteropServices;
  20.  
  21. #if AUTOCAD
  22. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  23. using Ap = Autodesk.AutoCAD.ApplicationServices;
  24. using Db = Autodesk.AutoCAD.DatabaseServices;
  25. using Ed = Autodesk.AutoCAD.EditorInput;
  26. using Rt = Autodesk.AutoCAD.Runtime;
  27. #endif
  28.  
  29. [assembly: Rt.ExtensionApplication(typeof(Bushman.CAD.Samples.Help
  30.   .ExtensionApplication))]
  31. [assembly: Rt.CommandClass(typeof(Bushman.CAD.Samples.Help.Commands))]
  32.  
  33. namespace Bushman.CAD.Samples.Help {
  34.   /// <summary>
  35.   /// Класс, в котором определён набор пользовательских команд AutoCAD
  36.   /// </summary>
  37.   public sealed class Commands {
  38.  
  39.     #region PInvoke
  40.  
  41. #if AUTOCAD_NEWER_THAN_2012
  42.     const String fnc_location = "accore.dll";
  43. #else
  44.     const String fnc_location = "acad.exe";
  45. #endif
  46.  
  47. #if AUTOCAD_NEWER_THAN_2014
  48.     const String x86_Prefix = "_";
  49. #else
  50.     const String x86_Prefix = "";
  51. #endif
  52.  
  53.     #region acedSetFunHelp
  54.     const String acedSetFunHelp_Name = "acedSetFunHelp";
  55.  
  56.     [DllImport(fnc_location, CharSet = CharSet.Auto,
  57.       CallingConvention = CallingConvention.Cdecl,
  58.       EntryPoint = "acedSetFunHelp")]
  59.     private static extern Int32 acedSetFunHelp_x64(
  60.         String functionName,
  61.         String helpFile,
  62.         String helpTopic,
  63.         Int32 cmd);
  64.  
  65.     [DllImport(fnc_location, CharSet = CharSet.Auto,
  66.       CallingConvention = CallingConvention.Cdecl,
  67.       EntryPoint = x86_Prefix + "acedSetFunHelp")]
  68.     private static extern Int32 acedSetFunHelp_x86(
  69.         String functionName,
  70.         String helpFile,
  71.         String helpTopic,
  72.         Int32 cmd);
  73.  
  74.  
  75.     internal static Int32 acedSetFunHelp(
  76.         String functionName,
  77.         String helpFile,
  78.         String helpTopic,
  79.         Int32 cmd) {
  80.       if(IntPtr.Size == 4)
  81.         return acedSetFunHelp_x86(functionName, helpFile, helpTopic, cmd);
  82.       else
  83.         return acedSetFunHelp_x64(functionName, helpFile, helpTopic, cmd);
  84.     }
  85.     #endregion // acedSetFunHelp
  86.     #endregion // PInvoke
  87.  
  88.     const String commandGroup = "Bushman";
  89.     const String throughAttribute = "ThroughAttribute";
  90.     internal const String throughAcedSetFunHelp = "ThroughAcedSetFunHelp";
  91.     const String throughProcess = "ThroughProcess";
  92.     const String helpPageExtension = ".htm";
  93.     const String chmFileName = "MyHelp.chm";
  94.     internal static readonly String asm_location = Path.GetDirectoryName(
  95.       Assembly.GetExecutingAssembly().Location);
  96.     // Предположим, что файл справки хранится в том же каталоге, что и DLL.
  97.     internal static readonly String chmFileFullName = Path.Combine(
  98.       asm_location, chmFileName);
  99.  
  100.     const String f1_msg = "\nНажмите клавишу F1 для открытия нужного " +
  101.         "раздела справочной системы.\n";
  102.  
  103.     /// <summary>
  104.     /// Пример открытия нужного раздела справки при помощи нажатия клавиши
  105.     /// F1 в момент выполнения команды (регистрация через атрибуты метода).
  106.     /// </summary>
  107.     [Rt.CommandMethod(commandGroup, throughAttribute, null,
  108.       Rt.CommandFlags.Session, null, chmFileName, throughAttribute)]
  109.     public void ThroughAttribute_Command() {
  110.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  111.       if(null == doc) {
  112.         return;
  113.       }
  114.       doc.Editor.GetPoint(f1_msg);
  115.     }
  116.  
  117.     /// <summary>
  118.     /// Пример открытия нужного раздела справки при помощи нажатия клавиши
  119.     /// F1 в момент выполнения команды (регистрация через функцию
  120.     /// acedSetFunHelp).
  121.     /// </summary>
  122.     [Rt.CommandMethod(commandGroup, throughAcedSetFunHelp,
  123.       Rt.CommandFlags.Session)]
  124.     public void ThroughAcedSetFunHelp_Command() {
  125.  
  126.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  127.       if(null == doc) {
  128.         return;
  129.       }
  130.       doc.Editor.GetPoint(f1_msg);
  131.     }
  132.  
  133.     /// <summary>
  134.     /// Пример открытия нужного раздела справки при помощи запуска внешнего
  135.     /// процесса с передачей ему необходимого параметра
  136.     /// </summary>
  137.     [Rt.CommandMethod(commandGroup, throughProcess, Rt.CommandFlags.Session)]
  138.     public void ThroughProcess_Command() {
  139.       Process process = new Process();
  140.  
  141.       String parameter = String.Format("mk:@MSITStore:{0}::/{1}{2}",
  142.         chmFileFullName.Replace(" ", "%20"), throughProcess, helpPageExtension);
  143.       ProcessStartInfo info = new ProcessStartInfo("hh", parameter);
  144.       process.StartInfo = info;
  145.       process.Start();
  146.     }
  147.   }
  148.  
  149.   /// <summary>
  150.   /// Класс, реализующий интерфейс IExtensionApplication.
  151.   /// </summary>
  152.   public sealed class ExtensionApplication : Rt.IExtensionApplication {
  153.  
  154.     /// <summary>
  155.     /// Код этого метода будет выполнен сразу после загрузки данной сборки.
  156.     /// </summary>
  157.     public void Initialize() {      
  158.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  159.       if(null == doc) {
  160.         cad.DocumentManager.DocumentActivated += DocumentActivated;
  161.         return;
  162.       }
  163.       WriteLoadingReport(doc);
  164.     }
  165.  
  166.     void DocumentActivated(object sender, Ap.DocumentCollectionEventArgs e) {
  167.       cad.DocumentManager.DocumentActivated -= DocumentActivated;
  168.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  169.       WriteLoadingReport(doc);
  170.     }
  171.  
  172.     private static void WriteLoadingReport(Ap.Document doc) {
  173.  
  174.       if(null == doc)
  175.         throw new ArgumentNullException("doc");
  176.       if(doc.IsDisposed)
  177.         throw new ArgumentException("doc.IsDisposed == true");
  178.  
  179.       using(doc.LockDocument()) {
  180.         String format = String.Empty;
  181.  
  182.         doc.Editor.WriteMessage("\nСборка \"{0}\" успешно загружена.\n",
  183.           Assembly.GetExecutingAssembly().Location);
  184.  
  185.         if(File.Exists(Commands.chmFileFullName)) {
  186.           Commands.acedSetFunHelp(Commands.throughAcedSetFunHelp,
  187.             Commands.chmFileFullName, Commands.throughAcedSetFunHelp, 0);
  188.           format = "\nФайл \"{0}\" найден. Регистрация раздела справки " +
  189.             "выполнена.\n";
  190.         }
  191.         else
  192.           format = "\nФайл \"{0}\" не найден.\n";
  193.  
  194.         doc.Editor.WriteMessage(format, Commands.chmFileFullName);        
  195.       }
  196.     }
  197.  
  198.     public void Terminate() { }
  199.   }
  200. }
Почему не открывается файл справочной системы, регистрацию которого я выполняю?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Пока проверил в AutoCAD 2013 x86 в Windows XP SP3 и AutoCAD 2013 x64 Windows 7 - всё работает. Повторить ошибку не смог.

Призываю читающих это тему попробовать и сообщить результаты. Причину установить пока не удалось. Ни одно из массы предположений не подтвердилось.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Цитировать
Command: NETLOAD
Сборка "E:\_Profiles\Visual Studio 2010\Projects\MyHelp\MyHelp\bin\Debug\MyHelp.dll" успешно загружена.
Файл "E:\_Profiles\Visual Studio 2010\Projects\MyHelp\MyHelp\bin\Debug\MyHelp.chm" найден. Регистрация раздела справки выполнена.
Command: THROUGHATTRIBUTE
Нажмите клавишу F1 для открытия нужного раздела справочной системы.
: *Cancel*
Command: *Cancel*
Command: THROUGHACEDSETFUNHELP
Нажмите клавишу F1 для открытия нужного раздела справочной системы.
: *Cancel*
Command: THROUGHPROCESS
Command: *Cancel*

Справка открылась в соответствующих разделах все 3 раза.
AutoCAD 2014 x64 , Win7 x64

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Boxa.Shu, спасибо!
Не очень понятно откуда берется *Cancel*.
p.S.: Хотел уточнить - запуск у тебя от имени Администратора идет или от обычного пользователя?
« Последнее редактирование: 25-06-2014, 17:08:06 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
ACAD 2010 Win7*32 - как и у автора - ThroughProcess - вызывает нужную справку, в остальных случаях по F1 - выскакивает автокадная.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Я проверял на пяти компьютерах:

- у двоих пользователей
- на двоих виртуальных машинках
- на домашнем ноутбуке

Везде результат один и тот же - тот, что обозначен мною в первом сообщении темы.

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Не очень понятно откуда берется *Cancel*.
p.S.: Хотел уточнить - запуск у тебя от имени Администратора идет или от обычного пользователя?
Я на Esc тыкал =) ,  запускал в режиме отладке из студии, студия вроде бы без админских прав запускается (соответствующие галочки сняты)
Тут видео:

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
ACAD 2010 Win7*32 - как и у автора - ThroughProcess - вызывает нужную справку, в остальных случаях по F1 - выскакивает автокадная.
Дима. А что в командной строке при загрузке dll?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Я уж стер - но было все в порядке - сборка загруженна, регистрация выполнена... (одна команда то работает).

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Проверил в AutoCAD 2015 SP1 x64 Win 7 x64 - всё работает. Такое чувство, что от версии AutoCAD не зависит.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Проверил еще в x64 AutoCAD 2012, 2013, 2014 - всё нормально
Проверил на всякий случай в x86 AutoCAD 2008, но в Win7 X64 - работает только последний вариант. При этом в этом же AutoCAD'е но в Windows XP x86 работает нормально.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
и тем не менее проблема есть, она не может не есть...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Пока я ничего не могу отправить в ADN DevHelp, т.к. на своём PC не могу ни подтвердить, ни опровергнуть наличие ошибки в последних трёх версиях AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Acad 2014*64, Win8.1:
сборка и файл помощи на рабочем столе:
сборка загруженна успешно, регистрация выполненна
THROUGHATTRIBUTE - автокад ругается что такого файла нету, после загружает свою справку
THROUGHACEDSETFUNHELP - открывает "правильную" справку - курсор на пункте about (в 2010 был на "своем" месте)
THROUGHPROCESS - открывает "правильную" справку - курсор на пункте about

сборка на рабочем столе, файл справки в папке автокада:
сборка загруженна успешно, файл справки не найден
THROUGHATTRIBUTE - открывает "правильную" справку - курсор на пункте about
THROUGHACEDSETFUNHELP - автокад "молча" загружает свою справку
THROUGHPROCESS - ругается что не удается открыть справку

в общем, как минимум, явно разные api в разные места смотрят...

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
THROUGHATTRIBUTE - автокад ругается что такого файла нету, после загружает свою справку
Решение, конечно через ж@пу, но всё же попробуй для этого случая на время добавить запись в каталоги поиска AutoCAD (предполагаю, что может сработать).

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Так я в этом даже не сомневаюсь - см. второй абзац (они все заработают если и сборка и справка будут в одной папке, которая при этом в "поиске" автокада).

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
сборка на рабочем столе, файл справки в папке автокада:
...
THROUGHPROCESS - ругается что не удается открыть справку
Это логично, поскольку данная команда ищет справку в каталоге сборки (в коде прописано).

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Да это я тоже понимаю - это для тебя "развернутый" лог.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
AutoCAD 2009 SP3 x64 Enu
Windows 8.1 Ultimate x64 Rus
Visual Studio 2013 Premium Enu

Компилировал исходный код как для AnyCPU, так и для x64. Работаю с правами обычного юзера (не админский профиль Windows). Результат тот же самый, что был обозначен мною в первом сообщении темы.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Цитировать
AutoCAD 2009...
На уровне подозрения - попробуй проверить компиляции под разные .Net (2.0 и 3.5).

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
2009-й использует 3.0, поэтому 2.0 не пройдёт. Я всегда для него компилирую с использованием 3.5 (ибо LINQ). Проверил в 3.0 - результат тот же.
« Последнее редактирование: 25-06-2014, 23:13:43 от Андрей Бушман »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Предлагаю радикальное средство - отказаться от встроенных методов работы со справкой AutoCAD, т.е. сделать собственную реализацию. Если я правильно понял вариант кода, используемый  в ThroughProcess работает всегда. Остается только одна проблема - заставить по нажатию F1 запускаться этот код.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Предлагаю радикальное средство - отказаться от встроенных методов работы со справкой AutoCAD, т.е. сделать собственную реализацию.
а может всё же, для начала, попытаться побеспокоить adn по теме, дабы зря не изобретать велосипеды?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
а может всё же, для начала, попытаться побеспокоить adn по теме, дабы зря не изобретать велосипеды?
Нет. Про AutoCAD 2009 и 2010 я им рассказывать не буду, а в последних трёх версиях пока только у тебя возникла проблема. Так что займемся велосипедом.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Итак первый вариант. Прошу тестировать:
Код - C# [Выбрать]
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Autodesk.AutoCAD.EditorInput;
  9.  
  10. [assembly: CommandClass(typeof(HelpUtils.MyCommands))]
  11.  
  12. namespace HelpUtils
  13. {
  14.     public class Helper : IDisposable
  15.     {
  16.         static int ver = Application.Version.Major;
  17.  
  18.         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  19.         public delegate int WindowHookProc(ref System.Windows.Forms.Message msg);
  20.  
  21.         private WindowHookProc callBackFunc = null;
  22.         #region AutoCAD >= 2013 // Версии от 2013 и ...
  23.         // x64
  24.         [DllImport("accore.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  25.           EntryPoint = "?acedRegisterFilterWinMsg@@YAHQ6AHPEAUtagMSG@@@Z@Z")]
  26.         private static extern int acedRegisterFilterWinMsg_64_R19(WindowHookProc callBackFunc);
  27.         [DllImport("accore.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  28.           EntryPoint = "?acedRemoveFilterWinMsg@@YAHQ6AHPEAUtagMSG@@@Z@Z")]
  29.         private static extern int acedRemoveFilterWinMsg_64_R19(WindowHookProc callBackFunc);
  30.         // x86
  31.         [DllImport("accore.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  32.           EntryPoint = "?acedRegisterFilterWinMsg@@YAHQ6AHPAUtagMSG@@@Z@Z")]
  33.         private static extern int acedRegisterFilterWinMsg_32_R19(WindowHookProc callBackFunc);
  34.         [DllImport("accore.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  35.           EntryPoint = "?acedRemoveFilterWinMsg@@YAHQ6AHPAUtagMSG@@@Z@Z")]
  36.         private static extern int acedRemoveFilterWinMsg_32_R19(WindowHookProc callBackFunc);
  37.         #endregion
  38.         #region AutoCAD <= 2012 // Версии от 2007 до 2012
  39.         // x64
  40.         [DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  41.           EntryPoint = "?acedRegisterFilterWinMsg@@YAHQ6AHPEAUtagMSG@@@Z@Z")]
  42.         private static extern int acedRegisterFilterWinMsg_64_R18(WindowHookProc callBackFunc);
  43.         [DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  44.           EntryPoint = "?acedRemoveFilterWinMsg@@YAHQ6AHPEAUtagMSG@@@Z@Z")]
  45.         private static extern int acedRemoveFilterWinMsg_64_R18(WindowHookProc callBackFunc);
  46.         // x86
  47.         [DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  48.           EntryPoint = "?acedRegisterFilterWinMsg@@YAHQ6AHPAUtagMSG@@@Z@Z")]
  49.         private static extern int acedRegisterFilterWinMsg_32_R18(WindowHookProc callBackFunc);
  50.         [DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  51.           EntryPoint = "?acedRemoveFilterWinMsg@@YAHQ6AHPAUtagMSG@@@Z@Z")]
  52.         private static extern int acedRemoveFilterWinMsg_32_R18(WindowHookProc callBackFunc);
  53.         #endregion
  54.         private static int acedRegisterFilterWinMsg(WindowHookProc callBackFunc)
  55.         {
  56.             if (ver < 19)
  57.             {
  58.                 if (IntPtr.Size == 4)
  59.                     return acedRegisterFilterWinMsg_32_R18(callBackFunc);
  60.                 else
  61.                     return acedRegisterFilterWinMsg_64_R18(callBackFunc);
  62.             }
  63.             else
  64.             {
  65.                 if (IntPtr.Size == 4)
  66.                     return acedRegisterFilterWinMsg_32_R19(callBackFunc);
  67.                 else
  68.                     return acedRegisterFilterWinMsg_64_R19(callBackFunc);
  69.             }
  70.         }
  71.         private static int acedRemoveFilterWinMsg(WindowHookProc callBackFunc)
  72.         {
  73.             if (ver < 19)
  74.             {
  75.                 if (IntPtr.Size == 4)
  76.                     return acedRemoveFilterWinMsg_32_R18(callBackFunc);
  77.                 else
  78.                     return acedRemoveFilterWinMsg_64_R18(callBackFunc);
  79.             }
  80.             else
  81.             {
  82.                 if (IntPtr.Size == 4)
  83.                     return acedRemoveFilterWinMsg_32_R19(callBackFunc);
  84.                 else
  85.                     return acedRemoveFilterWinMsg_64_R19(callBackFunc);
  86.             }
  87.         }
  88.  
  89.         const int WM_KEYDOWN = 0x100;
  90.         const int WM_KEYUP   = 0x101;
  91.         const int F1 = 0x70;
  92.  
  93.         private int WindowsHook(ref System.Windows.Forms.Message msg)
  94.         {
  95.             if (msg.Msg == WM_KEYDOWN && (int)msg.WParam == F1)
  96.             {
  97.                 // Вместо запуска процесса используем стандартный класс Help
  98.                 System.Windows.Forms.Help.ShowHelp(null, helpPath, helpTopic);
  99.                 //        Process process = new Process();
  100.                 //        string parameter = string.Format("mk:@MSITStore:{0}::/{1}",
  101.                 //          helpPath.Replace(" ", "%20"), helpTopic);
  102.                 //        ProcessStartInfo info = new ProcessStartInfo("hh", parameter);
  103.                 //        process.StartInfo = info;
  104.                 //        process.Start();
  105.                 return 1;
  106.             }
  107.             // Блокируем запуск стандартной справки по отпусканию F1
  108.             if (msg.Msg == WM_KEYUP && (int)msg.WParam == F1)
  109.                 return 1;
  110.             return 0;
  111.         }
  112.  
  113.         public string helpPath = null;
  114.         // Если есть .htm на конце, то незабываем
  115.         public string helpTopic = null;
  116.  
  117.         public Helper(string path, string topic)
  118.         {
  119.             helpPath = path; helpTopic = topic;
  120.             callBackFunc = new WindowHookProc(this.WindowsHook);
  121.             acedRegisterFilterWinMsg(callBackFunc);
  122.         }
  123.  
  124.         public void Dispose()
  125.         {
  126.             acedRemoveFilterWinMsg(callBackFunc);
  127.         }
  128.     }
  129.  
  130.     public class MyCommands
  131.     {
  132.         [CommandMethod("HelpUtils", "TestF1", CommandFlags.Modal)]
  133.         public void testHelp()
  134.         {
  135.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  136.             using (Helper hlp = new Helper("C:\\MyHelp.chm", "ThroughAttribute.htm"))
  137.             {
  138.                 ed.GetPoint("\nНажмите F1 для ThroughAttribute: ");
  139.                 // Можем динамически менять разделы справки, да и путь к файлу справки
  140.                 hlp.helpTopic = "ThroughAcedSetFunHelp.htm";
  141.                 ed.GetDouble("\nНажмите F1 для ThroughAcedSetFunHelp: ");
  142.                 hlp.helpTopic = "ThroughProcess.htm";
  143.                 ed.GetString("\nНажмите F1 для ThroughProcess: ");
  144.             }
  145.         }
  146.     }
  147. }

Для тестирования нужно поместить твой MyHelp.chm в корень диска C: или подправить функцию testHelp
Замечания (умеренные :) ) приветствуются.
« Последнее редактирование: 26-06-2014, 02:24:38 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я подумал, что иногда велосипед лучше, что встроенный инструмент. Во всяком случае ты можешь его контролировать и понимать как оно работает. Ну и в данном случае полученный (даже сейчас в первом приближении) функционал явно превышает возможности встроенной справки по acedSetFunHelp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Я подумал, что иногда велосипед лучше, что встроенный инструмент. Во всяком случае ты можешь его контролировать и понимать как оно работает.
Не спорю, однако то, что вы боитесь "барина побеспокоить" способствует тому, что постепенно API скатывается в состояние "ничего не знаю, на моём компьютере работает", вынуждая сторонних программистов писать свои "велосипеды".  Польза такого API стремится к нулю, ибо надеяться на "авось и у пользователя заработает" - это хреновая надежда. Ну, не хотите "тревожить боярина по пустякам" - не тревожьте - дело ваше, хотя меня и раздражает подобное отношение, как вы понимаете... На мой взгляд, ADN должен знать об обозначенной проблеме, дабы потом не округляли глаза, мол "а нам никто и не сообщал".

Ваш код, конечно же гляну, спасибо за него. Очень не нравится обилие использования PInvoke, но на безрыбье, как говорится, и рак лебедь...


Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Для того чтобы обращаться к ADN DevHelp с сообщением о баге необходимо выполнение нескольких условий:
1. Версия AutoCAD должна быть одной из последних трёх, на которой этот баг воспроизводится.
2. Была бы возможность описать ситуацию, в которой этот баг однозначно воспроизводится.
Что мы имеем в данном случае? То что у тебя происходит удовлетворяет этим пунктам? А главное как это тебе поможет, если тебе приходится работать с AutoCAD 2009?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Очень не нравится обилие использования PInvoke, но на безрыбье, как говорится, и рак лебедь...
Их тут как раз не слишком много. Просто я решил не пользоваться препроцессором. Фактически вызываются две функции, но в зависимости от разрядности и версии AutoCAD каждая из них имеет по четыре сигнатуры. Итого имеем восемь описиний функций для P/Invoke
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Нет. Про AutoCAD 2009 и 2010 я им рассказывать не буду, а в последних трёх версиях пока только у тебя возникла проблема
Александр, это я ни в коей мере не Вам - мысли вслух. Я считаю что если производитель не поддерживает более свой продукт (я не имю в виду, что, например, он обязан выпускать заплатки под новые версии операционок, либо обновления других компонентов - тот функционал который декларировался на момент выпуска) - то данную версию продукта надо законодательно признавать бесплатной и свободной к распостранению.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
то данную версию продукта надо законодательно признавать бесплатной и свободной к распостранению.
Ну если кому-то из "власть предержащих" (страну не уточняем, так как мы ведем абстрактный диалог) придёт в голову выполнить твою рекомендацию, то:
1. государство будет признано мировым сообществом как поддерживающее пиратство на государственном уровне.
2. производитель прекратит продавать в эту страну свой программный продукт.

P.S.: Администрация позиционирует этот форум, как форум технической поддержки и помощи программистам. Давайте этой позиции и придерживаться.  Луше проверь как у тебя работает мой код. :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Администрация позиционирует этот форум, как форум технической поддержки и помощи программистам. Давайте этой позиции и придерживаться.  Луше проверь как у тебя работает мой код.
Хотелось сказать свои соображения, но правила есть правила. Ваш код проверил - работает(2010).
з.ы. ИХМО при таком количестве нативного кода никак не могу назвать данную конструкцию целесообразной - если только делать отдельную dll с соотвествующими классами.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
ИХМО при таком количестве нативного кода никак не могу назвать данную конструкцию целесообразной - если только делать отдельную dll с соотвествующими классами.
В действительности нативного кода там чуть-чуть, но по поводу отдельный сборки и/или отдельного пространства имён для класса Helper - я полностью согласен.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Предлагаю не отклоняться от основной темы.

Цитата: Александр Ривилис
1. Версия AutoCAD должна быть одной из последних трёх, на которой этот баг воспроизводится.

Тестирую модифицированный вариант кода: добавлена команда ThroughAcedHelp, класс объявлен как static.

Код - C# [Выбрать]
  1. /* Commands.cs
  2.  * © Andrey Bushman, 2014
  3.  * При необходимости закомментируйте или раскомментируйте обозначенные ниже
  4.  * символы компиляции соответственно Вашей версии AutoCAD.
  5.  * В коде определены следующие команды:
  6.  * -  ThroughAttribute
  7.  * -  ThroughAcedSetFunHelp
  8.  * -  ThroughProcess
  9.  * -  ThroughAcedHelp
  10.  */
  11.  
  12. #define AUTOCAD
  13. #define AUTOCAD_NEWER_THAN_2012
  14. #define AUTOCAD_NEWER_THAN_2014
  15.  
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Reflection;
  20. using System.Diagnostics;
  21. using System.IO;
  22. using System.Runtime.InteropServices;
  23.  
  24. #if AUTOCAD
  25. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  26. using Ap = Autodesk.AutoCAD.ApplicationServices;
  27. using Db = Autodesk.AutoCAD.DatabaseServices;
  28. using Ed = Autodesk.AutoCAD.EditorInput;
  29. using Rt = Autodesk.AutoCAD.Runtime;
  30. using Wn = Autodesk.AutoCAD.Windows;
  31. #endif
  32.  
  33. [assembly: Rt.ExtensionApplication(typeof(Bushman.CAD.Samples.Help
  34.   .ExtensionApplication))]
  35. [assembly: Rt.CommandClass(typeof(Bushman.CAD.Samples.Help.Commands))]
  36.  
  37. namespace Bushman.CAD.Samples.Help {
  38.   /// <summary>
  39.   /// Класс, в котором определён набор пользовательских команд AutoCAD
  40.   /// </summary>
  41.   public static class Commands {
  42.  
  43.     #region PInvoke
  44.  
  45. #if AUTOCAD_NEWER_THAN_2012
  46.     const String fnc_location = "accore.dll";
  47. #else
  48.     const String fnc_location = "acad.exe";
  49. #endif
  50.  
  51. #if AUTOCAD_NEWER_THAN_2014
  52.     const String x86_Prefix = "_";
  53. #else
  54.     const String x86_Prefix = "";
  55. #endif
  56.  
  57.     #region acedSetFunHelp
  58.     const String acedSetFunHelp_Name = "acedSetFunHelp";
  59.  
  60.     [DllImport(fnc_location, CharSet = CharSet.Unicode,
  61.       CallingConvention = CallingConvention.Cdecl,
  62.       EntryPoint = "acedSetFunHelp")]
  63.     private static extern Int32 acedSetFunHelp_x64(
  64.         String functionName,
  65.         String helpFile,
  66.         String helpTopic,
  67.         Int32 cmd);
  68.  
  69.     [DllImport(fnc_location, CharSet = CharSet.Unicode,
  70.       CallingConvention = CallingConvention.Cdecl,
  71.       EntryPoint = x86_Prefix + "acedSetFunHelp")]
  72.     private static extern Int32 acedSetFunHelp_x86(
  73.         String functionName,
  74.         String helpFile,
  75.         String helpTopic,
  76.         Int32 cmd);
  77.  
  78.  
  79.     internal static Int32 acedSetFunHelp(
  80.         String functionName,
  81.         String helpFile,
  82.         String helpTopic,
  83.         Int32 cmd) {
  84.       if(IntPtr.Size == 4)
  85.         return acedSetFunHelp_x86(functionName, helpFile, helpTopic, cmd);
  86.       else
  87.         return acedSetFunHelp_x64(functionName, helpFile, helpTopic, cmd);
  88.     }
  89.     #endregion // acedSetFunHelp
  90.  
  91.     #region acedHelp
  92.  
  93.     [DllImport(fnc_location, CharSet = CharSet.Unicode,
  94.   CallingConvention = CallingConvention.Cdecl,
  95.   EntryPoint = "acedHelp")]
  96.     private static extern Int32 acedHelp_x64(
  97.         String helpFile,
  98.         String helpTopic,
  99.         Int32 cmd);
  100.  
  101.     [DllImport(fnc_location, CharSet = CharSet.Unicode,
  102.   CallingConvention = CallingConvention.Cdecl,
  103.   EntryPoint = x86_Prefix + "acedHelp")]
  104.     private static extern Int32 acedHelp_x86(
  105.         String helpFile,
  106.         String helpTopic,
  107.         Int32 cmd);
  108.  
  109.     internal static Int32 acedHelp(
  110.         String helpFile,
  111.         String helpTopic,
  112.         Int32 cmd) {
  113.       if(IntPtr.Size == 4)
  114.         return acedHelp_x86(helpFile, helpTopic, cmd);
  115.       else
  116.         return acedHelp_x64(helpFile, helpTopic, cmd);
  117.     }
  118.  
  119.     #endregion // acedHelp
  120.  
  121.     #endregion // PInvoke
  122.  
  123.     const String commandGroup = "Bushman";
  124.     const String throughAttribute = "ThroughAttribute";
  125.     internal const String throughAcedSetFunHelp = "ThroughAcedSetFunHelp";
  126.     internal const String throughAcedHelp = "ThroughAcedHelp";
  127.     const String throughProcess = "ThroughProcess";
  128.     const String helpPageExtension = ".htm";
  129.     const String chmFileName = "MyHelp.chm";
  130.     internal static readonly String asm_location = Path.GetDirectoryName(
  131.       Assembly.GetExecutingAssembly().Location);
  132.     // Предположим, что файл справки хранится в том же каталоге, что и DLL.
  133.     internal static readonly String chmFileFullName = Path.Combine(
  134.       asm_location, chmFileName);
  135.  
  136.     const String f1_msg = "\nНажмите клавишу F1 для открытия нужного " +
  137.         "раздела справочной системы.\n";
  138.  
  139.     /// <summary>
  140.     /// Пример открытия нужного раздела справки при помощи нажатия клавиши
  141.     /// F1 в момент выполнения команды (регистрация через атрибуты метода).
  142.     /// </summary>
  143.     [Rt.CommandMethod(commandGroup, throughAttribute, null,
  144.       Rt.CommandFlags.Session, null, chmFileName, throughAttribute)]
  145.     public static void ThroughAttribute_Command() {
  146.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  147.       if(null == doc) {
  148.         return;
  149.       }
  150.       doc.Editor.GetPoint(f1_msg);
  151.     }
  152.  
  153.     /// <summary>
  154.     /// Пример открытия нужного раздела справки при помощи нажатия клавиши
  155.     /// F1 в момент выполнения команды (регистрация через функцию
  156.     /// acedSetFunHelp).
  157.     /// </summary>
  158.     [Rt.CommandMethod(commandGroup, throughAcedSetFunHelp,
  159.       Rt.CommandFlags.Session)]
  160.     public static void ThroughAcedSetFunHelp_Command() {
  161.  
  162.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  163.       if(null == doc) {
  164.         return;
  165.       }
  166.       doc.Editor.GetPoint(f1_msg);
  167.     }
  168.  
  169.     /// <summary>
  170.     /// Пример открытия нужного раздела справки при помощи запуска внешнего
  171.     /// процесса с передачей ему необходимого параметра
  172.     /// </summary>
  173.     [Rt.CommandMethod(commandGroup, throughProcess, Rt.CommandFlags.Session)]
  174.     public static void ThroughProcess_Command() {
  175.       Process process = new Process();
  176.  
  177.       String parameter = String.Format("mk:@MSITStore:{0}::/{1}{2}",
  178.         chmFileFullName.Replace(" ", "%20"), throughProcess, helpPageExtension);
  179.       ProcessStartInfo info = new ProcessStartInfo("hh", parameter);
  180.       process.StartInfo = info;
  181.       process.Start();
  182.     }
  183.  
  184.     /// <summary>
  185.     /// Пример открытия нужного раздела справки при помощи нажатия клавиши
  186.     /// F1 в момент выполнения команды (регистрация через функцию
  187.     /// acedHelp).
  188.     /// </summary>
  189.     [Rt.CommandMethod(commandGroup, throughAcedHelp, Rt.CommandFlags.Session)]
  190.     public static void ThroughAcedHelp_Command() {
  191.       // Открываю тот же раздел справки, что и в команде создания процесса
  192.       Int32 result2 = Commands.acedHelp(Commands.chmFileFullName,
  193.         Commands.throughProcess, 0); // 5100
  194.     }
  195.   }
  196.  
  197.   /// <summary>
  198.   /// Класс, реализующий интерфейс IExtensionApplication.
  199.   /// </summary>
  200.   public sealed class ExtensionApplication : Rt.IExtensionApplication {
  201.  
  202.     /// <summary>
  203.     /// Код этого метода будет выполнен сразу после загрузки данной сборки.
  204.     /// </summary>
  205.     public void Initialize() {
  206.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  207.       if(null == doc) {
  208.         cad.DocumentManager.DocumentActivated += DocumentActivated;
  209.         return;
  210.       }
  211.       WriteLoadingReport(doc);
  212.  
  213.     }
  214.  
  215.     void DocumentActivated(object sender, Ap.DocumentCollectionEventArgs e) {
  216.       cad.DocumentManager.DocumentActivated -= DocumentActivated;
  217.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  218.       WriteLoadingReport(doc);
  219.     }
  220.  
  221.     private static void WriteLoadingReport(Ap.Document doc) {
  222.  
  223.       if(null == doc)
  224.         throw new ArgumentNullException("doc");
  225.       if(doc.IsDisposed)
  226.         throw new ArgumentException("doc.IsDisposed == true");
  227.  
  228.       using(doc.LockDocument()) {
  229.         String format = String.Empty;
  230.  
  231.         doc.Editor.WriteMessage("\nСборка \"{0}\" успешно загружена.\n",
  232.           Assembly.GetExecutingAssembly().Location);
  233.  
  234.         if(File.Exists(Commands.chmFileFullName)) {
  235.           Int32 result = Commands.acedSetFunHelp(Commands.throughAcedSetFunHelp,
  236.             Commands.chmFileFullName, Commands.throughAcedSetFunHelp, 0); // 5100
  237.  
  238.           format = "\nФайл \"{0}\" найден. Регистрация раздела справки " +
  239.             "выполнена.\n";
  240.         }
  241.         else
  242.           format = "\nФайл \"{0}\" не найден.\n";
  243.  
  244.         doc.Editor.WriteMessage(format, Commands.chmFileFullName);
  245.       }
  246.     }
  247.  
  248.     public void Terminate() { }
  249.   }
  250. }

Все перечисленные ниже версии AutoCAD установлены на одном компьютере, работающем под управлением Windows 7 x86 Ultimate Rus (виртуальная машинка VirtualBox). На компьютере установлены только AutoCAD 2009-2015, Notepad++, 7Zip, Gallio и Remote debugger для MS Visual Studio 2013.

IDE 2005-2013 установлены на др. виртуальной машинке VirtualBox, работающей под управлением Windows 7 x86 Ultimate. Выполняю удалённую отладку в режиме DEBUG, AnyCPU. В данном случае использую MS Visual Studio 2013 Premium Enu.

Поскольку вас интересует только последние три версии AutoCAD, то показываю результат лишь для них.

AutoCAD 2015 x86 Enu, .NET 4.5:

  ThroughAttribute - пытается открыть справку AutoCAD из Интернет.
  ThroughAcedSetFunHelp - пытается открыть справку AutoCAD из Интернет.
  ThroughProcess - открывает нужный раздел справки в нужном пользовательском CHM файле.
  ThroughAcedHelp - пытается открыть справку AutoCAD из Интернет.

Функции acedSetFunHelp и acedHelp в качестве результата возвращают значение 5100.

========================================

AutoCAD 2014 x86 Enu, .NET 4.0:

  ThroughAttribute - пытается открыть справку AutoCAD из Интернет.
  ThroughAcedSetFunHelp - пытается открыть справку AutoCAD из Интернет.
  ThroughProcess - открывает нужный раздел справки в нужном пользовательском CHM файле.
  ThroughAcedHelp - пытается открыть справку AutoCAD из Интернет.

Функции acedSetFunHelp и acedHelp в качестве результата возвращают значение 5100.

========================================

AutoCAD 2013 x86 Enu, .NET 4.0:

  ThroughAttribute - пытается открыть справку AutoCAD из Интернет.
  ThroughAcedSetFunHelp - пытается открыть справку AutoCAD из Интернет.
  ThroughProcess - открывает нужный раздел справки в нужном пользовательском CHM файле.
  ThroughAcedHelp - пытается открыть справку AutoCAD из Интернет.

Функции acedSetFunHelp и acedHelp в качестве результата возвращают значение 5100.

========================================

Как видим, во всех трёх случаях результат один и тот же.

Цитата: Александр Ривилис
2. Была бы возможность описать ситуацию, в которой этот баг однозначно воспроизводится.
Существует такая компания: Wintellect. Джон Роббинс, один из учредителей этой компании, в своей книге "Отладка приложений для Microsoft .NET" пишет (стр. 46-47):
Цитата: Джон Роббинс, стр. 46-47
Самый важный шаг процесса отладки - первый: воспроизведение ошибки. Иногда это трудно, иногда даже невозможно, но если вы не можете воспроизвести ошибку, то, вероятно, не сможете устранить её. Пытаясь повторить ошибку, иногда приходится прибегать к крайним мерам. Однажды в моём коде встретилась ошибка, которую я не мог воспроизвести, просто запустив программу. Однако мне в голову пришла мысль об определённых состояниях данных, которые могли  вызывать ошибку, поэтому я запустил программу в отладчике и ввёл данные, необходимые для воспроизведения ошибки, прямо в память. Это сработало.
...
Моё определение заключается в повторении ошибки на отдельно взятой машине один раз в течение 24-часового периода. Этого для моей компании достаточно, чтобы приняться за работу над ошибкой. Почему? Всё просто. Если вы сможете получить её на одной машине, то сможете добавить 30 машин и повторить ошибку 30 раз.  При воспроизведении ошибки многие люди делают ещё одну: они не используют в процессе отладки максимально возможное количество машин.
...
Даже если вы не можете воспроизвести ошибку, её всё равно необходимо занести в систему отслеживания ошибок. Если я встречаю ошибку, которую не могу повторить, я обязательно регистрирую её в системе, но оставляю примечание, говорящее, что воспроизвести её не удалось. Таким образом, если за эту часть кода несёт ответственность другой инженер, то он, по крайней мере, будет знать, что что-то не так. Регистрируя ошибку, которую не удалось воспроизвести, нужно как можно лучше описывать её. Если вы дадите достаточно хорошее описание, то это поможет вам или другому инженеру в итоге устранить проблему. Чрезвычайно важно дать всестороннее описание ошибки, так как это позволит заметить взаимосвязи между различными отчётами о неповторяемых ошибках и обнаружить определённые шаблоны в поведении ошибок.

Последнее, о чём я хочу сказать, рассуждая о воспроизведении ошибок - очень редко ошибки удаётся воспроизвести на машине, где вы осуществляете разработку. Причина заключается в том, что на машине для разработки у вас есть различные инструменты и процессы, которых нет на машине для обычного выполнения, или, что ещё хуже, вы можете работать в системе под учётной записью с правами администратора.  Учитывая, что и Microsoft и VMWare предоставляют свои виртуальные среды, нет никаких оправданий отсутствию на вашей машине виртуальной версии среды выполнения с возможностью удалённой отладки. Необходимо воспроизводить ошибки на виртуальной машине, поскольку это даёт лучшие шансы на обнаружение точных шаблонов.
Откровенно говоря, меня неприятно удивляет тот факт, что вас приходится уговаривать о том, чтобы принять меры к устранению обозначенного бага. Такое ощущение, что ваша задача - препятствовать регистрации того, что не удаётся воспроизвести сходу, мол "не вижу ошибку на своём компе, значит её не существует, а пользователь - да и хрен на него, это у него что-то не так с компьютером". В обозначенной мною выше книге написано, что сотрудников, подобным образом относящихся к работе они увольняют, поскольку компания заинтересована в качестве результатов своей работы. Судя по тому, как вы упираетесь - у автодеска иные приоритеты.
« Последнее редактирование: 27-06-2014, 17:48:51 от Андрей Бушман »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Как видим, во всех трёх случаях результат один и тот же.
Вот с этого нужно было и начинать. Пока я прихожу к выводу, что это глюк в AutoCAD x86 в Windows 7 x86. В таком виде уже можно и отправить в ADN DevHelp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
В таком виде уже можно и отправить в ADN DevHelp.
ИХМО, в таком не надо, формально баг .NetApi есть только в виде не работающей перегрузке аттрибута CommandMethod, что не работает вызов нативный acedSetFunHelp - это к .NetApi никак не относится (хоть и понятно, что, скорее всего, дело именно в нативной части). Если каким-то чудесным образом окажется, что из-под ARX acedSetFunHelp в указанных версиях будет работать, то по чему не работает "внешний" вызов - это реально не их забота (это не штатный вызов функции - с таким-же успехом можно спросить почему я на дельфи не могу arx писать - не предназначен). Если и из-под ARX сей метод не заработает(что скорее всего) - то это уже и оформлять как баг - и отправлять - там думаю и аттрибут заработает.
з.ы. по части .NetApi - если только писать helloword c соответствующими аттрибутами в CommandMethod...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Если и из-под ARX сей метод не заработает(что скорее всего) - то это уже и оформлять как баг - и отправлять - там думаю и аттрибут заработает.
Собственно именно это я и собирался сделать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
з.ы. по части .NetApi - если только писать helloword c соответствующими аттрибутами в CommandMethod...
чем выше обозначенные варианты не "helloword"?

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Я - если смотрю на кокай-то косяк в первую очередь обрезаю все лишнее - оставляяя только его суть - конечно с этим должны справится и автодесковцы, по в моем понимании это просто не очень культурно (да и заодно лишний раз самому убедится, что вот "голый" вызов апи и именно он не работает).

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
по в моем понимании это просто не очень культурно
У меня понимание иное. В коде показано, что в поисках источника проблемы были испробованы разные варианты решений. Это экономит время на разбирательство.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Сделал тестовый пример на ObjectARX для AutoCAD 2013 и 2014 x86
Загружать при помощи _APPLOAD.
Команды для проверки:
ThroughAcedSetFunHelp - должна по нажатию F1 появится справка  с пунктом ThroughAcedSetFunHelp
ThroughAcedHelp - должна появится сразу справка с пунктом ThroughAcedSetFunHelp
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Итак первый вариант. Прошу тестировать:
Этот .NET код работает (проверял в AutoCAD 2013 x86 Enu). Но! тот, который "Нажмите F1 для ThroughProcess:" открывает как то, что нужно (пользовательский раздел пользовательской справки), так и окно попытки лезть за справкой в инет (при первом вызове TestF1). При последующих вызовах TestF1 всё работает как надо.

P.S. Сейчас гляну вашу версию ARX...

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
мля...

перезапустил акад.
загрузил управляемую сборку (по прежнему смотрю ваш .net код).
запустил Testf1.
нажал и отпустил F1 - для "Нажмите F1 для ThroughAttribute:" запустились оба окна, как в прошлый раз с версией от "Нажмите F1 для ThroughProcess:".

последующие несколько вызовов команды TestF1 работали нормально. Затем та же фигня, но уже для "Нажмите F1 для ThroughAcedSetFunHelp:".

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
я вот думаю... помните ранее обозначенную здесь проблему? Может это как-то связано... Т.е. некоторая накладка при комбинации: Слабый хостовый комп + VirtualBox + скорость обработки нажатий клавиатуры.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
вот только когда я тестировал код, обозначенный в первом сообщении темы на домашнем нотике, там не было никаких виртуальных машин - всё установлено непосредственно на физ. машинке (хоть и дохлой до ужаса). Да и у юзеров когда тестировал - у них тоже физ. машины.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вот теперь и этот код проверь на домашней машине и у юзеров. Тут если появится и справка AutoCAD, то её появление скорее всего имеет другую природу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Сделал тестовый пример на ObjectARX для AutoCAD 2013 и 2014 x86
Загружать при помощи _APPLOAD.
Команды для проверки:
ThroughAcedSetFunHelp - должна по нажатию F1 появится справка  с пунктом ThroughAcedSetFunHelp
ThroughAcedHelp - должна появится сразу справка с пунктом ThroughAcedSetFunHelp
У меня оба обозначенных варианта щимятся за справкой в Интернет. Запускал в AutoCAD 2013 x86. В обоих случаях в консоль AutoCAD выводится правильное полное имя CHM файла справки.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Отлично. Теперь есть что отсылать в ADN DevHelp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Для тестирования под AutoCAD 2010 x86
Команды ThroughAcedSetFunHelp и ThroughAcedHelp
Интересует откроется ли справка и если да, то какая.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Работают однако оба варианта (в смыле и та, и та команда). Надо писать helloword на аттрибут ComandMethod (мне сейчас не до того). Видимо косяк похитрее.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
ACAD 2010 Win7*32 - как и у автора - ThroughProcess - вызывает нужную справку, в остальных случаях по F1 - выскакивает автокадная.
Работают однако оба варианта. Надо писать helloword на аттрибут ComandMethod (мне сейчас не до того). Видимо косяк похитрее.
Нет. Тут уже дело и не в атрибуте, т.к.  P/Invoke для acedHelp у тебя не сработало, а acedHelp из ObjectARX сработало. Нужно передохнуть и подумать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
p/invoke относится к .Net api как я к техаским рейжирам (то есть никак), да может быть при какой-либо хитром условии компиляции и еще черт знает чем он срабатывает - но это поле для творчества "любителей", а никак не поддержки Api (хотя по возрасту версии им уже все равно). Аттрибут документирован - и пусть покажут как его заставить работать.
Я уж и не вспомню - но у меня не все работало через, например дин. вызов (InvokeMember), но это к багам я отнести никак не могу.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
И чтоб окончательно все запутать, я таки написал helloword в виде лисп функции (ихмо так проверять гораздо удобней):
Код - C# [Выбрать]
  1. open Autodesk.AutoCAD.ApplicationServices
  2. open Autodesk.AutoCAD.Runtime
  3. open Autodesk.AutoCAD.DatabaseServices
  4. open Autodesk.AutoCAD.EditorInput
  5. open System.Runtime.InteropServices
  6. [<DllImport("acad.exe",CallingConvention=CallingConvention.Cdecl,
  7.             CharSet=CharSet.Auto)>] extern int acedSetFunHelp(string,string,string)
  8. let Rb=function
  9.   |null->[]
  10.   |(rb:ResultBuffer)->rb.AsArray()|>Array.toList
  11. let (|AcStr|_|) (x:TypedValue)=
  12.   match enum<LispDataType>(x.TypeCode|>int) with
  13.     |LispDataType.Text->x.Value:?>string|>Some
  14.     |_->None
  15. [<LispFunction "TestHelp">]
  16. let TestHelp arg=arg|>Rb|>function
  17.   |[AcStr fname;AcStr path;AcStr topic]->acedSetFunHelp(fname,path,topic)|>ignore
  18.   |_->"Ошибка аргумента - (testhelp имя_функции путь глава)"
  19.          |>Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage
Код - Auto/Visual Lisp [Выбрать]
  1. Команда: netload
  2. Команда: (testhelp "example" "d:/lib/myhelp.chm" "About")
  3. Команда: (defun c:example()(getpoint "Есть время на F1"))
  4. C:EXAMPLE
  5. Команда: example
  6. Есть время на F1 (1540.12 1359.01 0.0)
и здесь появляется нужная справка - то есть вызов работает
з.ы. Андрей - убери все лишнее.
з.з.ы да если выбрать другой топик - тоже работает корректно.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
з.ы. Андрей - убери все лишнее.
Во первых: я не знаю F# и ты об этом в курсе, так что подправить твой код я не смогу. Полагаю, что смогу вставить твой текущий код в новый проект и собрать его лишь под AutoCAD 2009-2012.

Во вторых: твой код не будет работать в AutoCAD версий более новых, чем 2012, поскольку начиная с 2013-й функция acedSetFunHelp определена не в "acad.exe", но в "accore.dll". Кроме того, начиная с 2015-го версия x86 этой функции будет иметь имя "_acedSetFunHelp".

В третьих: А.Н. Ривилис обозначил границу песочницы, в рамках которой он "играется": AutoCAD версий 2013-2015. В противном случае вопросы группой ADN будут не глядя пересылаться в "лигу защиты сексуальных меньшинств" (т.е. в американский госдеп.).

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
так что подправить твой код я не смогу...
твой код не будет работать в AutoCAD версий более новых
Я как-бы намекал, что вызов работает, "подреж" свой код как раз таки на "новые версии" и пр. - может ошибка там.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Отлично. Теперь есть что отсылать в ADN DevHelp.
Запускал ваш ARX в AutoCAD 2013-м x86 с правами администратора - результат аналогичен описанному мною для запуска из под обычного юзера.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
И чтоб окончательно все запутать, я таки написал helloword в виде лисп функции (ихмо так проверять гораздо удобней):
На вкус и цвет все фломастеры разные - мне так не удобней.
и здесь появляется нужная справка - то есть вызов работает
з.ы. Андрей - убери все лишнее.
з.з.ы да если выбрать другой топик - тоже работает корректно.
Подправил твой код так, чтобы он заработал под AutoCAD 2015 x86 (заменил acad.exe на accore.dll и переименовал acedSetFunHelp на _acedSetFunHelp):
module dimas_help_sample

open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.Runtime
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open System.Runtime.InteropServices
[<DllImport("accore.dll",CallingConvention=CallingConvention.Cdecl,
            CharSet=CharSet.Auto)>] extern int _acedSetFunHelp(string,string,string)
let Rb=function
  |null->[]
  |(rb:ResultBuffer)->rb.AsArray()|>Array.toList
let (|AcStr|_|) (x:TypedValue)=
  match enum<LispDataType>(x.TypeCode|>int) with
    |LispDataType.Text->x.Value:?>string|>Some
    |_->None
[<LispFunction "TestHelp">]
let TestHelp arg=arg|>Rb|>function
  |[AcStr fname;AcStr path;AcStr topic]->_acedSetFunHelp(fname,path,topic)|>ignore
  |_->"Ошибка аргумента - (testhelp имя_функции путь глава)"
         |>Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage
Результат показан во вложенном файле, как видишь - у меня твой вариант пытается открыть родную справку автокада из инета.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Хм. А в 2009-ом работает?
з.ы. Я не уверен, да и 2015 у меня нет, а точно acedSetFunHelp не скомпилирует (нужен именно _acedSetFunHelp) ? Проверь - если не сложно.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
На вкус и цвет все фломастеры разные - мне так не удобней.
Тоже правда, я из соображений что отладка так точно быстрей (поменять аргументы не требует перезагрузки), но пожалуйста могу и командой (в 2010x86 работает - проверял):
Код - C# [Выбрать]
  1. open Autodesk.AutoCAD.ApplicationServices
  2. open Autodesk.AutoCAD.Runtime
  3. open Autodesk.AutoCAD.DatabaseServices
  4. open Autodesk.AutoCAD.EditorInput
  5. open System.Runtime.InteropServices
  6. [<DllImport("acad.exe",CallingConvention=CallingConvention.Cdecl,
  7.             CharSet=CharSet.Auto)>] extern int acedSetFunHelp(string,string,string)
  8.  
  9. [<CommandMethod "example">]
  10. let Example()=
  11.   Application.DocumentManager.MdiActiveDocument.Editor.GetPoint("Press F1 th help...")|>ignore
  12.  
  13. type Init()=
  14.   interface IExtensionApplication with
  15.     member obj.Initialize()=
  16.       acedSetFunHelp("example","d:/lib/myhelp.chm","About")|>ignore
  17.     member obj.Terminate()=()

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Хм. А в 2009-ом работает?
Не до конца...

AutoCAD 2009 SP3 x86 Enu. Пробовал два варианта.
Первый:
Цитировать
(testhelp "example" "C:/public/ACAD/Debug/dimas_help_sample/myhelp.chm" "About")
(defun c:example()(getpoint "Есть время на F1"))
EXAMPLE
Второй:
Цитировать
(testhelp "example" "C:/public/ACAD/Debug/dimas_help_sample/myhelp.chm" "ThroughAttribute")
(defun c:example()(getpoint "Есть время на F1"))
EXAMPLE
Пользовательская справка открывается, но в обоих случаях текущим является первый раздел About (см. вложение).

Я не уверен, да и 2015 у меня нет, а точно acedSetFunHelp не скомпилирует (нужен именно _acedSetFunHelp) ? Проверь - если не сложно.
C++ компилятор от Microsoft для функций x86 теперь автоматом добавляет префикс в виде подчёркивания. Такой вот "подарочек" программистам... Поскольку я использую x86, то наличие обозначенного префикса (начиная с версии AutoCAD 2015) является необходимым.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
По поводу префикса для x86:
Цитировать
__stdcall
Соглашение об оформлении имен
К имени добавляется префикс в виде символа подчеркивания (_). После имени добавляется знак @, за которым следует количество байтов (в десятичном представлении) в списке аргументов. Поэтому функция, объявленная как int func( int a, double b ) декорируется следующим образом: _func@12
...
На процессорах ARM и 64-разрядных процессорах соглашение __stdcall принимается и игнорируется компилятором;
источник здесь.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
C++ компилятор от Microsoft для функций x86 теперь автоматом добавляет префикс в виде подчёркивания.
Извини за назойливость - точно не скомпилирует?

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
точно не скомпилирует?
скомпилировать-то он скомпилирует, но во время выполнения обязательно возникнет ошибка:
Цитировать
Исключение типа "System.EntryPointNotFoundException" возникло в dimas_help_sample.dll, но не было обработано в коде пользователя

Additional information: Unable to find an entry point named 'acedSetFunHelp' in DLL 'accore.dll'.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Не понятно, почему тогда работает F1 для родных команд AutoCAD... Похоже, что в этом случае используется какая-то другая функция, отличная от той, что применяется в случае пользовательских команд. Это, мягко говоря, было бы очень странно...

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Похоже, что в этом случае используется какая-то другая функция, отличная от той, что применяется в случае пользовательских команд.
Я тоже об этом думал...
Цитировать
Пользовательская справка открывается, но в обоих случаях текущим является первый раздел About
Там у тебя два сомнительных момента - во первых топик по другому называется (пробела нет), во вторых в одной сессии не факт что на одну команду можно переназначать, НО это все лирика - по ходу мой косяк - я копипастил название из твого chm (для вставки в команду) и видимо просто не закрыл его - то есть он "повторно" открылся на старом месте - сейчас проверил - да всегда About - в общем надо "порыть" еще.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
во первых топик по другому называется (пробела нет)
Ну так я как раз и не использую пробел, как и нужно.
во вторых в одной сессии не факт что на одну команду можно переназначать,
Когда я тестировал твой код, то для каждого из обозначенных мною вариантов перезапускал AutoCAD (для чистоты эксперимента).
Кроме того, в прошлом, используя acedSetFunHelp, я выполнял перерегистрацию справки под нужную локализацию без перезагрузки AutoCAD - все изменения применялись сразу же (здесь показывал).

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
и видимо просто не закрыл его - то есть он "повторно" открылся на старом месте
этой части фразы я не понял (очередные "точки\запятые" видимо).

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Открылась справка на About, я зашел в топик "Through Process", скопипастил его название и не закрыв ввел в функцию автокада на команду example2, при вызове команды т.к. chm уже открыт винда просто активировала окно (естественно на той-же вкладке где и была) - и я ошибочно решил - что все в  порядке.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Не понятно, почему тогда работает F1 для родных команд AutoCAD... Похоже, что в этом случае используется какая-то другая функция, отличная от той, что применяется в случае пользовательских команд. Это, мягко говоря, было бы очень странно...
Ну почему же другая функция? Скорее всего таже самая. Но только для стандартных команд AutoCAD в его справке есть соответствующие разделы для команд.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Но только для стандартных команд AutoCAD в его справке есть соответствующие разделы для команд.
В качестве значений параметров важны имя CHM файла и идентификатор (в виде строки) нужного раздела. Оба указаны в моём коде. А вы что подразумеваете под "разделами", если не это?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
В качестве значений параметров важны имя CHM файла и идентификатор (в виде строки) нужного раздела. Оба указаны в моём коде. А вы что подразумеваете под "разделами", если не это?
Вот такое впечатление, что у тебя AutoCAD игнорирует имя файла при вызове справке.

Ну и на всякий случай исходник (cpp-файл) для arx-файла, который я просил тестировать:
Код - C++ [Выбрать]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.cpp
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #include "resource.h"
  6.  
  7. //-----------------------------------------------------------------------------
  8. #define szRDS _RXST("")
  9. const TCHAR ThroughAcedSetFunHelp[] = _T("ThroughAcedSetFunHelp");
  10. CString helpPath;
  11. CString helpTopic;
  12.  
  13. //-----------------------------------------------------------------------------
  14. //----- ObjectARX EntryPoint
  15. class CMyHelpApp : public AcRxArxApp {
  16.  
  17. public:
  18.   CMyHelpApp () : AcRxArxApp () {}
  19.  
  20.   void GetHelpPath()
  21.   {
  22.     TCHAR buffer[_MAX_PATH] = _T("");
  23.     GetModuleFileName(_hdllInstance,buffer,sizeof(buffer));
  24.     TCHAR path_buffer[_MAX_PATH];
  25.     TCHAR drive[_MAX_DRIVE];
  26.     TCHAR dir[_MAX_DIR];
  27.     TCHAR fname[_MAX_FNAME];
  28.     TCHAR ext[_MAX_EXT];
  29.     _tsplitpath( buffer, drive, dir, fname, ext );
  30.     _tmakepath(path_buffer,drive,dir,fname,_T(".chm"));
  31.     helpPath = path_buffer;
  32.   }
  33.  
  34.   virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
  35.     // TODO: Load dependencies here
  36.  
  37.     // You *must* call On_kInitAppMsg here
  38.     AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
  39.  
  40.     // TODO: Add your initialization code here
  41.     GetHelpPath();
  42.  
  43.     return (retCode) ;
  44.   }
  45.  
  46.   virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
  47.     // TODO: Add your code here
  48.  
  49.     // You *must* call On_kUnloadAppMsg here
  50.     AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
  51.  
  52.     // TODO: Unload dependencies here
  53.  
  54.     return (retCode) ;
  55.   }
  56.  
  57.   virtual void RegisterServerComponents () {
  58.   }
  59.   // Команда AcedSetFunHelp
  60.   static void MyGroupThroughAcedSetFunHelp () {
  61.     acedSetFunHelp(ThroughAcedSetFunHelp,LPCTSTR(helpPath),ThroughAcedSetFunHelp,0);
  62.     ads_point p;
  63.     acutPrintf(_T("\nPath=%s"),LPCTSTR(helpPath));
  64.     acedGetPoint(NULL,_T("\nНажмите F1 для справки: "), p);
  65.   }
  66.   // Команда ThroughAcedHelp
  67.   static void MyGroupThroughAcedHelp () {
  68.     acedHelp(LPCTSTR(helpPath),ThroughAcedSetFunHelp,0);
  69.   }
  70.  
  71. } ;
  72.  
  73. //-----------------------------------------------------------------------------
  74. IMPLEMENT_ARX_ENTRYPOINT(CMyHelpApp)
  75.  
  76. ACED_ARXCOMMAND_ENTRY_AUTO(CMyHelpApp, MyGroup, ThroughAcedSetFunHelp, ThroughAcedSetFunHelp, ACRX_CMD_MODAL, NULL)
  77. ACED_ARXCOMMAND_ENTRY_AUTO(CMyHelpApp, MyGroup, ThroughAcedHelp, ThroughAcedHelp, ACRX_CMD_MODAL, NULL)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Вот такое впечатление, что у тебя AutoCAD игнорирует имя файла при вызове справке
но ведь функции возвращали 5100, сообщая тем самым, что "всё пучком"... Вы уже отправили вопрос в ADN?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
но ведь функции возвращали 5100, сообщая тем самым, что "всё пучком"...
Читаем документацию по функции acedSetFunHelp:
Цитировать
acedSetFunHelp() returns RTNORM if it is successful. If pszFunctionName does not start with C:, it returns RTERROR. No checking of the acedHelp() parameters (pszHelpfile, pszTopic, and iCmd) is done until the Help call is actually made.
Т.е. наличие файла и раздела для справки эта функция не проверяет. С другой стороны явный баг в документации по поводу требования C: Это требование действительно есть, но в lisp-функции (SetFunHelp ...), но не в функции acedSetFunHelp
Документация по функции acedHelp говорит:
Цитировать
The acedHelp() function returns RTNORM if it is successful. It returns RTERROR if the Help file is not found. Your application does not have to generate error messages because HTML Help reports errors directly to the user.
Значит help-файл находится. Другой вопрос какой именно...

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Другой вопрос какой именно...
а какие тут могут быть варианты? Конкретный CHM файл ведь чётко прописан (абсолютный путь).

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Если бы у меня был ответ на этот вопрос, я бы уже ответил... ;)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Да уж - Александр сам того не зная подсказал - я из-за сработавшей памяти на лисп функцию - пропустил параметр (int cmd) - а из-за типа вызова функция таки работала, но с ошибкой, исправил:
Код - C# [Выбрать]
  1. open Autodesk.AutoCAD.ApplicationServices
  2. open Autodesk.AutoCAD.Runtime
  3. open Autodesk.AutoCAD.DatabaseServices
  4. open Autodesk.AutoCAD.EditorInput
  5. open System.Runtime.InteropServices
  6. [<DllImport("acad.exe",CallingConvention=CallingConvention.Cdecl,
  7.             CharSet=CharSet.Auto)>] extern int acedSetFunHelp(string,string,string,int)
  8.  
  9. [<CommandMethod "example">]
  10. let Example()=
  11.   Application.DocumentManager.MdiActiveDocument.Editor.GetPoint("Press F1 th help...")|>ignore
  12.  
  13. type Init()=
  14.   interface IExtensionApplication with
  15.     member obj.Initialize()=
  16.       acedSetFunHelp("example","d:/lib/myhelp.chm","ThroughAttribute",0)|>ignore
  17.     member obj.Terminate()=()

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Сейчас скорее всего (при изменении соотв. имен) заработает и 2015 версия - я думаю ломилась в интернет просто за разделом которого нет (другая внутренния обработка Api).

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
В 2009 x86 работает. В 2015 x86 лезет в интернет.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
В 2009 x86 работает.
Интересно.
В 2015 x86 лезет в интернет.
Подчеркивание перед именем функции ставил? Кстати разница между твоей командой и командой Димы:
1) Нет группы
2) Команда в контексте документа.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Подчеркивание перед именем функции ставил?
Ну конечно же ставил. Если бы не ставил, то получил бы исключение в процессе выполнения кода.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Если бы не ставил, то получил бы исключение в процессе выполнения кода.
Не обязательно. Я обратил внимание, на то, что ряд функций имеет дублированное имя (и с подчеркиванием и без).
И еще для меня пока непонятная ситуация. В ObjectARX 2013 (как и в ObjectARX 2015) в accore.lib x86 функция _acedSetFunHelp (т.е. с подчеркиванием), а в получаемом MyHelp.arx она без подчеркивания, как и в accore.dll в AutoCAD 2013
accore.dll от AutoCAD 2015 x86 у меня нет. Так что проверить не могу.

P.S.: Нашел таки дистрибутив AutoCAD 2015 x86 и вытащил из него accore.dll
И вот что вижу:
Код - INI [Выбрать]
  1. ?acedHelp@@YAHPB_W0H@Z
  2. acedHelp
  3. _acedHelp
Код - INI [Выбрать]
  1. ?acedSetFunHelp@@YAHPB_W00H@Z
  2. _acedSetFunHelp
Т.е. acedHelp можно звать и с подчеркиванием и без, хотя я не уверен что действия эквиваленты. А acedSetFunHelp только с подчеркиванием.
« Последнее редактирование: 27-06-2014, 17:16:09 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Давай пробывать бредятину замени "ThroughAttribute" на "ThroughAttribute.htm"

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Давай пробывать бредятину
Не надо. Я обратил внимание на то, что твой код работает в 2009-м, хотя почти ничем не отличается от моего, за исключением флага: Modal вместо Session. Я  в ходе экспериментов менял флаг, однако делал это то ли в 2013-м, то ли в 2015-м.

Итак, вот, что пробовал сейчас:

Код - C# [Выбрать]
  1. /* Commands.cs
  2.  * © Andrey Bushman, 2014
  3.  * При необходимости закомментируйте или раскомментируйте обозначенные ниже
  4.  * символы компиляции соответственно Вашей версии AutoCAD.
  5.  * В коде определены следующие команды:
  6.  * -  Cmd1
  7.  * -  Cmd2
  8.  */
  9.  
  10. #define AUTOCAD
  11. // #define AUTOCAD_NEWER_THAN_2012
  12. // #define AUTOCAD_NEWER_THAN_2014
  13.  
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Reflection;
  18. using System.Diagnostics;
  19. using System.IO;
  20. using System.Runtime.InteropServices;
  21.  
  22. #if AUTOCAD
  23. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  24. using Ap = Autodesk.AutoCAD.ApplicationServices;
  25. using Db = Autodesk.AutoCAD.DatabaseServices;
  26. using Ed = Autodesk.AutoCAD.EditorInput;
  27. using Rt = Autodesk.AutoCAD.Runtime;
  28. using Wn = Autodesk.AutoCAD.Windows;
  29. #endif
  30.  
  31. namespace Bushman.CAD.Samples.Help {
  32.   public class Commands : Rt.IExtensionApplication {
  33.  
  34.     #region PInvoke
  35.  
  36. #if AUTOCAD_NEWER_THAN_2012
  37.     const String fnc_location = "accore.dll";
  38. #else
  39.     const String fnc_location = "acad.exe";
  40. #endif
  41.  
  42. #if AUTOCAD_NEWER_THAN_2014
  43.     const String x86_Prefix = "_";
  44. #else
  45.     const String x86_Prefix = "";
  46. #endif
  47.  
  48.     #region acedSetFunHelp
  49.     const String acedSetFunHelp_Name = "acedSetFunHelp";
  50.  
  51.     [DllImport(fnc_location, CharSet = CharSet.Unicode,
  52.       CallingConvention = CallingConvention.Cdecl,
  53.       EntryPoint = "acedSetFunHelp")]
  54.     private static extern Int32 acedSetFunHelp_x64(
  55.         String functionName,
  56.         String helpFile,
  57.         String helpTopic,
  58.         Int32 cmd);
  59.  
  60.     [DllImport(fnc_location, CharSet = CharSet.Unicode,
  61.       CallingConvention = CallingConvention.Cdecl,
  62.       EntryPoint = x86_Prefix + "acedSetFunHelp")]
  63.     private static extern Int32 acedSetFunHelp_x86(
  64.         String functionName,
  65.         String helpFile,
  66.         String helpTopic,
  67.         Int32 cmd);
  68.  
  69.  
  70.     internal static Int32 acedSetFunHelp(
  71.         String functionName,
  72.         String helpFile,
  73.         String helpTopic,
  74.         Int32 cmd) {
  75.       if(IntPtr.Size == 4)
  76.         return acedSetFunHelp_x86(functionName, helpFile, helpTopic, cmd);
  77.       else
  78.         return acedSetFunHelp_x64(functionName, helpFile, helpTopic, cmd);
  79.     }
  80.     #endregion // acedSetFunHelp
  81.  
  82.     #endregion // PInvoke
  83.  
  84.     const String throughAcedSetFunHelp = "ThroughAcedSetFunHelp";
  85.  
  86.     const String f1_msg = "\nНажмите клавишу F1 для открытия нужного " +
  87.         "раздела справочной системы.\n";
  88.  
  89.     [Rt.CommandMethod("cmd1", Rt.CommandFlags.Modal)]
  90.     public static void Cmd1_Command() {
  91.  
  92.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  93.       if(null == doc) {
  94.         return;
  95.       }
  96.       using(doc.LockDocument()) {
  97.         doc.Editor.GetPoint(f1_msg);
  98.       }      
  99.     }
  100.  
  101.     [Rt.CommandMethod("cmd2", Rt.CommandFlags.Session)]
  102.     public static void Cmd2_Command() {
  103.  
  104.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  105.       if(null == doc) {
  106.         return;
  107.       }
  108.       using(doc.LockDocument()) {
  109.         doc.Editor.GetPoint(f1_msg);
  110.       }
  111.     }
  112.  
  113.     public void Initialize() {
  114.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  115.  
  116.       Int32 result = Commands.acedSetFunHelp("cmd1",
  117.             @"C:\public\ACAD\Debug\MyHelp\MyHelp.chm", throughAcedSetFunHelp, 0);
  118.       Int32 result2 = Commands.acedSetFunHelp("cmd2",
  119.             @"C:\public\ACAD\Debug\MyHelp\MyHelp.chm", throughAcedSetFunHelp, 0);
  120.     }
  121.     public void Terminate() { }
  122.   }
  123. }

В AutoCAD 2009 x86 успешно работает Cmd1, но не работает Cmd2 (открывает справку акада). Если в Cmd2 меняю Model на Session, то всё работает.
Однако этот фокус не проходит ни в 2013-м x86, ни в 2015-м x86: оба варианта лезут за справкой в интернет.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
В этом своём коде заменил все Session на Modal. В AutoCAD 2009 x86 почти всё заработало... А именно: кроме ThroughAttribute всё отработало как полагается. В случае ThroughAttribute получаю сообщение, что CHM файл не найден. Если добавить запись в каталоги поиска AutoCAD, то и ThroughAttribute начинает работать.

Однако можно в каталоги поиска добавить только одну запись, общую для всех плагинов: например "C:\AutoCAD\Plugins". Затем в этом каталоге размещать плагины по своим подкаталогам. Тогда можно через атрибуты указывать файл справки так:
Код - C# [Выбрать]
  1. [CommandMethod(commandGroup, commandName, null, CommandFlags.Modal, null,
  2.     @".\MyPluginName\Documentation" + chmFileName, commandName)]
В AutoCAD 2009 x86 это работает (в др. не проверял).

Это чтобы под каждый плагин не добавлять в каталоги поиска очередную запись. Чем меньше записей, тем быстрее AutoCAD будет выполнять поиск. Такой способ позволяет хранить файл справки в каталоге, отличном от каталога размещения DLL. Например, DLL файлы плагина могут размещаться в подкаталоге .\MyPlugin\bin по соответствующим подкаталогам (как показано здесь). А файл документации будет один на все версии DLL и храниться в .\MyPlugin\Documentation.
« Последнее редактирование: 27-06-2014, 18:15:07 от Андрей Бушман »

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Подводя итоги: уже в который раз убеждаюсь, что наша компания правильно делает, что не переходит с AutoCAD 2009 на более новые версии. Разница в использовании весьма ощутима как в плане скорости работы AutoCAD, так и в плане количества косяков\багов. И каждая новая версия AutoCAD лишний раз подтверждает правильность нашего выбора.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Пока проверил в AutoCAD 2013 x86 в Windows XP SP3 и AutoCAD 2013 x64 Windows 7 - всё работает. Повторить ошибку не смог.

Цитата: Boxa.Shu
Справка открылась в соответствующих разделах все 3 раза.
AutoCAD 2014 x64 , Win7 x64

Цитата: Дима_
ACAD 2010 Win7*32 - как и у автора - ThroughProcess - вызывает нужную справку, в остальных случаях по F1 - выскакивает автокадная.

Цитата: Александр Ривилис
Проверил еще в x64 AutoCAD 2012, 2013, 2014 - всё нормально
Проверил на всякий случай в x86 AutoCAD 2008, но в Win7 X64 - работает только последний вариант. При этом в этом же AutoCAD'е но в Windows XP x86 работает нормально.

Цитата: Дима_
Acad 2014*64, Win8.1:
сборка и файл помощи на рабочем столе:
сборка загруженна успешно, регистрация выполненна
THROUGHATTRIBUTE - автокад ругается что такого файла нету, после загружает свою справку
THROUGHACEDSETFUNHELP - открывает "правильную" справку - курсор на пункте about (в 2010 был на "своем" месте)
THROUGHPROCESS - открывает "правильную" справку - курсор на пункте about

сборка на рабочем столе, файл справки в папке автокада:
сборка загруженна успешно, файл справки не найден
THROUGHATTRIBUTE - открывает "правильную" справку - курсор на пункте about
THROUGHACEDSETFUNHELP - автокад "молча" загружает свою справку
THROUGHPROCESS - ругается что не удается открыть справку

Цитировать
и т.д.

В моём случае замена Sessoin на Modal помогло. У всех аналогично?

Пока получается (судя по обозначенным выше цитатам), что на одних компьютерах, для команд уровня приложения [Session], пользовательская справка работает, а на других нет... Причина непонятна.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Собрался с духом и отправил запрос в ADN DevHelp. Пока ограничил его проверкой работы acedHelp и acedSetFunHelp в AutoCAD 2013...2015 и Windows 7 x86. Дальше будет видно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Собрался с духом и отправил запрос в ADN DevHelp.
No comments...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Получил ответ о том, что они проверили в AutoCAD 2015 x86 и x64 и не выявили ошибку. На всякий случай написали для .NET в AutoCAD 2015

Код - C# [Выбрать]
  1. /*x64*/
  2. [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "?acedSetFunHelp@@YAHPEB_W00H@Z", ExactSpelling = true)]
  3. private static extern int acedSetFunHelp64(string functionName, string helpFile,string helpTopic,int cmd);
  4.  
  5.  
  6. /*x86*/
  7. [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "?acedSetFunHelp@@YAHPB_W00H@Z", ExactSpelling = true)]
  8. private static extern int acedSetFunHelp32(string functionName, string helpFile,string helpTopic,int cmd);

Не думаю, что это поможет, но можешь попробовать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
они проверили в AutoCAD 2015 x86 и x64 и не выявили ошибку
Браво! Значит проблемы не существует.


Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Так в 2015, в"голом" виде:
Код - C# [Выбрать]
  1. [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "?acedSetFunHelp@@YAHPB_W00H@Z", ExactSpelling = true)]
  2. private static extern int acedSetFunHelp32(string functionName, string helpFile,string helpTopic,int cmd);
работает или нет?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Было предложено проверить еще один вариант:
Код - C# [Выбрать]
  1. [Rt.CommandMethod(commandGroup, throughAcedSetFunHelp,
  2. Rt.CommandFlags.Session)]
  3. public void ThroughAcedSetFunHelp_Command()
  4. {
  5.  
  6. Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  7. if (null == doc)
  8. {
  9.     return;
  10. }
  11. string CmdName = "c:"+ throughAcedSetFunHelp.ToUpper();
  12. acedSetFunHelp(CmdName, chmFileFullName, "", 0);
  13. doc.Editor.GetPoint(f1_msg);
  14. }
Но мы его вроде уже проверяли.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Уточняйте версию и разрядность AutoCAD, для которых хотите проверить. На данный момент времени у меня на работе происходит замена локальных виртуальных машин (образы для VirtualBox) на серверные (образы для VMware), с установкой соответствующего софта. В виду этого в течении нескольких рабочих дней у меня нет возможности попробовать код (в выходные я занят др. делами).

На сегодняшний день полностью укомплектована только машинка разработчика (win 7 x64). Машинка с AutoCAD'ами (win 7 x64) в процессе формирования (создана, но пока не установлены AutoCAD'ы, удалённые отладчики и Gallio). Правда 32-х битную машинку мне пока не выделят, т.к. на сервере не хватает ресурсов. На одном из серверов ещё "живёт" одна старая виртуальная машинка, выделенная мне несколько лет назад для удалённого тестирования AutoCAD 2009 x86, но у неё слишком маленький диск: 20 Гб и он, к сожалению, не расширяется - так уж создали её админы. Т.о. установить на неё ещё и AutoCAD 2010-2015 не получится (места не хватит).

Т.о. теперь у меня ситуация меняется с точностью до наоборот: смогу тестировать под x64, но не смогу под x86 (за исключением AutoCAD 2009, который на данной дискотеке нынче "не в моде").
« Последнее редактирование: 12-07-2014, 10:46:09 от Андрей Бушман »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Уточняйте версию и разрядность AutoCAD, для которых хотите проверить.
Как обычно желательно последнюю. В крайнем случае из трех последних.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение