Несколько вопросов по Адд-инам

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Несколько вопросов по Адд-инам

Сообщение arthur2 » 08.05.2019 (Ср) 21:45

Итак, я в Адд-ине.
1. Как мне открыть группу, зная путь? Как открыть проект - понятно. А вот если группу?
2. Как закрыть проект или группу так, чтобы бейсик предложил сохраниться?
3. Как запустить проект с полной компиляцией? Можно ли сделать полную компиляцию, не запуская проект?
Артур
 
   

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Re: Несколько вопросов по Адд-инам

Сообщение NashRus » 09.05.2019 (Чт) 15:06

[offtop] просто интересно, зачем и кому это актуально в 2019 году? хоть примерно...

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Несколько вопросов по Адд-инам

Сообщение arthur2 » 09.05.2019 (Чт) 20:53

Мне.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Несколько вопросов по Адд-инам

Сообщение Хакер » 10.05.2019 (Пт) 7:33

arthur2 писал(а):1. Как мне открыть группу, зная путь? Как открыть проект - понятно. А вот если группу?

Так же, как и проект:
Function AddFromFile(PathName As String, [Exclusive As Boolean = False]) As VBNewProjects
Member of VBIDE.VBProjects
Adds or opens a project or group project and returns a collection of all projects added using AddFromFile.

Второй параметр должен быть True.

arthur2 писал(а):2. Как закрыть проект или группу так, чтобы бейсик предложил сохраниться?

Если без грязных трюков, а только через объектную модель, которую предоставляют Add-in'ам, то похоже, что никак.

Правда в том, что метод VBProjects::Remove всегда проверяет, есть ли в проекте не сохранённые изменения, и всегда пытается спросить, хочет ли пользователь их сохранить.

VBProjects::Remove вызывает RemoveProject, та вызывает _PromptSaveProject, та вызывает _PromptSaveChanges. Последняя показывает знаменитый диалог.

В недрах VB IDE существует функция VBDialogCover2, которая отвечает за показ любых (всех) диалогов, порождаемых с причастностью IDE. То есть это и диалог подтверждения сохранения, и диалог создания нового проекта, диалог Options, диалог About и даже диалоги MsgBox и InputBox, показываемые при работе выполняемых проектов или вызываемых из Immediate Pane. То есть функция, через которую проходят все запросы на показ диалога.

В этой функции есть код, который проверяет особый флаг g_nInOLECall — если флаг стоит, порождения диалога не происходит, а вместо этого осуществляется немедленный возврат из функции (с кодом 1).
VBDialogCover2_killer_branch.png
VBDialogCover2_killer_branch.png (3.61 Кб) Просмотров: 1859


Флаг устанавливается (точнее инкрементируется/декрементируется) методами VBDispatch::EnterOleFunc / VBDispatch::ExitOleFunc.

Беда в том, что все методы объектной модели, доступные Add-In'ам, имеют «внутрянку», обёрнутую между парой вызовов EnterOleFunc и ExitOleFunc. В том числе и метод VBProjects::Remove, с помощью которого можно выгрузить проект, обёрнут в эту пару:
VBProjects.Remove_internals.png
VBProjects.Remove_internals.png (15.58 Кб) Просмотров: 1859


Из-за этого отображения диалога сохранения несохранённого не происходит.

У «грязных трюков» есть два направления хода мыслей:
  • Менять предусмотренную логику работы VB IDE. Если заNOPить инструкцию JNZ ..., то прекрасно всё будет работать так, как ты хочешь. VB будет предлагать сохраниться, а зависимости от выбора между Yes, No и Cancel будет либо закрытие проекта с сохранением, либо закрытие без сохранения, либо отмена закрытия (что для меня немного удивительно, потому что я сначала считал, что именно из-за невозможности адекватной обработки нажатия на «Cancel» весь этот запрет и придуман). Что характерно, в случае нажатия «Cancel» никакой ошибки не выбрасывается, вызывающий код не получает информации о том, состоялось ли вообще удаление проекта из списка загруженных..
    Главный минус: ряд сторонних плагинов может полагаться на существующие «правила игры» (догма, что обращения к объектной моделью не приведут к показу каких бы то ни было IDE-шных диалогов, и что обращения не могут быть отменены пользователем, потому что его никто не спрашивает, а значит, если ошибки не произошло, значит операция выполнилась успешно). Изменение правил игры может поломать работу таких плагинов.

  • Не пользоваться объектной моделью, а делать закрытие проекта через обращение к меню, как будто это пользователь жмёт пунктик «File —> Remove Project».
    Главный минус: геморрой с нахождением нужного пункта, ведь среда может быть руссифицированной, а пункт может быть вообще убран из меню «File» за счёт возможности делать «Customize».

  • Менюшный пункт «Remove Project» и метод VBProjects::Remove — оба стекаются к функции RemoveProject. Если вызывать её напрямую, то не будет вызова EnterOleFunc и ExitOleFunc, а значит не будет установлен особый флаг, а значит ничего не помешает показу диалога, а проект будет удалён из IDE как если бы мы воспользовались пунктом меню. Да, эта функция не экспортируется, её придётся находить каким-то способом. Но в первом варианте «грязных трюков» надо находить место, которое надо NOP-ить. А здесь, в отличие от первого варианта, нет проблемы с совместимостью с другими плагинами.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Несколько вопросов по Адд-инам

Сообщение arthur2 » 11.05.2019 (Сб) 8:28

Хакер писал(а):Так же, как и проект
Вот же ж... Что называется, между глаз проскочило.
Хакер писал(а): а делать через обращение к меню
Да, кстати, тоже возник вопрос - можно ли каким-нибудь образом добраться до встроенных команд среды. Ведь каждой кнопе и меню назначена какая-то команда - неужели нельзя такую команду вызвать как-то программно?
Хакер писал(а):Да, эта функция не экспортируется
А как искать функции, которые не экпортируются?
И да - можно запустить проект программно? Типа SendKey Ctrl+F5
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Несколько вопросов по Адд-инам

Сообщение Хакер » 15.05.2019 (Ср) 14:53

arthur2 писал(а):А как искать функции, которые не экпортируются?

По сигнатуре.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Несколько вопросов по Адд-инам

Сообщение arthur2 » 19.05.2019 (Вс) 10:02

Это что-то вроде того, как ты искал DllFunctionCall?

В общем и целом, в любом случае искать каждую конкретную функцию, связанную с каждой конкретной командой - не очень универсально. Сейчас мне нужно закрыть проект, а потом вдруг понадобится, скажем, вызвать диалог поиска. Как бы добраться до произвольной команды?

Хакер писал(а):Не пользоваться объектной моделью, а делать закрытие проекта через обращение к меню, как будто это пользователь жмёт пунктик «File —> Remove Project».
Главный минус: геморрой с нахождением нужного пункта, ведь среда может быть руссифицированной, а пункт может быть вообще убран из меню «File» за счёт возможности делать «Customize».
А если на этот случай создать собственное меню, добавить туда избранные команды и их вызывать? Это сработает? Не пойму, как бы к этому подступиться...

Возник ещё один вопрос. Я при старте запускаю выбранный проект (конкретно тот, в котором произошел крэш). Теперь надо бы не дать бейсику запустить стартовое окно. Пока делаю тупо - жду по таймеру, пока оно появится, и закрываю. Но это какой-то прямо костыль-костыль...
Артур
 
   


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 54

    TopList