Microsoft Access Team made an interesting post and a follow-up on how to add a transparent layer that cover the screen to focus the attention of the user to a login form or other important popup window.
The trick is to use some WIN 32 API calls to modify the transparency of a standard MS Access form made to cover the screen.
The effect is quite neat and I thought I would try it and make a sample database for others to tinker with it.
My version allows you to chose between covering the whole screen or just the main Access window and it will test if it’s running under a Remote Desktop Terminal and disable the layer in that case.
###Update 07MAY2008###
Following Rob’s improvements I made another sample database that incorporates his code with a few improvements:
* I added the LightBoxForm.LayerToFullScreen
property so users can choose explicitly how they want the layer to be shown.
* I moved the code to hide the layer into a Hide() sub so you can just show/hide the layer using LightboxForm.Show
and LightboxForm.Hide
.
* I changed the Form’s Resize
event code in the `LightBoxForm` class to avoid flickering: resizing the form within its `Resize` event actually trigger the `Resize` event again a second time which causes flickering.
I simply modified the code to make the form totally transparent (opacity of 0) the first time the event is fired and assign it the expected opacity when the event handler in re-entered.
~~~~brush:vb
‘—————————————————————————–
‘ Handle the Layer Form Resize event
‘—————————————————————————–
Private Sub m_objForm_Resize()
Static busyResizing As Boolean
Dim lngStyle As Long
Dim r As RECT
‘ disable screen updates
m_objForm.Painting = False
‘ When the form opens initially, we make it totally transparent to avoid flickering
lngStyle = GetWindowLong(m_objForm.hWnd, GWL_EXSTYLE)
SetWindowLong m_objForm.hWnd, GWL_EXSTYLE, lngStyle Or WS_EX_LAYERED
SetLayeredWindowAttributes m_objForm.hWnd, 0, 0, LWA_ALPHA
‘ If the Access window is maximized, then maximize the lightbox form.
‘ If the Access window is not maximized, then
‘ position the lightbox form so that it covers the Access window
If IsZoomed(hWndAccessApp()) Or m_bLayerToFullScreen Then
DoCmd.Maximize
Else
GetWindowRect Application.hWndAccessApp(), r
MoveWindow m_objForm.hWnd, r.x1, r.y1, (r.x2 – r.x1), (r.y2 – r.y1), True
End If
If busyResizing Then
‘ Get the current window style, then set transparency
lngStyle = GetWindowLong(m_objForm.hWnd, GWL_EXSTYLE)
SetWindowLong m_objForm.hWnd, GWL_EXSTYLE, lngStyle Or WS_EX_LAYERED
SetLayeredWindowAttributes m_objForm.hWnd, 0, (m_sngOpacity * 255), LWA_ALPHA
‘ enable screen updates
m_objForm.Painting = True
‘ Back to normal
busyResizing = False
Else
busyResizing = True
End If
End Sub
~~~~
###Samples###
There are now 2 sample databases. Ech zip contains a Microsoft Access 2007 ACCDB file and its conversion to Access 2000[^1] and Access 2002-2003 MDB but please note that I have not been been able to test those in older version of Access and that form transparency doesn’t work in Operating Systems older than Windows 2000.
Download TransparentLayer02b.zip (138KB), recommended version
(improved, more flexible version, based on Rob’s updated article).
Download TransparentLayer01b.zip (122KB), original version
(simple code, based Rob’s original article).
###Troubleshooting###
* _If you are getting security warnings:_ make sure that you open the database from a Trusted Location or you will receive a security prompt.
If you don’t know how to do that, check these steps.
* _If the layer appears on top of the login form instead of behind:_ make sure that the top-most form has ist Modal
properties set to `Yes` and the `frmLightBox` form has its modal property set to `No`.
If you improve on it, please let me know and I’ll post it here for all to find.
[^1]: A specific version for Access 2000 now included in the archive (updated 25JUL2008).
Comments
Thanks for posting the demo!
I have a small question, why a class module? It just work with the old module like in example #1 Why complicate your life by using a class module, for my experience the purpose of the class module is to expose functionality of your project outside your project, but why to this simple code. I will appreciate if you really explain. By the way, great work, i will definetly use this in my projects.
Im curious: what editor you use for the vba editor that shows the line numbers and that alternate row hightlight. It looks very nice and atractive to work on that 🙂 Please share . . .
@Edwin: I agree that the version with the Class is actually a bit more complex but it’s still quite educational and it nicely encapsulate the functionality. You end-up using only one global property (LightboxForm) to manage all layer functions. Whether you prefer one version or the other is up to you, that’s why I left both samples. Regarding the colour formatting of the code, I’m afraid that it just looks that way because I use a code syntax highlighter in my web pages…
Thanks for your answer, i was reading the comments on microsoft rss, and i think you are the appropiate guy so i can ask this question. I used to have code from lebans.com to highlight the current row in datasheet or continuos form, also to highlight the row based on some conditions, (the access embeed conditional format only supports 3) lebans created a solution for this, but now is outdated, i think you can revise the api’s and create a new solution(maybe give it to microsoft 🙂 ) The thing is that if you look into excel you have a great conditional formatting options even with icons and all that stuff, but that doesnt exist for excel. What do you say, can you do it?
Hi Edwin. Thanks for the vote of confidence 🙂 I’ll look into Stephan Leban’s code and see if there is something to expand on there. The issue with taking row highlighting and conditional formatting further is that Access doesn’t expose a lot of its internal functionalities. One of the problems is that controls like textboxes are not really normal windows controls (with a few exceptions). These lightweight controls are rendered internally by Access as images on the form until the focus moves to them. The OnPaint event is also fairly limited and only exists at the form section level and not the control level. So extending Access’ behaviour in that regard is probably too hard to be worth the time, especially when you consider that whatever you do may be rendered useless or incompatible by the next version of Access. Also to consider is that when more features are needed, it is probably better and easier to just include managed components in your forms: with the Form Interop Toolkit you can use .Net controls in Access. It requires some work and it’s not as tightly integrated or as easy as I’d want but it’s possible. By doing that you could include just about anything in your forms, and you open your application to a world of more interesting controls than the limited ones provided in Access. I plan to make a series of articles on that subject in the next few weeks.
Both options fade the whole screen on my Vista SP1 machine. Nice Gentoo logo placement
@Phil: I can’t replicate that behaviour on Vista and the main sample database included in this page seems to be working fine for me. Did you try the sample databases or did you implement it yourself? Have you found where the issue could come from? I’d like to know if this is really a bug or something else.
Renaud . . . i have 2 questions. a) did you saw lebans code for conditional formmating? b) i love excel conditional formatting specially with the icons and all that stuff . . ., do you think we can use that in access 2007?
Hi, It is not possible to open the database with Access 2000…
Hi Olcay, this is now fixed. I have included a specific version for Access 2000. Any issue please let me know.
Hi Renaud, Version 2000 works fine…Thanks…
Hi, Is it possible to have the layer just fill a form on a database which has the Access Window hidden? That is to say just the visible form greyed out while a smaller popup > modal is open? Thanks, Garry
@good job there, the tool works fine… one thing is to remark… the obvious mistake mistake(error) of ACC on the command “hide” and “show” window….it will cause that the main window is getting wider then the actual screen… obviously ACC is extent the screen to double the area and move the hidden MAIN window in this area… my suggestion is : Declare Function ShowWindow Lib “user32” _ (ByVal hWnd As Long, ByVal nCmdShow As Long) _ As Long Function AccessMaximize() Dim ma% ma% = ShowWindow(hWndAccessApp, 2) End Function ‘0 = Hide ‘1 = Restore ‘2 = Minimize ‘3 = Maximize kind regards from Germany mfg Dieter
me again, sorry accidentally clicked to fast on the cmdbuttom submit.. well the function above is one way and needs to be placed in the “open event” … the code below is a nother way to hide and show the main window…. btw. be aware, that u need to place function to make the main window visible again… otherwise u wont have any main ACC window anymore…. here is another code to realize it …. based on the same API Option Compare Database Option Explicit ‘Das wirklich komplette Ausblenden geht mit API. ‘Im Deklarationsbereich des Formularmodules in deinem Übersichtsformular: Const SW_HIDE = 0 ‘in A00 ist dazu noch nötig: Const SW_NORMAL = 1 Private Declare Function ShowWindow Lib “user32” _ (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long ‘In der Öffnen-Sub deines Übersichtsformulares: ‘open a sub in ur main form Private Sub Form_Open(Cancel As Integer) Dim hWindow As Long Dim nResult As Long Dim nCmdShow As Long hWindow = Application.hWndAccessApp nCmdShow = SW_HIDE nResult = ShowWindow(ByVal hWindow, ByVal nCmdShow) 'in A00 ist dazu noch nötig: ' ONLY in ACC 2000 u additional need : Call ShowWindow(Me.hwnd, SW_NORMAL) End Sub ‘ Code to reactivate the Main ACC window placed on close in the START Form Private Sub Form_Close() Dim hWindow As Long Dim nResult As Long Dim nCmdShow As Long hWindow = Application.hWndAccessApp nCmdShow = SW_NORMAL nResult = ShowWindow(ByVal hWindow, ByVal nCmdShow) End Sub EFFECT: the develop View responds normal
Hi, thanks for this great tip, Have a question regards Form resize event. Am trying to capture Access Main window resize event, and move a custom command bar on statusbar. I have done some work with API, but the event and coordinates are difficult and get out of screen when move my frmStatusBar accordingly. Do You have a suggestion regarding this?! Regards, Justin
Dude your work is amazing!! I have been working as access developer for just short of three years now and i thought i has learnt everything possible but u have showed me other wise. I have a question – will the transparent background work in runtime version? i am referring to run time 2007
hi, i used this sample on access 2010 and two mode viewed full screen mod. main access windows code dosn’t run. please correct!
Awesome work. I changed m_lngBackColor = vbBlack to m_lngBackColor = vbred in my application….sweeeeeet!
I have the French version of access 2013 and the database refuses to open after implementing the transparent layer. However it worked nicely on the english version of access 2016 version. I was wondering if you have tested it on other languages versions of access.
Thank you very much, its awesome
Comments are closed.