打开表单时隐藏访问窗口

Posted

技术标签:

【中文标题】打开表单时隐藏访问窗口【英文标题】:Hide access window when opening a form 【发布时间】:2016-04-10 09:33:44 【问题描述】:

我的 Access 数据库有一个 autoexec 宏,它可以打开一个主菜单(表单)。所有必要的功能都是菜单(表单)控制的,我想隐藏访问窗口以便只显示表单。我被提到http://www.tek-tips.com/faqs.cfm?fid=2562 但这不适用于更高版本。是否有适用于 Access 2007-2013 的 sn-p?

【问题讨论】:

我不确定那是什么,但它确实有效。谢谢 【参考方案1】:

这是我在 Acc 2003 和 2007 应用程序中运行的代码,在 2010 环境中运行:

Private Sub Form_Load()
   'Hide Data-Base Window:
   DoCmd.SelectObject acTable, , True
   DoCmd.RunCommand acCmdWindowHide
  '...Other Actions...
end sub

为了在 2007 年及更高版本中隐藏功能区,请使用我找到的这条线 here:

DoCmd.ShowToolbar "Ribbon", acToolbarNo

【讨论】:

这是完美的。只是一个简单的命令。我寻找另一个类似的命令来隐藏功能区,但找不到任何东西。这可能吗? @Robert Kendall 我在答案中添加了这行代码 感谢功能区技巧。在 Access 2016 中,旧的“AllowFullMenus”和“AllowBuiltInToolbars”没有隐藏文件菜单和帮助菜单。【参考方案2】:

看来您的目标是限制数据库用户可以使用的 Access UI 功能。您希望将它们限制为您通过启动表单提供的选项。

在这种情况下,请复制您的 ACCDB 文件并将其文件扩展名更改为 ACCDR。然后,当您从 Windows 资源管理器中打开 ACCDR 时,Access 将以“运行时模式”打开它。运行时模式抑制了大多数标准 UI 选项。例如,导航窗格不显示,甚至无法打开。它还为您提供了一个非常小的功能区版本;大多数标准功能区选项都已消失。

运行时模式还有其他后果,您应该调查一下它是否适合您的需求。一个重要问题是运行时模式会在遇到未处理的错误时退出应用程序。

如果 ACCDR/运行时模式适合您的特定情况,那么它是一种限制数据库 UI 功能的廉价方式。但是,请注意用户可能会复制 ACCDR 并将文件扩展名更改回 ACCDB,因此仅此方法可能无法满足您的安全要求。

【讨论】:

您还可以创建一个 accde 文件,并使用“/excl /runtime”命令行开关运行它。第一个以独占模式打开它,因此 Access 跳过多用户环境检查,第二个将用户限制为运行时选项。攻击者将能够将表和查询从 accde 复制到新的 accdb,但表单和 vba 代码将受到保护。可以绕过这种保护,但不是很简单。【参考方案3】:

这是我使用到 2016 年的产品:

Option Compare Database
Option Explicit

