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

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

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

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

  • 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 видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение