MS Access: Modal Dialogs with Transparent Backgrounds (redux)

Thursday, May 1, 2008

Microsoft Access 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.

The transparent layer covering the main Window onlyThe transparent layer covering the full screen

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

DownloadDownload TransparentLayer02b.zip (138KB), recommended version
(improved, more flexible version, based on Rob’s updated article).

DownloadDownload 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). 

Entry Filed under  :  Database,MSAccess,Programming

19 Comments Add your own

  • 1. Fred Boer  |  May 8th, 2008 at 2:03 am

    Thanks for posting the demo!

  • 2. Edwin Blancovitch  |  May 8th, 2008 at 11:37 pm

    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.

  • 3. Edwin Blancovitch  |  May 8th, 2008 at 11:43 pm

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

  • 4. Renaud  |  May 9th, 2008 at 7:47 am

    @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…

  • 5. Edwin Blancovitch  |  May 13th, 2008 at 12:20 am

    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?

  • 6. Renaud  |  May 13th, 2008 at 10:00 am

    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.

  • 7. Phil  |  May 16th, 2008 at 1:33 am

    Both options fade the whole screen on my Vista SP1 machine.

    Nice Gentoo logo placement

  • 8. Renaud  |  May 18th, 2008 at 7:08 pm

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

  • 9. Edwin Blancovitch  |  June 5th, 2008 at 4:52 am

    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?

  • 10. Olcay Misirlioglu  |  July 25th, 2008 at 1:03 pm

    Hi, It is not possible to open the database with Access 2000…

  • 11. Renaud  |  July 25th, 2008 at 1:54 pm

    Hi Olcay, this is now fixed. I have included a specific version for Access 2000. Any issue please let me know.

  • 12. Olcay Misirlioglu  |  July 25th, 2008 at 2:13 pm

    Hi Renaud,

    Version 2000 works fine…Thanks…

  • 13. Garry  |  January 15th, 2009 at 8:35 pm

    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

  • 14. HellsBells  |  November 26th, 2009 at 4:09 pm

    @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

  • 15. BellsBells  |  November 26th, 2009 at 4:28 pm

    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

  • 16. Justin  |  August 8th, 2011 at 4:31 pm

    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

  • 17. Stephen Poynter  |  August 25th, 2011 at 7:45 pm

    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

  • 18. mehemt  |  April 2nd, 2012 at 9:20 am

    hi,

    i used this sample on access 2010 and two mode viewed full screen mod.

    main access windows code dosn’t run.

    please correct!

  • 19. Michael  |  July 26th, 2012 at 3:51 pm

    Awesome work. I changed m_lngBackColor = vbBlack to m_lngBackColor = vbred in my application….sweeeeeet!

Leave a Comment

(Will not be shown)
Notify me of follow-up comments via e-mail

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


about

Renaud This is a simple technical weblog where I dump thoughts and experiences from my computer-related world.
It is mostly focused on software development but I also have wider interests and dabble in architecture, business and system administration.
More About me…

My StackOverflow Profile
My (sporadically active) StackOVerflow account

Most Recent Posts

Categories

Links