Открытие пользовательской формы на неправильной книге - PullRequest
0 голосов
/ 03 октября 2018

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

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

Если пользователь работает в другой рабочей книге на мониторе 1, а затем нажимает кнопку, чтобы открыть дополнительную пользовательскую форму на мониторе 2, дополнительная пользовательская форма открывается на мониторе 1 и ведет себякак будто его родитель - другая рабочая тетрадь.Чтобы исправить это поведение, пользователь должен щелкнуть ячейку в книге монитора 2, а затем нажать кнопку, чтобы открыть вспомогательную форму пользователя.Так что, похоже, проблема активации книги, но это не так.

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

Вот основной код, который я использую для запуска вторичной пользовательской формы при нажатии кнопки:

Private Sub CommandButton1_Click()

    With UserForm2
        .StartUpPosition = 0
        .Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
        .Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
        .Show vbModeless

    End With

End Sub

Я нашел это мышление, мне просто нужно явно установить родительское окно userforms перед его показом, но userform вообще не откроется с этим кодом: http://www.cpearson.com/excel/SetParent.aspx

Я надеюсь, что этоимеет смысл.Это сложно объяснить.

1 Ответ

0 голосов
/ 03 октября 2018

Если у вас есть ссылка на Workbook, для которого вы хотите установить родительский элемент формы, вам нужно всего лишь два дескриптора окна, чтобы перейти к SetParent.Для Workbook вы можете просто использовать переменную g_workbook, чтобы получить ее Window, которая предоставляет свойство Hwnd.

Для UserForm вам потребуется использовать вторуюВызов API (FindWindow).Просто передайте ему заголовок вашего окна (и, необязательно, класс, если вы беспокоитесь, что он не уникален), и он возвращает дескриптор окна.Поместите это в объявления в верхней части модуля:

#If VBA7 Then
    Private Declare PtrSafe Function SetParent Lib "user32" ( _
        ByVal hWndChild As Long, _
        ByVal hWndNewParent As Long) As Long

    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
        (ByVal lpClassName As String, _
        ByVal lpWindowName As String) As Long
#Else
    Private Declare Function SetParent Lib "user32" ( _
        ByVal hWndChild As Long, _
        ByVal hWndNewParent As Long) As Long

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
        (ByVal lpClassName As String, _
        ByVal lpWindowName As String) As Long
#End If

Затем сделайте вызов SetParent, прежде чем показать форму:

Private Sub CommandButton1_Click()
    With New UserForm2
        .StartUpPosition = 0

        Dim host As Window
        Set host = g_workbook.Windows(1)
        'You can also calculate these on the host position if you want.
        .Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
        .Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)

        Dim handle As Long
        handle = FindWindow(vbNullString, .Caption)
        SetParent handle, host.Hwnd

        .Show vbModeless
    End With
End Sub

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...