vba 访问应用程序,带有表单任务栏图标的隐藏应用程序窗口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26594043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Access Application, Hidden Application Window With Form Taskbar Icon
提问by Brandon Meyer
I have an access application with one main form. When you open the application, an AutoExec macro hides the application via the Windows API apiShowWindow. Then, the AutoExec opens up the main form which is set to Popup. This all works beautifully; my database guts are hidden and the form opens up and just floats along.
我有一个带有一个主表单的访问应用程序。当您打开应用程序时,AutoExec 宏通过 Windows API apiShowWindow 隐藏应用程序。然后,AutoExec 打开设置为 Popup 的主窗体。这一切都很好;我的数据库胆量被隐藏,表单打开并漂浮。
However, when the access database gets hidden, you loose the taskbar icon. I have a custom icon set in the Options\Current Database\Application Icon setting. If I don't hide the database, this icon displays just fine in the task bar.
但是,当访问数据库被隐藏时,您会丢失任务栏图标。我在 Options\Current Database\Application Icon 设置中设置了一个自定义图标。如果我不隐藏数据库,此图标在任务栏中显示得很好。
I found an API workaround that will show an icon in the taskbar for just the form. It goes a little something like this:
我找到了一个 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
This approach does work; I get an icon in the taskbar dedicated to just the form. However, the icon in the taskbar is the standard Access icon.
这种方法确实有效;我在任务栏中得到一个专门用于表单的图标。但是,任务栏中的图标是标准的 Access 图标。
In response to this problem, I added another API call using the SendMessageA:
针对这个问题,我使用 SendMessageA 添加了另一个 API 调用:
Public Declare Function SendMessage32 Lib "user32" Alias _ "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long
公共声明函数 SendMessage32 Lib "user32" 别名 _ "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long
Executed thus:
如此执行:
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
Keep in mind that I have tried the above four lines of 'SendMessages' in various orders inside of and outside of, top of and bottom of the AppTasklist Sub to no avail.
请记住,我已经在 AppTasklist Sub 内部和外部、顶部和底部的各种顺序中尝试了上述四行“SendMessages”,但均无济于事。
It does appear to work at the application level, but it never seems to work at the form level.
它似乎在应用程序级别工作,但它似乎永远不会在表单级别工作。
For those of you familiar with this particular predicament, let me list some of the other options outside of VBA that I have tried.
对于熟悉这种特殊困境的人,让我列出一些我尝试过的 VBA 之外的其他选项。
1.) Taskbar\Properties\Taskbar buttons. I've changed this menu option to 'Never Combine' and 'Combine When Taskbar Is Full'. So, basically, this does work; I now get my icon for just the folder and the little label. BUT(!), it only works if the users have these settings checked on their end. In my experience, almost no one uses any of the options except 'Always combine, hide labels'.
1.) 任务栏\属性\任务栏按钮。我已将此菜单选项更改为“从不合并”和“任务栏已满时合并”。所以,基本上,这确实有效;我现在只得到文件夹和小标签的图标。但是(!),只有当用户在他们的最后检查这些设置时才有效。根据我的经验,除了“始终合并、隐藏标签”之外,几乎没有人使用任何选项。
2.) Changing the Registry settings. You can change the following registry key to change the default icon an application uses: "HKEY_CLASSES_ROOT\Access.Application.14\DefaultIcon(Default)." However, most users (myself included) don't have access to the HKEY_CLASSES_ROOT part of the registry. Furthermore, I would have to write some code to find the proper key and then change it (which I could do) but, it's unclear if this change would be immediate--not to mention I'd have to change it back when exiting the application.
2.) 更改注册表设置。您可以更改以下注册表项以更改应用程序使用的默认图标:“HKEY_CLASSES_ROOT\Access.Application.14\DefaultIcon(Default)”。但是,大多数用户(包括我自己)无权访问注册表的 HKEY_CLASSES_ROOT 部分。此外,我将不得不编写一些代码来找到正确的密钥,然后更改它(我可以这样做)但是,目前尚不清楚这种更改是否会立即生效——更不用说我在退出时必须将其更改回来应用。
3.) Right-clicking the pinned application, then right clicking the application in the menu does give you a properties menu with a button called 'Change Icon...' in the 'Shortcut' tab. However, for a program like Access, this button is greyed out.
3.) 右键单击固定的应用程序,然后右键单击菜单中的应用程序确实会为您提供一个属性菜单,其中包含“快捷方式”选项卡中名为“更改图标...”的按钮。但是,对于像 Access 这样的程序,这个按钮是灰色的。
I am using Windows 7 and Access 2010.
我使用的是 Windows 7 和 Access 2010。
Is it possible to force the Taskbar Icon in the above scenario to something other than the standard Access Icon?
是否可以将上述场景中的任务栏图标强制为标准访问图标以外的其他图标?
I feel like there's ether a little something I'm missing, or an API function that could be used, or a better SendMessage constant, or that, maybe, it just can't be done.
我觉得我缺少一些东西,或者可以使用的 API 函数,或者更好的 SendMessage 常量,或者,也许,它只是无法完成。
Any help would be greatly appreciated.
任何帮助将不胜感激。
Also, as a disclaimer (I guess): obviously the above code was pulled from other posts from this forum and others. Most of it was unattributed from whence I got it. I've made some minor tweeks to make it work in Access as opposed to that other piece of Microsoft Software that keeps getting in my search results so I will not name it here.
另外,作为免责声明(我猜):显然上面的代码是从这个论坛和其他人的其他帖子中提取的。大部分都没有归属于我从哪里得到它。我做了一些小调整,让它在 Access 中工作,而不是不断出现在我的搜索结果中的其他 Microsoft 软件,所以我不会在这里命名它。
Thanks!
谢谢!
回答by Brandon Meyer
Okay. So I'm going to answer my own question. Apparently all I really needed was a break from the action and to type out my problem. A short time after I posted the question, I got back on the horse and tried some more search terms. I eventually came across a post which really didn't seem fruitfull at the outset because it wasn't clear to me if the poster and myself were dealing with the same scenario.
好的。所以我要回答我自己的问题。显然,我真正需要的只是从行动中休息一下并写出我的问题。在我发布问题后不久,我重新开始并尝试了更多搜索词。我最终遇到了一个帖子,一开始看起来确实没有成果,因为我不清楚海报和我自己是否正在处理相同的场景。
I found my answer here:
我在这里找到了答案:
http://www.access-programmers.co.uk/forums/showthread.php?t=231422
http://www.access-programmers.co.uk/forums/showthread.php?t=231422
First off, your application must open via a shortcut. Fortunately for me, I've been using a Desktop shortcut from the begining.
首先,您的应用程序必须通过快捷方式打开。对我来说幸运的是,我从一开始就一直在使用桌面快捷方式。
When I started building the application, I knew from the outset that I would be using a VBScript to do the installation of the application (as well as updating when a newer version get's released). In that script, I create a Desktop shortcut to the application which I store in the user's Documents directory. I also store the application icon in that directory which I attach to the application shortcut.
当我开始构建应用程序时,我从一开始就知道我将使用 VBScript 来安装应用程序(以及在发布新版本时进行更新)。在该脚本中,我为应用程序创建了一个桌面快捷方式,并将其存储在用户的 Documents 目录中。我还将应用程序图标存储在我附加到应用程序快捷方式的那个目录中。
If you've never created a shortcut via vba/script, you'll essentially do something like this (written in vbScript):
如果你从来没有通过 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
Now, the target of the shortcut started out being something like this:
现在,快捷方式的目标开始是这样的:
"C:\Users\UserName\Public\Documents\MyCoolApp\MyCoolApp.accdb"
Obviously your users may have a different enterprise structure for the Documents location...
显然,您的用户可能对 Documents 位置具有不同的企业结构...
What the above reference post suggests doing is turning that shortcut into a psuedo command line script.
上面的参考帖子建议做的是将该快捷方式转换为伪命令行脚本。
To do this:
去做这个:
First, your actual target is going to be the path to the user's version of access (Runtime or full), like such:
首先,您的实际目标将是用户访问版本(运行时或完整)的路径,如下所示:
"C:\Program Files (x86)\Microsoft Office\Office14\MSACCESS.EXE"
IMPORTANT! You will have to wrap this target in double-quotes, i.e.:
重要的!您必须将此目标用双引号括起来,即:
.TargetPath = Chr(34) & strAccessPath & Chr(34)
Next (and you won't find this in the above post, I had to figure it out), you'll need to set the Argument to the directory of the application, like such:
接下来(你不会在上面的帖子中找到这个,我必须弄清楚),你需要将 Argument 设置为应用程序的目录,如下所示:
"C:\Users\UserName\Public\Documents\MyCoolApp\MyCoolApp.accdb"
IMPORTANT! Again, you'll have to wrap the arguments in double-quotes, i.e.:
重要的!同样,您必须将参数用双引号括起来,即:
.Arguments = Chr(34) & strAppPath & Chr(34)
Also important, I hope your app IS cool.
同样重要的是,我希望你的应用很酷。
Once you have this shortcut set up, essentially you're making it so your application will have it's own workgroup on the taskbar. I.e., if Access is open in general, your application will have it's own group on the taskbar. This group will have your cool, custom icon associated with it. And as a huge unexpected bonus, you'll be able to pin your shortcut to the taskbar outside of Access. SWEEEEEET!
一旦你设置了这个快捷方式,本质上你就是在制作它,这样你的应用程序将在任务栏上拥有它自己的工作组。即,如果 Access 通常是打开的,您的应用程序将在任务栏上拥有它自己的组。该组将拥有与之关联的酷炫自定义图标。作为一个巨大的意外奖励,您将能够将快捷方式固定到 Access 之外的任务栏。亲爱的!
Good luck!
祝你好运!