我有一个运行单独进程的excel vba应用程序。在外部过程中,初始化具有中止按钮的进度指示器。对于最终用户而言,中止按钮可用是至关重要的。查看外部进程是否也很有用。
我希望将进度指示器/中止按钮放在外部进程的顶部。但我不会强迫用户形成一切。
我尝试使用findwindow / setwindowpos,导致以下问题:
如果我在运行进程之前初始化HWND_TOPMOST,那么无论用户想要什么,userform始终位于顶部。我发现这非常烦人,特别是如果出现某种错误,其中debuging窗口可能被非活动的vba用户窗体阻止。但是,工作簿仍然处于所需的背景中。
如果我使用HWND_TOP(在外部进程启动并运行之后),则激活整个工作簿(不仅仅是用户表单),然后隐藏外部应用程序的进度。与激活工作簿相比,它不是很有用。
是否有关于如何将用户表单放在外部应用程序前面的建议,同时仍然允许用户停用它?
代码段:
Option Explicit
' Code stolen with pride from various sources.
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
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
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOSIZE = &H1
Public Const HWND_TOP = 0
Public Const HWND_BOTTOM = 1
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public id As Integer
Public ProgressForm As fProgress
' Main routine, launch application and progress indicator.
Sub LoadForm()
Set ProgressForm = New fProgress
ProgressForm.Show
' Force userform to front, makes it on top but does not allow reorder of windows.
ForceToFront ProgressForm
' Run external process, notepad used for example.
id = Shell("notepad", vbNormalFocus)
End Sub
' Routine to bring userform to front after the external program is up and running.
Sub TestBringToFront()
BringToFront ProgressForm
End Sub
Sub BringToFront(fm As fProgress)
Dim hwnd As Long, ret As Variant
hwnd = FindWindow("ThunderDFrame", fm.Caption)
ret = SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Sub
Sub ForceToFront(fm As fProgress)
Dim hwnd As Long, ret As Variant
hwnd = FindWindow("ThunderDFrame", fm.Caption)
ret = SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Sub
答案 0 :(得分:0)
不幸的是,这是Windows和应用程序的指定行为。但是,我可以建议一些解决方法: