Системные модальные проблемы MessageBoxW при щелчке правой кнопкой мыши внутри приложения Solidworks

Я написал программу VBA 7.0, которая автоматизирует некоторые вещи в Solidworks. Одна из вещей, которые мне нужно сделать, это проверить наличие опечаток в нескольких областях документа Solidworks. Что я сделал, так это использовал API-вызов MessageBoxW для отображения системного модального окна сообщения, чтобы у них была возможность исправить опечатку, прежде чем продолжить, или отменить.

Окно сообщений отображается нормально, и я могу войти в работающее приложение Solidworks и работать в нем, но когда я щелкаю правой кнопкой мыши в программе и пытаюсь использовать контекстное меню ПКМ, начинают происходить некоторые странные вещи.
1) Мышь кнопки больше не работают в программе или в окне сообщений. Окна других приложений продолжают нормально реагировать, но любые щелчки мышью (ПКМ или ЛКМ) в любом месте окна приложения Solidworks или в окне сообщения ничего не дают. Окна не зависают - я могу нажать клавишу выхода, чтобы выйти из контекстного меню, и тогда все работает нормально. Щелчки кнопки мыши просто не регистрируются, пока открыто контекстное меню. 2) Контекстное меню ПКМ "становится системным модальным". Я не уверен, что это то, что происходит, но лучший способ, которым я мог придумать, чтобы описать это. По сути, контекстное меню будет отображаться поверх всех других окон приложений. Я все еще могу работать в других окнах, хотя и без каких-либо негативных эффектов, кроме контекстного меню.

Не уверен, что это проблема с Solidworks, функцией MessageBoxW или их комбинацией.

РЕДАКТИРОВАТЬ: Это происходит ТОЛЬКО во время отображения окна сообщения, когда закрытое поведение является нормальным.

Я вызываю функции API следующим образом:

lngReply=WinMsgBox(Prompt:="Can you do this thing for me? blah blah",Title:="Action required",Buttons:=vbOkCancel + vbInformation + vbSystemModal

Option Explicit

Private Declare PtrSafe Function MessageBoxW Lib "User32" _
                                       (Optional ByVal hWnd As Long, _
                                        Optional ByVal Prompt As LongPtr, _
                                        Optional ByVal Title As LongPtr, _
                                        Optional ByVal Buttons As Long) _
                                    As Long


Public Function WinMsgBox(Optional ByRef hWnd As Long, _
                        Optional ByRef Prompt As String, _
                        Optional ByRef Title As String, _
                        Optional ByRef Buttons As Long) _
                    As Long

WinMsgBox = MessageBoxW(hWnd, StrPtr(Prompt), StrPtr(Title), Buttons)

End Function

person CBRF23    schedule 05.11.2014    source источник
comment
Вы имеете в виду, что это происходит, когда отображается окно сообщения, или оно сохраняется после закрытия диалогового окна?   -  person Jonathan Potter    schedule 06.11.2014
comment
Хороший вопрос - это происходит ТОЛЬКО при отображении окна сообщения, когда оно закрыто, поведение нормальное. Я отредактировал исходный вопрос с этой информацией.   -  person CBRF23    schedule 06.11.2014
comment
Итак, окно сообщения является модальным и отключает все окна. Так что это вполне ожидаемо. Единственный реальный недостаток в том, что контекстное меню еще не закрылось. Должно быть, возможно, проблема в хост-программе.   -  person Hans Passant    schedule 06.11.2014
comment
Окно сообщений запускает собственный модальный цикл сообщений. Если цикл сообщений Solidworks каким-либо образом нестандартен (например, он может использовать опубликованные сообщения потока, которые не отправляются в окно), то он перестанет работать, пока выполняется другой цикл сообщений.   -  person Jonathan Potter    schedule 06.11.2014


Ответы (1)


Звучит как что-то, что просто не может работать. Модальное диалоговое окно запускает собственный цикл обработки событий, отключает своего родителя и может захватывать мышь. Проблемы прямо на линии. Я удивлен, что он так хорошо работает.

Лучшим решением было бы немодальное диалоговое окно или приложение, написанное как диалог. Вы можете сделать его «сверху», чтобы он просто оставался там, пока они не будут готовы его убрать.


Немодальное диалоговое окно создается с помощью CreateDialog(). Примерно так: http://www.winprog.org/tutorial/modeless_dialogs.html . И самый верхний — это стиль: WS_EX_TOPMOST. Я не могу помочь с превращением этого в VB.

person david.pfx    schedule 06.11.2014
comment
Глядя на документацию для функции MessageBox, похоже, что единственными вариантами являются Application Modal, System Modal или Task Modal. Как мне создать немодальное диалоговое окно? Создать пользовательскую форму программно и вызвать с помощью .show vbModeless или что-то в этом роде? Если да, то как мне заставить его сидеть сверху? - person CBRF23; 06.11.2014
comment
Я посмотрю на CreateDialog() и посмотрю, что я могу сделать. - person CBRF23; 07.11.2014