Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Application, Hidden Application Window With Form Taskbar Icon

Tags:

vba

api

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.

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.

I found an API workaround that will show an icon in the taskbar for just the form. It goes a little something like this:

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.

In response to this problem, I added another API call using the SendMessageA:

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

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.

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.

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'.

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.

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.

I am using Windows 7 and 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.

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.

Thanks!

like image 781
Brandon Meyer Avatar asked Oct 27 '14 18:10

Brandon Meyer


People also ask

How do I get the hidden icons back on my taskbar?

Press and hold or right-click any empty space on the taskbar and select Taskbar settings. Under Taskbar corner icons: Select On for any icons you want to see on the taskbar. Select Off for any icons you don't want to see on the taskbar.

How do I show hidden icons on taskbar Windows 11?

You can find hidden icons by clicking the up arrow icon in the taskbar notification area. The flyout menu that displays hidden icons is the taskbar corner overflow menu.

How do I change the icon on an Access form?

In the Forms Designer, click the Properties page. Click Change Large Icon or Change Small Icon. Select the icon that you want to use and then click Open.

What is the use of this icon on the taskbar?

Clicking these icons allow the user to easily switch between programs or windows, with the currently active program or window usually appearing differently from the rest. In more recent versions of operating systems, users can also "pin" programs or files so that they can be accessed quickly, often with a single click.


1 Answers

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

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.

If you've never created a shortcut via vba/script, you'll essentially do something like this (written in 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...

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:

"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!

Good luck!

like image 86
Brandon Meyer Avatar answered Oct 02 '22 05:10

Brandon Meyer