有没有一种方法可以在IDE中显示用户表单而不是主机应用程序?

7
我在*.xlam插件中创建了一个用户窗体,并在IDE中创建了一个新的命令栏和按钮,但当我单击按钮时,用户窗体会在Excel中打开,并且焦点被强制从IDE中移开。有没有一种方法可以在IDE中打开用户窗体而不是宿主应用程序,而不必使用.Net COM Add-in?
以下是创建命令栏和按钮以及处理按钮单击事件的代码。
Option Explicit

Public WithEvents cmdBarEvents As VBIDE.CommandBarEvents

Private Sub Class_Initialize()
    CreateCommandBar
End Sub

Private Sub Class_Terminate()
    Application.VBE.CommandBars("VBIDE").Delete
End Sub

Private Sub CreateCommandBar()

    Dim bar As CommandBar
    Set bar = Application.VBE.CommandBars.Add("VBIDE", MsoBarPosition.msoBarFloating, False, True)
    bar.Visible = True

    Dim btn As CommandBarButton
    Set btn = bar.Controls.Add(msoControlButton, , , , True)
    btn.Caption = "Show Form"
    btn.OnAction = "ShowForm"
    btn.FaceId = 59

    Set cmdBarEvents = Application.VBE.Events.CommandBarEvents(btn)

End Sub

Private Sub cmdBarEvents_Click(ByVal CommandBarControl As Object, handled As Boolean, CancelDefault As Boolean)

    CallByName Me, CommandBarControl.OnAction, VbMethod

End Sub

Public Sub ShowForm()
    Dim frm As New UserForm1
    frm.Show
End Sub

P.S. 你可能需要以下代码来移除命令栏...

Application.VBE.CommandBars("VBIDE").Delete

是的:将其制作成VBE插件,而不是Excel插件! ;) - Mathieu Guindon
你的意思是一个浮动的用户窗体,它不会夺取焦点吗? - Siddharth Rout
我希望 用户窗体 能够获得焦点,而不是Excel从IDE中夺取焦点。我不知道这是否可能 @SiddharthRout。 - RubberDuck
啊,我现在明白你在尝试什么了。 - Siddharth Rout
我已经做了修改。您可能需要刷新页面。我要去睡觉了。如果您有任何问题,明天早上会查看 :) - Siddharth Rout
显示剩余3条评论
1个回答

7

这里有一个替代方案。

在用户表单上放置一个按钮。为了演示目的,我使用了这个

enter image description here

接下来在用户表单中添加以下代码:

Private Sub CommandButton1_Click()
    Unload Me
    Application.Visible = True
End Sub

接下来将这段代码粘贴到您的类模块的顶部

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Dim Ret As Long, ChildRet 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

Private Const HWND_TOPMOST = -1
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_SHOWWINDOW = &H40

最后,将你的 Sub ShowForm() 更改为以下内容。
Public Sub ShowForm()
    Dim frm As New UserForm1
    Dim Ret As Long

    frm.Show vbModeless

    Application.Visible = False

    Ret = FindWindow("ThunderDFrame", frm.Caption)

    SetWindowPos Ret, HWND_TOPMOST, 100, 100, 250, 200, _
    SWP_NOACTIVATE Or SWP_SHOWWINDOW
End Sub

这是您获得的内容

输入图像描述此处

编辑

更多想法。 为了防止用户在单击表情符号时创建更多的用户窗体,请将Sub ShowForm()更改为以下内容。(另一种选择是禁用表情符号,并在卸载表单时重新启用它?

Public Sub ShowForm()
    Dim frm As New UserForm1
    Dim Ret As Long
    Dim formCaption As String

    '~~> Set Userform Caption
    formCaption = "Blah Blah"

    On Error Resume Next
    Ret = FindWindow("ThunderDFrame", formCaption)
    On Error GoTo 0

    '~~> If already there in an instance then exit sub
    If Ret <> 0 Then Exit Sub

    frm.Show vbModeless
    frm.Caption = formCaption

    Application.Visible = False

    Ret = FindWindow("ThunderDFrame", frm.Caption)

    SetWindowPos Ret, HWND_TOPMOST, 100, 100, 250, 200, _
    SWP_NOACTIVATE Or SWP_SHOWWINDOW
End Sub

@RubberDuck:很酷 :) 晚安! - Siddharth Rout
1
+1 鼓励你!...看起来使用 COM 加载项会更容易一些 ;) - Mathieu Guindon
@retailcoder:比 Com Add-In 更容易吗?不是。绝对不是。这太容易了 :). 话虽如此,我会选择 COM Add-In 还是它?嗯,最终取决于我要做什么。如果只是小功能,那我会使用 VBA。我只在想要为自定义任务“扩展” Office 应用的功能时使用 Com-Addins。特别是一些我无法从 VBA 处理的事情。 - Siddharth Rout
漂亮的黑客。谢谢!不过,我认为COM插件最终会成为我们的选择。有一个点,我们真的只是在推动VBA超出了我们应该做的范围。 - RubberDuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接