'''HIDE WINDOW MODULE
'''USE THIS TO ACTIVATE HIDE WINDOW MODULE
''' SixHatHideWindow(SW_SHOWMINIMIZED)

Global Const SW_HIDE = 0
Global Const SW_SHOWNORMAL = 1
Global Const SW_SHOWMINIMIZED = 2
Global Const SW_SHOWMAXIMIZED = 3

Private Declare Function apiShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Function SixHatHideWindow(nCmdShow As Long)
    Dim loX As Long
    Dim loForm As Form
    On Error Resume Next
    Set loForm = Screen.ActiveForm

    If Err <> 0 Then
        loX = apiShowWindow(hWndAccessApp, nCmdShow)
        Err.Clear
    End If

    If nCmdShow = SW_SHOWMINIMIZED And loForm.Modal = True Then
        MsgBox "Cannot minimize Access with " _
        & (loForm.Caption + " ") _
        & "form on screen"
    ElseIf nCmdShow = SW_HIDE And loForm.PopUp <> True Then
        MsgBox "Cannot hide Access with " _
        & (loForm.Caption + " ") _
        & "form on screen"
    Else
        loX = apiShowWindow(hWndAccessApp, nCmdShow)
    End If
    SixHatHideWindow = (loX <> 0)
End Function

简单地隐藏窗口:Call SixHatHideWindow(SW_SHOWMINIMIZED)

还请注意:根据哪个版本,即 32 位或 64 位,您可能需要添加 PtrSafe 属性,因此如果您对此有问题,请声明 API 函数,如下所示:Private Declare PtrSafe Function apiShowWindow...

【讨论】:

我粘贴了这个并添加了一个按钮来运行代码:SixHatHideWindow(SW_SHOWMINIMIZED) 但我得到一个错误:“对象不包含自动化对象'SW_SHOWMINIMIZED'” 我之前在同一个模块中收到过这个错误。一直是因为其他地方的编译错误。做这个; 1. 注释掉你刚刚添加的这个模块......然后编译并修复可能在其他地方弹出的任何错误。如果在其他地方没有发现其他错误,请取消注释模块并压缩并修复数据库。这应该有望解决问题。 另请注意,您应该在加载事件之前触发的表单的打开事件上调用该函数 当你说调用函数时,这是否与使用操作行运行宏相同:SixHatHideWindow(SW_SHOWMINIMIZED)? 在某种意义上是的...我自己通常不再使用宏,但他们最终所做的只是为您生成您的 VBA 代码。我从来没有从 AutoExec 宏触发过这个功能......但它仍然应该工作。我认为您遇到的问题可能是由于您尝试使用其他模块来隐藏窗口...如果它有您所说的问题,那么它可能无法编译。你按照我的建议编译了吗?【参考方案4】:

我试图完成隐藏 Access 应用程序窗口并使用可以从 Outlook 运行的弹出表单。这就是我遇到这篇文章的方式。但我发现,在 Windows 7 64 位上使用 Outlook 2013 64 位,甚至不需要 SixHatHideWindow 函数。在 Outlook 2013 中使用以下代码可以完成相同的操作。 (不要忘记在 VBA 中添加对 Access 对象库的引用。)此过程保存当前活动 Outlook 窗口中的标题,启动 Access 的新隐藏实例(应用程序窗口不可见),打开指定的 Access 数据库,运行指定的窗体(可见),在窗体关闭时退出 Access 实例,并重新激活原始 Outlook 活动窗口。我没有在任何其他环境中测试过这个,也没有使用运行时访问。

这种方法的好处是它不需要在 Access 数据库的表单打开事件中插入任何特殊代码。所有必要的代码都包含在 Outlook VBA 中。数据库表单的弹出和模式属性也不需要在数据库中设置为“是”。

本例中的表单是一个复杂的表单,包含一个选项卡控件和几个子表单。无论表单是从 Access 本身打开还是通过 Outlook 自动打开,一切似乎都可以正常工作。

注意:即使 Access 不可见,SetWindowPos api 也会设置 Access 主窗口的位置和大小。当 Access 关闭时,用户下次打开 Access 时,它将重新打开到由 SetWindowPos api 设置的大小和位置。这对用户来说可能很烦人,因此 SetWindowPos api 将 Access 应用程序窗口设置为全屏大小。下次用户打开 Access 时,它将在他们的屏幕上最大化。可能有更复杂的方法来处理这个问题,但这种方法既快速又简单,而且大多数用户在大多数情况下都使用最大化的 Access。

希望这对某人有所帮助。

Private Declare PtrSafe Function SetWindowPos Lib "user32.dll" (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 Declare PtrSafe Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As Long
Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

Sub OpenAccessFrmProjDetails()
      Dim accapp As Access.Application
      Dim HoldCaption As String
      Dim ScreenRect As RECT
      Dim ret As Long
      Dim width As Variant
      Dim height As Variant

      'Get the width and height of the screen in pixels
10    ret = GetClientRect(CLng(GetDesktopWindow()), ScreenRect)
20    width = ScreenRect.Right - ScreenRect.Left
30    height = ScreenRect.Bottom - ScreenRect.Top

      'Get Outlook activewindow caption
40    HoldCaption = ActiveWindow.Caption

      'Display the Access database form
50    Set accapp = New Access.Application
60    With accapp
70        .opencurrentdatabase ("C:\Users\pmf\Documents\Programming Development\Access Visibility Testing\Hidden.accdb")
80        SetWindowPos .hWndAccessApp, 0, 0, 0, width, height, 0
90        .DoCmd.OpenForm FormName:="frmProjDetails", WindowMode:=acDialog
100   End With

110   Set accapp = Nothing

      'Reactivate Outlook
120   AppActivate HoldCaption

110   End Sub

【讨论】:

你为什么使用行号?自 1988 年 GW-BASIC 以来,这些就不再需要了。 @HackSlash 备注:有一个 erl 对象,其中包含当前子/函数中发生最后一个错误的行的标识符,但仅当标识符是数字时。我实际上有一个行号实用程序可以将此信息用于错误日志。【参考方案5】:

中查看此解决方案

https://msaccess.erpmakers.com/Articles_MSAccess/0013-how%20to%20hide%20all%20access%20objects%20including%20navigation%20menu%20and%20ribbon%20using%20microsoft%20access%20vba.php

我在 acees 2016 中测试了该解决方案对我的工作,并稍作改动

我在模块中插入内容并在手动创建的宏ExcAuto中调用函数VerifyLoadApplication()

接下来,在vba编辑器中编译所有代码->调试->编译并验证所有代码vba中没有空子例程,以避免在acccde中转换acccdb失败

但我在第一次打开 accde 文件时遇到问题,它工作正常,但是对于所有下一个打开的文件,主页和文件选项卡出现

在网上搜索并在本地测试代码并找到此解决方案

'注释两条指令

'CurrentDb.Properties("AllowFullMenus") = False
'CurrentDb.Properties("AllowBuiltInToolbars") = False

'并用这个指令替换

DoCmd.ShowToolbar "Ribbon", acToolbarNo

你可以在代码的第一方中对两个指令做同样的事情,条件为真

【讨论】:

以上是关于打开表单时隐藏访问窗口的主要内容,如果未能解决你的问题,请参考以下文章

由任务计划程序启动时隐藏 C# winform 应用程序窗口

启动时隐藏单一表单

如何在窗口调整大小时隐藏 Facebook 聊天框?

打开第二个窗口后隐藏主窗口?另外,当第二个窗口被用户关闭时,主窗口如何重新出现?

如果用户没有权限,如何在登录后从菜单中隐藏Web表单?

隐藏打开的窗口的快捷键是啥?