Индикатор выполнения с использованием Office VBA

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

Однако я не могу сохранить эту форму поверх всех других окон Office.

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

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

Возможно, я только что пропустил отель "стейонтоп" или что-то в этом роде?

Спасибо


person user51498    schedule 01.02.2009    source источник


Ответы (1)


Я не думаю, что есть какой-либо встроенный способ, чтобы форма оставалась на вершине в VBA, но один вопрос: вызываете ли вы DoEvents, когда что-то обновляете в своей форме? По моему опыту, форма не перерисовывается, если, например, вы не вызываете DoEvents, прежде чем нажимать оператор Next в цикле.

Если это не ваша проблема, вы можете использовать вызовы Windows API, чтобы поместить окно вверху, хотя я не уверен, что оно останется вверху, используя этот код:

Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long

Const SWP_NOMOVE = 2
Const SWP_NOSIZE As Long = 1
Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2

Private Declare Function SetWindowPos Lib "user32" _
      (ByVal hwnd As Long, _
      ByVal hWndInsertAfter As Long, _
      ByVal x As Long, _
      ByVal y As Long, _
      ByVal cx As Long, _
      ByVal cy As Long, _
      ByVal wFlags As Long) As Long

Private Function SetTopMostWindow(hwnd As Long, Topmost As Boolean) As Long

   If Topmost = True Then 'Make the window topmost
      SetTopMostWindow = SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)
   Else
      SetTopMostWindow = SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)
      SetTopMostWindow = False
   End If
End Function

Private Function GetFormHwnd() As Long
    GetFormHwnd = FindWindow(CLng(0), Me.Caption)
End Function

Public Sub SetFormAsTopMostWindow()
    Call SetTopMostWindow(GetFormHwnd(), True)
End Sub

Я поместил это в модуль кода формы, и, похоже, он работает при перемещении других приложений; он остается на вершине.

person Jon Fournier    schedule 02.02.2009
comment
Спасибо, поиграю с этим. - person user51498; 02.02.2009