3

Этот вопрос связан с вопросом о переполнении стека, но я чувствовал, что в глубине души проблема не столько в программировании, сколько в ограничениях программы, вот почему я спрашиваю здесь.

Я надеюсь, что кто-то сможет объяснить несоответствия, которые я вижу в Windows Snap, при использовании события изменения размера окна в качестве триггера для некоторого кода VBA.

У меня есть этот код в модуле ThisWorkbook . Это добавляет 1 к значению A1 в первом листе каждый раз, когда окно изменяется:

Private Sub Workbook_WindowResize(ByVal Wn As Window)
Dim n As Integer

n = ThisWorkbook.Worksheets(1).Range("a1").Value
ThisWorkbook.Worksheets(1).Range("a1").Value = n + 1

End Sub

Событие сработает, когда:

  • Окно развернуто или свернуто
  • Изменение размера окна путем перетаскивания краев внутрь / наружу
  • Окно привязывается в сторону, нажимая Windows+ стрелка на клавиатуре
  • Окно (a) привязывается к одной стороне в результате привязки другого окна (b) к одной стороне, а затем выбирается первое окно (a) из миниатюр Windows Snap Assist.

Событие не сработает, когда:

  • Окно привязывается в сторону, перетаскивая окно к краю экрана с помощью мыши
  • Окно отстегивается от стороны, перетаскивая окно мышью

Что я пробовал

Я проверил документацию MSDN для более подробной информации об ограничениях события Windows Resize. Как вы можете видеть по этой ссылке, там недостаточно информации, чтобы быть полезной в этой ситуации.

Я также проверил через Stack Overflow и Super User и не нашел никаких других вопросов, в которых упоминается использование Windows Snap в качестве триггера для макроса, кроме того, который упоминался в начале моего вопроса.


Изменить: я также пытался Application_WindowResize, который дает тот же результат.

Я использовал этот код в модуле ThisWorkbook для инициализации событий приложения:

Private WithEvents App As Application

Private Sub Workbook_Open()
    Set App = Application
End Sub

И этот код после закрытия и повторного открытия книги, чтобы проверить триггер события:

Private Sub App_WindowResize(ByVal Wb As Workbook, ByVal Wn As Window)
Dim n As Integer

n = ThisWorkbook.Worksheets(1).Range("a1").Value
ThisWorkbook.Worksheets(1).Range("a1").Value = n + 1

End Sub

Для пояснения, этот код выполняется в новой книге, более ранний код отсутствует в VBE. Я вижу тот же результат, что и выше, событие запускается для всего, кроме перетаскивания и привязки к краю экрана с помощью мыши.


Может кто-нибудь сказать мне, почему событие Windows Resize не срабатывает в описанных выше случаях?

1 ответ1

1

Событие Resize с тех пор всегда было нестабильным в Excel и не улучшилось в последних версиях. В некоторых случаях он никогда не работал полностью, включая развернутые или свернутые окна, и, очевидно, привязка использует аналогичный механизм.

Поэтому для решения проблемы требуется непосредственное взаимодействие с Windows API и перехват сообщений Windows, касающихся изменения размера.

Метод 1: Создание нового насоса сообщений для приложения

Весь последний код VB вы найдете в последней записи Джаафара Трибака из публикации « Обнаружение изменения размера окна приложения Excel».

В двух словах, вам нужно объявить функции API-интерфейса Windows FindWindow и SetWindowLong и использовать их для поиска окна приложения с именем XLMAIN и установить собственный насос сообщений. Затем вы перехватываете соответствующие сообщения Windows, обрабатываете их и, наконец, передаете их в Windows. Весь код слишком длинный, чтобы воспроизвести его здесь, и адаптация к вашим потребностям потребует некоторых знаний VB и Windows API.

Способ 2: использование C DLL

Для 32-разрядных версий Excel вы можете использовать C DLL (Dynamic Load Library) SubCls.dll и модуль кода modSubCls.bas загрузить с этого сайта.

Описание того, как их использовать, можно найти в посте « Определить событие изменения размера окна».

В заключение я отмечаю, что не знаю простого решения этой проблемы. Я боюсь, что вам нужно будет заняться тяжелым программированием, чтобы обойти эти недостатки Excel.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .