5

我一直在尝试让 Microsoft Access 从主 Access 窗口中“退出”,这样我就可以隐藏 Access 窗口并仅在桌面上显示表单,以便可以轻松地将其放置在其他应用程序旁边。

起初我发现了一些使用 Access 自己的 Form.PopUp 属性的代码示例,但这不能在运行时设置,只能在设计视图中设置。尽管这似乎实现了我想要做的事情,但有两个缺点:

  1. 在设计视图和普通视图之间切换需要“关闭”两者之间的窗口 - 我宁愿保持打开状态以保留当前状态,特别是因为它用于创建必须未保存的新记录。

  2. 我想从主表单打开其他表单,除非它们也被设置为“弹出”,否则这些表单似乎也不适用于这种方法。但这很麻烦,因为这些也需要放入设计视图等,我不确定在两个弹出窗口之间切换是否容易。

然后我找到了一个名为 SetParent 的 API 函数,它似乎可以满足我的需要。我使用了以下命令(VBA 语法):

SetParent ShowForm.hWnd
ShowWindow hWndAccessApp, SW_HIDE
ShowWindow ShowForm.hWnd, SW_SHOWNORMAL

但我遇到了两个问题(可能相关:

  1. 该窗口似乎反应迟钝(例如,我无法输入它,并且单击按钮似乎也不起作用)。

  2. 当我执行 ALT+TAB 时,我得到了一个 BSOD:

    BugCheck 1000008E, {c0000005, 9e3573f5, 88d9da10, 0}
    Probably caused by : win32k.sys ( win32k!xxxNextWindow+3a6 )
    at win32k!EngLineTo+1a641
    

有没有其他方法可以做到这一点,以便我可以拥有一个没有访问窗口的表单,该访问窗口能够在主访问窗口之外调用和显示其他访问表单?

我在SetParent API 文档中注意到还有一些其他事情需要完成 - 更改 UI 状态和更改窗口样式,但我找不到正确的方法来完成它们。这样做会解决 BSOD 和无响应问题吗?

感谢您的任何想法!

4

3 回答 3

1

问题的核心问题可以用下面的代码来解决。– 但是,有一些限制(见下文)。

我建议您将此代码粘贴到新的 VBA 模块中,但您也可以将其放入表单的模块中。

Private Const GWL_STYLE As Long = -16

Private Const WS_CHILD As Long = &H40000000
Private Const WS_POPUP As Long = &H80000000

Private Const SW_HIDE As Long = 0
Private Const SW_SHOW As Long = 5
Private Const SW_MINIMIZE As Long = 6

Private Declare PtrSafe Function SetParent Lib "User32.dll" (ByVal hWndChild As LongPtr, ByVal hWndNewParent As LongPtr) As LongPtr
Private Declare PtrSafe Function SetWindowLong Lib "User32.dll" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
Private Declare PtrSafe Function GetWindowLong Lib "User32.dll" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function ShowWindow Lib "User32.dll" (ByVal hWnd As LongPtr, ByVal nCmdShow As Long) As Boolean

Public Sub MakePopupWindow(ByVal hWnd As LongPtr)

    Dim windowStyle As LongPtr

    Call SetParent(hWnd, 0)

    windowStyle = GetWindowLong(hWnd, GWL_STYLE)
    windowStyle = windowStyle Xor WS_CHILD
    windowStyle = windowStyle Or WS_POPUP

    Call SetWindowLong(hWnd, GWL_STYLE, windowStyle)

    Call ShowWindow(Application.hWndAccessApp, SW_HIDE)
    Call ShowWindow(hWnd, SW_SHOW)

End Sub

此代码会将任何 Access 表单转换为类似 PopUp 的表单,该表单可以移动到 Access 主窗口之外。它将窗体的父窗口设置为桌面窗口,并将删除 WS_CHILD 窗口样式并添加 WS_POPUP 样式。

该代码可以随时调用,不需要任何特定的设计时设置。要在任何窗体上调用代码,只需调用 MakePopupWindow 方法并将目标窗体的 hWnd 传递给它。

当前的实现有一些限制:

1.) 当前数据库的文档窗口选项必须设置为重叠窗口。我想应该也可以使用选项卡式文档进行这项工作,但这需要对目标窗口的窗口样式进行额外的更改。

2.) 形式的转换是单向的。我无法找到将表单重新集成回 Access 主窗口的方法。只是颠倒代码,没有用。

于 2016-03-07T15:32:53.373 回答
0

我正在做同样的事情,但从 C# 开始,基本上我有一个选项卡面板,我将我的 MS Access 窗口放在里面,我可以点击按钮,但我仍在输入文本框,由于某种原因不起作用,我可以检查复选框并做其他没有问题的事情..

无论如何,如果您可以留下您的电子邮件或以某种方式与您联系,我们可以一起解决这个问题,两个人有更好的机会解决这个问题,现在我所做的如下:

        SetParent([Access window handle], [current handle from my tab page]);
        SetWindowPos([Access window handle], 0, 0, 0, this.Width, this.Height, 0x0001);
        SetWindowLong([Access window handle], -16, 4194304);
于 2013-10-11T15:35:06.087 回答
0

您无需任何 API 代码即可实现此目的。只需几个简单的设置。

使用常规表单,关闭选项卡,并使用选项卡式界面。

结果是这样的:

在此处输入图像描述

如果您愿意,可以在启动时添加一行 VBA 以隐藏功能区。

DoCmd.ShowToolbar "Ribbon", acToolbarNo

我非常推荐上述内容,因为不需要 API 代码等。实际上只需要一行代码。如果您需要启动一个可以移动到 UI 之外的附加表单,那么您可以启动一个弹出式表单。

于 2016-03-07T17:08:18.287 回答