访问应用程序,带有表单任务栏图标的隐藏应用程序窗口

时间:2014-10-27 18:10:53

标签: vba api

我有一个主要表单的访问应用程序。当您打开应用程序时,AutoExec宏通过Windows API apiShowWindow隐藏应用程序。然后,AutoExec打开设置为Popup的主窗体。这一切都很美妙;我的数据库内容被隐藏,表单打开并且只是浮动。

但是,当访问数据库被隐藏时,您将丢失任务栏图标。我在Options \ Current Database \ Application Icon设置中设置了自定义图标。如果我不隐藏数据库,则此图标在任务栏中显示正常。

我找到了一个API解决方法,它将在任务栏中仅为表单显示一个图标。它有点像这样:

Public Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" _
(ByVal hWnd As Long, _
 ByVal nIndex As Long) As Long

Public Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" _
(ByVal hWnd As Long, _
 ByVal nIndex As Long, _
 ByVal dwNewLong As Long) As Long

Public 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 Sub AppTasklist(frmHwnd)
Dim WStyle  As Long
Dim Result  As Long

WStyle = GetWindowLong(frmHwnd, GWL_EXSTYLE)

WStyle = WStyle Or WS_EX_APPWINDOW

Result = SetWindowPos(frmHwnd, HWND_TOP, 0, 0, 0, 0, _
                      SWP_NOMOVE Or _
                      SWP_NOSIZE Or _
                      SWP_NOACTIVATE Or _
                      SWP_HIDEWINDOW)

Result = SetWindowLong(frmHwnd, GWL_EXSTYLE, WStyle)
Debug.Print Result

Result = SetWindowPos(frmHwnd, HWND_TOP, 0, 0, 0, 0, _
                      SWP_NOMOVE Or _
                      SWP_NOSIZE Or _
                      SWP_NOACTIVATE Or _
                      SWP_SHOWWINDOW)


End Sub

这种方法确实有效;我在任务栏中获得了一个专用于表单的图标。但是,任务栏中的图标是标准的Access图标。

为了解决这个问题,我使用SendMessageA添加了另一个API调用:

  

Public Declare Function SendMessage32 Lib" user32"别名_   " SendMessageA" (ByVal hWnd As Long,ByVal wMsg As Long,_ ByVal wParam   作为Long,ByVal lParam As Long)As Long

执行:

Private Const WM_SETICON = &H80
Private Const ICON_SMALL = 0&
Private Const ICON_BIG = 1&

Dim icoPth  As String: icoPth = CurrentProject.Path & "\MyAppIcon.ico"
Dim NewIco  As Long: NewIco = ExtractIcon32(0, icoPth, 0)
Dim frmHwnd As Long: frmHwnd = Me.hwnd 'the form's handle

SendMessage32 frmHwnd, WM_SETICON, ICON_SMALL, NewIco
SendMessage32 frmHwnd, WM_SETICON, ICON_BIG, NewIco

SendMessage32 hWndAccessApp, WM_SETICON, ICON_SMALL, NewIco
SendMessage32 hWndAccessApp, WM_SETICON, ICON_BIG, NewIco

请记住,我已经尝试了以上四行“发送消息”'在AppTasklist Sub内部和外部,顶部和底部的各种顺序无济于事。

它看起来似乎在应用程序级别工作,但它似乎永远不会在表单级别工作。

对于那些熟悉这种特殊困境的人,让我列出一些我尝试过的VBA之外的其他选择。

1。)任务栏\属性\任务栏按钮。我已将此菜单选项更改为“永不合并”。和任务栏已满时组合'。所以,基本上,这确实有效;我现在只获取文件夹和小标签的图标。但是(!),它仅在用户在其末尾检查了这些设置时才有效。根据我的经验,几乎没有人使用任何选项,除了'总是合并,隐藏标签'。

2.。)更改注册表设置。您可以更改以下注册表项以更改应用程序使用的默认图标:" HKEY_CLASSES_ROOT \ Access.Application.14 \ DefaultIcon(默认)。"但是,大多数用户(包括我自己)无法访问注册表的HKEY_CLASSES_ROOT部分。此外,我必须编写一些代码来找到正确的密钥,然后更改它(我可以做)但是,不清楚这种变化是否会立即 - 更不用说我必须退出应用程序时将其更改回来。

3。)右键单击固定的应用程序,然后右键单击菜单中的应用程序会为您提供一个属性菜单,其中包含一个名为“更改图标...”的按钮。在'快捷方式'标签。但是,对于像Access这样的程序,此按钮显示为灰色。

我正在使用Windows 7和Access 2010。

是否可以将上述场景中的任务栏图标强制为标准Access图标以外的其他内容?

我觉得那里有一些我缺少的东西,或者可以使用的API函数,或者更好的SendMessage常量,或者说,它可能不是完成。

非常感谢任何帮助。

另外,作为免责声明(我猜):显然上面的代码是从这个论坛和其他人的其他帖子中提取的。其中大部分都是从我得到的那里获得的。我已经做了一些小小的调整,使其在Access中工作,而不是那些不断进入我的搜索结果的Microsoft软件,所以我不会在这里命名。

谢谢!

1 个答案:

答案 0 :(得分:2)

好。所以我要回答我自己的问题。显然我真正需要的只是从行动中解脱出来并输出我的问题。在我发布问题后的短暂时间内,我重新回到马上并尝试了更多搜索条件。我最终遇到了一篇文章,一开始看起来并不富有成效,因为如果海报和我自己处理相同的情景,我并不清楚。

我在这里找到了答案:

http://www.access-programmers.co.uk/forums/showthread.php?t=231422

首先,您的应用程序必须通过快捷方式打开。对我来说幸运的是,我一直在使用桌面快捷方式。

当我开始构建应用程序时,我从一开始就知道我将使用VBScript来安装应用程序(以及在更新版本发布时进行更新)。在该脚本中,我创建了应用程序的桌面快捷方式,我将其存储在用户的Documents目录中。我还将应用程序图标存储在我附加到应用程序快捷方式的目录中。

如果您从未通过vba / script创建快捷方式,那么您基本上会做这样的事情(用vbScript编写):

Dim WinShell
Dim ShtCut

Set WinShell = CreateObject("WScript.Shell")
Set ShtCut = WinShell.CreateShortcut(strDesktopPath & "\MyCoolApp.lnk")

With ShtCut
     .TargetPath = (See below)
     .Arguments = (See below)
     .IconLocation = ...
     .Desciption = "This is the coolest app, yo!"
     .WorkingDirectory = strAppPath
     .WindowStyle = 1
     .Save
End With

现在,快捷方式的目标开始是这样的:

"C:\Users\UserName\Public\Documents\MyCoolApp\MyCoolApp.accdb"

显然,您的用户可能对文档位置有不同的企业结构...

上面的参考文章建议做的是将该快捷方式转换为伪造的命令行脚本。

要做到这一点:

首先,您的实际目标将成为用户访问版本(运行时或完整版)的路径,如下所示:

"C:\Program Files (x86)\Microsoft Office\Office14\MSACCESS.EXE"

重要!你必须用双引号包装这个目标,即:

.TargetPath = Chr(34) & strAccessPath & Chr(34)

接下来(你在上面的帖子中找不到这个,我不得不弄清楚),你需要将Argument设置为应用程序的目录,如:

"C:\Users\UserName\Public\Documents\MyCoolApp\MyCoolApp.accdb"

重要!同样,你必须用双引号包装参数,即:

.Arguments = Chr(34) & strAppPath & Chr(34)

同样重要的是,我希望你的应用很酷。

设置此快捷方式后,基本上您可以创建此快捷方式,以便您的应用程序在任务栏上拥有自己的工作组。即,如果Access一般是打开的,那么您的应用程序将在任务栏上拥有它自己的组。该群组将为您提供酷炫的自定义图标。作为一个巨大的意外奖励,您可以将快捷方式固定到Access之外的任务栏。 SWEEEEEET!

祝你好运!